annotate Libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua @ 201:3447634f0388 tip

Added tag v97 for changeset 6e8838b231d4
author Yellowfive
date Wed, 13 Jan 2021 13:12:13 -0600
parents e635cd648e01
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 -------------------------------------------------------------------------------]]
yellowfive@106 5 local Type, Version = "ScrollFrame", 24
yellowfive@57 6 local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
yellowfive@57 7 if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end
yellowfive@57 8
yellowfive@57 9 -- Lua APIs
yellowfive@57 10 local pairs, assert, type = pairs, assert, type
yellowfive@57 11 local min, max, floor, abs = math.min, math.max, math.floor, math.abs
yellowfive@57 12
yellowfive@57 13 -- WoW APIs
yellowfive@57 14 local CreateFrame, UIParent = CreateFrame, UIParent
yellowfive@57 15
yellowfive@57 16 --[[-----------------------------------------------------------------------------
yellowfive@57 17 Support functions
yellowfive@57 18 -------------------------------------------------------------------------------]]
yellowfive@57 19 local function FixScrollOnUpdate(frame)
yellowfive@57 20 frame:SetScript("OnUpdate", nil)
yellowfive@57 21 frame.obj:FixScroll()
yellowfive@57 22 end
yellowfive@57 23
yellowfive@57 24 --[[-----------------------------------------------------------------------------
yellowfive@57 25 Scripts
yellowfive@57 26 -------------------------------------------------------------------------------]]
yellowfive@57 27 local function ScrollFrame_OnMouseWheel(frame, value)
yellowfive@57 28 frame.obj:MoveScroll(value)
yellowfive@57 29 end
yellowfive@57 30
yellowfive@57 31 local function ScrollFrame_OnSizeChanged(frame)
yellowfive@57 32 frame:SetScript("OnUpdate", FixScrollOnUpdate)
yellowfive@57 33 end
yellowfive@57 34
yellowfive@57 35 local function ScrollBar_OnScrollValueChanged(frame, value)
yellowfive@57 36 frame.obj:SetScroll(value)
yellowfive@57 37 end
yellowfive@57 38
yellowfive@57 39 --[[-----------------------------------------------------------------------------
yellowfive@57 40 Methods
yellowfive@57 41 -------------------------------------------------------------------------------]]
yellowfive@57 42 local methods = {
yellowfive@57 43 ["OnAcquire"] = function(self)
yellowfive@57 44 self:SetScroll(0)
yellowfive@57 45 self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
yellowfive@57 46 end,
yellowfive@57 47
yellowfive@57 48 ["OnRelease"] = function(self)
yellowfive@57 49 self.status = nil
yellowfive@57 50 for k in pairs(self.localstatus) do
yellowfive@57 51 self.localstatus[k] = nil
yellowfive@57 52 end
yellowfive@57 53 self.scrollframe:SetPoint("BOTTOMRIGHT")
yellowfive@57 54 self.scrollbar:Hide()
yellowfive@57 55 self.scrollBarShown = nil
yellowfive@57 56 self.content.height, self.content.width = nil, nil
yellowfive@57 57 end,
yellowfive@57 58
yellowfive@57 59 ["SetScroll"] = function(self, value)
yellowfive@57 60 local status = self.status or self.localstatus
yellowfive@57 61 local viewheight = self.scrollframe:GetHeight()
yellowfive@57 62 local height = self.content:GetHeight()
yellowfive@57 63 local offset
yellowfive@57 64
yellowfive@57 65 if viewheight > height then
yellowfive@57 66 offset = 0
yellowfive@57 67 else
yellowfive@57 68 offset = floor((height - viewheight) / 1000.0 * value)
yellowfive@57 69 end
yellowfive@57 70 self.content:ClearAllPoints()
yellowfive@57 71 self.content:SetPoint("TOPLEFT", 0, offset)
yellowfive@57 72 self.content:SetPoint("TOPRIGHT", 0, offset)
yellowfive@57 73 status.offset = offset
yellowfive@57 74 status.scrollvalue = value
yellowfive@57 75 end,
yellowfive@57 76
yellowfive@57 77 ["MoveScroll"] = function(self, value)
yellowfive@57 78 local status = self.status or self.localstatus
yellowfive@57 79 local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
yellowfive@57 80
yellowfive@57 81 if self.scrollBarShown then
yellowfive@57 82 local diff = height - viewheight
yellowfive@57 83 local delta = 1
yellowfive@57 84 if value < 0 then
yellowfive@57 85 delta = -1
yellowfive@57 86 end
yellowfive@57 87 self.scrollbar:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000))
yellowfive@57 88 end
yellowfive@57 89 end,
yellowfive@57 90
yellowfive@57 91 ["FixScroll"] = function(self)
yellowfive@57 92 if self.updateLock then return end
yellowfive@57 93 self.updateLock = true
yellowfive@57 94 local status = self.status or self.localstatus
yellowfive@57 95 local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight()
yellowfive@57 96 local offset = status.offset or 0
yellowfive@57 97 local curvalue = self.scrollbar:GetValue()
yellowfive@57 98 -- Give us a margin of error of 2 pixels to stop some conditions that i would blame on floating point inaccuracys
yellowfive@57 99 -- No-one is going to miss 2 pixels at the bottom of the frame, anyhow!
yellowfive@57 100 if viewheight < height + 2 then
yellowfive@57 101 if self.scrollBarShown then
yellowfive@57 102 self.scrollBarShown = nil
yellowfive@57 103 self.scrollbar:Hide()
yellowfive@57 104 self.scrollbar:SetValue(0)
yellowfive@57 105 self.scrollframe:SetPoint("BOTTOMRIGHT")
yellowfive@57 106 self:DoLayout()
yellowfive@57 107 end
yellowfive@57 108 else
yellowfive@57 109 if not self.scrollBarShown then
yellowfive@57 110 self.scrollBarShown = true
yellowfive@57 111 self.scrollbar:Show()
yellowfive@57 112 self.scrollframe:SetPoint("BOTTOMRIGHT", -20, 0)
yellowfive@57 113 self:DoLayout()
yellowfive@57 114 end
yellowfive@57 115 local value = (offset / (viewheight - height) * 1000)
yellowfive@57 116 if value > 1000 then value = 1000 end
yellowfive@57 117 self.scrollbar:SetValue(value)
yellowfive@57 118 self:SetScroll(value)
yellowfive@57 119 if value < 1000 then
yellowfive@57 120 self.content:ClearAllPoints()
yellowfive@57 121 self.content:SetPoint("TOPLEFT", 0, offset)
yellowfive@57 122 self.content:SetPoint("TOPRIGHT", 0, offset)
yellowfive@57 123 status.offset = offset
yellowfive@57 124 end
yellowfive@57 125 end
yellowfive@57 126 self.updateLock = nil
yellowfive@57 127 end,
yellowfive@57 128
yellowfive@57 129 ["LayoutFinished"] = function(self, width, height)
yellowfive@57 130 self.content:SetHeight(height or 0 + 20)
yellowfive@57 131 self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate)
yellowfive@57 132 end,
yellowfive@57 133
yellowfive@57 134 ["SetStatusTable"] = function(self, status)
yellowfive@57 135 assert(type(status) == "table")
yellowfive@57 136 self.status = status
yellowfive@57 137 if not status.scrollvalue then
yellowfive@57 138 status.scrollvalue = 0
yellowfive@57 139 end
yellowfive@57 140 end,
yellowfive@57 141
yellowfive@57 142 ["OnWidthSet"] = function(self, width)
yellowfive@57 143 local content = self.content
yellowfive@57 144 content.width = width
yellowfive@57 145 end,
yellowfive@57 146
yellowfive@57 147 ["OnHeightSet"] = function(self, height)
yellowfive@57 148 local content = self.content
yellowfive@57 149 content.height = height
yellowfive@57 150 end
yellowfive@57 151 }
yellowfive@57 152 --[[-----------------------------------------------------------------------------
yellowfive@57 153 Constructor
yellowfive@57 154 -------------------------------------------------------------------------------]]
yellowfive@57 155 local function Constructor()
yellowfive@57 156 local frame = CreateFrame("Frame", nil, UIParent)
yellowfive@57 157 local num = AceGUI:GetNextWidgetNum(Type)
yellowfive@57 158
yellowfive@57 159 local scrollframe = CreateFrame("ScrollFrame", nil, frame)
yellowfive@57 160 scrollframe:SetPoint("TOPLEFT")
yellowfive@57 161 scrollframe:SetPoint("BOTTOMRIGHT")
yellowfive@57 162 scrollframe:EnableMouseWheel(true)
yellowfive@57 163 scrollframe:SetScript("OnMouseWheel", ScrollFrame_OnMouseWheel)
yellowfive@57 164 scrollframe:SetScript("OnSizeChanged", ScrollFrame_OnSizeChanged)
yellowfive@57 165
yellowfive@57 166 local scrollbar = CreateFrame("Slider", ("AceConfigDialogScrollFrame%dScrollBar"):format(num), scrollframe, "UIPanelScrollBarTemplate")
yellowfive@57 167 scrollbar:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, -16)
yellowfive@57 168 scrollbar:SetPoint("BOTTOMLEFT", scrollframe, "BOTTOMRIGHT", 4, 16)
yellowfive@57 169 scrollbar:SetMinMaxValues(0, 1000)
yellowfive@57 170 scrollbar:SetValueStep(1)
yellowfive@57 171 scrollbar:SetValue(0)
yellowfive@57 172 scrollbar:SetWidth(16)
yellowfive@57 173 scrollbar:Hide()
yellowfive@57 174 -- set the script as the last step, so it doesn't fire yet
yellowfive@57 175 scrollbar:SetScript("OnValueChanged", ScrollBar_OnScrollValueChanged)
yellowfive@57 176
yellowfive@57 177 local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND")
yellowfive@57 178 scrollbg:SetAllPoints(scrollbar)
yellowfive@106 179 scrollbg:SetColorTexture(0, 0, 0, 0.4)
yellowfive@57 180
yellowfive@57 181 --Container Support
yellowfive@57 182 local content = CreateFrame("Frame", nil, scrollframe)
yellowfive@57 183 content:SetPoint("TOPLEFT")
yellowfive@57 184 content:SetPoint("TOPRIGHT")
yellowfive@57 185 content:SetHeight(400)
yellowfive@57 186 scrollframe:SetScrollChild(content)
yellowfive@57 187
yellowfive@57 188 local widget = {
yellowfive@57 189 localstatus = { scrollvalue = 0 },
yellowfive@57 190 scrollframe = scrollframe,
yellowfive@57 191 scrollbar = scrollbar,
yellowfive@57 192 content = content,
yellowfive@57 193 frame = frame,
yellowfive@57 194 type = Type
yellowfive@57 195 }
yellowfive@57 196 for method, func in pairs(methods) do
yellowfive@57 197 widget[method] = func
yellowfive@57 198 end
yellowfive@57 199 scrollframe.obj, scrollbar.obj = widget, widget
yellowfive@57 200
yellowfive@57 201 return AceGUI:RegisterAsContainer(widget)
yellowfive@57 202 end
yellowfive@57 203
yellowfive@57 204 AceGUI:RegisterWidgetType(Type, Constructor, Version)