annotate ui/AmrUiScrollFrame.lua @ 201:3447634f0388 tip

Added tag v97 for changeset 6e8838b231d4
author Yellowfive
date Wed, 13 Jan 2021 13:12:13 -0600
parents a0894ffebd15
children
rev   line source
yellowfive@57 1 --[[-----------------------------------------------------------------------------
yellowfive@57 2 ScrollFrame Container
yellowfive@57 3 Plain container that scrolls its content and doesn't grow in height.
yellowfive@57 4 Based on AceGUI ScrollFrame, but with a custom scrollbar look.
yellowfive@57 5 -------------------------------------------------------------------------------]]
yellowfive@57 6 local Type, Version = "AmrUiScrollFrame", 1
yellowfive@57 7 local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
yellowfive@57 8 if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
yellowfive@57 9
yellowfive@57 10 local Amr = LibStub("AceAddon-3.0"):GetAddon("AskMrRobot")
yellowfive@57 11
yellowfive@57 12 -- Lua APIs
yellowfive@57 13 local pairs, assert, type = pairs, assert, type
yellowfive@133 14 local min, max, floor = math.min, math.max, math.floor
yellowfive@57 15
yellowfive@57 16 -- WoW APIs
yellowfive@57 17 local CreateFrame, UIParent = CreateFrame, UIParent
yellowfive@57 18
yellowfive@57 19 --[[-----------------------------------------------------------------------------
yellowfive@57 20 Support functions
yellowfive@57 21 -------------------------------------------------------------------------------]]
yellowfive@57 22 local function FixScrollOnUpdate(frame)
yellowfive@57 23 frame:SetScript("OnUpdate", nil)
yellowfive@57 24 frame.obj:FixScroll()
yellowfive@57 25 end
yellowfive@57 26
yellowfive@57 27 --[[-----------------------------------------------------------------------------
yellowfive@57 28 Scripts
yellowfive@57 29 -------------------------------------------------------------------------------]]
yellowfive@57 30 local function ScrollFrame_OnMouseWheel(frame, value)
yellowfive@57 31 frame.obj:MoveScroll(value)
yellowfive@57 32 end
yellowfive@57 33
yellowfive@57 34 local function ScrollFrame_OnSizeChanged(frame)
yellowfive@57 35 frame:SetScript("OnUpdate", FixScrollOnUpdate)
yellowfive@57 36 end
yellowfive@57 37
yellowfive@57 38 local function ScrollBar_OnScrollValueChanged(frame, value)
yellowfive@57 39 frame.obj:SetScroll(value)
yellowfive@57 40 end
yellowfive@57 41
yellowfive@57 42 local function ScrollBar_UpArrowClick(frame)
yellowfive@57 43 frame.obj:MoveScroll(50)
yellowfive@57 44 end
yellowfive@57 45
yellowfive@57 46 local function ScrollBar_DownArrowClick(frame)
yellowfive@57 47 frame.obj:MoveScroll(-50)
yellowfive@57 48 end
yellowfive@57 49
yellowfive@57 50 --[[-----------------------------------------------------------------------------
yellowfive@57 51 Methods
yellowfive@57 52 -------------------------------------------------------------------------------]]
yellowfive@57 53 local methods = {
yellowfive@57 54 ["OnAcquire"] = function(self)
yellowfive@57 55 self:SetScroll(0)
yellowfive@57 56 self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
yellowfive@57 57 end,
yellowfive@57 58
yellowfive@57 59 ["OnRelease"] = function(self)
yellowfive@57 60 self.status = nil
yellowfive@57 61 for k in pairs(self.localstatus) do
yellowfive@57 62 self.localstatus[k] = nil
yellowfive@57 63 end
yellowfive@57 64 self.scrollframe:SetPoint("BOTTOMRIGHT")
yellowfive@57 65 self.scrollbar:Hide()
yellowfive@57 66 self.uparrow:Hide()
yellowfive@57 67 self.downarrow:Hide()
yellowfive@57 68 self.scrollBarShown = nil
yellowfive@57 69 self.content.height, self.content.width = nil, nil
yellowfive@57 70 end,
yellowfive@57 71
yellowfive@57 72 ["SetScroll"] = function(self, value)
yellowfive@57 73 local status = self.status or self.localstatus
yellowfive@57 74 local viewheight = self.scrollframe:GetHeight()
yellowfive@57 75 local height = self.content:GetHeight()
yellowfive@57 76 local offset
yellowfive@57 77
yellowfive@57 78 if viewheight > height then
yellowfive@57 79 offset = 0
yellowfive@57 80 else
yellowfive@57 81 offset = floor((height - viewheight) / 1000.0 * value)
yellowfive@57 82 end
yellowfive@57 83 self.content:ClearAllPoints()
yellowfive@57 84 self.content:SetPoint("TOPLEFT", 0, offset)
yellowfive@57 85 self.content:SetPoint("TOPRIGHT", 0, offset)
yellowfive@57 86 status.offset = offset
yellowfive@57 87 status.scrollvalue = value
yellowfive@57 88 end,
yellowfive@57 89
yellowfive@57 90 ["MoveScroll"] = function(self, value)
yellowfive@57 91 local status = self.status or self.localstatus
yellowfive@57 92 local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
yellowfive@57 93
yellowfive@57 94 if self.scrollBarShown then
yellowfive@57 95 local diff = height - viewheight
yellowfive@57 96 local delta = 1
yellowfive@57 97 if value < 0 then
yellowfive@57 98 delta = -1
yellowfive@57 99 end
yellowfive@57 100 self.scrollbar:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
yellowfive@57 101 end
yellowfive@57 102 end,
yellowfive@57 103
yellowfive@57 104 ["FixScroll"] = function(self)
yellowfive@57 105 if self.updateLock then return end
yellowfive@57 106 self.updateLock = true
yellowfive@57 107 local status = self.status or self.localstatus
yellowfive@57 108 local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
yellowfive@57 109 local offset = status.offset or 0
yellowfive@133 110 --local curvalue = self.scrollbar:GetValue()
yellowfive@57 111 -- Give us a margin of error of 2 pixels to stop some conditions that i would blame on floating point inaccuracys
yellowfive@57 112 -- No-one is going to miss 2 pixels at the bottom of the frame, anyhow!
yellowfive@57 113 if viewheight < height + 2 then
yellowfive@57 114 if self.scrollBarShown then
yellowfive@57 115 self.scrollBarShown = nil
yellowfive@57 116 self.scrollbar:Hide()
yellowfive@57 117 self.uparrow:Hide()
yellowfive@57 118 self.downarrow:Hide()
yellowfive@57 119 self.scrollbar:SetValue(0)
yellowfive@57 120 self.scrollframe:SetPoint("BOTTOMRIGHT")
yellowfive@57 121 self:DoLayout()
yellowfive@57 122 end
yellowfive@57 123 else
yellowfive@57 124 if not self.scrollBarShown then
yellowfive@57 125 self.scrollBarShown = true
yellowfive@57 126 self.scrollbar:Show()
yellowfive@57 127 self.uparrow:Show()
yellowfive@57 128 self.downarrow:Show()
yellowfive@57 129 self.scrollframe:SetPoint("BOTTOMRIGHT", -20, 0)
yellowfive@57 130 self:DoLayout()
yellowfive@57 131 end
yellowfive@57 132 local value = (offset / (viewheight - height) * 1000)
yellowfive@57 133 if value > 1000 then value = 1000 end
yellowfive@57 134 self.scrollbar:SetValue(value)
yellowfive@57 135 self:SetScroll(value)
yellowfive@57 136 if value < 1000 then
yellowfive@57 137 self.content:ClearAllPoints()
yellowfive@57 138 self.content:SetPoint("TOPLEFT", 0, offset)
yellowfive@57 139 self.content:SetPoint("TOPRIGHT", 0, offset)
yellowfive@57 140 status.offset = offset
yellowfive@57 141 end
yellowfive@57 142 end
yellowfive@57 143 self.updateLock = nil
yellowfive@57 144 end,
yellowfive@57 145
yellowfive@57 146 ["LayoutFinished"] = function(self, width, height)
yellowfive@57 147 self.content:SetHeight(height or 0 + 20)
yellowfive@57 148 self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
yellowfive@57 149 end,
yellowfive@57 150
yellowfive@57 151 ["SetStatusTable"] = function(self, status)
yellowfive@57 152 assert(type(status) == "table")
yellowfive@57 153 self.status = status
yellowfive@57 154 if not status.scrollvalue then
yellowfive@57 155 status.scrollvalue = 0
yellowfive@57 156 end
yellowfive@57 157 end,
yellowfive@57 158
yellowfive@57 159 ["OnWidthSet"] = function(self, width)
yellowfive@57 160 local content = self.content
yellowfive@57 161 content.width = width
yellowfive@57 162 end,
yellowfive@57 163
yellowfive@57 164 ["OnHeightSet"] = function(self, height)
yellowfive@57 165 local content = self.content
yellowfive@57 166 content.height = height
yellowfive@57 167 end
yellowfive@57 168 }
yellowfive@57 169 --[[-----------------------------------------------------------------------------
yellowfive@57 170 Constructor
yellowfive@57 171 -------------------------------------------------------------------------------]]
yellowfive@57 172 local function Constructor()
yellowfive@57 173 local frame = CreateFrame("Frame", nil, UIParent)
yellowfive@57 174 local num = AceGUI:GetNextWidgetNum(Type)
yellowfive@57 175
yellowfive@57 176 local scrollframe = CreateFrame("ScrollFrame", nil, frame)
yellowfive@57 177 scrollframe:SetPoint("TOPLEFT")
yellowfive@57 178 scrollframe:SetPoint("BOTTOMRIGHT")
yellowfive@57 179 scrollframe:EnableMouseWheel(true)
yellowfive@57 180 scrollframe:SetScript("OnMouseWheel", ScrollFrame_OnMouseWheel)
yellowfive@57 181 scrollframe:SetScript("OnSizeChanged", ScrollFrame_OnSizeChanged)
yellowfive@57 182
yellowfive@57 183 local scrollbar = CreateFrame("Slider", ("AmrUiScrollFrame%dScrollBar"):format(num), scrollframe)
yellowfive@57 184 scrollbar:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, -16)
yellowfive@57 185 scrollbar:SetPoint("BOTTOMLEFT", scrollframe, "BOTTOMRIGHT", 4, 16)
yellowfive@57 186 scrollbar:SetMinMaxValues(0, 1000)
yellowfive@57 187 scrollbar:SetValueStep(1)
yellowfive@57 188 scrollbar:SetValue(0)
yellowfive@57 189 scrollbar:SetWidth(16)
yellowfive@57 190 scrollbar:Hide()
yellowfive@57 191
yellowfive@57 192 local thumb = Amr.CreateTexture(scrollbar, Amr.Colors.Gray)
yellowfive@57 193 thumb:SetWidth(16)
yellowfive@57 194 thumb:SetHeight(32)
yellowfive@57 195 scrollbar:SetThumbTexture(thumb)
yellowfive@57 196
yellowfive@57 197 local uparrow = CreateFrame("Button", nil, frame)
yellowfive@57 198 uparrow:SetWidth(16)
yellowfive@57 199 uparrow:SetHeight(16)
yellowfive@57 200
yellowfive@57 201 local tex = uparrow:CreateTexture()
yellowfive@57 202 tex:SetWidth(16)
yellowfive@57 203 tex:SetHeight(16)
yellowfive@57 204 tex:SetTexture("Interface\\AddOns\\" .. Amr.ADDON_NAME .. "\\Media\\IconScrollUp")
yellowfive@57 205 tex:SetPoint("LEFT", uparrow, "LEFT")
yellowfive@57 206 uparrow:SetNormalTexture(tex)
yellowfive@57 207
yellowfive@57 208 uparrow:SetPoint("BOTTOMRIGHT", scrollbar, "TOPRIGHT")
yellowfive@57 209 uparrow:SetScript("OnClick", ScrollBar_UpArrowClick)
yellowfive@57 210 uparrow:Hide()
yellowfive@57 211
yellowfive@57 212 local downarrow = CreateFrame("Button", nil, frame)
yellowfive@57 213 downarrow:SetWidth(16)
yellowfive@57 214 downarrow:SetHeight(16)
yellowfive@57 215
yellowfive@57 216 tex = downarrow:CreateTexture()
yellowfive@57 217 tex:SetWidth(16)
yellowfive@57 218 tex:SetHeight(16)
yellowfive@57 219 tex:SetTexture("Interface\\AddOns\\" .. Amr.ADDON_NAME .. "\\Media\\IconScrollDown")
yellowfive@57 220 tex:SetPoint("LEFT", downarrow, "LEFT")
yellowfive@57 221 downarrow:SetNormalTexture(tex)
yellowfive@57 222
yellowfive@57 223 downarrow:SetPoint("TOPRIGHT", scrollbar, "BOTTOMRIGHT")
yellowfive@57 224 downarrow:SetScript("OnClick", ScrollBar_DownArrowClick)
yellowfive@57 225 downarrow:Hide()
yellowfive@57 226
yellowfive@57 227 -- set the script as the last step, so it doesn't fire yet
yellowfive@57 228 scrollbar:SetScript("OnValueChanged", ScrollBar_OnScrollValueChanged)
yellowfive@57 229
yellowfive@57 230 local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
yellowfive@57 231 scrollbg:SetPoint("TOPLEFT", scrollbar, "TOPLEFT", 0, 16)
yellowfive@57 232 scrollbg:SetPoint("BOTTOMRIGHT", scrollbar, "BOTTOMRIGHT", 0, -16)
yellowfive@81 233 scrollbg:SetColorTexture(0, 0, 0, 0.3)
yellowfive@57 234
yellowfive@57 235 --Container Support
yellowfive@57 236 local content = CreateFrame("Frame", nil, scrollframe)
yellowfive@57 237 content:SetPoint("TOPLEFT")
yellowfive@57 238 content:SetPoint("TOPRIGHT")
yellowfive@57 239 content:SetHeight(400)
yellowfive@57 240 scrollframe:SetScrollChild(content)
yellowfive@57 241
yellowfive@57 242 local widget = {
yellowfive@57 243 localstatus = { scrollvalue = 0 },
yellowfive@57 244 scrollframe = scrollframe,
yellowfive@57 245 uparrow = uparrow,
yellowfive@57 246 downarrow = downarrow,
yellowfive@57 247 scrollbar = scrollbar,
yellowfive@57 248 content = content,
yellowfive@57 249 frame = frame,
yellowfive@57 250 type = Type
yellowfive@57 251 }
yellowfive@57 252 for method, func in pairs(methods) do
yellowfive@57 253 widget[method] = func
yellowfive@57 254 end
yellowfive@57 255 scrollframe.obj, scrollbar.obj, uparrow.obj, downarrow.obj = widget, widget, widget, widget
yellowfive@57 256
yellowfive@57 257 return AceGUI:RegisterAsContainer(widget)
yellowfive@57 258 end
yellowfive@57 259
yellowfive@57 260 AceGUI:RegisterWidgetType(Type, Constructor, Version)