diff --git a/libs/LibStub/LibStub.luac b/libs/LibStub/LibStub.luac new file mode 100644 index 0000000..0f737d3 Binary files /dev/null and b/libs/LibStub/LibStub.luac differ diff --git a/libs/StdUi.zip b/libs/StdUi.zip new file mode 100644 index 0000000..e4ac383 Binary files /dev/null and b/libs/StdUi.zip differ diff --git a/libs/StdUi/.gitignore b/libs/StdUi/.gitignore new file mode 100644 index 0000000..8aa70a8 --- /dev/null +++ b/libs/StdUi/.gitignore @@ -0,0 +1,2 @@ +.idea +tests \ No newline at end of file diff --git a/libs/StdUi/StdUi.lua b/libs/StdUi/StdUi.lua new file mode 100755 index 0000000..3cd08ac --- /dev/null +++ b/libs/StdUi/StdUi.lua @@ -0,0 +1,297 @@ +local MAJOR, MINOR = 'StdUi', 5; +--- @class StdUi +local StdUi = LibStub:NewLibrary(MAJOR, MINOR); + +if not StdUi then + return +end + +local TableInsert = tinsert; + +StdUi.moduleVersions = {}; +if not StdUiInstances then + StdUiInstances = {StdUi}; +else + TableInsert(StdUiInstances, StdUi); +end + +function StdUi:NewInstance() + local instance = CopyTable(self); + instance:ResetConfig(); + TableInsert(StdUiInstances, instance); + return instance; +end + +function StdUi:RegisterModule(module, version) + self.moduleVersions[module] = version; +end + +function StdUi:UpgradeNeeded(module, version) + if not self.moduleVersions[module] then + return true; + end + + return self.moduleVersions[module] < version; +end + +function StdUi:RegisterWidget(name, func) + if not self[name] then + self[name] = func; + return true; + end + + return false; +end + +function StdUi:InitWidget(widget) + widget.isWidget = true; + + function widget:GetChildrenWidgets() + local children = {widget:GetChildren()}; + local result = {}; + for i = 1, #children do + local child = children[i]; + if child.isWidget then + TableInsert(result, child); + end + end + + return result; + end +end + +function StdUi:SetObjSize(obj, width, height) + if width then + obj:SetWidth(width); + end + + if height then + obj:SetHeight(height); + end +end + +function StdUi:SetTextColor(fontString, colorType) + colorType = colorType or 'normal'; + if fontString.SetTextColor then + local c = self.config.font.color[colorType]; + fontString:SetTextColor(c.r, c.g, c.b, c.a); + end +end + +StdUi.SetHighlightBorder = function(self) + if self.target then + self = self.target; + end + + if self.isDisabled then + return + end + + local hc = self.stdUi.config.highlight.color; + if not self.origBackdropBorderColor then + self.origBackdropBorderColor = {self:GetBackdropBorderColor()}; + end + self:SetBackdropBorderColor(hc.r, hc.g, hc.b, 1); +end + +StdUi.ResetHighlightBorder = function(self) + if self.target then + self = self.target; + end + + if self.isDisabled then + return + end + + local hc = self.origBackdropBorderColor; + if hc then + self:SetBackdropBorderColor(unpack(hc)); + end +end + +function StdUi:HookHoverBorder(object) + if not object.SetBackdrop then + Mixin(object, BackdropTemplateMixin) + end + object:HookScript('OnEnter', self.SetHighlightBorder); + object:HookScript('OnLeave', self.ResetHighlightBorder); +end + +function StdUi:ApplyBackdrop(frame, type, border, insets) + local config = frame.config or self.config; + local backdrop = { + bgFile = config.backdrop.texture, + edgeFile = config.backdrop.texture, + edgeSize = 1, + }; + if insets then + backdrop.insets = insets; + end + if not frame.SetBackdrop then + Mixin(frame, BackdropTemplateMixin) + end + frame:SetBackdrop(backdrop); + + type = type or 'button'; + border = border or 'border'; + + if config.backdrop[type] then + frame:SetBackdropColor( + config.backdrop[type].r, + config.backdrop[type].g, + config.backdrop[type].b, + config.backdrop[type].a + ); + end + + if config.backdrop[border] then + frame:SetBackdropBorderColor( + config.backdrop[border].r, + config.backdrop[border].g, + config.backdrop[border].b, + config.backdrop[border].a + ); + end +end + +function StdUi:ClearBackdrop(frame) + if not frame.SetBackdrop then + Mixin(frame, BackdropTemplateMixin) + end + frame:SetBackdrop(nil); +end + +function StdUi:ApplyDisabledBackdrop(frame, enabled) + if frame.target then + frame = frame.target; + end + + if enabled then + self:ApplyBackdrop(frame, 'button', 'border'); + self:SetTextColor(frame, 'normal'); + if frame.label then + self:SetTextColor(frame.label, 'normal'); + end + + if frame.text then + self:SetTextColor(frame.text, 'normal'); + end + frame.isDisabled = false; + else + self:ApplyBackdrop(frame, 'buttonDisabled', 'borderDisabled'); + self:SetTextColor(frame, 'disabled'); + if frame.label then + self:SetTextColor(frame.label, 'disabled'); + end + + if frame.text then + self:SetTextColor(frame.text, 'disabled'); + end + frame.isDisabled = true; + end +end + +function StdUi:HookDisabledBackdrop(frame) + local this = self; + hooksecurefunc(frame, 'Disable', function(self) + this:ApplyDisabledBackdrop(self, false); + end); + + hooksecurefunc(frame, 'Enable', function(self) + this:ApplyDisabledBackdrop(self, true); + end); +end + +function StdUi:StripTextures(frame) + for i = 1, frame:GetNumRegions() do + local region = select(i, frame:GetRegions()); + + if region and region:GetObjectType() == 'Texture' then + region:SetTexture(nil); + end + end +end + +function StdUi:MakeDraggable(frame, handle) + frame:SetMovable(true); + frame:EnableMouse(true); + frame:RegisterForDrag('LeftButton'); + frame:SetScript('OnDragStart', frame.StartMoving); + frame:SetScript('OnDragStop', frame.StopMovingOrSizing); + + if handle then + handle:EnableMouse(true); + handle:SetMovable(true); + handle:RegisterForDrag('LeftButton'); + + handle:SetScript('OnDragStart', function(self) + frame.StartMoving(frame); + end); + + handle:SetScript('OnDragStop', function(self) + frame.StopMovingOrSizing(frame); + end); + end +end + +-- Make a frame resizable +function StdUi:MakeResizable(frame, direction) + -- Possible resize directions and handle rotation values + local anchorDirections = { + ["TOP"] = 0, + ["TOPRIGHT"] = 1.5708, + ["RIGHT"] = 0, + ["BOTTOMRIGHT"] = 0, + ["BOTTOM"] = 0, + ["BOTTOMLEFT"] = -1.5708, + ["LEFT"] = 0, + ["TOPLEFT"] = 3.1416, + } + + direction = string.upper(direction); + + -- Return if invalid direction + if not anchorDirections[direction] then return false end + + frame:SetResizable(true); + + -- Create the resize anchor + local anchor = CreateFrame("Button", nil, frame); + anchor:SetPoint(direction, frame, direction); + + -- Attach side anchor to adjacent sides of frame + if direction == "TOP" or direction == "BOTTOM" then + anchor:SetHeight(self.config.resizeHandle.height); + anchor:SetPoint("LEFT", frame, "LEFT", self.config.resizeHandle.width, 0); + anchor:SetPoint("RIGHT", frame, "RIGHT", self.config.resizeHandle.width*-1, 0); + elseif direction == "LEFT" or direction == "RIGHT" then + anchor:SetWidth(self.config.resizeHandle.width); + anchor:SetPoint("TOP", frame, "TOP", 0, self.config.resizeHandle.height*-1); + anchor:SetPoint("BOTTOM", frame, "BOTTOM", 0, self.config.resizeHandle.height); + else + -- Set the corner anchor textures + anchor:SetNormalTexture(self.config.resizeHandle.texture.normal); + anchor:SetHighlightTexture(self.config.resizeHandle.texture.highlight); + anchor:SetPushedTexture(self.config.resizeHandle.texture.pushed); + + -- Set size and rotate corner anchor + anchor:SetSize(self.config.resizeHandle.width, self.config.resizeHandle.height); + anchor:GetNormalTexture():SetRotation(anchorDirections[direction]); + anchor:GetHighlightTexture():SetRotation(anchorDirections[direction]); + anchor:GetPushedTexture():SetRotation(anchorDirections[direction]); + end + + -- Resize anchor click handlers + anchor:SetScript("OnMouseDown", function(self, button) + if button == "LeftButton" then + frame:StartSizing(direction); + frame:SetUserPlaced(true); + end + end) + anchor:SetScript("OnMouseUp", function(self, button) + if button == "LeftButton" then + frame:StopMovingOrSizing(); + end + end) +end + diff --git a/libs/StdUi/StdUi.xml b/libs/StdUi/StdUi.xml new file mode 100755 index 0000000..f3e03e0 --- /dev/null +++ b/libs/StdUi/StdUi.xml @@ -0,0 +1,30 @@ + +