From cd691a3c5bd6451ec9d146d5ab63510c2effda7f Mon Sep 17 00:00:00 2001 From: jeffi Date: Mon, 1 Jul 2024 17:59:16 -0500 Subject: [PATCH] Updates. --- DiesalGUI-2.0/DiesalGUI-2.0.lua | 12 +- DiesalGUI-2.0/Objects/DropDown.lua | 115 ++++-- DiesalGUI-2.0/Objects/DropDownItem.lua | 29 +- DiesalGUI-2.0/Objects/DropDownPullout.lua | 414 ++++++++++++++++++++++ DiesalGUI-2.0/Objects/ObjectBase.lua | 13 +- 5 files changed, 551 insertions(+), 32 deletions(-) create mode 100644 DiesalGUI-2.0/Objects/DropDownPullout.lua diff --git a/DiesalGUI-2.0/DiesalGUI-2.0.lua b/DiesalGUI-2.0/DiesalGUI-2.0.lua index a7a5c77..0a5edfe 100644 --- a/DiesalGUI-2.0/DiesalGUI-2.0.lua +++ b/DiesalGUI-2.0/DiesalGUI-2.0.lua @@ -366,30 +366,34 @@ function DiesalGUI:Release(object) object.frame:ClearAllPoints() object.frame:Hide() object.frame:SetParent(UIParent) + for k,v in pairs(object.userdata) do + object.userdata[k] = nil + end releaseObject(object, object.type) end ---@alias Diesal.GUI.Object.Focusable ---|Diesal.GUI.Object.ComboBox ---|Diesal.GUI.Object.DropDown +---|Diesal.GUI.Object.DropDownPullout -- Set FocusedObject: Menu, Dropdown, editBox etc.... ---@param object Diesal.GUI.Object.Focusable function DiesalGUI:SetFocus(object) - if self.FocusedObject and self.FocusedObject ~= object then + if DiesalGUI.FocusedObject and DiesalGUI.FocusedObject ~= object then DiesalGUI:ClearFocus() end - self.FocusedObject = object + DiesalGUI.FocusedObject = object end -- Clear focus from the FocusedObject function DiesalGUI:ClearFocus() - local FocusedObject = self.FocusedObject + local FocusedObject = DiesalGUI.FocusedObject if FocusedObject then if FocusedObject.ClearFocus then -- FocusedObject is Focusable Frame FocusedObject:ClearFocus() end - self.FocusedObject = nil + DiesalGUI.FocusedObject = nil end end diff --git a/DiesalGUI-2.0/Objects/DropDown.lua b/DiesalGUI-2.0/Objects/DropDown.lua index 4ca7b79..3b87637 100644 --- a/DiesalGUI-2.0/Objects/DropDown.lua +++ b/DiesalGUI-2.0/Objects/DropDown.lua @@ -82,11 +82,63 @@ local function sortList(list, orderedKeys) return orderedKeys end + +local function OnPulloutOpen(this) + local self = this.userdata.obj + local value = self.value + + if not self.multiselect then + for i, item in this:IterateItems() do + --item:SetValue(item.userdata.value == value) + end + end + + self.open = true + self:FireEvent("OnOpened") +end + +local function OnPulloutClose(this) + local self = this.userdata.obj + self.open = nil + self:FireEvent("OnClosed") +end + +local function fixlevels(parent, ...) + local i = 1 + local child = select(i, ...) + while child do + child:SetFrameLevel(parent:GetFrameLevel() + 1) + fixlevels(child, child:GetChildren()) + i = i + 1 + child = select(i, ...) + end +end + +local function fixstrata(strata, parent, ...) + local i = 1 + local child = select(i, ...) + parent:SetFrameStrata(strata) + while child do + fixstrata(strata, child, child:GetChildren()) + i = i + 1 + child = select(i, ...) + end +end + + -- ~~| Dropdown Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ---@class Diesal.GUI.DropDown.Methods local methods = { ---@param self Diesal.GUI.Object.DropDown OnAcquire = function(self) + --local pullout = DiesalGUI:Create("DiesalDropDownPullout") + --self.pullout = pullout + --self.pullout.userdata.obj = self + --self.pullout:SetEventListener("OnClose", OnPulloutClose) + --self.pullout:SetEventListener("OnOpen", OnPulloutOpen) + --self.pullout.frame:SetFrameLevel(self.frame:GetFrameLevel() + 1) + --fixlevels(self.pullout.frame, self.pullout.frame:GetChildren()) + self:ApplySettings() self:SetStylesheet(Stylesheet) -- self:SetStylesheet(wireFrameSheet) @@ -95,7 +147,11 @@ local methods = { end, ---@param self Diesal.GUI.Object.DropDown - OnRelease = function(self) end, + OnRelease = function(self) + if self.pullout then + self.pullout:Release() + end + end, ---@param self Diesal.GUI.Object.DropDown ApplySettings = function(self) @@ -128,6 +184,8 @@ local methods = { local foldColor = "353535" local expandColor = "5a5a5a" self.dropdown:SetFrameStrata("TOOLTIP") + self.pullout.settings.items = {} + self.pullout:Clear() for position, item in ipairs(settings.list) do local dropdownItem = DiesalGUI:Create("DiesalDropDownItem") DiesalGUI:OnMouse(dropdownItem.frame, "LeftButton") @@ -165,6 +223,7 @@ local methods = { }) end end + self.pullout:AddItem(dropdownItem, true) end self:ApplySettings() end, @@ -346,6 +405,24 @@ local methods = { }) end end, + ---@param self Diesal.GUI.Object.DropDown + ---@param button MouseButton + ---@param down boolean + OnClick = function(self, button, down) + if button == "LeftButton" then + if self.open then + self.open = false + self.pullout:Close() + self.arrow:SetRotation(0) + DiesalGUI:ClearFocus() + else + self.open = true + self.pullout:Open("TOPLEFT", self.frame, "BOTTOMLEFT", 0, 0) + DiesalGUI:SetFocus(self.pullout) + self.arrow:SetRotation(math.pi) + end + end + end, } ---@class Diesal.GUI.Object.DropDown.Settings : Diesal.GUI.ObjectBase.Settings @@ -372,9 +449,11 @@ local function Constructor() ---@field dropdown Frame ---@field content Frame ---@field value string + ---@field pullout DiesalDropDownPullout local self = DiesalGUI:Create(Type, true) self:SetMethods(methods) - self.dropdownShown = true + self.dropdownShown = false + self.open = false local frame = CreateFrame("Button", nil, DiesalGUI.UIParent) frame:SetFrameStrata("TOOLTIP") @@ -396,25 +475,9 @@ local function Constructor() -- OnValueSelected(event,selectedKey,selectedValue,selectionTable) -- OnEnter, OnLeave -- ~~ Construct ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + frame:RegisterForClicks("AnyDown") frame:SetScript("OnClick", function(this, button, down) - if button == "LeftButton" then - if self.dropdown:IsVisible() then - self.arrow:SetRotation(0) - self.dropdown:SetParent(self.frame) - self.dropdown:Hide() - else - self.arrow:SetRotation(math.pi) - self.dropdown:SetParent(UIParent) - DiesalGUI:OnMouse(self.dropdown, button) - self:FixStrata("TOOLTIP", self.dropdown, { - self.dropdown:GetChildren() --[[@as Frame]], - }) - if self.settings.dropdownWidth then - self.dropdown:SetPoint("TOPRIGHT", frame, "BOTTOMRIGHT", frame:GetWidth() + self.settings.dropdownWidth, -2) - end - self.dropdown:Show() - end - end + self:OnClick(button, down) self:FireEvent("OnClick", button, down) end) frame:SetScript("OnEnter", function(this, ...) @@ -448,6 +511,11 @@ local function Constructor() end) dropdown:SetScript("OnHide", function(this) self.dropdownShown = false + if self.pullout then + self.pullout:Close() + end + self.arrow:SetRotation(0) + DiesalGUI:ClearFocus() end) dropdown:Hide() self.dropdown = dropdown @@ -460,6 +528,13 @@ local function Constructor() self[method] = func end ]] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + self.pullout = DiesalGUI:Create("DiesalDropDownPullout") + self.pullout.userdata.obj = self + self.pullout:SetEventListener("OnClose", OnPulloutClose) + self.pullout:SetEventListener("OnOpen", OnPulloutOpen) + self.pullout.frame:SetFrameLevel(self.frame:GetFrameLevel() + 1) + fixlevels(self.pullout.frame, self.pullout.frame:GetChildren()) + self.pullout:SetDropDown(self) self:SetObj(self.frame) return self end diff --git a/DiesalGUI-2.0/Objects/DropDownItem.lua b/DiesalGUI-2.0/Objects/DropDownItem.lua index e965619..38a3699 100644 --- a/DiesalGUI-2.0/Objects/DropDownItem.lua +++ b/DiesalGUI-2.0/Objects/DropDownItem.lua @@ -21,6 +21,18 @@ local Stylesheet = { alpha = 0.1, }, } + +local function fixlevels(parent, ...) + local i = 1 + local child = select(i, ...) + while child do + child:SetFrameLevel(parent:GetFrameLevel() + 1) + fixlevels(child, child:GetChildren()) + i = i + 1 + child = select(i, ...) + end +end + -- ~~| DropdownItem Methods |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ---@class Diesal.GUI.DropDownItem.Methods local methods = { @@ -45,13 +57,14 @@ local methods = { local dropdownSettings = settings.parentObject.settings local text = self.text if settings.position == 1 then - self:SetPoint("TOPLEFT") + --self:SetPoint("TOPLEFT") else - self:SetPoint("TOPLEFT", settings.parentObject.children[settings.position - 1].frame, "BOTTOMLEFT", 0, 0) + --self:SetPoint("TOPLEFT", settings.parentObject.children[settings.position - 1].frame, "BOTTOMLEFT", 0, 0) end - self:SetPoint("RIGHT") + --self:SetPoint("RIGHT") self:SetHeight(dropdownSettings.itemHeight) + --self:SetHeight(text:GetLineHeight()) self:SetText(settings.value) @@ -106,6 +119,7 @@ local methods = { self:SetSelected(true) dropdownText = settings.value selectionTable = { settings.key } + dropdown.pullout:Hide() dropdown.dropdown:Hide() end else @@ -125,6 +139,14 @@ local methods = { self.settings.selected = selected and true or false self.check[selected and "Show" or "Hide"](self.check) end, + ---@param self Diesal.GUI.Object.DropDown.Item + ---@param pullout Diesal.GUI.Object.DropDownPullout + SetPullout = function(self, pullout) + self.pullout = pullout + self.frame:SetParent(nil) + self.frame:SetParent(pullout.itemFrame) + fixlevels(pullout.itemFrame, pullout.itemFrame:GetChildren()) + end, } ---@class Diesal.GUI.DropDownItem.Settings : Diesal.GUI.ObjectBase.Settings @@ -148,6 +170,7 @@ local function Constructor() ---@field icon2 Texture ---@field text FontString ---@field settings Diesal.GUI.DropDownItem.Settings + ---@field pullout Diesal.GUI.Object.DropDownPullout local self = DiesalGUI:Create(Type, true) local frame = CreateFrame("Button", nil, DiesalGUI.UIParent) frame:SetToplevel(true) diff --git a/DiesalGUI-2.0/Objects/DropDownPullout.lua b/DiesalGUI-2.0/Objects/DropDownPullout.lua new file mode 100644 index 0000000..a72d6f5 --- /dev/null +++ b/DiesalGUI-2.0/Objects/DropDownPullout.lua @@ -0,0 +1,414 @@ +---@type Diesal.GUI +local DiesalGUI = LibStub("DiesalGUI-2.0") +---@type Diesal.Tools +local DiesalTools = LibStub("DiesalTools-2.0") +---@type Diesal.Style +local DiesalStyle = LibStub("DiesalStyle-2.0") +-- ~~| Diesal Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +local Colors = DiesalStyle.Colors +local HSL, ShadeColor, TintColor = DiesalTools.HSL, DiesalTools.ShadeColor, DiesalTools.TintColor +-- ~~| Lua Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +local tsort = table.sort +local sub, format, lower, upper, gsub = string.sub, string.format, string.lower, string.upper, string.gsub + +-- ~~| WoW Upvalues |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +-- ~~| Dropdown |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +local Type = "DiesalDropDownPullout" +local Version = 1 + +---@type backdropInfo +local backdrop = { + bgFile = "Interface\\ChatFrame\\ChatFrameBackground", + edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", + edgeSize = 8, + tileSize = 8, + tile = true, + insets = { left = 2, right = 2, top = 2, bottom = 2 }, +} + +local sliderBackdrop = { + bgFile = "Interface\\Buttons\\UI-SliderBar-Background", + edgeFile = "Interface\\Buttons\\UI-SliderBar-Border", + tile = true, + tileSize = 8, + edgeSize = 8, + insets = { left = 3, right = 3, top = 3, bottom = 3 }, +} + +local Stylesheet = { + ["frame-background"] = { + type = "texture", + layer = "BACKGROUND", + color = Colors.UI_100, + alpha = 0.95, + }, + ["frame-inline"] = { + type = "outline", + layer = "BORDER", + color = "ffffff", + alpha = 0.02, + position = -1, + }, + ["frame-shadow"] = { + type = "shadow", + }, +} + +local defaultWidth = 200 +local defaultMaxItems = 20 + +local function fixlevels(parent, ...) + local i = 1 + local child = select(i, ...) + while child do + child:SetFrameLevel(parent:GetFrameLevel() + 1) + fixlevels(child, child:GetChildren()) + i = i + 1 + child = select(i, ...) + end +end + +local function fixstrata(strata, parent, ...) + local i = 1 + local child = select(i, ...) + parent:SetFrameStrata(strata) + while child do + fixstrata(strata, child, child:GetChildren()) + i = i + 1 + child = select(i, ...) + end +end + +-- HACK: This should be no part of the pullout, but there +-- is no other 'clean' way to response to any item-OnEnter +-- Used to close Submenus when an other item is entered +local function OnEnter(item) + local self = item.pullout + for k, v in ipairs(self.settings.items) do + if v.CloseMenu and v ~= item then + v:CloseMenu() + end + end +end + +---@class Diesal.GUI.DropDownPullout.Methods +local methods = { + ---@param self Diesal.GUI.Object.DropDownPullout + OnAcquire = function(self) + self.frame:SetParent(DiesalGUI.UIParent) + end, + + ---@param self Diesal.GUI.Object.DropDownPullout + OnRelease = function(self) + self:ClearAllPoints() + self:Hide() + end, + ---@param self Diesal.GUI.Object.DropDownPullout + ApplySettings = function(self) end, + ---@param self Diesal.GUI.Object.DropDownPullout + GetItemsHeight = function(self) + local itemHeight = 0 + for i, item in ipairs(self.settings.items) do + itemHeight = itemHeight + item.text:GetStringHeight() + end + return itemHeight + end, + ---@param self Diesal.GUI.Object.DropDownPullout + GetMaxHeight = function(self) + local maxHeight = 0 + for i, item in ipairs(self.settings.items) do + if i <= self.maxItems then + maxHeight = maxHeight + item:GetHeight(false) + end + end + return maxHeight + --return self:GetMaxItemHeight() * min(self.maxItems, #self.settings.items) + end, + ---@param self Diesal.GUI.Object.DropDownPullout + ---@param item DiesalDropDownItem + ---@param setPoints? boolean + AddItem = function(self, item, setPoints) + table.insert(self.settings.items, item) + local maxWidth = 8 + (item.settings.indent * 6) + (16 * 2) + if item.text then + maxWidth = maxWidth + item.text:GetUnboundedStringWidth() + end + if item.check then + maxWidth = maxWidth + item.check:GetWidth() + 4 + end + self.settings.maxItemWidth = max(self.settings.maxItemWidth, maxWidth) + --self.frame:SetHeight(min(self:GetItemsHeight() + 28, self:GetMaxHeight() + 28)) + if setPoints then + item:SetPoint("LEFT", self.itemFrame, "LEFT", 20, 0) + item:SetPoint("RIGHT", self.itemFrame, "RIGHT", 0, 0) + end + item:SetPullout(self) + --item:SetScript("OnEnter", OnEnter) + end, + ---@param self Diesal.GUI.Object.DropDownPullout + ---@param value number + SetScroll = function(self, value) + local status = self.scrollStatus + local scrollFrame, itemFrame = self.scrollFrame, self.itemFrame + local height, viewheight = scrollFrame:GetHeight(), itemFrame:GetHeight() + --local minVal, maxVal = self.slider:GetMinMaxValues() + local minVal, maxVal = height, viewheight + local offset + if height > viewheight then + offset = 0 + self.slider2:Hide() + else + offset = floor(maxVal * value) + self.slider2:Show() + end + itemFrame:ClearAllPoints() + itemFrame:SetPoint("TOPLEFT", scrollFrame, "TOPLEFT", 0, offset) + itemFrame:SetPoint("TOPRIGHT", scrollFrame, "TOPRIGHT", self.slider2:IsShown() and -6 or 0, offset) + status.offset = offset + status.scrollvalue = (maxVal * value) + end, + ---@param self Diesal.GUI.Object.DropDownPullout + ---@param value number + MoveScroll = function(self, value) + local status = self.scrollStatus + local frame, child = self.scrollFrame, self.itemFrame + local height, viewheight = frame:GetHeight(), child:GetHeight() + --local minVal, maxVal = self.slider:GetMinMaxValues() + local minVal, maxVal = height, self:GetItemsHeight() + --child:SetHeight(self:GetItemsHeight()) + if height > viewheight then + self.slider2:Hide() + else + self.slider2:Show() + local diff = height - viewheight + local delta = 1 + if value < 0 then + delta = -1 + end + local scrollToVal = min(max(status.scrollvalue + delta * (maxVal / (diff / self.settings.itemHeight)), 0), maxVal) + self.slider2:SetScrollPercentage(scrollToVal/maxVal) + --self.slider:SetValue(scrollToVal) + end + end, + ---@param self Diesal.GUI.Object.DropDownPullout + FixScroll = function(self) + local status = self.scrollStatus + local frame, child = self.scrollFrame, self.itemFrame + local height, viewheight = frame:GetHeight(), child:GetHeight() + local offset = status.offset or 0 + local minVal, maxVal = height, viewheight + if viewheight < height then + self.slider2:Hide() + child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, offset) + self.scrollFrame:SetVerticalScroll(0) + else + self.slider2:Show() + local value = (offset / (viewheight - height) * maxVal) + --self.slider:SetValue(value) + self:SetScroll(value) + if value < maxVal then + child:ClearAllPoints() + child:SetPoint("TOPLEFT", frame, "TOPLEFT", 0, offset) + child:SetPoint("TOPRIGHT", frame, "TOPRIGHT", 0, offset) + status.offset = offset + end + end + end, + ---@param self Diesal.GUI.Object.DropDownPullout + ---@param point FramePoint + ---@param relFrame Frame + ---@param relPoint FramePoint + ---@param x number + ---@param y number + Open = function(self, point, relFrame, relPoint, x, y) + local items = self.settings.items + local frame = self.frame + local itemFrame = self.itemFrame + + frame:SetPoint(point, relFrame, relPoint, x, y) + local maxWidth = self.settings.maxItemWidth + self.slider2:GetWidth() + if self.dropdown.settings.dropdownWidth then + if self.dropdown.settings.dropdownWidth > maxWidth then + frame:SetWidth(self.dropdown.settings.dropdownWidth) + else + frame:SetWidth(maxWidth) + end + else + frame:SetWidth(max(maxWidth, self.dropdown.frame:GetWidth())) + --frame:SetPoint("TOPRIGHT", relFrame, "BOTTOMRIGHT", x, y) + end + local height = 0 + for i, item in ipairs(items) do + item:SetPoint("TOPLEFT", i == 1 and itemFrame or items[i - 1].frame, i == 1 and "TOPLEFT" or "BOTTOMLEFT", 0, 0) + item:Show() + height = height + item.text:GetStringHeight() + end + frame:Show() + frame:SetHeight(self:GetMaxHeight()) + itemFrame:SetHeight(self:GetItemsHeight()) + self.scrollFrame:SetScrollChild(itemFrame) + fixstrata("TOOLTIP", self.scrollFrame, self.scrollFrame:GetChildren()) + self:FireEvent("OnOpen") + end, + ---@param self Diesal.GUI.Object.DropDownPullout + Close = function(self) + self.frame:Hide() + self:FireEvent("OnClose") + end, + ---@param self Diesal.GUI.Object.DropDownPullout + Clear = function(self) + local items = self.settings.items + for i, item in ipairs(items) do + items[i] = nil + end + for i,item in ipairs(self.itemFrame) do + end + end, + ---@param self Diesal.GUI.Object.DropDownPullout + IterateItems = function(self) + return ipairs(self.settings.items) + end, + ---@param self Diesal.GUI.Object.DropDownPullout + SetHideOnLeave = function(self, val) + self.hideOnLeave = val + end, + ---@param self Diesal.GUI.Object.DropDownPullout + GetRightBorderWidth = function(self) + return 6 + (self.slider:IsShown() and 12 or 0) + end, + ---@param self Diesal.GUI.Object.DropDownPullout + GetLeftBorderWidth = function(self) + return 6 + end, + ---@param self Diesal.GUI.Object.DropDownPullout + ClearFocus = function(self) + self:Hide() + end, + ---@param self Diesal.GUI.Object.DropDownPullout + ---@param height? number + SetItemHeight = function(self, height) + self.settings.itemHeight = height or self.defaults.itemHeight + end, + ---@param self Diesal.GUI.Object.DropDownPullout + SetDropDown = function (self, dropdown) + self.dropdown = dropdown + end +} + +---@class Diesal.GUI.Object.DropDownPullout.Settings : Diesal.GUI.ObjectBase.Settings +---@field width number +---@field itemHeight number +---@field sliderWidth number +---@field hideOnLeave boolean +---@field items DiesalDropDownItem[] +---@field maxItemWidth number + +---@class DiesalDropDownPullout : Diesal.GUI.Object.DropDownPullout + +local function Constructor() + ---@class Diesal.GUI.Object.DropDownPullout : Diesal.GUI.ObjectBase, Diesal.GUI.DropDownPullout.Methods + ---@field settings Diesal.GUI.Object.DropDownPullout.Settings + ---@field items DiesalDropDownItem[] + ---@field dropdown DiesalDropDown + local self = DiesalGUI:Create(Type, true) + self:SetMethods(methods) + local frame = CreateFrame("Frame", nil, DiesalGUI.UIParent, "BackdropTemplate") + self.frame = frame + self:SetObj(self.frame) + + self.defaults = { + width = 200, + itemHeight = 12, + sliderWidth = 10, + hideOnLeave = true, + items = {}, + maxItemWidth = 0, + } + + self.scrollStatus = { + scrollvalue = 0, + } + self.hideOnLeave = false + self.maxItems = 20 + + frame:SetBackdrop(backdrop) + frame:SetBackdropColor(0, 0, 0, 1) + frame:SetBackdropBorderColor(0.2, 0.2, 0.2, 1) + frame:SetFrameStrata("FULLSCREEN_DIALOG") + frame:SetClampedToScreen(true) + frame:SetWidth(self.defaults.width) + frame:SetHeight(34) + frame:SetScript("OnHide", function(this) + self.dropdown.open = nil + self.dropdown.arrow:SetRotation(0) + DiesalGUI:ClearFocus() + end) + + self:CreateRegion("Frame", "content", frame) + + local scrollFrame = CreateFrame("ScrollFrame", nil, frame, "ScrollFrameTemplate") + local itemFrame = CreateFrame("Frame", nil, scrollFrame) + + self.scrollFrame = scrollFrame + self.itemFrame = itemFrame + + self:SetObj(self.scrollFrame) + self:SetObj(self.itemFrame) + + ---@type MinimalScrollBar + local slider2 = scrollFrame.ScrollBar + self.slider2 = slider2 + self.slider2:SetPoint("TOPLEFT", self.scrollFrame, "TOPRIGHT", -20, -2) + self.slider2:SetPoint("BOTTOMLEFT", self.scrollFrame, "BOTTOMRIGHT", -20, 5) + self.scrollFrame:SetVerticalScroll(0) + self.slider2:SetVisibleExtentPercentage(0.25) + self.slider2:SetThumbExtent(0.25) + self.slider2:RegisterCallback("OnScroll", function(this, percent) + self:SetScroll(percent) + end, self.slider2) + --local slider = CreateFrame("Slider", nil, scrollFrame, "BackdropTemplate") + --slider:SetOrientation("VERTICAL") + --slider:SetHitRectInsets(0, 0, -10, 0) + --slider:SetBackdrop(sliderBackdrop) + --slider:SetWidth(8) + --slider:SetThumbTexture("Interface\\Buttons\\UI-SliderBar-Button-Vertical") + --slider:SetFrameStrata("FULLSCREEN_DIALOG") + --self.slider = slider + --self:SetObj(self.slider) + scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT") + scrollFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT") + scrollFrame:EnableMouseWheel(true) + --[[ scrollFrame:SetScript("OnMouseWheel", function(this, value) + self:MoveScroll(value) + self:FireEvent("OnMouseWheel", value) + end) ]] + scrollFrame:SetToplevel(true) + scrollFrame:SetFrameStrata("FULLSCREEN_DIALOG") + + itemFrame:SetPoint("TOPLEFT", scrollFrame, "TOPLEFT", 0, 0) + itemFrame:SetPoint("TOPRIGHT", scrollFrame, "TOPRIGHT", -6, 0) + --itemFrame:SetHeight(400) + itemFrame:SetToplevel(true) + itemFrame:SetFrameStrata("FULLSCREEN_DIALOG") + scrollFrame.ItemFrame = itemFrame + scrollFrame:SetScrollChild(scrollFrame.ItemFrame) + + --slider:SetPoint("TOPLEFT", scrollFrame, "TOPRIGHT", -16, 0) + --slider:SetPoint("BOTTOMLEFT", scrollFrame, "BOTTOMRIGHT", -16, 0) + --slider:SetScript("OnValueChanged", function(this, value) + --self:SetScroll(value) + --end) + --slider:SetMinMaxValues(0, 1) + --slider:SetValueStep(1) + --slider:SetValue(0) + + scrollFrame:Show() + itemFrame:Show() + --slider:Hide() + + self:FixScroll() + + return self +end +DiesalGUI:RegisterObjectConstructor(Type, Constructor, Version) diff --git a/DiesalGUI-2.0/Objects/ObjectBase.lua b/DiesalGUI-2.0/Objects/ObjectBase.lua index 4166295..8228485 100644 --- a/DiesalGUI-2.0/Objects/ObjectBase.lua +++ b/DiesalGUI-2.0/Objects/ObjectBase.lua @@ -64,8 +64,9 @@ local ObjectBase = { ---@generic T : Diesal.GUI.ObjectBase ---@param self T | Diesal.GUI.ObjectBase - GetHeight = function(self) - return self.frame:GetHeight() + ---@param ignoreRect? boolean + GetHeight = function(self, ignoreRect) + return self.frame:GetHeight(ignoreRect) end, ---@generic T : Diesal.GUI.ObjectBase @@ -164,6 +165,7 @@ local ObjectBase = { ---|Frame ---|Texture ---|Diesal.Object + ---|BackdropTemplate --#region DiesalObjectMethods @@ -247,7 +249,7 @@ local ObjectBase = { ---@generic T : Diesal.GUI.ObjectBase ---@param self T - ---@param frame Frame + ---@param frame (Frame | BackdropTemplate | ScrollFrame | ScrollFrameTemplate)? SetObj = function(self, frame) ---@diagnostic disable-next-line: inject-field frame.obj = self @@ -460,8 +462,8 @@ DiesalGUI.ObjectBase = ObjectBase ---@field width number ---@class Diesal.GUI.ObjectBase.Methods ----@field OnAcquire fun() ----@field OnRelease fun() +---@field OnAcquire fun(self) +---@field OnRelease fun(self) ---@field ApplySettings fun(self) ---@alias DiesalObjectBase Diesal.GUI.ObjectBase @@ -490,6 +492,7 @@ local Constructor = function(objectType) children = {}, eventListeners = {}, methods = {}, + userdata = {}, } for k, v in pairs(ObjectBase) do