diff --git a/lib/Types.lua b/lib/Types.lua index bf26b6b..9f8e6eb 100644 --- a/lib/Types.lua +++ b/lib/Types.lua @@ -471,9 +471,8 @@ export type WidgetUtility = { UNKNOWN_TEXTURE: string, }, - GuiInset: Vector2?, - setGuiInset: () -> Vector2, - getGuiInset: () -> Vector2, + GuiOffset: Vector2, + MouseOffset: Vector2, findBestWindowPosForPopup: (refPos: Vector2, size: Vector2, outerMin: Vector2, outerMax: Vector2) -> Vector2, getScreenSizeForWindow: (thisWidget: Widget) -> Vector2, diff --git a/lib/demoWindow.lua b/lib/demoWindow.lua index e83e00c..84045a3 100644 --- a/lib/demoWindow.lua +++ b/lib/demoWindow.lua @@ -634,8 +634,14 @@ return function(Iris: Types.Iris) do Iris.CollapsingHeader({ "Widgets" }) do + Iris.SeparatorText({ "GuiService" }) + Iris.Text({ `GuiOffset: {Iris.Internal._utility.GuiOffset}` }) + Iris.Text({ `MouseOffset: {Iris.Internal._utility.MouseOffset}` }) + Iris.SeparatorText({ "UserInputService" }) Iris.Text({ `MousePosition: {Iris.Internal._utility.UserInputService:GetMouseLocation()}` }) + Iris.Text({ `MouseLocation: {Iris.Internal._utility.getMouseLocation()}` }) + Iris.Text({ `Left Control: {Iris.Internal._utility.UserInputService:IsKeyDown(Enum.KeyCode.LeftControl)}` }) Iris.Text({ `Right Control: {Iris.Internal._utility.UserInputService:IsKeyDown(Enum.KeyCode.RightControl)}` }) end @@ -778,7 +784,6 @@ return function(Iris: Types.Iris) Iris.SeparatorText({ "Config" }) BooleanInput({ "UseScreenGUIs" }) - BooleanInput({ "IgnoreGuiInset" }) SliderInput("DragNum", { "DisplayOrderOffset", 1, 0 }) SliderInput("DragNum", { "ZIndexOffset", 1, 0 }) SliderInput("SliderNum", { "MouseDoubleClickTime", 0.1, 0, 5 }) diff --git a/lib/widgets/Input.lua b/lib/widgets/Input.lua index fd7ef0d..8195532 100644 --- a/lib/widgets/Input.lua +++ b/lib/widgets/Input.lua @@ -873,7 +873,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) local max: number = ActiveSlider.arguments.Max and getValueByIndex(ActiveSlider.arguments.Max, ActiveIndex, ActiveSlider.arguments) or defaultMax[ActiveDataType][ActiveIndex] local GrabWidth: number = GrabBar.AbsoluteSize.X - local Offset: number = widgets.getMouseLocation().X - (SliderField.AbsolutePosition.X + GrabWidth / 2) + local Offset: number = widgets.getMouseLocation().X - (SliderField.AbsolutePosition.X - widgets.GuiOffset.X + GrabWidth / 2) local Ratio: number = Offset / (SliderField.AbsoluteSize.X - GrabWidth) local Positions: number = math.floor((max - min) / increment) local newValue: number = math.clamp(math.round(Ratio * Positions) * increment + min, min, max) diff --git a/lib/widgets/Menu.lua b/lib/widgets/Menu.lua index ecd96e2..82f38e3 100644 --- a/lib/widgets/Menu.lua +++ b/lib/widgets/Menu.lua @@ -78,7 +78,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) local MouseLocation: Vector2 = widgets.getMouseLocation() for _, menu: Types.Widget in MenuStack do for _, container: GuiObject in { menu.ChildContainer, menu.Instance } do - local rectMin: Vector2 = container.AbsolutePosition + local rectMin: Vector2 = container.AbsolutePosition - widgets.GuiOffset local rectMax: Vector2 = rectMin + container.AbsoluteSize if widgets.isPosInsideRect(MouseLocation, rectMin, rectMax) then isInMenu = true @@ -256,9 +256,9 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end) local ChildContainer: ScrollingFrame = Instance.new("ScrollingFrame") - ChildContainer.Name = "ChildContainer" - ChildContainer.BackgroundColor3 = Iris._config.WindowBgColor - ChildContainer.BackgroundTransparency = Iris._config.WindowBgTransparency + ChildContainer.Name = "MenuContainer" + ChildContainer.BackgroundColor3 = Iris._config.PopupBgColor + ChildContainer.BackgroundTransparency = Iris._config.PopupBgTransparency ChildContainer.BorderSizePixel = 0 ChildContainer.Size = UDim2.fromOffset(0, 0) ChildContainer.AutomaticSize = Enum.AutomaticSize.XY diff --git a/lib/widgets/Window.lua b/lib/widgets/Window.lua index 5779381..6f3bc1d 100644 --- a/lib/widgets/Window.lua +++ b/lib/widgets/Window.lua @@ -214,7 +214,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) local position: Vector2 = widgets.getMouseLocation() for _, window in windowWidgets do local ResizeBorder: TextButton = window.Instance and window.Instance.WindowButton.ResizeBorder - if ResizeBorder and widgets.isPosInsideRect(position, ResizeBorder.AbsolutePosition, ResizeBorder.AbsolutePosition + ResizeBorder.AbsoluteSize) then + if ResizeBorder and widgets.isPosInsideRect(position, ResizeBorder.AbsolutePosition - widgets.GuiOffset, ResizeBorder.AbsolutePosition - widgets.GuiOffset + ResizeBorder.AbsoluteSize) then inWindow = true break end diff --git a/lib/widgets/init.lua b/lib/widgets/init.lua index aacf573..8201679 100644 --- a/lib/widgets/init.lua +++ b/lib/widgets/init.lua @@ -29,23 +29,26 @@ return function(Iris: Types.Internal) end end - function widgets.setGuiInset() - local inset = widgets.GuiService:GetGuiInset() + -- acts as an offset where the absolute position of the base frame is not zero, such as IgnoreGuiInset or for stories + widgets.GuiOffset = Vector2.zero + -- the registered mouse position always ignores the topbar, so needs a separate variable offset + widgets.MouseOffset = if Iris._config.IgnoreGuiInset then Vector2.zero else widgets.GuiService:GetGuiInset() + + -- the topbar inset changes updates a frame later. + local connection: RBXScriptConnection = widgets.GuiService:GetPropertyChangedSignal("TopbarInset"):Once(function() + widgets.MouseOffset = if Iris._config.IgnoreGuiInset then Vector2.zero else widgets.GuiService:GetGuiInset() + end) + -- in case the topbar doesn't change, we cancel the event. + task.delay(3, function() + connection:Disconnect() + end) - -- Inset is not guaranteed to be set upon initialization. - if inset.Magnitude > 0 then - widgets.GuiInset = inset - end - - return inset - end - - function widgets.getGuiInset() - return widgets.GuiInset or widgets.setGuiInset() + function widgets.getMouseLocation(): Vector2 + return widgets.UserInputService:GetMouseLocation() - widgets.MouseOffset end - function widgets.getMouseLocation(): Vector2 - return widgets.UserInputService:GetMouseLocation() - widgets.getGuiInset() + function widgets.isPosInsideRect(pos: Vector2, rectMin: Vector2, rectMax: Vector2): boolean + return pos.X > rectMin.X and pos.X < rectMax.X and pos.Y > rectMin.Y and pos.Y < rectMax.Y end function widgets.findBestWindowPosForPopup(refPos: Vector2, size: Vector2, outerMin: Vector2, outerMax: Vector2): Vector2 @@ -68,8 +71,21 @@ return function(Iris: Types.Internal) return clampedPos end - function widgets.isPosInsideRect(pos: Vector2, rectMin: Vector2, rectMax: Vector2): boolean - return pos.X > rectMin.X and pos.X < rectMax.X and pos.Y > rectMin.Y and pos.Y < rectMax.Y + function widgets.getScreenSizeForWindow(thisWidget: Types.Widget): Vector2 -- possible parents are GuiBase2d, CoreGui, PlayerGui + if thisWidget.Instance:IsA("GuiBase2d") then + return thisWidget.Instance.AbsoluteSize + else + local rootParent = thisWidget.Instance.Parent + if rootParent:IsA("GuiBase2d") then + return rootParent.AbsoluteSize + else + if rootParent.Parent:IsA("GuiBase2d") then + return rootParent.AbsoluteSize + else + return workspace.CurrentCamera.ViewportSize + end + end + end end function widgets.extend(superClass: Types.WidgetClass, subClass: Types.WidgetClass): Types.WidgetClass @@ -134,25 +150,6 @@ return function(Iris: Types.Internal) return ObjectValue end - function widgets.getScreenSizeForWindow(thisWidget: Types.Widget): Vector2 -- possible parents are GuiBase2d, CoreGui, PlayerGui - local size: Vector2 - if thisWidget.Instance:IsA("GuiBase2d") then - size = thisWidget.Instance.AbsoluteSize - else - local rootParent = thisWidget.Instance.Parent - if rootParent:IsA("GuiBase2d") then - size = rootParent.AbsoluteSize - else - if rootParent.Parent:IsA("GuiBase2d") then - size = rootParent.AbsoluteSize - else - size = workspace.CurrentCamera.ViewportSize - end - end - end - return size - end - -- below uses Iris local textParams: GetTextBoundsParams = Instance.new("GetTextBoundsParams") diff --git a/stories/exampleStory.story.lua b/stories/exampleStory.story.lua index 01c46ab..cb7dcb5 100644 --- a/stories/exampleStory.story.lua +++ b/stories/exampleStory.story.lua @@ -1,7 +1,8 @@ local ReplicatedStorage = game:GetService("ReplicatedStorage") +local Types = require(ReplicatedStorage.Iris.Types) return function(parent: GuiObject) - local Iris = require(ReplicatedStorage.Iris) + local Iris: Types.Iris = require(ReplicatedStorage.Iris) local Input = require(script.Parent.UserInputService) Input.SinkFrame.Parent = parent @@ -10,6 +11,12 @@ return function(parent: GuiObject) Iris.UpdateGlobalConfig({ UseScreenGUIs = false, }) + Iris.Internal._utility.GuiOffset = Input.SinkFrame.AbsolutePosition + Iris.Internal._utility.MouseOffset = Input.SinkFrame.AbsolutePosition + Input.SinkFrame:GetPropertyChangedSignal("AbsolutePosition"):Connect(function() + Iris.Internal._utility.GuiOffset = Input.SinkFrame.AbsolutePosition + Iris.Internal._utility.MouseOffset = Input.SinkFrame.AbsolutePosition + end) Iris.Init(parent)