Asa@0: local AceGUI = LibStub("AceGUI-3.0") Asa@0: Asa@0: -- Lua APIs Asa@0: local pairs, assert, type = pairs, assert, type Asa@0: local min, max, floor = math.min, math.max, math.floor Asa@0: Asa@0: -- WoW APIs Asa@0: local CreateFrame, UIParent = CreateFrame, UIParent Asa@0: Asa@0: Asa@0: ------------- Asa@0: -- Widgets -- Asa@0: ------------- Asa@0: --[[ Asa@0: Widgets must provide the following functions Asa@0: Acquire() - Called when the object is aquired, should set everything to a default hidden state Asa@0: Release() - Called when the object is Released, should remove any anchors and hide the Widget Asa@0: Asa@0: And the following members Asa@0: frame - the frame or derivitive object that will be treated as the widget for size and anchoring purposes Asa@0: type - the type of the object, same as the name given to :RegisterWidget() Asa@0: Asa@0: Widgets contain a table called userdata, this is a safe place to store data associated with the wigdet Asa@0: It will be cleared automatically when a widget is released Asa@0: Placing values directly into a widget object should be avoided Asa@0: Asa@0: If the Widget can act as a container for other Widgets the following Asa@0: content - frame or derivitive that children will be anchored to Asa@0: Asa@0: The Widget can supply the following Optional Members Asa@0: Asa@0: Asa@0: ]] Asa@0: Asa@0: -------------------------- Asa@0: -- Scroll Frame -- Asa@0: -------------------------- Asa@0: do Asa@0: local Type = "ScrollFrame" Asa@0: local Version = 9 Asa@0: Asa@0: local function OnAcquire(self) Asa@0: Asa@0: end Asa@0: Asa@0: local function OnRelease(self) Asa@0: self.frame:ClearAllPoints() Asa@0: self.frame:Hide() Asa@0: self.status = nil Asa@0: -- do SetScroll after niling status, but before clearing localstatus Asa@0: -- so the scroll value isnt populated back into status, but not kept in localstatus either Asa@0: self:SetScroll(0) Asa@0: for k in pairs(self.localstatus) do Asa@0: self.localstatus[k] = nil Asa@0: end Asa@0: self.scrollframe:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",0,0) Asa@0: self.scrollbar:Hide() Asa@0: self.scrollBarShown = nil Asa@0: self.content.height, self.content.width = nil, nil Asa@0: end Asa@0: Asa@0: local function SetScroll(self, value) Asa@0: local status = self.status or self.localstatus Asa@0: local viewheight = self.scrollframe:GetHeight() Asa@0: local height = self.content:GetHeight() Asa@0: local offset Asa@0: Asa@0: if viewheight > height then Asa@0: offset = 0 Asa@0: else Asa@0: offset = floor((height - viewheight) / 1000.0 * value) Asa@0: end Asa@0: self.content:ClearAllPoints() Asa@0: self.content:SetPoint("TOPLEFT", self.scrollframe, "TOPLEFT", 0, offset) Asa@0: self.content:SetPoint("TOPRIGHT", self.scrollframe, "TOPRIGHT", 0, offset) Asa@0: status.offset = offset Asa@0: status.scrollvalue = value Asa@0: end Asa@0: Asa@0: local function MoveScroll(self, value) Asa@0: local status = self.status or self.localstatus Asa@0: local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight() Asa@0: Asa@0: if height > viewheight then Asa@0: self.scrollbar:Hide() Asa@0: else Asa@0: self.scrollbar:Show() Asa@0: local diff = height - viewheight Asa@0: local delta = 1 Asa@0: if value < 0 then Asa@0: delta = -1 Asa@0: end Asa@0: self.scrollbar:SetValue(min(max(status.scrollvalue + delta*(1000/(diff/45)),0), 1000)) Asa@0: end Asa@0: end Asa@0: Asa@0: Asa@0: local function FixScroll(self) Asa@0: if self.updateLock then return end Asa@0: self.updateLock = true Asa@0: local status = self.status or self.localstatus Asa@0: local height, viewheight = self.scrollframe:GetHeight(), self.content:GetHeight() Asa@0: local offset = status.offset or 0 Asa@0: local curvalue = self.scrollbar:GetValue() Asa@0: if viewheight < height then Asa@0: if self.scrollBarShown then Asa@0: self.scrollBarShown = nil Asa@0: self.scrollbar:Hide() Asa@0: self.scrollbar:SetValue(0) Asa@0: self.scrollframe:SetPoint("BOTTOMRIGHT",self.frame,"BOTTOMRIGHT",0,0) Asa@0: self:DoLayout() Asa@0: end Asa@0: else Asa@0: if not self.scrollBarShown then Asa@0: self.scrollBarShown = true Asa@0: self.scrollbar:Show() Asa@0: self.scrollframe:SetPoint("BOTTOMRIGHT", self.frame,"BOTTOMRIGHT",-20,0) Asa@0: self:DoLayout() Asa@0: end Asa@0: local value = (offset / (viewheight - height) * 1000) Asa@0: if value > 1000 then value = 1000 end Asa@0: self.scrollbar:SetValue(value) Asa@0: self:SetScroll(value) Asa@0: if value < 1000 then Asa@0: self.content:ClearAllPoints() Asa@0: self.content:SetPoint("TOPLEFT", self.scrollframe, "TOPLEFT", 0, offset) Asa@0: self.content:SetPoint("TOPRIGHT", self.scrollframe, "TOPRIGHT", 0, offset) Asa@0: status.offset = offset Asa@0: end Asa@0: end Asa@0: self.updateLock = nil Asa@0: end Asa@0: Asa@0: local function OnMouseWheel(this, value) Asa@0: this.obj:MoveScroll(value) Asa@0: end Asa@0: Asa@0: local function OnScrollValueChanged(this, value) Asa@0: this.obj:SetScroll(value) Asa@0: end Asa@0: Asa@0: local function FixScrollOnUpdate(this) Asa@0: this:SetScript("OnUpdate", nil) Asa@0: this.obj:FixScroll() Asa@0: end Asa@0: Asa@0: local function OnSizeChanged(this) Asa@0: this:SetScript("OnUpdate", FixScrollOnUpdate) Asa@0: end Asa@0: Asa@0: local function LayoutFinished(self, width, height) Asa@0: self.content:SetHeight(height or 0 + 20) Asa@0: self.scrollframe:SetScript("OnUpdate", FixScrollOnUpdate) Asa@0: end Asa@0: Asa@0: -- called to set an external table to store status in Asa@0: local function SetStatusTable(self, status) Asa@0: assert(type(status) == "table") Asa@0: self.status = status Asa@0: if not status.scrollvalue then Asa@0: status.scrollvalue = 0 Asa@0: end Asa@0: end Asa@0: Asa@0: local function OnWidthSet(self, width) Asa@0: local content = self.content Asa@0: content.width = width Asa@0: end Asa@0: Asa@0: Asa@0: local function OnHeightSet(self, height) Asa@0: local content = self.content Asa@0: content.height = height Asa@0: end Asa@0: Asa@0: local function Constructor() Asa@0: local frame = CreateFrame("Frame", nil, UIParent) Asa@0: local self = {} Asa@0: self.type = Type Asa@0: Asa@0: self.OnRelease = OnRelease Asa@0: self.OnAcquire = OnAcquire Asa@0: Asa@0: self.MoveScroll = MoveScroll Asa@0: self.FixScroll = FixScroll Asa@0: self.SetScroll = SetScroll Asa@0: self.LayoutFinished = LayoutFinished Asa@0: self.SetStatusTable = SetStatusTable Asa@0: self.OnWidthSet = OnWidthSet Asa@0: self.OnHeightSet = OnHeightSet Asa@0: Asa@0: self.localstatus = {} Asa@0: self.frame = frame Asa@0: frame.obj = self Asa@0: Asa@0: --Container Support Asa@0: local scrollframe = CreateFrame("ScrollFrame", nil, frame) Asa@0: scrollframe.obj = self Asa@0: scrollframe:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, 0) Asa@0: scrollframe:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 0) Asa@0: scrollframe:EnableMouseWheel(true) Asa@0: scrollframe:SetScript("OnMouseWheel", OnMouseWheel) Asa@0: scrollframe:SetScript("OnSizeChanged", OnSizeChanged) Asa@0: self.scrollframe = scrollframe Asa@0: Asa@0: local content = CreateFrame("Frame", nil, scrollframe) Asa@0: content.obj = self Asa@0: content:SetPoint("TOPLEFT", scrollframe, "TOPLEFT", 0, 0) Asa@0: content:SetPoint("TOPRIGHT", scrollframe, "TOPRIGHT", 0, 0) Asa@0: content:SetHeight(400) Asa@0: self.content = content Asa@0: scrollframe:SetScrollChild(content) Asa@0: Asa@0: local num = AceGUI:GetNextWidgetNum(Type) Asa@0: local name = ("AceConfigDialogScrollFrame%dScrollBar"):format(num) Asa@0: local scrollbar = CreateFrame("Slider", name, scrollframe, "UIPanelScrollBarTemplate") Asa@0: scrollbar.obj = self Asa@0: scrollbar:SetPoint("TOPLEFT", scrollframe, "TOPRIGHT", 4, -16) Asa@0: scrollbar:SetPoint("BOTTOMLEFT", scrollframe, "BOTTOMRIGHT", 4, 16) Asa@0: scrollbar:SetScript("OnValueChanged", OnScrollValueChanged) Asa@0: scrollbar:SetMinMaxValues(0, 1000) Asa@0: scrollbar:SetValueStep(1) Asa@0: scrollbar:SetValue(0) Asa@0: scrollbar:SetWidth(16) Asa@0: scrollbar:Hide() Asa@0: self.scrollbar = scrollbar Asa@0: Asa@0: local scrollbg = scrollbar:CreateTexture(nil, "BACKGROUND") Asa@0: scrollbg:SetAllPoints(scrollbar) Asa@0: scrollbg:SetTexture(0, 0, 0, 0.4) Asa@0: Asa@0: self.localstatus.scrollvalue = 0 Asa@0: Asa@0: --self:FixScroll() Asa@0: AceGUI:RegisterAsContainer(self) Asa@0: --AceGUI:RegisterAsWidget(self) Asa@0: return self Asa@0: end Asa@0: Asa@0: AceGUI:RegisterWidgetType(Type,Constructor,Version) Asa@0: end