Mercurial > wow > askmrrobot
diff Libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua @ 57:01b63b8ed811 v21
total rewrite to version 21
author | yellowfive |
---|---|
date | Fri, 05 Jun 2015 11:05:15 -0700 |
parents | |
children | e635cd648e01 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua Fri Jun 05 11:05:15 2015 -0700 @@ -0,0 +1,204 @@ +--[[----------------------------------------------------------------------------- +ScrollFrame Container +Plain container that scrolls its content and doesn't grow in height. +-------------------------------------------------------------------------------]] +local Type, Version = "ScrollFrame", 23 +local AceGUI = LibStub and LibStub("AceGUI-3.0", true) +if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end + +-- Lua APIs +local pairs, assert, type = pairs, assert, type +local min, max, floor, abs = math.min, math.max, math.floor, math.abs + +-- WoW APIs +local CreateFrame, UIParent = CreateFrame, UIParent + +--[[----------------------------------------------------------------------------- +Support functions +-------------------------------------------------------------------------------]] +local function FixScrollOnUpdate(frame) + frame:SetScript("OnUpdate", nil) + frame.obj:FixScroll() +end + +--[[----------------------------------------------------------------------------- +Scripts +-------------------------------------------------------------------------------]] +local function ScrollFrame_OnMouseWheel(frame, value) + frame.obj:MoveScroll(value) +end + +local function ScrollFrame_OnSizeChanged(frame) + frame:SetScript("OnUpdate", FixScrollOnUpdate) +end + +local function ScrollBar_OnScrollValueChanged(frame, value) + frame.obj:SetScroll(value) +end + +--[[----------------------------------------------------------------------------- +Methods +-------------------------------------------------------------------------------]] +local methods = { + ["OnAcquire"] = function(self) + self:SetScroll(0) + self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate) + end, + + ["OnRelease"] = function(self) + self.status = nil + for k in pairs(self.localstatus) do + self.localstatus[k] = nil + end + self.scrollframe:SetPoint("BOTTOMRIGHT") + self.scrollbar:Hide() + self.scrollBarShown = nil + self.content.height, self.content.width = nil, nil + end, + + ["SetScroll"] = function(self, value) + local status = self.status or self.localstatus + local viewheight = self.scrollframe:GetHeight() + local height = self.content:GetHeight() + local offset + + if viewheight > height then + offset = 0 + else + offset = floor((height - viewheight) / 1000.0 * value) + end + self.content:ClearAllPoints() + self.content:SetPoint("TOPLEFT", 0, offset) + self.content:SetPoint("TOPRIGHT", 0, offset) + status.offset = offset + status.scrollvalue = value + end, + + ["MoveScroll"] = function(self, value) + local status = self.status or self.localstatus + local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight() + + if self.scrollBarShown then + local diff = height - viewheight + local delta = 1 + if value < 0 then + delta = -1 + end + self.scrollbar:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000)) + end + end, + + ["FixScroll"] = function(self) + if self.updateLock then return end + self.updateLock = true + local status = self.status or self.localstatus + local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight() + local offset = status.offset or 0 + local curvalue = self.scrollbar:GetValue() + -- Give us a margin of error of 2 pixels to stop some conditions that i would blame on floating point inaccuracys + -- No-one is going to miss 2 pixels at the bottom of the frame, anyhow! + if viewheight < height + 2 then + if self.scrollBarShown then + self.scrollBarShown = nil + self.scrollbar:Hide() + self.scrollbar:SetValue(0) + self.scrollframe:SetPoint("BOTTOMRIGHT") + self:DoLayout() + end + else + if not self.scrollBarShown then + self.scrollBarShown = true + self.scrollbar:Show() + self.scrollframe:SetPoint("BOTTOMRIGHT", -20, 0) + self:DoLayout() + end + local value = (offset / (viewheight - height) * 1000) + if value > 1000 then value = 1000 end + self.scrollbar:SetValue(value) + self:SetScroll(value) + if value < 1000 then + self.content:ClearAllPoints() + self.content:SetPoint("TOPLEFT", 0, offset) + self.content:SetPoint("TOPRIGHT", 0, offset) + status.offset = offset + end + end + self.updateLock = nil + end, + + ["LayoutFinished"] = function(self, width, height) + self.content:SetHeight(height or 0 + 20) + self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate) + end, + + ["SetStatusTable"] = function(self, status) + assert(type(status) == "table") + self.status = status + if not status.scrollvalue then + status.scrollvalue = 0 + end + end, + + ["OnWidthSet"] = function(self, width) + local content = self.content + content.width = width + end, + + ["OnHeightSet"] = function(self, height) + local content = self.content + content.height = height + end +} +--[[----------------------------------------------------------------------------- +Constructor +-------------------------------------------------------------------------------]] +local function Constructor() + local frame = CreateFrame("Frame", nil, UIParent) + local num = AceGUI:GetNextWidgetNum(Type) + + local scrollframe = CreateFrame("ScrollFrame", nil, frame) + scrollframe:SetPoint("TOPLEFT") + scrollframe:SetPoint("BOTTOMRIGHT") + scrollframe:EnableMouseWheel(true) + scrollframe:SetScript("OnMouseWheel", ScrollFrame_OnMouseWheel) + scrollframe:SetScript("OnSizeChanged", ScrollFrame_OnSizeChanged) + + local scrollbar = CreateFrame("Slider", ("AceConfigDialogScrollFrame%dScrollBar"):format(num), scrollframe, "UIPanelScrollBarTemplate") + scrollbar:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, -16) + scrollbar:SetPoint("BOTTOMLEFT", scrollframe, "BOTTOMRIGHT", 4, 16) + scrollbar:SetMinMaxValues(0, 1000) + scrollbar:SetValueStep(1) + scrollbar:SetValue(0) + scrollbar:SetWidth(16) + scrollbar:Hide() + -- set the script as the last step, so it doesn't fire yet + scrollbar:SetScript("OnValueChanged", ScrollBar_OnScrollValueChanged) + + local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND") + scrollbg:SetAllPoints(scrollbar) + scrollbg:SetTexture(0, 0, 0, 0.4) + + --Container Support + local content = CreateFrame("Frame", nil, scrollframe) + content:SetPoint("TOPLEFT") + content:SetPoint("TOPRIGHT") + content:SetHeight(400) + scrollframe:SetScrollChild(content) + + local widget = { + localstatus = { scrollvalue = 0 }, + scrollframe = scrollframe, + scrollbar = scrollbar, + content = content, + frame = frame, + type = Type + } + for method, func in pairs(methods) do + widget[method] = func + end + scrollframe.obj, scrollbar.obj = widget, widget + + return AceGUI:RegisterAsContainer(widget) +end + +AceGUI:RegisterWidgetType(Type, Constructor, Version)