diff --git a/lib/API.lua b/lib/API.lua index c769432..d68cb9b 100644 --- a/lib/API.lua +++ b/lib/API.lua @@ -2,7 +2,7 @@ local Types = require(script.Parent.Types) return function(Iris: Types.Iris) -- basic wrapper for nearly every widget, saves space. - local function wrapper(name: string): (arguments: Types.WidgetArguments?, states: Types.WidgetStates?) -> Types.Widget + local function wrapper(name: string) return function(arguments: Types.WidgetArguments?, states: Types.WidgetStates?): Types.Widget return Iris.Internal._Insert(name, arguments, states) end @@ -84,7 +84,7 @@ return function(Iris: Types.Iris) --[=[ @function SetFocusedWindow @within Iris - @param window Types.Widget -- the window to focus. + @param window Types.Window -- the window to focus. Sets the focused window to the window provided, which brings it to the front and makes it active. ]=] @@ -362,9 +362,9 @@ return function(Iris: Types.Iris) } ``` ]=] - Iris.TextWrapped = function(arguments: Types.WidgetArguments): Types.Widget + Iris.TextWrapped = function(arguments: Types.WidgetArguments): Types.Text arguments[2] = true - return Iris.Internal._Insert("Text", arguments) + return Iris.Internal._Insert("Text", arguments) :: Types.Text end --[=[ @@ -387,10 +387,10 @@ return function(Iris: Types.Iris) } ``` ]=] - Iris.TextColored = function(arguments: Types.WidgetArguments): Types.Widget + Iris.TextColored = function(arguments: Types.WidgetArguments): Types.Text arguments[3] = arguments[2] arguments[2] = nil - return Iris.Internal._Insert("Text", arguments) + return Iris.Internal._Insert("Text", arguments) :: Types.Text end --[=[ @@ -1495,7 +1495,7 @@ return function(Iris: Types.Iris) } ``` ]=] - Iris.ComboArray = function(arguments: Types.WidgetArguments, states: Types.WidgetStates?, selectionArray: { any }) + Iris.ComboArray = function(arguments: Types.WidgetArguments, states: Types.WidgetStates?, selectionArray: { T }) local defaultState if states == nil then defaultState = Iris.State(selectionArray[1]) @@ -1503,7 +1503,7 @@ return function(Iris: Types.Iris) defaultState = states end local thisWidget = Iris.Internal._Insert("Combo", arguments, defaultState) - local sharedIndex: Types.State = thisWidget.state.index + local sharedIndex: Types.State = thisWidget.state.index for _, Selection in selectionArray do Iris.Internal._Insert("Selectable", { Selection, Selection }, { index = sharedIndex } :: Types.States) end @@ -1560,6 +1560,38 @@ return function(Iris: Types.Iris) return thisWidget end + + --[=[ + @private + @prop InputEnum Iris.InputEnum + @within Slider + @tag Widget + @tag HasState + + A field which allows the user to slide a grip to enter a number within a range. + You can ctrl + click to directly input a number, like InputNum. + + ```lua + hasChildren = false + hasState = true + Arguments = { + Text: string? = "InputEnum", + Increment: number? = 1, + Min: number? = 0, + Max: number? = 100, + Format: string? | { string }? = [DYNAMIC] -- Iris will dynamically generate an approriate format. + } + Events = { + numberChanged: () -> boolean, + hovered: () -> boolean + } + States = { + number: State?, + editingText: State?, + enumItem: EnumItem + } + ``` + ]=] Iris.InputEnum = Iris.ComboEnum --[[ @@ -1640,7 +1672,7 @@ return function(Iris: Types.Iris) then the next cell will be the first column of the next row. ]=] Iris.NextColumn = function() - local parentWidget: Types.Widget = Iris.Internal._GetParentWidget() + local parentWidget = Iris.Internal._GetParentWidget() :: Types.Table assert(parentWidget.type == "Table", "Iris.NextColumn can only be called within a table.") parentWidget.RowColumnIndex += 1 end @@ -1653,7 +1685,7 @@ return function(Iris: Types.Iris) In a table, directly sets the index of the column. ]=] Iris.SetColumnIndex = function(columnIndex: number) - local parentWidget: Types.Widget = Iris.Internal._GetParentWidget() + local parentWidget = Iris.Internal._GetParentWidget() :: Types.Table assert(parentWidget.type == "Table", "Iris.SetColumnIndex can only be called within a table.") assert(columnIndex >= parentWidget.InitialNumColumns, "Iris.SetColumnIndex Argument must be in column range") parentWidget.RowColumnIndex = math.floor(parentWidget.RowColumnIndex / parentWidget.InitialNumColumns) + (columnIndex - 1) @@ -1668,7 +1700,7 @@ return function(Iris: Types.Iris) ]=] Iris.NextRow = function() -- sets column Index back to 0, increments Row - local parentWidget: Types.Widget = Iris.Internal._GetParentWidget() + local parentWidget = Iris.Internal._GetParentWidget() :: Types.Table assert(parentWidget.type == "Table", "Iris.NextColumn can only be called within a table.") local InitialNumColumns: number = parentWidget.InitialNumColumns local nextRow: number = math.floor((parentWidget.RowColumnIndex + 1) / InitialNumColumns) * InitialNumColumns diff --git a/lib/Internal.lua b/lib/Internal.lua index da363df..ac37e99 100644 --- a/lib/Internal.lua +++ b/lib/Internal.lua @@ -127,7 +127,7 @@ return function(Iris: Types.Iris): Types.Internal Returns the states current value. ]=] - function StateClass:get(): any -- you can also simply use .value + function StateClass:get(): T -- you can also simply use .value return self.value end @@ -137,7 +137,7 @@ return function(Iris: Types.Iris): Types.Internal Allows the caller to assign the state object a new value, and returns the new value. ]=] - function StateClass:set(newValue: any): any + function StateClass:set(newValue: T): T if newValue == self.value then -- no need to update on no change. return self.value @@ -158,7 +158,7 @@ return function(Iris: Types.Iris): Types.Internal Allows the caller to connect a callback which is called when the states value is changed. ]=] - function StateClass:onChange(callback: (newValue: any) -> ()): () -> () + function StateClass:onChange(callback: (newValue: T) -> ()): () -> () local connectionIndex: number = #self.ConnectedFunctions + 1 self.ConnectedFunctions[connectionIndex] = callback return function() @@ -443,7 +443,7 @@ return function(Iris: Types.Iris): Types.Internal end local thisWidget: Types.Widget = if lastWidget == nil then Internal._GenNewWidget(widgetType, arguments, states, ID) else lastWidget - local parentWidget: Types.Widget = thisWidget.parentWidget + local parentWidget: Types.ParentWidget = thisWidget.parentWidget if thisWidget.type ~= "Window" and thisWidget.type ~= "Tooltip" then if thisWidget.ZIndex ~= parentWidget.ZOffset then @@ -472,9 +472,10 @@ return function(Iris: Types.Iris): Types.Internal parentWidget.ZOffset += 1 if thisWidgetClass.hasChildren then + local thisParent = thisWidget :: Types.ParentWidget -- a parent widget, so we increase our depth. - thisWidget.ZOffset = 0 - thisWidget.ZUpdate = false + thisParent.ZOffset = 0 + thisParent.ZUpdate = false Internal._stackIndex += 1 Internal._IDStack[Internal._stackIndex] = thisWidget.ID end @@ -501,7 +502,7 @@ return function(Iris: Types.Iris): Types.Internal ]=] function Internal._GenNewWidget(widgetType: string, arguments: Types.Arguments, states: Types.WidgetStates?, ID: Types.ID): Types.Widget local parentId: Types.ID = Internal._IDStack[Internal._stackIndex] - local parentWidget: Types.Widget = Internal._VDOM[parentId] + local parentWidget: Types.ParentWidget = Internal._VDOM[parentId] local thisWidgetClass: Types.WidgetClass = Internal._widgets[widgetType] -- widgets are just tables with properties. @@ -534,31 +535,32 @@ return function(Iris: Types.Iris): Types.Internal local eventMTParent if thisWidgetClass.hasState then + local stateWidget = thisWidget :: Types.StateWidget if states then - for index: string, state: Types.State in states do + for index: string, state: Types.State in states do if not (type(state) == "table" and getmetatable(state :: any) == Internal.StateClass) then -- generate a new state. - states[index] = Internal._widgetState(thisWidget, index, state) + states[index] = Internal._widgetState(stateWidget, index, state) end end - thisWidget.state = states - for _, state: Types.State in states do - state.ConnectedWidgets[thisWidget.ID] = thisWidget + stateWidget.state = states + for _, state: Types.State in states do + state.ConnectedWidgets[stateWidget.ID] = stateWidget end else - thisWidget.state = {} + stateWidget.state = {} end - thisWidgetClass.GenerateState(thisWidget) - thisWidgetClass.UpdateState(thisWidget) + thisWidgetClass.GenerateState(stateWidget) + thisWidgetClass.UpdateState(stateWidget) -- the state MT can't be itself because state has to explicitly only contain stateClass objects - thisWidget.stateMT = {} - setmetatable(thisWidget.state, thisWidget.stateMT) + stateWidget.stateMT = {} + setmetatable(stateWidget.state, stateWidget.stateMT) - thisWidget.__index = thisWidget.state - eventMTParent = thisWidget.stateMT + stateWidget.__index = stateWidget.state + eventMTParent = stateWidget.stateMT else eventMTParent = thisWidget end @@ -630,7 +632,7 @@ return function(Iris: Types.Iris): Types.Internal Connects the state to the widget. If no state exists then a new one is created. Called for every state in every widget if the user does not provide a state. ]=] - function Internal._widgetState(thisWidget: Types.Widget, stateName: string, initialValue: any): Types.State + function Internal._widgetState(thisWidget: Types.StateWidget, stateName: string, initialValue: any): Types.State local ID: Types.ID = thisWidget.ID .. stateName if Internal._states[ID] then Internal._states[ID].ConnectedWidgets[thisWidget.ID] = thisWidget @@ -675,7 +677,7 @@ return function(Iris: Types.Iris): Types.Internal Returns the parent widget of the currently active widget, based on the stack depth. ]=] - function Internal._GetParentWidget(): Types.Widget + function Internal._GetParentWidget(): Types.ParentWidget return Internal._VDOM[Internal._IDStack[Internal._stackIndex]] end diff --git a/lib/PubTypes.lua b/lib/PubTypes.lua new file mode 100644 index 0000000..e345ddb --- /dev/null +++ b/lib/PubTypes.lua @@ -0,0 +1,39 @@ +local Types = require(script.Parent.Types) + +export type ID = Types.ID +export type State = Types.State + +export type Widget = Types.Widget +export type Root = Types.Root +export type Window = Types.Window +export type Tooltip = Types.Tooltip +export type MenuBar = Types.MenuBar +export type Menu = Types.Menu +export type MenuItem = Types.MenuItem +export type MenuToggle = Types.MenuToggle +export type Separator = Types.Separator +export type Indent = Types.Indent +export type SameLine = Types.SameLine +export type Group = Types.Group +export type Text = Types.Text +export type SeparatorText = Types.SeparatorText +export type Button = Types.Button +export type Checkbox = Types.Checkbox +export type RadioButton = Types.RadioButton +export type Image = Types.Image +export type ImageButton = Types.ImageButton +export type Tree = Types.Tree +export type CollapsingHeader = Types.CollapsingHeader +export type Input = Types.Input +export type InputColor3 = Types.InputColor3 +export type InputColor4 = Types.InputColor4 +export type InputEnum = Types.InputEnum +export type InputText = Types.InputText +export type Selectable = Types.Selectable +export type Combo = Types.Combo +export type ProgressBar = Types.ProgressBar +export type Table = Types.Table + +export type Iris = Types.Iris + +return {} diff --git a/lib/Types.lua b/lib/Types.lua index 022f8de..da969fb 100644 --- a/lib/Types.lua +++ b/lib/Types.lua @@ -1,9 +1,61 @@ -export type ID = string - --- Arguments, States & Events +local WidgetTypes = require(script.Parent.WidgetTypes) + +export type ID = WidgetTypes.ID +export type State = WidgetTypes.State + +export type Hovered = WidgetTypes.Hovered +export type Clicked = WidgetTypes.Clicked +export type RightClicked = WidgetTypes.RightClicked +export type DoubleClicked = WidgetTypes.DoubleClicked +export type CtrlClicked = WidgetTypes.CtrlClicked +export type Active = WidgetTypes.Active +export type Checked = WidgetTypes.Checked +export type Unchecked = WidgetTypes.Unchecked +export type Opened = WidgetTypes.Opened +export type Closed = WidgetTypes.Closed +export type Collapsed = WidgetTypes.Collapsed +export type Uncollapsed = WidgetTypes.Uncollapsed +export type Selected = WidgetTypes.Selected +export type Unselected = WidgetTypes.Unselected +export type Changed = WidgetTypes.Changed +export type NumberChanged = WidgetTypes.NumberChanged +export type TextChanged = WidgetTypes.TextChanged + +export type Widget = WidgetTypes.Widget +export type ParentWidget = WidgetTypes.ParentWidget +export type StateWidget = WidgetTypes.StateWidget + +export type Root = WidgetTypes.Root +export type Window = WidgetTypes.Window +export type Tooltip = WidgetTypes.Tooltip +export type MenuBar = WidgetTypes.MenuBar +export type Menu = WidgetTypes.Menu +export type MenuItem = WidgetTypes.MenuItem +export type MenuToggle = WidgetTypes.MenuToggle +export type Separator = WidgetTypes.Separator +export type Indent = WidgetTypes.Indent +export type SameLine = WidgetTypes.SameLine +export type Group = WidgetTypes.Group +export type Text = WidgetTypes.Text +export type SeparatorText = WidgetTypes.SeparatorText +export type Button = WidgetTypes.Button +export type Checkbox = WidgetTypes.Checkbox +export type RadioButton = WidgetTypes.RadioButton +export type Image = WidgetTypes.Image +export type ImageButton = WidgetTypes.ImageButton +export type Tree = WidgetTypes.Tree +export type CollapsingHeader = WidgetTypes.CollapsingHeader +export type Input = WidgetTypes.Input +export type InputColor3 = WidgetTypes.InputColor3 +export type InputColor4 = WidgetTypes.InputColor4 +export type InputEnum = WidgetTypes.InputEnum +export type InputText = WidgetTypes.InputText +export type Selectable = WidgetTypes.Selectable +export type Combo = WidgetTypes.Combo +export type ProgressBar = WidgetTypes.ProgressBar +export type Table = WidgetTypes.Table export type InputDataType = number | Vector2 | Vector3 | UDim | UDim2 | Color3 | Rect | { number } -export type InputDataTypes = "Num" | "Vector2" | "Vector3" | "UDim" | "UDim2" | "Color3" | "Color4" | "Rect" | "Enum" | "" | string export type Argument = any export type Arguments = { @@ -64,32 +116,22 @@ export type Arguments = { Disabled: boolean, } -export type State = { - value: any, - ConnectedWidgets: { [ID]: Widget }, - ConnectedFunctions: { (any) -> () }, - - get: (self: State) -> any, - set: (self: State, newValue: any) -> (), - onChange: (self: State, funcToConnect: (any) -> ()) -> () -> (), -} - export type States = { - [string]: State, - number: State, - color: State, - transparency: State, - editingText: State, - index: State, - - size: State, - position: State, - progress: State, - scrollDistance: State, - - isChecked: State, - isOpened: State, - isUncollapsed: State, + [string]: State, + number: State, + color: State, + transparency: State, + editingText: State, + index: State, + + size: State, + position: State, + progress: State, + scrollDistance: State, + + isChecked: State, + isOpened: State, + isUncollapsed: State, } export type Event = { @@ -102,102 +144,21 @@ export type Events = { [string]: Event } export type WidgetArguments = { [number]: Argument } export type WidgetStates = { - number: State?, - color: State?, - transparency: State?, - editingText: State?, - index: State?, - - size: State?, - position: State?, - scrollDistance: State?, - - isChecked: State?, - isOpened: State?, - isUncollapsed: State?, - - [string]: State, -} - -type EventAPI = () -> boolean -export type Widget = { - ID: ID, - type: string, - lastCycleTick: number, - trackedEvents: {}, - parentWidget: Widget, - UID: string, - - state: States, - arguments: Arguments, - providedArguments: Arguments, - - Instance: GuiObject, - ZIndex: number, - - -- Parents - ChildContainer: GuiObject, - ZOffset: number, - ZUpdate: boolean, - - usesScreenGUI: boolean, - - -- Combo & Table properties - ButtonColors: { [string]: Color3 | number }, - - RowColumnIndex: number, - InitialNumColumns: number, - ColumnInstances: { Frame }, - CellInstances: { Frame }, - - -- Event Props - isHoveredEvent: boolean, - - lastClickedTick: number, - lastClickedTime: number, - lastClickedPosition: Vector2, - - lastRightClickedTick: number, - lastDoubleClickedTick: number, - lastCtrlClickedTick: number, - - lastCheckedTick: number, - lastUncheckedTick: number, - lastOpenedTick: number, - lastClosedTick: number, - lastSelectedTick: number, - lastUnselectedTick: number, - lastCollapsedTick: number, - lastUncollapsedTick: number, - - lastNumberChangedTick: number, - lastTextchangeTick: number, - lastShortcutTick: number, - - -- Events - hovered: EventAPI, - clicked: EventAPI, - rightClicked: EventAPI, - ctrlClicked: EventAPI, - doubleClicked: EventAPI, - - checked: EventAPI, - unchecked: EventAPI, - activated: EventAPI, - deactivated: EventAPI, - collapsed: EventAPI, - uncollapsed: EventAPI, - selected: EventAPI, - unselected: EventAPI, - opened: EventAPI, - closed: EventAPI, - - active: EventAPI, - - numberChanged: EventAPI, - textChanged: EventAPI, - - [string]: EventAPI & State, + [string]: State, + number: State?, + color: State?, + transparency: State?, + editingText: State?, + index: State?, + + size: State?, + position: State?, + progress: State?, + scrollDistance: State?, + + isChecked: State?, + isOpened: State?, + isUncollapsed: State?, } export type WidgetClass = { @@ -218,146 +179,6 @@ export type WidgetClass = { ChildDiscarded: (thisWidget: Widget, thisChild: Widget) -> (), } --- Iris - -export type Iris = { - --[[ - ----------- - WIDGETS - ----------- - ]] - - End: () -> (), - - -- Window API - Window: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - Tooltip: (arguments: WidgetArguments) -> Widget, - - -- Menu Widget API - MenuBar: () -> Widget, - Menu: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - MenuItem: (arguments: WidgetArguments) -> Widget, - MenuToggle: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - - -- Format Widget API - Separator: () -> Widget, - Indent: (arguments: WidgetArguments?) -> Widget, - SameLine: (arguments: WidgetArguments?) -> Widget, - Group: () -> Widget, - - -- Text Widget API - Text: (arguments: WidgetArguments) -> Widget, - TextWrapped: (arguments: WidgetArguments) -> Widget, - TextColored: (arguments: WidgetArguments) -> Widget, - SeparatorText: (arguments: WidgetArguments) -> Widget, - InputText: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - - -- Basic Widget API - Button: (arguments: WidgetArguments) -> Widget, - SmallButton: (arguments: WidgetArguments) -> Widget, - Checkbox: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - RadioButton: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - - -- Tree Widget API - Tree: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - CollapsingHeader: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - - -- Input Widget API - InputNum: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - InputVector2: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - InputVector3: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - InputUDim: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - InputUDim2: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - InputRect: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - InputColor3: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - InputColor4: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - - -- Drag Widget API - DragNum: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - DragVector2: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - DragVector3: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - DragUDim: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - DragUDim2: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - DragRect: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - - -- Slider Widget API - SliderNum: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - SliderVector2: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - SliderVector3: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - SliderUDim: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - SliderUDim2: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - SliderRect: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - SliderEnum: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - - -- Combo Widget Widget API - Selectable: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - Combo: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - ComboArray: (arguments: WidgetArguments, states: WidgetStates?, selectionArray: { any }) -> Widget, - ComboEnum: (arguments: WidgetArguments, states: WidgetStates?, enumType: Enum) -> Widget, - InputEnum: (arguments: WidgetArguments, states: WidgetStates?, enumType: Enum) -> Widget, - - ProgressBar: (arguments: WidgetArguments, states: WidgetStates?) -> Widget, - - Image: (arguments: WidgetArguments) -> Widget, - ImageButton: (arguments: WidgetArguments) -> Widget, - - -- Table Widget Api - Table: (arguments: WidgetArguments) -> Widget, - NextColumn: () -> (), - SetColumnIndex: (columnIndex: number) -> (), - NextRow: () -> (), - - --[[ - --------- - STATE - --------- - ]] - - State: (initialValue: any) -> State, - WeakState: (initialValue: any) -> State, - ComputedState: (firstState: State, onChangeCallback: (firstState: any) -> any) -> State, - - --[[ - ------------- - FUNCTIONS - ------------- - ]] - - Init: (playerInstance: BasePlayerGui?, eventConnection: (RBXScriptConnection | () -> ())?) -> Iris, - Shutdown: () -> (), - Connect: (self: Iris, callback: () -> ()) -> () -> (), - Append: (userInstance: GuiObject) -> (), - ForceRefresh: () -> (), - - -- Widget - SetFocusedWindow: (thisWidget: Widget?) -> (), - - -- ID API - PushId: (id: ID) -> (), - PopId: () -> (), - SetNextWidgetID: (id: ID) -> (), - - -- Config API - UpdateGlobalConfig: (deltaStyle: { [string]: any }) -> (), - PushConfig: (deltaStyle: { [string]: any }) -> (), - PopConfig: () -> (), - - --[[ - -------------- - PROPERTIES - -------------- - ]] - - Internal: Internal, - Disabled: boolean, - Args: { [string]: { [string]: number } }, - Events: { [string]: () -> boolean }, - - TemplateConfig: { [string]: Config }, - _config: Config, - ShowDemoWindow: () -> Widget, -} - export type Internal = { --[[ -------------- @@ -376,9 +197,10 @@ export type Internal = { -- Widgets & Instances _widgets: { [string]: WidgetClass }, + _widgetCount: number, _stackIndex: number, _rootInstance: GuiObject?, - _rootWidget: Widget, + _rootWidget: ParentWidget, _lastWidget: Widget, SelectionImageObject: Frame, parentInstance: BasePlayerGui, @@ -399,7 +221,7 @@ export type Internal = { _VDOM: { [ID]: Widget }, -- State - _states: { [ID]: State }, + _states: { [ID]: State }, -- Callback _postCycleCallbacks: { () -> () }, @@ -417,9 +239,9 @@ export type Internal = { StateClass: { __index: any, - get: (self: State) -> any, - set: (self: State, newValue: any) -> any, - onChange: (self: State, callback: (newValue: any) -> ()) -> (), + get: (self: State) -> any, + set: (self: State, newValue: any) -> any, + onChange: (self: State, callback: (newValue: any) -> ()) -> (), }, --[[ @@ -437,10 +259,10 @@ export type Internal = { _ContinueWidget: (ID: ID, widgetType: string) -> Widget, _DiscardWidget: (widgetToDiscard: Widget) -> (), - _widgetState: (thisWidget: Widget, stateName: string, initialValue: any) -> State, + _widgetState: (thisWidget: Widget, stateName: string, initialValue: any) -> State, _EventCall: (thisWidget: Widget, eventName: string) -> boolean, - _GetParentWidget: () -> Widget, - SetFocusedWindow: (thisWidget: Widget?) -> (), + _GetParentWidget: () -> ParentWidget, + SetFocusedWindow: (thisWidget: WidgetTypes.Window?) -> (), -- Generate _generateEmptyVDOM: () -> { [ID]: Widget }, @@ -489,25 +311,25 @@ export type WidgetUtility = { UISizeConstraint: (Parent: GuiObject, MinSize: Vector2?, MaxSize: Vector2?) -> UISizeConstraint, applyTextStyle: (thisInstance: TextLabel | TextButton | TextBox) -> (), - applyInteractionHighlights: (thisWidget: Widget, Property: string, Button: GuiButton, Highlightee: GuiObject, Colors: { [string]: any }) -> (), - applyInteractionHighlightsWithMultiHighlightee: (thisWidget: Widget, Property: string, Button: GuiButton, Highlightees: { { GuiObject | { [string]: Color3 | number } } }) -> (), + applyInteractionHighlights: (Property: string, Button: GuiButton, Highlightee: GuiObject, Colors: { [string]: any }) -> (), + applyInteractionHighlightsWithMultiHighlightee: (Property: string, Button: GuiButton, Highlightees: { { GuiObject | { [string]: Color3 | number } } }) -> (), applyFrameStyle: (thisInstance: GuiObject, noPadding: boolean?, noCorner: boolean?) -> (), - applyButtonClick: (thisWidget: Widget, thisInstance: GuiButton, callback: () -> ()) -> (), - applyButtonDown: (thisWidget: Widget, thisInstance: GuiButton, callback: (x: number, y: number) -> ()) -> (), - applyMouseEnter: (thisWidget: Widget, thisInstance: GuiObject, callback: () -> ()) -> (), - applyMouseLeave: (thisWidget: Widget, thisInstance: GuiObject, callback: () -> ()) -> (), - applyInputBegan: (thisWidget: Widget, thisInstance: GuiObject, callback: (input: InputObject) -> ()) -> (), - applyInputEnded: (thisWidget: Widget, thisInstance: GuiObject, callback: (input: InputObject) -> ()) -> (), + applyButtonClick: (thisInstance: GuiButton, callback: () -> ()) -> (), + applyButtonDown: (thisInstance: GuiButton, callback: (x: number, y: number) -> ()) -> (), + applyMouseEnter: (thisInstance: GuiObject, callback: () -> ()) -> (), + applyMouseLeave: (thisInstance: GuiObject, callback: () -> ()) -> (), + applyInputBegan: (thisInstance: GuiObject, callback: (input: InputObject) -> ()) -> (), + applyInputEnded: (thisInstance: GuiObject, callback: (input: InputObject) -> ()) -> (), registerEvent: (event: string, callback: (...any) -> ()) -> (), EVENTS: { - hover: (pathToHovered: (thisWidget: Widget) -> GuiObject) -> Event, - click: (pathToClicked: (thisWidget: Widget) -> GuiButton) -> Event, - rightClick: (pathToClicked: (thisWidget: Widget) -> GuiButton) -> Event, - doubleClick: (pathToClicked: (thisWidget: Widget) -> GuiButton) -> Event, - ctrlClick: (pathToClicked: (thisWidget: Widget) -> GuiButton) -> Event, + hover: (pathToHovered: (thisWidget: Widget & Hovered) -> GuiObject) -> Event, + click: (pathToClicked: (thisWidget: Widget & Clicked) -> GuiButton) -> Event, + rightClick: (pathToClicked: (thisWidget: Widget & RightClicked) -> GuiButton) -> Event, + doubleClick: (pathToClicked: (thisWidget: Widget & DoubleClicked) -> GuiButton) -> Event, + ctrlClick: (pathToClicked: (thisWidget: Widget & CtrlClicked) -> GuiButton) -> Event, }, abstractButton: WidgetClass, @@ -645,4 +467,143 @@ export type Config = { MouseDragThreshold: number, } +type WidgetCall = (arguments: A, states: S, E...) -> W + +export type Iris = { + --[[ + ----------- + WIDGETS + ----------- + ]] + + End: () -> (), + + -- Window API + Window: WidgetCall, + Tooltip: WidgetCall, + + -- Menu Widget API + MenuBar: () -> Widget, + Menu: WidgetCall, + MenuItem: WidgetCall, + MenuToggle: WidgetCall, + + -- Format Widget API + Separator: () -> Separator, + Indent: (arguments: WidgetArguments?) -> Indent, + SameLine: (arguments: WidgetArguments?) -> SameLine, + Group: () -> Group, + + -- Text Widget API + Text: WidgetCall, + TextWrapped: WidgetCall, + TextColored: WidgetCall, + SeparatorText: WidgetCall, + InputText: WidgetCall, + + -- Basic Widget API + Button: WidgetCall, + SmallButton: WidgetCall, + Checkbox: WidgetCall, + RadioButton: WidgetCall, + + -- Tree Widget API + Tree: WidgetCall, + CollapsingHeader: WidgetCall, + + -- Input Widget API + InputNum: WidgetCall, WidgetArguments, WidgetStates?>, + InputVector2: WidgetCall, WidgetArguments, WidgetStates?>, + InputVector3: WidgetCall, WidgetArguments, WidgetStates?>, + InputUDim: WidgetCall, WidgetArguments, WidgetStates?>, + InputUDim2: WidgetCall, WidgetArguments, WidgetStates?>, + InputRect: WidgetCall, WidgetArguments, WidgetStates?>, + InputColor3: WidgetCall, + InputColor4: WidgetCall, + + -- Drag Widget API + DragNum: WidgetCall, WidgetArguments, WidgetStates?>, + DragVector2: WidgetCall, WidgetArguments, WidgetStates?>, + DragVector3: WidgetCall, WidgetArguments, WidgetStates?>, + DragUDim: WidgetCall, WidgetArguments, WidgetStates?>, + DragUDim2: WidgetCall, WidgetArguments, WidgetStates?>, + DragRect: WidgetCall, WidgetArguments, WidgetStates?>, + + -- Slider Widget API + SliderNum: WidgetCall, WidgetArguments, WidgetStates?>, + SliderVector2: WidgetCall, WidgetArguments, WidgetStates?>, + SliderVector3: WidgetCall, WidgetArguments, WidgetStates?>, + SliderUDim: WidgetCall, WidgetArguments, WidgetStates?>, + SliderUDim2: WidgetCall, WidgetArguments, WidgetStates?>, + SliderRect: WidgetCall, WidgetArguments, WidgetStates?>, + + -- Combo Widget Widget API + Selectable: WidgetCall, + Combo: WidgetCall, + ComboArray: WidgetCall, + ComboEnum: WidgetCall, + InputEnum: WidgetCall, + + ProgressBar: WidgetCall, + + Image: WidgetCall, + ImageButton: WidgetCall, + + -- Table Widget Api + Table: WidgetCall, + NextColumn: () -> (), + SetColumnIndex: (columnIndex: number) -> (), + NextRow: () -> (), + + --[[ + --------- + STATE + --------- + ]] + + State: (initialValue: T) -> State, + WeakState: (initialValue: T) -> T, + ComputedState: (firstState: State, onChangeCallback: (firstState: T) -> U) -> State, + + --[[ + ------------- + FUNCTIONS + ------------- + ]] + + Init: (playerInstance: BasePlayerGui?, eventConnection: (RBXScriptConnection | () -> ())?) -> Iris, + Shutdown: () -> (), + Connect: (self: Iris, callback: () -> ()) -> () -> (), + Append: (userInstance: GuiObject) -> (), + ForceRefresh: () -> (), + + -- Widget + SetFocusedWindow: (thisWidget: Window?) -> (), + + -- ID API + PushId: (id: ID) -> (), + PopId: () -> (), + SetNextWidgetID: (id: ID) -> (), + + -- Config API + UpdateGlobalConfig: (deltaStyle: { [string]: any }) -> (), + PushConfig: (deltaStyle: { [string]: any }) -> (), + PopConfig: () -> (), + + --[[ + -------------- + PROPERTIES + -------------- + ]] + + Internal: Internal, + Disabled: boolean, + Args: { [string]: { [string]: number } }, + Events: { [string]: () -> boolean }, + + TemplateConfig: { [string]: Config }, + _config: Config, + ShowDemoWindow: () -> Window, +} + return {} diff --git a/lib/WidgetTypes.lua b/lib/WidgetTypes.lua new file mode 100644 index 0000000..1fe9e9d --- /dev/null +++ b/lib/WidgetTypes.lua @@ -0,0 +1,419 @@ +export type ID = string + +export type State = { + value: T, + ConnectedWidgets: { [ID]: Widget }, + ConnectedFunctions: { (T) -> () }, + + get: (self: State) -> T, + set: (self: State, newValue: T) -> (), + onChange: (self: State, funcToConnect: (T) -> ()) -> () -> (), +} + +export type Widget = { + ID: ID, + type: string, + lastCycleTick: number, + trackedEvents: {}, + parentWidget: ParentWidget, + + arguments: {}, + providedArguments: {}, + + Instance: GuiObject, + ZIndex: number, +} + +export type ParentWidget = Widget & { + ChildContainer: GuiObject, + ZOffset: number, + ZUpdate: boolean, +} + +export type StateWidget = Widget & { + state: { + [string]: State, + }, +} + +-- Events + +export type Hovered = { + isHoveredEvent: boolean, + hovered: () -> boolean, +} + +export type Clicked = { + lastClickedTick: number, + clicked: () -> boolean, +} + +export type RightClicked = { + lastRightClickedTick: number, + rightClicked: () -> boolean, +} + +export type DoubleClicked = { + lastClickedTime: number, + lastClickedPosition: Vector2, + lastDoubleClickedTick: number, + doubleClicked: () -> boolean, +} + +export type CtrlClicked = { + lastCtrlClickedTick: number, + ctrlClicked: () -> boolean, +} + +export type Active = { + active: () -> boolean, +} + +export type Checked = { + lastCheckedTick: number, + checked: () -> boolean, +} + +export type Unchecked = { + lastUncheckedTick: number, + unchecked: () -> boolean, +} + +export type Opened = { + lastOpenedTick: number, + opened: () -> boolean, +} + +export type Closed = { + lastClosedTick: number, + closed: () -> boolean, +} + +export type Collapsed = { + lastCollapsedTick: number, + collapsed: () -> boolean, +} + +export type Uncollapsed = { + lastUncollapsedTick: number, + uncollapsed: () -> boolean, +} + +export type Selected = { + lastSelectedTick: number, + selected: () -> boolean, +} + +export type Unselected = { + lastUnselectedTick: number, + unselected: () -> boolean, +} + +export type Changed = { + lastChangedTick: number, + changed: () -> boolean, +} + +export type NumberChanged = { + lastNumberChangedTick: number, + numberChanged: () -> boolean, +} + +export type TextChanged = { + lastTextChangedTick: number, + textChanged: () -> boolean, +} + +-- Widgets + +-- Window + +export type Root = ParentWidget + +export type Window = ParentWidget & { + usesScreenGuis: boolean, + + arguments: { + Title: string?, + NoTitleBar: boolean?, + NoBackground: boolean?, + NoCollapse: boolean?, + NoClose: boolean?, + NoMove: boolean?, + NoScrollbar: boolean?, + NoResize: boolean?, + NoNav: boolean?, + NoMenu: boolean?, + }, + + state: { + size: State, + position: State, + isUncollapsed: State, + isOpened: State, + scrollDistance: State, + }, +} & Opened & Closed & Collapsed & Uncollapsed & Hovered + +export type Tooltip = Widget & { + arguments: { + Text: string, + }, +} + +-- Menu + +export type MenuBar = ParentWidget + +export type Menu = ParentWidget & { + ButtonColors: { [string]: Color3 | number }, + + arguments: { + Text: string?, + }, + + state: { + isOpened: State, + }, +} & Clicked & Opened & Closed & Hovered + +export type MenuItem = Widget & { + arguments: { + Text: string, + KeyCode: Enum.KeyCode?, + ModifierKey: Enum.ModifierKey?, + }, +} & Clicked & Hovered + +export type MenuToggle = Widget & { + arguments: { + Text: string, + KeyCode: Enum.KeyCode?, + ModifierKey: Enum.ModifierKey?, + }, + + state: { + isChecked: State, + }, +} & Checked & Unchecked & Hovered + +-- Format + +export type Separator = Widget + +export type Indent = ParentWidget & { + arguments: { + Width: number?, + }, +} + +export type SameLine = ParentWidget & { + arguments: { + Width: number?, + VerticalAlignment: Enum.VerticalAlignment?, + }, +} + +export type Group = ParentWidget + +-- Text + +export type Text = Widget & { + arguments: { + Text: string, + Wrapped: boolean?, + Color: Color3?, + RichText: boolean?, + }, +} & Hovered + +export type SeparatorText = Widget & { + arguments: { + Text: string, + }, +} & Hovered + +-- Basic + +export type Button = Widget & { + arguments: { + Text: string?, + }, +} & Clicked & RightClicked & DoubleClicked & CtrlClicked & Hovered + +export type Checkbox = Widget & { + arguments: { + Text: string?, + }, + + state: { + isChecked: State, + }, +} & Unchecked & Checked & Hovered + +export type RadioButton = Widget & { + arguments: { + Text: string?, + Index: any, + }, + + state: { + index: State, + }, + + active: () -> boolean, +} & Selected & Unselected & Active & Hovered + +-- Image + +export type Image = Widget & { + arguments: { + Image: string, + Size: UDim2, + Rect: Rect?, + ScaleType: Enum.ScaleType?, + TileSize: UDim2?, + SliceCenter: Rect?, + SliceScale: number?, + ResampleMode: Enum.ResamplerMode?, + }, +} & Hovered + +export type ImageButton = Image & Clicked & RightClicked & DoubleClicked & CtrlClicked + +-- Tree + +export type Tree = CollapsingHeader & { + arguments: { + SpanAvailWidth: boolean?, + NoIndent: boolean?, + }, +} + +export type CollapsingHeader = ParentWidget & { + arguments: { + Text: string?, + }, + + state: { + isUncollapsed: State, + }, +} & Collapsed & Uncollapsed & Hovered + +-- Input +export type Input = Widget & { + lastClickedTime: number, + lastClickedPosition: Vector2, + + arguments: { + Text: string?, + Increment: T, + Min: T, + Max: T, + Format: { string }, + Prefix: { string }, + NoButtons: boolean?, + }, + + state: { + number: State, + editingText: State, + }, +} & NumberChanged & Hovered + +export type InputColor3 = Input<{ number }> & { + arguments: { + UseFloats: boolean?, + UseHSV: boolean?, + }, + + state: { + color: State, + editingText: State, + }, +} & NumberChanged & Hovered + +export type InputColor4 = InputColor3 & { + state: { + transparency: State, + }, +} + +export type InputEnum = Input & { + state: { + enumItem: State, + }, +} + +export type InputText = Widget & { + arguments: { + Text: string?, + TextHint: string?, + ReadOnly: boolean?, + MultiLine: boolean?, + }, + + state: { + text: State, + }, +} & TextChanged & Hovered + +-- Combo + +export type Selectable = Widget & { + ButtonColors: { [string]: Color3 | number }, + + arguments: { + Text: string?, + Index: any?, + NoClick: boolean?, + }, + + state: { + index: State, + }, +} & Selected & Unselected & Clicked & RightClicked & DoubleClicked & CtrlClicked & Hovered + +export type Combo = ParentWidget & { + ComboChildrenHeight: number, + + arguments: { + Text: string?, + NoButton: boolean?, + NoPreview: boolean?, + }, + + state: { + index: State, + isOpened: State, + }, +} & Opened & Closed & Clicked & Hovered + +-- Plot + +export type ProgressBar = Widget & { + arguments: { + Text: string?, + Format: string?, + }, + + state: { + progress: State, + }, +} & Changed & Hovered + +export type Table = ParentWidget & { + RowColumnIndex: number, + InitialNumColumns: number, + ColumnInstances: { Frame }, + CellInstances: { Frame }, + + arguments: { + NumColumns: number, + RowBg: boolean?, + BordersOuter: boolean?, + BordersInner: boolean?, + }, +} & Hovered + +return {} diff --git a/lib/demoWindow.lua b/lib/demoWindow.lua index ea6e1c6..6de49a2 100644 --- a/lib/demoWindow.lua +++ b/lib/demoWindow.lua @@ -28,7 +28,7 @@ return function(Iris: Types.Iris) do Iris.SeparatorText({ "Basic" }) - local radioButtonState = Iris.State(1) + local radioButtonState: Types.State = Iris.State(1) Iris.Button({ "Button" }) Iris.SmallButton({ "SmallButton" }) Iris.Text({ "Text" }) @@ -468,7 +468,7 @@ return function(Iris: Types.Iris) if Iris.InputNum({ "# of repeat", 1, 1, 50 }, { number = numRepeat }).numberChanged() then dynamicText:set(string.rep("Hello ", numRepeat:get())) end - if Iris.Checkbox({ "Show dynamic text tooltip" }).isChecked.value then + if Iris.Checkbox({ "Show dynamic text tooltip" }).state.isChecked.value then Iris.Tooltip({ dynamicText:get() }) end end @@ -558,7 +558,7 @@ return function(Iris: Types.Iris) Iris.End() Iris.PushConfig({ ItemWidth = UDim.new(1, -150) }) - local enteredText = Iris.InputText({ "ID field" }, { text = Iris.State(runtimeInfoWindow.ID) }).text.value + local enteredText = Iris.InputText({ "ID field" }, { text = Iris.State(runtimeInfoWindow.ID) }).state.text.value Iris.PopConfig() Iris.Indent() @@ -611,7 +611,7 @@ return function(Iris: Types.Iris) end Iris.End() - if Iris.Tree({ "Widgets" }).isUncollapsed.value then + if Iris.Tree({ "Widgets" }).state.isUncollapsed.value then local widgetCount = 0 local widgetStr = "" for _, v in lastVDOM do @@ -625,7 +625,7 @@ return function(Iris: Types.Iris) end Iris.End() - if Iris.Tree({ "States" }).isUncollapsed.value then + if Iris.Tree({ "States" }).state.isUncollapsed.value then local stateCount = 0 local stateStr = "" for i, v in states do @@ -961,6 +961,8 @@ return function(Iris: Types.Iris) if Iris.Button({ "Revert" }).clicked() then Iris.UpdateGlobalConfig(Iris.TemplateConfig.colorDark) Iris.UpdateGlobalConfig(Iris.TemplateConfig.sizeDefault) + ThemeState:set("Dark Theme") + SizeState:set("Classic Size") end helpMarker("Reset Iris to the default theme and size.") @@ -1008,7 +1010,8 @@ return function(Iris: Types.Iris) Iris.SameLine() do - if Iris.Button({ selectedEvent:get() .. " to reveal text" })[selectedEvent:get()]() then + local button = Iris.Button({ selectedEvent:get() .. " to reveal text" }) + if button[selectedEvent:get()]() then showEventText:set(not showEventText:get()) end if showEventText:get() then @@ -1237,7 +1240,7 @@ return function(Iris: Types.Iris) Iris.PushConfig({ ContentWidth = UDim.new(0, 150) }) Iris.DragNum({ "number", 1, 0, 100 }, { number = value }) - Iris.ComboEnum({ "axis" }, { index = index }, Enum.Axis) + Iris.InputEnum({ "axis" }, { index = index }, Enum.Axis) Iris.PopConfig() Iris.SameLine() @@ -1249,7 +1252,7 @@ return function(Iris: Types.Iris) Iris.PushConfig({ ContentWidth = UDim.new(0.5, 0) }) Iris.DragNum({ "number", 1, 0, 100 }, { number = value }) - Iris.ComboEnum({ "axis" }, { index = index }, Enum.Axis) + Iris.InputEnum({ "axis" }, { index = index }, Enum.Axis) Iris.PopConfig() Iris.SameLine() @@ -1338,15 +1341,15 @@ return function(Iris: Types.Iris) -- main demo window return function() - local NoTitleBar = Iris.State(false) - local NoBackground = Iris.State(false) - local NoCollapse = Iris.State(false) - local NoClose = Iris.State(true) - local NoMove = Iris.State(false) - local NoScrollbar = Iris.State(false) - local NoResize = Iris.State(false) - local NoNav = Iris.State(false) - local NoMenu = Iris.State(false) + local NoTitleBar: Types.State = Iris.State(false) + local NoBackground: Types.State = Iris.State(false) + local NoCollapse: Types.State = Iris.State(false) + local NoClose: Types.State = Iris.State(true) + local NoMove: Types.State = Iris.State(false) + local NoScrollbar: Types.State = Iris.State(false) + local NoResize: Types.State = Iris.State(false) + local NoNav: Types.State = Iris.State(false) + local NoMenu: Types.State = Iris.State(false) if showMainWindow.value == false then Iris.Checkbox({ "Open main window" }, { isChecked = showMainWindow }) @@ -1354,7 +1357,7 @@ return function(Iris: Types.Iris) end debug.profilebegin("Iris/Demo/Window") - local window: Types.Widget = Iris.Window({ + local window: Types.Window = Iris.Window({ [Iris.Args.Window.Title] = "Iris Demo Window", [Iris.Args.Window.NoTitleBar] = NoTitleBar.value, [Iris.Args.Window.NoBackground] = NoBackground.value, diff --git a/lib/init.lua b/lib/init.lua index bb865c2..dfaff30 100644 --- a/lib/init.lua +++ b/lib/init.lua @@ -167,7 +167,7 @@ end property or by the current parent widget from the stack. ]=] function Iris.Append(userInstance: GuiObject) - local parentWidget: Types.Widget = Internal._GetParentWidget() + local parentWidget: Types.ParentWidget = Internal._GetParentWidget() local widgetInstanceParent: GuiObject if Internal._config.Parent then widgetInstanceParent = Internal._config.Parent :: any @@ -401,7 +401,7 @@ end In this example, the code will work properly, and increment every frame. ::: ]=] -function Iris.State(initialValue: any): Types.State +function Iris.State(initialValue: T): Types.State local ID: Types.ID = Internal._getID(2) if Internal._states[ID] then return Internal._states[ID] @@ -422,7 +422,7 @@ end Constructs a new state object, subsequent ID calls will return the same object, except all widgets connected to the state are discarded, the state reverts to the passed initialValue ]=] -function Iris.WeakState(initialValue: any): Types.State +function Iris.WeakState(initialValue: T): Types.State local ID: Types.ID = Internal._getID(2) if Internal._states[ID] then if next(Internal._states[ID].ConnectedWidgets) == nil then @@ -456,7 +456,7 @@ end ``` ::: ]=] -function Iris.ComputedState(firstState: Types.State, onChangeCallback: (firstState: any) -> any): Types.State +function Iris.ComputedState(firstState: Types.State, onChangeCallback: (firstState: T) -> U): Types.State local ID: Types.ID = Internal._getID(2) if Internal._states[ID] then @@ -466,8 +466,8 @@ function Iris.ComputedState(firstState: Types.State, onChangeCallback: (firstSta value = onChangeCallback(firstState.value), ConnectedWidgets = {}, ConnectedFunctions = {}, - } :: any - firstState:onChange(function(newValue: any) + } :: Types.State + firstState:onChange(function(newValue: T) Internal._states[ID]:set(onChangeCallback(newValue)) end) setmetatable(Internal._states[ID], Internal.StateClass) diff --git a/lib/widgets/Button.lua b/lib/widgets/Button.lua index ac2e18c..6a3a906 100644 --- a/lib/widgets/Button.lua +++ b/lib/widgets/Button.lua @@ -24,7 +24,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget): TextButton + Generate = function(thisWidget: Types.Button) local Button: TextButton = Instance.new("TextButton") Button.Size = UDim2.fromOffset(0, 0) Button.BackgroundColor3 = Iris._config.ButtonColor @@ -36,7 +36,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) widgets.applyFrameStyle(Button) - widgets.applyInteractionHighlights(thisWidget, "Background", Button, Button, { + widgets.applyInteractionHighlights("Background", Button, Button, { Color = Iris._config.ButtonColor, Transparency = Iris._config.ButtonTransparency, HoveredColor = Iris._config.ButtonHoveredColor, @@ -50,11 +50,11 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Button end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Button) local Button = thisWidget.Instance :: TextButton Button.Text = thisWidget.arguments.Text or "Button" end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Button) thisWidget.Instance:Destroy() end, } :: Types.WidgetClass @@ -62,7 +62,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) --stylua: ignore Iris.WidgetConstructor("Button", widgets.extend(abstractButton, { - Generate = function(thisWidget: Types.Widget): TextButton + Generate = function(thisWidget: Types.Button) local Button: TextButton = abstractButton.Generate(thisWidget) Button.Name = "Iris_Button" @@ -73,7 +73,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) --stylua: ignore Iris.WidgetConstructor("SmallButton", widgets.extend(abstractButton, { - Generate = function(thisWidget: Types.Widget): TextButton + Generate = function(thisWidget: Types.Button) local SmallButton = abstractButton.Generate(thisWidget) :: TextButton SmallButton.Name = "Iris_SmallButton" diff --git a/lib/widgets/Checkbox.lua b/lib/widgets/Checkbox.lua index b6e472b..4a3fd31 100644 --- a/lib/widgets/Checkbox.lua +++ b/lib/widgets/Checkbox.lua @@ -10,22 +10,22 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) }, Events = { ["checked"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget): boolean + ["Init"] = function(_thisWidget: Types.Checkbox) end, + ["Get"] = function(thisWidget: Types.Checkbox): boolean return thisWidget.lastCheckedTick == Iris._cycleTick end, }, ["unchecked"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget): boolean + ["Init"] = function(_thisWidget: Types.Checkbox) end, + ["Get"] = function(thisWidget: Types.Checkbox): boolean return thisWidget.lastUncheckedTick == Iris._cycleTick end, }, - ["hovered"] = widgets.EVENTS.hover(function(thisWidget: Types.Widget): GuiObject + ["hovered"] = widgets.EVENTS.hover(function(thisWidget: Types.Widget) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget): TextButton + Generate = function(thisWidget: Types.Checkbox) local Checkbox: TextButton = Instance.new("TextButton") Checkbox.Name = "Iris_Checkbox" Checkbox.AutomaticSize = Enum.AutomaticSize.XY @@ -51,7 +51,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) widgets.applyFrameStyle(Box, true) widgets.UIPadding(Box, (checkboxSize // 10) * Vector2.one) - widgets.applyInteractionHighlights(thisWidget, "Background", Checkbox, Box, { + widgets.applyInteractionHighlights("Background", Checkbox, Box, { Color = Iris._config.FrameBgColor, Transparency = Iris._config.FrameBgTransparency, HoveredColor = Iris._config.FrameBgHoveredColor, @@ -72,7 +72,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Checkmark.Parent = Box - widgets.applyButtonClick(thisWidget, Checkbox, function() + widgets.applyButtonClick(Checkbox, function() local wasChecked: boolean = thisWidget.state.isChecked.value thisWidget.state.isChecked:set(not wasChecked) end) @@ -89,20 +89,20 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Checkbox end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Checkbox) local Checkbox = thisWidget.Instance :: TextButton Checkbox.TextLabel.Text = thisWidget.arguments.Text or "Checkbox" end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Checkbox) thisWidget.Instance:Destroy() widgets.discardState(thisWidget) end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.Checkbox) if thisWidget.state.isChecked == nil then thisWidget.state.isChecked = Iris._widgetState(thisWidget, "checked", false) end end, - UpdateState = function(thisWidget: Types.Widget) + UpdateState = function(thisWidget: Types.Checkbox) local Checkbox = thisWidget.Instance :: TextButton local Box = Checkbox.Box :: Frame local Checkmark: ImageLabel = Box.Checkmark diff --git a/lib/widgets/Combo.lua b/lib/widgets/Combo.lua index 84fb72d..626242e 100644 --- a/lib/widgets/Combo.lua +++ b/lib/widgets/Combo.lua @@ -12,20 +12,20 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) }, Events = { ["selected"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.Selectable) end, + ["Get"] = function(thisWidget: Types.Selectable) return thisWidget.lastSelectedTick == Iris._cycleTick end, }, ["unselected"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.Selectable) end, + ["Get"] = function(thisWidget: Types.Selectable) return thisWidget.lastUnselectedTick == Iris._cycleTick end, }, ["active"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.Selectable) end, + ["Get"] = function(thisWidget: Types.Selectable) return thisWidget.state.index.value == thisWidget.arguments.Index end, }, @@ -50,7 +50,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Selectable.SelectableButton end), }, - Generate = function(thisWidget: Types.Widget): Frame + Generate = function(thisWidget: Types.Selectable) local Selectable: Frame = Instance.new("Frame") Selectable.Name = "Iris_Selectable" Selectable.Size = UDim2.new(Iris._config.ItemWidth, UDim.new(0, Iris._config.TextSize + 2 * Iris._config.FramePadding.Y - Iris._config.ItemSpacing.Y)) @@ -79,9 +79,9 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ActiveTransparency = Iris._config.HeaderActiveTransparency, } - widgets.applyInteractionHighlights(thisWidget, "Background", SelectableButton, SelectableButton, thisWidget.ButtonColors) + widgets.applyInteractionHighlights("Background", SelectableButton, SelectableButton, thisWidget.ButtonColors) - widgets.applyButtonClick(thisWidget, SelectableButton, function() + widgets.applyButtonClick(SelectableButton, function() if thisWidget.arguments.NoClick ~= true then if type(thisWidget.state.index.value) == "boolean" then thisWidget.state.index:set(not thisWidget.state.index.value) @@ -95,16 +95,16 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Selectable end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Selectable) local Selectable = thisWidget.Instance :: Frame local SelectableButton: TextButton = Selectable.SelectableButton SelectableButton.Text = thisWidget.arguments.Text or "Selectable" end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Selectable) thisWidget.Instance:Destroy() widgets.discardState(thisWidget) end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.Selectable) if thisWidget.state.index == nil then if thisWidget.arguments.Index ~= nil then error("a shared state index is required for Selectables with an Index argument", 5) @@ -112,7 +112,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.state.index = Iris._widgetState(thisWidget, "index", false) end end, - UpdateState = function(thisWidget: Types.Widget) + UpdateState = function(thisWidget: Types.Selectable) local Selectable = thisWidget.Instance :: Frame local SelectableButton: TextButton = Selectable.SelectableButton if thisWidget.state.index.value == (thisWidget.arguments.Index or true) then @@ -129,12 +129,12 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) local AnyOpenedCombo: boolean = false local ComboOpenedTick: number = -1 - local OpenedCombo: Types.Widget? = nil + local OpenedCombo: Types.Combo? = nil - local function UpdateChildContainerTransform(thisWidget: Types.Widget) + local function UpdateChildContainerTransform(thisWidget: Types.Combo) local Combo = thisWidget.Instance :: Frame - local ChildContainer = thisWidget.ChildContainer :: ScrollingFrame local PreviewContainer = Combo.PreviewContainer :: TextButton + local ChildContainer = thisWidget.ChildContainer :: ScrollingFrame ChildContainer.Size = UDim2.fromOffset(PreviewContainer.AbsoluteSize.X, 0) @@ -202,14 +202,14 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) }, Events = { ["opened"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.Combo) end, + ["Get"] = function(thisWidget: Types.Combo) return thisWidget.lastOpenedTick == Iris._cycleTick end, }, ["closed"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.Combo) end, + ["Get"] = function(thisWidget: Types.Combo) return thisWidget.lastClosedTick == Iris._cycleTick end, }, @@ -220,7 +220,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.Combo) local frameHeight: number = Iris._config.TextSize + 2 * Iris._config.FramePadding.Y local Combo: Frame = Instance.new("Frame") @@ -290,7 +290,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) -- for some reason ImGui Combo has no highlights for Active, only hovered. -- so this deviates from ImGui, but its a good UX change - widgets.applyInteractionHighlightsWithMultiHighlightee(thisWidget, "Background", PreviewContainer, { + widgets.applyInteractionHighlightsWithMultiHighlightee("Background", PreviewContainer, { { PreviewLabel, { @@ -316,7 +316,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) }, }) - widgets.applyButtonClick(thisWidget, PreviewContainer, function() + widgets.applyButtonClick(PreviewContainer, function() if AnyOpenedCombo and OpenedCombo ~= thisWidget then return end @@ -369,7 +369,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.ChildContainer = ChildContainer return Combo end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Combo) local Iris_Combo = thisWidget.Instance :: Frame local PreviewContainer = Iris_Combo.PreviewContainer :: TextButton local PreviewLabel: TextLabel = PreviewContainer.PreviewLabel @@ -397,12 +397,11 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) PreviewContainer.AutomaticSize = Enum.AutomaticSize.Y end end, - ChildAdded = function(thisWidget: Types.Widget, _thisChild: Types.Widget) - -- default to largest size if there are widgets other than selectables inside the combo + ChildAdded = function(thisWidget: Types.Combo, _thisChild: Types.Widget) UpdateChildContainerTransform(thisWidget) return thisWidget.ChildContainer end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.Combo) if thisWidget.state.index == nil then thisWidget.state.index = Iris._widgetState(thisWidget, "index", "No Selection") end @@ -415,7 +414,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.state.isOpened = Iris._widgetState(thisWidget, "isOpened", false) end end, - UpdateState = function(thisWidget: Types.Widget) + UpdateState = function(thisWidget: Types.Combo) local Combo = thisWidget.Instance :: Frame local ChildContainer = thisWidget.ChildContainer :: ScrollingFrame local PreviewContainer = Combo.PreviewContainer :: TextButton @@ -447,7 +446,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) local stateIndex: any = thisWidget.state.index.value PreviewLabel.Text = if typeof(stateIndex) == "EnumItem" then stateIndex.Name else tostring(stateIndex) end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Combo) thisWidget.Instance:Destroy() widgets.discardState(thisWidget) end, diff --git a/lib/widgets/Format.lua b/lib/widgets/Format.lua index 9140e8b..7603706 100644 --- a/lib/widgets/Format.lua +++ b/lib/widgets/Format.lua @@ -7,7 +7,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) hasChildren = false, Args = {}, Events = {}, - Generate = function(thisWidget: Types.Widget): Frame + Generate = function(thisWidget: Types.Separator) local Separator: Frame = Instance.new("Frame") Separator.Name = "Iris_Separator" Separator.BackgroundColor3 = Iris._config.SeparatorColor @@ -25,8 +25,8 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Separator end, - Update = function(_thisWidget: Types.Widget) end, - Discard = function(thisWidget: Types.Widget) + Update = function(_thisWidget: Types.Separator) end, + Discard = function(thisWidget: Types.Separator) thisWidget.Instance:Destroy() end, } :: Types.WidgetClass) @@ -39,7 +39,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ["Width"] = 1, }, Events = {}, - Generate = function(thisWidget: Types.Widget): Frame + Generate = function(thisWidget: Types.Indent) local Indent: Frame = Instance.new("Frame") Indent.Name = "Iris_Indent" Indent.BackgroundTransparency = 1 @@ -53,7 +53,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Indent end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Indent) local Indent = thisWidget.Instance :: Frame local indentWidth: number @@ -64,10 +64,10 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end Indent.UIPadding.PaddingLeft = UDim.new(0, indentWidth) end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Indent) thisWidget.Instance:Destroy() end, - ChildAdded = function(thisWidget: Types.Widget, _thisChild: Types.Widget) + ChildAdded = function(thisWidget: Types.Indent, _thisChild: Types.Widget) return thisWidget.Instance end, } :: Types.WidgetClass) @@ -81,7 +81,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ["VerticalAlignment"] = 2, }, Events = {}, - Generate = function(thisWidget: Types.Widget): Frame + Generate = function(thisWidget: Types.SameLine) local SameLine: Frame = Instance.new("Frame") SameLine.Name = "Iris_SameLine" SameLine.BackgroundTransparency = 1 @@ -94,7 +94,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return SameLine end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.SameLine) local Sameline = thisWidget.Instance :: Frame local uiListLayout: UIListLayout = Sameline.UIListLayout local itemWidth: number @@ -110,10 +110,10 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) uiListLayout.VerticalAlignment = Enum.VerticalAlignment.Center end end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.SameLine) thisWidget.Instance:Destroy() end, - ChildAdded = function(thisWidget: Types.Widget, _thisChild: Types.Widget) + ChildAdded = function(thisWidget: Types.SameLine, _thisChild: Types.Widget) return thisWidget.Instance end, } :: Types.WidgetClass) @@ -124,7 +124,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) hasChildren = true, Args = {}, Events = {}, - Generate = function(thisWidget: Types.Widget): Frame + Generate = function(thisWidget: Types.Group) local Group: Frame = Instance.new("Frame") Group.Name = "Iris_Group" Group.AutomaticSize = Enum.AutomaticSize.XY @@ -138,11 +138,11 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Group end, - Update = function(_thisWidget: Types.Widget) end, - Discard = function(thisWidget: Types.Widget) + Update = function(_thisWidget: Types.Group) end, + Discard = function(thisWidget: Types.Group) thisWidget.Instance:Destroy() end, - ChildAdded = function(thisWidget: Types.Widget, _thisChild: Types.Widget) + ChildAdded = function(thisWidget: Types.Group, _thisChild: Types.Widget) return thisWidget.Instance end, } :: Types.WidgetClass) diff --git a/lib/widgets/Image.lua b/lib/widgets/Image.lua index 3b37ba2..e0f5666 100644 --- a/lib/widgets/Image.lua +++ b/lib/widgets/Image.lua @@ -14,7 +14,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ["SliceCenter"] = 7, ["SliceScale"] = 8, }, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Image) thisWidget.Instance:Destroy() end, } :: Types.WidgetClass @@ -26,7 +26,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.Image) local Image: ImageLabel = Instance.new("ImageLabel") Image.Name = "Iris_Image" Image.BackgroundTransparency = 1 @@ -39,7 +39,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Image end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Image) local Image = thisWidget.Instance :: ImageLabel Image.Image = thisWidget.arguments.Image or widgets.ICONS.UNKNOWN_TEXTURE @@ -89,7 +89,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.ImageButton) local Button: ImageButton = Instance.new("ImageButton") Button.Name = "Iris_ImageButton" Button.AutomaticSize = Enum.AutomaticSize.XY @@ -112,7 +112,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Image.ImageTransparency = Iris._config.ImageTransparency Image.Parent = Button - widgets.applyInteractionHighlights(thisWidget, "Background", Button, Button, { + widgets.applyInteractionHighlights("Background", Button, Button, { Color = Iris._config.FrameBgColor, Transparency = Iris._config.FrameBgTransparency, HoveredColor = Iris._config.FrameBgHoveredColor, @@ -123,7 +123,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Button end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.ImageButton) local Button = thisWidget.Instance :: TextButton local Image: ImageLabel = Button.ImageLabel diff --git a/lib/widgets/Input.lua b/lib/widgets/Input.lua index 1a5f685..55ab8f0 100644 --- a/lib/widgets/Input.lua +++ b/lib/widgets/Input.lua @@ -1,48 +1,52 @@ local Types = require(script.Parent.Parent.Types) +type InputDataTypes = "Num" | "Vector2" | "Vector3" | "UDim" | "UDim2" | "Color3" | "Color4" | "Rect" | "Enum" | "" | string + return function(Iris: Types.Internal, widgets: Types.WidgetUtility) local numberChanged = { ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Get"] = function(thisWidget: Types.Input) return thisWidget.lastNumberChangedTick == Iris._cycleTick end, } - local function getValueByIndex(value: Types.InputDataType, index: number, arguments: Types.Arguments): number - if typeof(value) == "number" then - return value - elseif typeof(value) == "Vector2" then + local function getValueByIndex(value: T, index: number, arguments: any): number + local t: string = typeof(value) + local v = value :: any + if t == "number" then + return v + elseif t == "Vector2" then if index == 1 then - return value.X + return v.X elseif index == 2 then - return value.Y + return v.Y end - elseif typeof(value) == "Vector3" then + elseif t == "Vector3" then if index == 1 then - return value.X + return v.X elseif index == 2 then - return value.Y + return v.Y elseif index == 3 then - return value.Z + return v.Z end - elseif typeof(value) == "UDim" then + elseif t == "UDim" then if index == 1 then - return value.Scale + return v.Scale elseif index == 2 then - return value.Offset + return v.Offset end - elseif typeof(value) == "UDim2" then + elseif t == "UDim2" then if index == 1 then - return value.X.Scale + return v.X.Scale elseif index == 2 then - return value.X.Offset + return v.X.Offset elseif index == 3 then - return value.Y.Scale + return v.Y.Scale elseif index == 4 then - return value.Y.Offset + return v.Y.Offset end - elseif typeof(value) == "Color3" then - local color: { number } = arguments.UseHSV and { value:ToHSV() } or { value.R, value.G, value.B } + elseif t == "Color3" then + local color: { number } = arguments.UseHSV and { v:ToHSV() } or { v.R, v.G, v.B } if index == 1 then return color[1] elseif index == 2 then @@ -50,90 +54,90 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) elseif index == 3 then return color[3] end - elseif typeof(value) == "Rect" then + elseif t == "Rect" then if index == 1 then - return value.Min.X + return v.Min.X elseif index == 2 then - return value.Min.Y + return v.Min.Y elseif index == 3 then - return value.Max.X + return v.Max.X elseif index == 4 then - return value.Max.Y + return v.Max.Y end - elseif typeof(value) == "table" then - return value[index] + elseif t == "table" then + return v[index] end error(`Incorrect datatype or value: {value} {typeof(value)} {index}`) end - local function updateValueByIndex(value: Types.InputDataType, index: number, newValue: number, arguments: Types.Arguments): Types.InputDataType + local function updateValueByIndex(value: T, index: number, newValue: number, arguments: Types.Arguments): T if typeof(value) == "number" then - return newValue + return newValue :: any elseif typeof(value) == "Vector2" then if index == 1 then - return Vector2.new(newValue, value.Y) + return Vector2.new(newValue, value.Y) :: any elseif index == 2 then - return Vector2.new(value.X, newValue) + return Vector2.new(value.X, newValue) :: any end elseif typeof(value) == "Vector3" then if index == 1 then - return Vector3.new(newValue, value.Y, value.Z) + return Vector3.new(newValue, value.Y, value.Z) :: any elseif index == 2 then - return Vector3.new(value.X, newValue, value.Z) + return Vector3.new(value.X, newValue, value.Z) :: any elseif index == 3 then - return Vector3.new(value.X, value.Y, newValue) + return Vector3.new(value.X, value.Y, newValue) :: any end elseif typeof(value) == "UDim" then if index == 1 then - return UDim.new(newValue, value.Offset) + return UDim.new(newValue, value.Offset) :: any elseif index == 2 then - return UDim.new(value.Scale, newValue) + return UDim.new(value.Scale, newValue) :: any end elseif typeof(value) == "UDim2" then if index == 1 then - return UDim2.new(UDim.new(newValue, value.X.Offset), value.Y) + return UDim2.new(UDim.new(newValue, value.X.Offset), value.Y) :: any elseif index == 2 then - return UDim2.new(UDim.new(value.X.Scale, newValue), value.Y) + return UDim2.new(UDim.new(value.X.Scale, newValue), value.Y) :: any elseif index == 3 then - return UDim2.new(value.X, UDim.new(newValue, value.Y.Offset)) + return UDim2.new(value.X, UDim.new(newValue, value.Y.Offset)) :: any elseif index == 4 then - return UDim2.new(value.X, UDim.new(value.Y.Scale, newValue)) + return UDim2.new(value.X, UDim.new(value.Y.Scale, newValue)) :: any end elseif typeof(value) == "Rect" then if index == 1 then - return Rect.new(Vector2.new(newValue, value.Min.Y), value.Max) + return Rect.new(Vector2.new(newValue, value.Min.Y), value.Max) :: any elseif index == 2 then - return Rect.new(Vector2.new(value.Min.X, newValue), value.Max) + return Rect.new(Vector2.new(value.Min.X, newValue), value.Max) :: any elseif index == 3 then - return Rect.new(value.Min, Vector2.new(newValue, value.Max.Y)) + return Rect.new(value.Min, Vector2.new(newValue, value.Max.Y)) :: any elseif index == 4 then - return Rect.new(value.Min, Vector2.new(value.Max.X, newValue)) + return Rect.new(value.Min, Vector2.new(value.Max.X, newValue)) :: any end elseif typeof(value) == "Color3" then if arguments.UseHSV then local h: number, s: number, v: number = value:ToHSV() if index == 1 then - return Color3.fromHSV(newValue, s, v) + return Color3.fromHSV(newValue, s, v) :: any elseif index == 2 then - return Color3.fromHSV(h, newValue, v) + return Color3.fromHSV(h, newValue, v) :: any elseif index == 3 then - return Color3.fromHSV(h, s, newValue) + return Color3.fromHSV(h, s, newValue) :: any end end if index == 1 then - return Color3.new(newValue, value.G, value.B) + return Color3.new(newValue, value.G, value.B) :: any elseif index == 2 then - return Color3.new(value.R, newValue, value.B) + return Color3.new(value.R, newValue, value.B) :: any elseif index == 3 then - return Color3.new(value.R, value.G, newValue) + return Color3.new(value.R, value.G, newValue) :: any end end error(`Incorrect datatype or value {value} {typeof(value)} {index}`) end - local defaultIncrements: { [Types.InputDataTypes]: { number } } = { + local defaultIncrements: { [InputDataTypes]: { number } } = { Num = { 1 }, Vector2 = { 1, 1 }, Vector3 = { 1, 1, 1 }, @@ -144,7 +148,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Rect = { 1, 1, 1, 1 }, } - local defaultMin: { [Types.InputDataTypes]: { number } } = { + local defaultMin: { [InputDataTypes]: { number } } = { Num = { 0 }, Vector2 = { 0, 0 }, Vector3 = { 0, 0, 0 }, @@ -153,7 +157,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Rect = { 0, 0, 0, 0 }, } - local defaultMax: { [Types.InputDataTypes]: { number } } = { + local defaultMax: { [InputDataTypes]: { number } } = { Num = { 100 }, Vector2 = { 100, 100 }, Vector3 = { 100, 100, 100 }, @@ -162,7 +166,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Rect = { 960, 960, 960, 960 }, } - local defaultPrefx: { [Types.InputDataTypes]: { string } } = { + local defaultPrefx: { [InputDataTypes]: { string } } = { Num = { "" }, Vector2 = { "X: ", "Y: " }, Vector3 = { "X: ", "Y: ", "Z: " }, @@ -175,7 +179,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Rect = { "X: ", "Y: ", "X: ", "Y: " }, } - local defaultSigFigs: { [Types.InputDataTypes]: { number } } = { + local defaultSigFigs: { [InputDataTypes]: { number } } = { Num = { 0 }, Vector2 = { 0, 0 }, Vector3 = { 0, 0, 0 }, @@ -189,9 +193,9 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) --[[ Input ]] - local generateInputScalar: (dataType: Types.InputDataTypes, components: number, defaultValue: any) -> Types.WidgetClass + local generateInputScalar: (dataType: InputDataTypes, components: number, defaultValue: any) -> Types.WidgetClass do - local function generateButtons(thisWidget: Types.Widget, parent: GuiObject, rightPadding: number, textHeight: number) + local function generateButtons(thisWidget: Types.Input, parent: GuiObject, rightPadding: number, textHeight: number) rightPadding += 2 * Iris._config.ItemInnerSpacing.X + 2 * textHeight local SubButton = widgets.abstractButton.Generate(thisWidget) :: TextButton @@ -203,15 +207,15 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) SubButton.Size = UDim2.fromOffset(Iris._config.TextSize + 2 * Iris._config.FramePadding.Y, Iris._config.TextSize) SubButton.Parent = parent - widgets.applyButtonClick(thisWidget, SubButton, function() + widgets.applyButtonClick(SubButton, function() local isCtrlHeld: boolean = widgets.UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) or widgets.UserInputService:IsKeyDown(Enum.KeyCode.RightControl) - local changeValue: number = (thisWidget.arguments.Increment and getValueByIndex(thisWidget.arguments.Increment, 1, thisWidget.arguments) or 1) * (isCtrlHeld and 100 or 1) + local changeValue: number = (thisWidget.arguments.Increment and getValueByIndex(thisWidget.arguments.Increment, 1, thisWidget.arguments :: Types.Argument) or 1) * (isCtrlHeld and 100 or 1) local newValue: number = thisWidget.state.number.value - changeValue if thisWidget.arguments.Min ~= nil then - newValue = math.max(newValue, getValueByIndex(thisWidget.arguments.Min, 1, thisWidget.arguments)) + newValue = math.max(newValue, getValueByIndex(thisWidget.arguments.Min, 1, thisWidget.arguments :: Types.Argument)) end if thisWidget.arguments.Max ~= nil then - newValue = math.min(newValue, getValueByIndex(thisWidget.arguments.Max, 1, thisWidget.arguments)) + newValue = math.min(newValue, getValueByIndex(thisWidget.arguments.Max, 1, thisWidget.arguments :: Types.Argument)) end thisWidget.state.number:set(newValue) thisWidget.lastNumberChangedTick = Iris._cycleTick + 1 @@ -226,15 +230,15 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) AddButton.Size = UDim2.fromOffset(Iris._config.TextSize + 2 * Iris._config.FramePadding.Y, Iris._config.TextSize) AddButton.Parent = parent - widgets.applyButtonClick(thisWidget, AddButton, function() + widgets.applyButtonClick(AddButton, function() local isCtrlHeld: boolean = widgets.UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) or widgets.UserInputService:IsKeyDown(Enum.KeyCode.RightControl) - local changeValue: number = (thisWidget.arguments.Increment and getValueByIndex(thisWidget.arguments.Increment, 1, thisWidget.arguments) or 1) * (isCtrlHeld and 100 or 1) + local changeValue: number = (thisWidget.arguments.Increment and getValueByIndex(thisWidget.arguments.Increment, 1, thisWidget.arguments :: Types.Argument) or 1) * (isCtrlHeld and 100 or 1) local newValue: number = thisWidget.state.number.value + changeValue if thisWidget.arguments.Min ~= nil then - newValue = math.max(newValue, getValueByIndex(thisWidget.arguments.Min, 1, thisWidget.arguments)) + newValue = math.max(newValue, getValueByIndex(thisWidget.arguments.Min, 1, thisWidget.arguments :: Types.Argument)) end if thisWidget.arguments.Max ~= nil then - newValue = math.min(newValue, getValueByIndex(thisWidget.arguments.Max, 1, thisWidget.arguments)) + newValue = math.min(newValue, getValueByIndex(thisWidget.arguments.Max, 1, thisWidget.arguments :: Types.Argument)) end thisWidget.state.number:set(newValue) thisWidget.lastNumberChangedTick = Iris._cycleTick + 1 @@ -243,7 +247,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return rightPadding end - function generateInputScalar(dataType: Types.InputDataTypes, components: number, defaultValue: any) + function generateInputScalar(dataType: InputDataTypes, components: number, defaultValue: any) return { hasState = true, hasChildren = false, @@ -260,7 +264,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.Input) local Input: Frame = Instance.new("Frame") Input.Name = "Iris_Input" .. dataType Input.Size = UDim2.fromScale(1, 0) @@ -276,7 +280,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) local textHeight: number = Iris._config.TextSize + 2 * Iris._config.FramePadding.Y if components == 1 then - rightPadding = generateButtons(thisWidget, Input, rightPadding, textHeight) + rightPadding = generateButtons(thisWidget :: any, Input, rightPadding, textHeight) end -- we divide the total area evenly between each field. This includes accounting for any additional boxes and the offset. @@ -316,14 +320,14 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) newValue = math.max(newValue, getValueByIndex(thisWidget.arguments.Min, index, thisWidget.arguments)) end if thisWidget.arguments.Max ~= nil then - newValue = math.min(newValue, getValueByIndex(thisWidget.arguments.Max, index, thisWidget.arguments)) + newValue = math.min(newValue, getValueByIndex(thisWidget.arguments.Max, index, thisWidget.arguments :: any)) end if thisWidget.arguments.Increment then newValue = math.round(newValue / getValueByIndex(thisWidget.arguments.Increment, index, thisWidget.arguments)) * getValueByIndex(thisWidget.arguments.Increment, index, thisWidget.arguments) end - thisWidget.state.number:set(updateValueByIndex(thisWidget.state.number.value, index, newValue, thisWidget.arguments)) + thisWidget.state.number:set(updateValueByIndex(thisWidget.state.number.value, index, newValue, thisWidget.arguments :: any)) thisWidget.lastNumberChangedTick = Iris._cycleTick + 1 end local format: string = thisWidget.arguments.Format[index] or thisWidget.arguments.Format[1] @@ -357,7 +361,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Input end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Input) local Input = thisWidget.Instance :: GuiObject local TextLabel: TextLabel = Input.TextLabel TextLabel.Text = thisWidget.arguments.Text or `Input {dataType}` @@ -402,11 +406,11 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.arguments.Prefix = defaultPrefx[dataType] end end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Input) thisWidget.Instance:Destroy() widgets.discardState(thisWidget) end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.Input) if thisWidget.state.number == nil then thisWidget.state.number = Iris._widgetState(thisWidget, "number", defaultValue) end @@ -414,7 +418,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.state.editingText = Iris._widgetState(thisWidget, "editingText", 0) end end, - UpdateState = function(thisWidget: Types.Widget) + UpdateState = function(thisWidget: Types.Input) local Input = thisWidget.Instance :: GuiObject for index = 1, components do @@ -433,14 +437,14 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) --[[ Drag ]] - local generateDragScalar: (dataType: Types.InputDataTypes, components: number, defaultValue: any) -> Types.WidgetClass - local generateColorDragScalar: (dataType: Types.InputDataTypes, ...any) -> Types.WidgetClass + local generateDragScalar: (dataType: InputDataTypes, components: number, defaultValue: any) -> Types.WidgetClass + local generateColorDragScalar: (dataType: InputDataTypes, ...any) -> Types.WidgetClass do local PreviouseMouseXPosition: number = 0 local AnyActiveDrag: boolean = false - local ActiveDrag: Types.Widget? = nil + local ActiveDrag: Types.Input? = nil local ActiveIndex: number = 0 - local ActiveDataType: Types.InputDataTypes | "" = "" + local ActiveDataType: InputDataTypes | "" = "" local function updateActiveDrag() local currentMouseX: number = widgets.getMouseLocation().X @@ -453,11 +457,12 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return end - local state: Types.State = ActiveDrag.state.number + local state: Types.State = ActiveDrag.state.number if ActiveDataType == "Color3" or ActiveDataType == "Color4" then - state = ActiveDrag.state.color + local Drag = ActiveDrag :: any + state = Drag.state.color if ActiveIndex == 4 then - state = ActiveDrag.state.transparency + state = Drag.state.transparency end end @@ -477,11 +482,11 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) newValue = math.min(newValue, getValueByIndex(ActiveDrag.arguments.Max, ActiveIndex, ActiveDrag.arguments)) end - state:set(updateValueByIndex(state.value, ActiveIndex, newValue, ActiveDrag.arguments)) + state:set(updateValueByIndex(state.value, ActiveIndex, newValue, ActiveDrag.arguments :: any)) ActiveDrag.lastNumberChangedTick = Iris._cycleTick + 1 end - local function DragMouseDown(thisWidget: Types.Widget, dataTypes: Types.InputDataTypes, index: number, x: number, y: number) + local function DragMouseDown(thisWidget: Types.Input, dataTypes: InputDataTypes, index: number, x: number, y: number) local currentTime: number = widgets.getTime() local isTimeValid: boolean = currentTime - thisWidget.lastClickedTime < Iris._config.MouseDoubleClickTime local isCtrlHeld: boolean = widgets.UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) or widgets.UserInputService:IsKeyDown(Enum.KeyCode.RightControl) @@ -517,7 +522,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end end) - function generateDragScalar(dataType: Types.InputDataTypes, components: number, defaultValue: any) + function generateDragScalar(dataType: InputDataTypes, components: number, defaultValue: any) return { hasState = true, hasChildren = false, @@ -534,7 +539,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.Input) thisWidget.lastClickedTime = -1 thisWidget.lastClickedPosition = Vector2.zero @@ -599,7 +604,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) DragField.Parent = Drag - widgets.applyInteractionHighlights(thisWidget, "Background", DragField, DragField, { + widgets.applyInteractionHighlights("Background", DragField, DragField, { Color = Iris._config.FrameBgColor, Transparency = Iris._config.FrameBgTransparency, HoveredColor = Iris._config.FrameBgHoveredColor, @@ -624,14 +629,15 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) InputField.FocusLost:Connect(function() local newValue: number? = tonumber(InputField.Text:match("-?%d*%.?%d*")) - local state: Types.State = thisWidget.state.number + local state: Types.State = thisWidget.state.number + local widget = thisWidget :: any if dataType == "Color4" and index == 4 then - state = thisWidget.state.transparency + state = widget.state.transparency elseif dataType == "Color3" or dataType == "Color4" then - state = thisWidget.state.color + state = widget.state.color end if newValue ~= nil then - if dataType == "Color3" or dataType == "Color4" and not thisWidget.arguments.UseFloats then + if dataType == "Color3" or dataType == "Color4" and not widget.arguments.UseFloats then newValue = newValue / 255 end if thisWidget.arguments.Min ~= nil then @@ -645,12 +651,12 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) newValue = math.round(newValue / getValueByIndex(thisWidget.arguments.Increment, index, thisWidget.arguments)) * getValueByIndex(thisWidget.arguments.Increment, index, thisWidget.arguments) end - state:set(updateValueByIndex(state.value, index, newValue, thisWidget.arguments)) + state:set(updateValueByIndex(state.value, index, newValue, thisWidget.arguments :: any)) thisWidget.lastNumberChangedTick = Iris._cycleTick + 1 end local value: number = getValueByIndex(state.value, index, thisWidget.arguments) - if dataType == "Color3" or dataType == "Color4" and not thisWidget.arguments.UseFloats then + if dataType == "Color3" or dataType == "Color4" and not widget.arguments.UseFloats then value = math.round(value * 255) end @@ -672,8 +678,8 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.state.editingText:set(index) end) - widgets.applyButtonDown(thisWidget, DragField, function(x: number, y: number) - DragMouseDown(thisWidget, dataType, index, x, y) + widgets.applyButtonDown(DragField, function(x: number, y: number) + DragMouseDown(thisWidget :: any, dataType, index, x, y) end) end @@ -690,7 +696,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Drag end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Input) local Input = thisWidget.Instance :: GuiObject local TextLabel: TextLabel = Input.TextLabel TextLabel.Text = thisWidget.arguments.Text or `Drag {dataType}` @@ -730,11 +736,11 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.arguments.Prefix = defaultPrefx[dataType] end end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Input) thisWidget.Instance:Destroy() widgets.discardState(thisWidget) end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.Input) if thisWidget.state.number == nil then thisWidget.state.number = Iris._widgetState(thisWidget, "number", defaultValue) end @@ -742,21 +748,22 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.state.editingText = Iris._widgetState(thisWidget, "editingText", false) end end, - UpdateState = function(thisWidget: Types.Widget) + UpdateState = function(thisWidget: Types.Input) local Drag = thisWidget.Instance :: Frame + local widget = thisWidget :: any for index = 1, components do - local state: Types.State = thisWidget.state.number + local state: Types.State = thisWidget.state.number if dataType == "Color3" or dataType == "Color4" then - state = thisWidget.state.color + state = widget.state.color if index == 4 then - state = thisWidget.state.transparency + state = widget.state.transparency end end local DragField = Drag:FindFirstChild("DragField" .. tostring(index)) :: TextButton local InputField: TextBox = DragField.InputField local value: number = getValueByIndex(state.value, index, thisWidget.arguments) - if (dataType == "Color3" or dataType == "Color4") and not thisWidget.arguments.UseFloats then + if (dataType == "Color3" or dataType == "Color4") and not widget.arguments.UseFloats then value = math.round(value * 255) end @@ -780,17 +787,17 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) if dataType == "Color3" or dataType == "Color4" then local ColorBox: ImageLabel = Drag.ColorBox - ColorBox.BackgroundColor3 = thisWidget.state.color.value + ColorBox.BackgroundColor3 = widget.state.color.value if dataType == "Color4" then - ColorBox.ImageTransparency = 1 - thisWidget.state.transparency.value + ColorBox.ImageTransparency = 1 - widget.state.transparency.value end end end, } end - function generateColorDragScalar(dataType: Types.InputDataTypes, ...: any) + function generateColorDragScalar(dataType: InputDataTypes, ...: any) local defaultValues: { any } = { ... } local input: Types.WidgetClass = generateDragScalar(dataType, dataType == "Color4" and 4 or 3, defaultValues[1]) @@ -801,7 +808,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ["UseHSV"] = 3, ["Format"] = 4, }, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.InputColor4) local Input = thisWidget.Instance :: GuiObject local TextLabel: TextLabel = Input.TextLabel TextLabel.Text = thisWidget.arguments.Text or `Drag {dataType}` @@ -828,7 +835,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Iris._widgets[thisWidget.type].UpdateState(thisWidget) end end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.InputColor4) if thisWidget.state.color == nil then thisWidget.state.color = Iris._widgetState(thisWidget, "color", defaultValues[1]) end @@ -848,13 +855,13 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) --[[ Slider ]] - local generateSliderScalar: (dataType: Types.InputDataTypes, components: number, defaultValue: any) -> Types.WidgetClass + local generateSliderScalar: (dataType: InputDataTypes, components: number, defaultValue: any) -> Types.WidgetClass local generateEnumSliderScalar: (enum: Enum, item: EnumItem) -> Types.WidgetClass do local AnyActiveSlider: boolean = false - local ActiveSlider: Types.Widget? = nil + local ActiveSlider: Types.Input? = nil local ActiveIndex: number = 0 - local ActiveDataType: Types.InputDataTypes | "" = "" + local ActiveDataType: InputDataTypes | "" = "" local function updateActiveSlider() if AnyActiveSlider == false then @@ -878,11 +885,11 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) local Positions: number = math.floor((max - min) / increment) local newValue: number = math.clamp(math.round(Ratio * Positions) * increment + min, min, max) - ActiveSlider.state.number:set(updateValueByIndex(ActiveSlider.state.number.value, ActiveIndex, newValue, ActiveSlider.arguments)) + ActiveSlider.state.number:set(updateValueByIndex(ActiveSlider.state.number.value, ActiveIndex, newValue, ActiveSlider.arguments :: any)) ActiveSlider.lastNumberChangedTick = Iris._cycleTick + 1 end - local function SliderMouseDown(thisWidget: Types.Widget, dataType: Types.InputDataTypes, index: number) + local function SliderMouseDown(thisWidget: Types.Input, dataType: InputDataTypes, index: number) local isCtrlHeld: boolean = widgets.UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) or widgets.UserInputService:IsKeyDown(Enum.KeyCode.RightControl) if isCtrlHeld then thisWidget.state.editingText:set(index) @@ -914,7 +921,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end end) - function generateSliderScalar(dataType: Types.InputDataTypes, components: number, defaultValue: any) + function generateSliderScalar(dataType: InputDataTypes, components: number, defaultValue: any) return { hasState = true, hasChildren = false, @@ -931,7 +938,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.Input) local Slider: Frame = Instance.new("Frame") Slider.Name = "Iris_Slider" .. dataType Slider.Size = UDim2.fromScale(1, 0) @@ -985,7 +992,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) OverlayText.Parent = SliderField - widgets.applyInteractionHighlights(thisWidget, "Background", SliderField, SliderField, { + widgets.applyInteractionHighlights("Background", SliderField, SliderField, { Color = Iris._config.FrameBgColor, Transparency = Iris._config.FrameBgTransparency, HoveredColor = Iris._config.FrameBgHoveredColor, @@ -1022,7 +1029,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) newValue = math.round(newValue / getValueByIndex(thisWidget.arguments.Increment, index, thisWidget.arguments)) * getValueByIndex(thisWidget.arguments.Increment, index, thisWidget.arguments) end - thisWidget.state.number:set(updateValueByIndex(thisWidget.state.number.value, index, newValue, thisWidget.arguments)) + thisWidget.state.number:set(updateValueByIndex(thisWidget.state.number.value, index, newValue, thisWidget.arguments :: any)) thisWidget.lastNumberChangedTick = Iris._cycleTick + 1 end @@ -1045,8 +1052,8 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.state.editingText:set(index) end) - widgets.applyButtonDown(thisWidget, SliderField, function() - SliderMouseDown(thisWidget, dataType, index) + widgets.applyButtonDown(SliderField, function() + SliderMouseDown(thisWidget :: any, dataType, index) end) local GrabBar: Frame = Instance.new("Frame") @@ -1079,7 +1086,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Slider end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Input) local Input = thisWidget.Instance :: GuiObject local TextLabel: TextLabel = Input.TextLabel TextLabel.Text = thisWidget.arguments.Text or `Slider {dataType}` @@ -1143,11 +1150,11 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end end end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Input) thisWidget.Instance:Destroy() widgets.discardState(thisWidget) end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.Input) if thisWidget.state.number == nil then thisWidget.state.number = Iris._widgetState(thisWidget, "number", defaultValue) end @@ -1155,7 +1162,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.state.editingText = Iris._widgetState(thisWidget, "editingText", false) end end, - UpdateState = function(thisWidget: Types.Widget) + UpdateState = function(thisWidget: Types.Input) local Slider = thisWidget.Instance :: Frame for index = 1, components do @@ -1213,7 +1220,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Args = { ["Text"] = 1, }, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.InputEnum) local Input = thisWidget.Instance :: GuiObject local TextLabel: TextLabel = Input.TextLabel TextLabel.Text = thisWidget.arguments.Text or "Input Enum" @@ -1229,7 +1236,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) GrabBar.Size = UDim2.new(grabScaleSize, 0, 1, 0) end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.InputEnum) if thisWidget.state.number == nil then thisWidget.state.number = Iris._widgetState(thisWidget, "number", item.Value) end @@ -1285,18 +1292,18 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) }, Events = { ["textChanged"] = { - ["Init"] = function(thisWidget: Types.Widget) - thisWidget.lastTextchangeTick = 0 + ["Init"] = function(thisWidget: Types.InputText) + thisWidget.lastTextChangedTick = 0 end, - ["Get"] = function(thisWidget: Types.Widget) - return thisWidget.lastTextchangeTick == Iris._cycleTick + ["Get"] = function(thisWidget: Types.InputText) + return thisWidget.lastTextChangedTick == Iris._cycleTick end, }, ["hovered"] = widgets.EVENTS.hover(function(thisWidget: Types.Widget) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.InputText) local InputText: Frame = Instance.new("Frame") InputText.Name = "Iris_InputText" InputText.AutomaticSize = Enum.AutomaticSize.Y @@ -1329,7 +1336,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) InputField.FocusLost:Connect(function() thisWidget.state.text:set(InputField.Text) - thisWidget.lastTextchangeTick = Iris._cycleTick + 1 + thisWidget.lastTextChangedTick = Iris._cycleTick + 1 end) local frameHeight: number = Iris._config.TextSize + 2 * Iris._config.FramePadding.Y @@ -1348,7 +1355,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return InputText end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.InputText) local InputText = thisWidget.Instance :: Frame local TextLabel: TextLabel = InputText.TextLabel local InputField: TextBox = InputText.InputField @@ -1356,18 +1363,18 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) TextLabel.Text = thisWidget.arguments.Text or "Input Text" InputField.PlaceholderText = thisWidget.arguments.TextHint or "" InputField.TextEditable = not thisWidget.arguments.ReadOnly - InputField.MultiLine = thisWidget.arguments.MultiLine + InputField.MultiLine = thisWidget.arguments.MultiLine or false end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.InputText) thisWidget.Instance:Destroy() widgets.discardState(thisWidget) end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.InputText) if thisWidget.state.text == nil then thisWidget.state.text = Iris._widgetState(thisWidget, "text", "") end end, - UpdateState = function(thisWidget: Types.Widget) + UpdateState = function(thisWidget: Types.InputText) local InputText = thisWidget.Instance :: Frame local InputField: TextBox = InputText.InputField diff --git a/lib/widgets/Menu.lua b/lib/widgets/Menu.lua index 12c5e2a..d5279be 100644 --- a/lib/widgets/Menu.lua +++ b/lib/widgets/Menu.lua @@ -2,12 +2,12 @@ local Types = require(script.Parent.Parent.Types) return function(Iris: Types.Internal, widgets: Types.WidgetUtility) local AnyMenuOpen: boolean = false - local ActiveMenu: Types.Widget? = nil - local MenuStack: { Types.Widget } = {} + local ActiveMenu: Types.Menu? = nil + local MenuStack: { Types.Menu } = {} local function EmptyMenuStack(menuIndex: number?) for index = #MenuStack, menuIndex and menuIndex + 1 or 1, -1 do - local widget: Types.Widget = MenuStack[index] + local widget: Types.Menu = MenuStack[index] widget.state.isOpened:set(false) widget.Instance.BackgroundColor3 = Iris._config.HeaderColor @@ -22,7 +22,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end end - local function UpdateChildContainerTransform(thisWidget: Types.Widget) + local function UpdateChildContainerTransform(thisWidget: Types.Menu) local submenu: boolean = thisWidget.parentWidget.type == "Menu" local Menu = thisWidget.Instance :: Frame @@ -79,7 +79,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) -- this only checks if we clicked outside all the menus. If we clicked in any menu, then the hover function handles this. local isInMenu: boolean = false local MouseLocation: Vector2 = widgets.getMouseLocation() - for _, menu: Types.Widget in MenuStack do + for _, menu: Types.Menu in MenuStack do for _, container: GuiObject in { menu.ChildContainer, menu.Instance } do local rectMin: Vector2 = container.AbsolutePosition - widgets.GuiOffset local rectMax: Vector2 = rectMin + container.AbsoluteSize @@ -104,7 +104,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) hasChildren = true, Args = {}, Events = {}, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.MenuBar) local MenuBar: Frame = Instance.new("Frame") MenuBar.Name = "MenuBar" MenuBar.Size = UDim2.fromScale(1, 0) @@ -124,10 +124,10 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Update = function() end, - ChildAdded = function(thisWidget: Types.Widget) + ChildAdded = function(thisWidget: Types.MenuBar, _thisChild: Types.Widget) return thisWidget.Instance end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.MenuBar) thisWidget.Instance:Destroy() end, } :: Types.WidgetClass) @@ -147,19 +147,19 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), ["opened"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.Menu) end, + ["Get"] = function(thisWidget: Types.Menu) return thisWidget.lastOpenedTick == Iris._cycleTick end, }, ["closed"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.Menu) end, + ["Get"] = function(thisWidget: Types.Menu) return thisWidget.lastClosedTick == Iris._cycleTick end, }, }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.Menu) local Menu: TextButton thisWidget.ButtonColors = { Color = Iris._config.HeaderColor, @@ -228,9 +228,9 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) widgets.applyTextStyle(Menu) widgets.UIPadding(Menu, Vector2.new(Iris._config.ItemSpacing.X, Iris._config.FramePadding.Y)) end - widgets.applyInteractionHighlights(thisWidget, "Background", Menu, Menu, thisWidget.ButtonColors) + widgets.applyInteractionHighlights("Background", Menu, Menu, thisWidget.ButtonColors) - widgets.applyButtonClick(thisWidget, Menu, function() + widgets.applyButtonClick(Menu, function() local openMenu: boolean = if #MenuStack <= 1 then not thisWidget.state.isOpened.value else true thisWidget.state.isOpened:set(openMenu) @@ -246,9 +246,9 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end end) - widgets.applyMouseEnter(thisWidget, Menu, function() + widgets.applyMouseEnter(Menu, function() if AnyMenuOpen and ActiveMenu and ActiveMenu ~= thisWidget then - local parentMenu: Types.Widget = thisWidget.parentWidget + local parentMenu = thisWidget.parentWidget :: Types.Menu local parentIndex: number? = table.find(MenuStack, parentMenu) EmptyMenuStack(parentIndex) @@ -296,7 +296,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.ChildContainer = ChildContainer return Menu end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Menu) local Menu = thisWidget.Instance :: TextButton local TextLabel: TextLabel if thisWidget.parentWidget.type == "Menu" then @@ -306,19 +306,19 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end TextLabel.Text = thisWidget.arguments.Text or "Menu" end, - ChildAdded = function(thisWidget: Types.Widget, _thisChild: Types.Widget) + ChildAdded = function(thisWidget: Types.Menu, _thisChild: Types.Widget) UpdateChildContainerTransform(thisWidget) return thisWidget.ChildContainer end, - ChildDiscarded = function(thisWidget: Types.Widget, _thisChild: Types.Widget) + ChildDiscarded = function(thisWidget: Types.Menu, _thisChild: Types.Widget) UpdateChildContainerTransform(thisWidget) end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.Menu) if thisWidget.state.isOpened == nil then thisWidget.state.isOpened = Iris._widgetState(thisWidget, "isOpened", false) end end, - UpdateState = function(thisWidget: Types.Widget) + UpdateState = function(thisWidget: Types.Menu) local ChildContainer = thisWidget.ChildContainer :: ScrollingFrame if thisWidget.state.isOpened.value then @@ -333,7 +333,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ChildContainer.Visible = false end end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Menu) thisWidget.Instance:Destroy() widgets.discardState(thisWidget) end, @@ -356,7 +356,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.MenuItem) local MenuItem: TextButton = Instance.new("TextButton") MenuItem.Name = "MenuItem" MenuItem.BackgroundTransparency = 1 @@ -371,7 +371,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) UIPadding.PaddingTop = UIPadding.PaddingTop - UDim.new(0, 1) widgets.UIListLayout(MenuItem, Enum.FillDirection.Horizontal, UDim.new(0, Iris._config.ItemInnerSpacing.X)) - widgets.applyInteractionHighlights(thisWidget, "Background", MenuItem, MenuItem, { + widgets.applyInteractionHighlights("Background", MenuItem, MenuItem, { Color = Iris._config.HeaderColor, Transparency = 1, HoveredColor = Iris._config.HeaderHoveredColor, @@ -380,12 +380,12 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ActiveTransparency = Iris._config.HeaderHoveredTransparency, }) - widgets.applyButtonClick(thisWidget, MenuItem, function() + widgets.applyButtonClick(MenuItem, function() EmptyMenuStack() end) - widgets.applyMouseEnter(thisWidget, MenuItem, function() - local parentMenu: Types.Widget = thisWidget.parentWidget + widgets.applyMouseEnter(MenuItem, function() + local parentMenu = thisWidget.parentWidget :: Types.Menu if AnyMenuOpen and ActiveMenu and ActiveMenu ~= parentMenu then local parentIndex: number? = table.find(MenuStack, parentMenu) @@ -424,7 +424,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return MenuItem end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.MenuItem) local MenuItem = thisWidget.Instance :: TextButton local TextLabel: TextLabel = MenuItem.TextLabel local Shortcut: TextLabel = MenuItem.Shortcut @@ -438,7 +438,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end end end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.MenuItem) thisWidget.Instance:Destroy() end, } :: Types.WidgetClass) @@ -454,14 +454,14 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) }, Events = { ["checked"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget): boolean + ["Init"] = function(_thisWidget: Types.MenuToggle) end, + ["Get"] = function(thisWidget: Types.MenuToggle): boolean return thisWidget.lastCheckedTick == Iris._cycleTick end, }, ["unchecked"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget): boolean + ["Init"] = function(_thisWidget: Types.MenuToggle) end, + ["Get"] = function(thisWidget: Types.MenuToggle): boolean return thisWidget.lastUncheckedTick == Iris._cycleTick end, }, @@ -469,7 +469,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.MenuToggle) local MenuItem: TextButton = Instance.new("TextButton") MenuItem.Name = "MenuItem" MenuItem.BackgroundTransparency = 1 @@ -484,7 +484,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) UIPadding.PaddingTop = UIPadding.PaddingTop - UDim.new(0, 1) widgets.UIListLayout(MenuItem, Enum.FillDirection.Horizontal, UDim.new(0, Iris._config.ItemInnerSpacing.X)).VerticalAlignment = Enum.VerticalAlignment.Center - widgets.applyInteractionHighlights(thisWidget, "Background", MenuItem, MenuItem, { + widgets.applyInteractionHighlights("Background", MenuItem, MenuItem, { Color = Iris._config.HeaderColor, Transparency = 1, HoveredColor = Iris._config.HeaderHoveredColor, @@ -493,14 +493,14 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ActiveTransparency = Iris._config.HeaderHoveredTransparency, }) - widgets.applyButtonClick(thisWidget, MenuItem, function() + widgets.applyButtonClick(MenuItem, function() local wasChecked: boolean = thisWidget.state.isChecked.value thisWidget.state.isChecked:set(not wasChecked) EmptyMenuStack() end) - widgets.applyMouseEnter(thisWidget, MenuItem, function() - local parentMenu: Types.Widget = thisWidget.parentWidget + widgets.applyMouseEnter(MenuItem, function() + local parentMenu = thisWidget.parentWidget :: Types.Menu if AnyMenuOpen and ActiveMenu and ActiveMenu ~= parentMenu then local parentIndex: number? = table.find(MenuStack, parentMenu) @@ -555,12 +555,12 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return MenuItem end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.MenuToggle) if thisWidget.state.isChecked == nil then thisWidget.state.isChecked = Iris._widgetState(thisWidget, "isChecked", false) end end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.MenuToggle) local MenuItem = thisWidget.Instance :: TextButton local TextLabel: TextLabel = MenuItem.TextLabel local Shortcut: TextLabel = MenuItem.Shortcut @@ -574,7 +574,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end end end, - UpdateState = function(thisWidget: Types.Widget) + UpdateState = function(thisWidget: Types.MenuToggle) local MenuItem = thisWidget.Instance :: TextButton local Icon: ImageLabel = MenuItem.Icon @@ -586,7 +586,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.lastUncheckedTick = Iris._cycleTick + 1 end end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.MenuToggle) thisWidget.Instance:Destroy() widgets.discardState(thisWidget) end, diff --git a/lib/widgets/Plot.lua b/lib/widgets/Plot.lua index b83b3ac..7a40ff5 100644 --- a/lib/widgets/Plot.lua +++ b/lib/widgets/Plot.lua @@ -15,13 +15,13 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), ["changed"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) - return thisWidget.lastNumberChangedTick == Iris._cycleTick + ["Init"] = function(_thisWidget: Types.ProgressBar) end, + ["Get"] = function(thisWidget: Types.ProgressBar) + return thisWidget.lastChangedTick == Iris._cycleTick end, }, }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.ProgressBar) local ProgressBar: Frame = Instance.new("Frame") ProgressBar.Name = "Iris_ProgressBar" ProgressBar.Size = UDim2.new(Iris._config.ItemWidth, UDim.new()) @@ -88,12 +88,12 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return ProgressBar end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.ProgressBar) if thisWidget.state.progress == nil then thisWidget.state.progress = Iris._widgetState(thisWidget, "Progress", 0) end end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.ProgressBar) local Progress = thisWidget.Instance :: Frame local TextLabel: TextLabel = Progress.TextLabel local Bar = Progress.Bar :: Frame @@ -105,7 +105,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) TextLabel.Text = thisWidget.arguments.Text or "Progress Bar" end, - UpdateState = function(thisWidget: Types.Widget) + UpdateState = function(thisWidget: Types.ProgressBar) local ProgressBar = thisWidget.Instance :: Frame local Bar = ProgressBar.Bar :: Frame local Progress: TextLabel = Bar.Progress @@ -129,9 +129,9 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) else Value.Text = string.format("%d%%", progress * 100) end - thisWidget.lastNumberChangedTick = Iris._cycleTick + 1 + thisWidget.lastChangedTick = Iris._cycleTick + 1 end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.ProgressBar) thisWidget.Instance:Destroy() widgets.discardState(thisWidget) end, diff --git a/lib/widgets/RadioButton.lua b/lib/widgets/RadioButton.lua index 68657cc..485833f 100644 --- a/lib/widgets/RadioButton.lua +++ b/lib/widgets/RadioButton.lua @@ -11,20 +11,20 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) }, Events = { ["selected"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.RadioButton) end, + ["Get"] = function(thisWidget: Types.RadioButton) return thisWidget.lastSelectedTick == Iris._cycleTick end, }, ["unselected"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.RadioButton) end, + ["Get"] = function(thisWidget: Types.RadioButton) return thisWidget.lastUnselectedTick == Iris._cycleTick end, }, ["active"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.RadioButton) end, + ["Get"] = function(thisWidget: Types.RadioButton) return thisWidget.state.index.value == thisWidget.arguments.Index end, }, @@ -32,7 +32,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.RadioButton) local RadioButton: TextButton = Instance.new("TextButton") RadioButton.Name = "Iris_RadioButton" RadioButton.AutomaticSize = Enum.AutomaticSize.XY @@ -67,7 +67,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Circle.BackgroundTransparency = Iris._config.CheckMarkTransparency widgets.UICorner(Circle) - widgets.applyInteractionHighlights(thisWidget, "Background", RadioButton, Button, { + widgets.applyInteractionHighlights("Background", RadioButton, Button, { Color = Iris._config.FrameBgColor, Transparency = Iris._config.FrameBgTransparency, HoveredColor = Iris._config.FrameBgHoveredColor, @@ -76,7 +76,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ActiveTransparency = Iris._config.FrameBgActiveTransparency, }) - widgets.applyButtonClick(thisWidget, RadioButton, function() + widgets.applyButtonClick(RadioButton, function() thisWidget.state.index:set(thisWidget.arguments.Index) end) @@ -92,7 +92,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return RadioButton end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.RadioButton) local RadioButton = thisWidget.Instance :: TextButton local TextLabel: TextLabel = RadioButton.TextLabel @@ -101,16 +101,16 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Iris._widgets[thisWidget.type].UpdateState(thisWidget) end end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.RadioButton) thisWidget.Instance:Destroy() widgets.discardState(thisWidget) end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.RadioButton) if thisWidget.state.index == nil then - thisWidget.state.index = Iris._widgetState(thisWidget, "index", thisWidget.arguments.Value) + thisWidget.state.index = Iris._widgetState(thisWidget, "index", thisWidget.arguments.Index) end end, - UpdateState = function(thisWidget: Types.Widget) + UpdateState = function(thisWidget: Types.RadioButton) local RadioButton = thisWidget.Instance :: TextButton local Button = RadioButton.Button :: Frame local Circle: Frame = Button.Circle diff --git a/lib/widgets/Root.lua b/lib/widgets/Root.lua index e9ffea2..941f420 100644 --- a/lib/widgets/Root.lua +++ b/lib/widgets/Root.lua @@ -9,7 +9,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) hasChildren = true, Args = {}, Events = {}, - Generate = function(_thisWidget: Types.Widget) + Generate = function(_thisWidget: Types.Root) local Root: Folder = Instance.new("Folder") Root.Name = "Iris_Root" @@ -95,7 +95,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Root end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Root) if NumNonWindowChildren > 0 then local Root = thisWidget.Instance :: any local PseudoWindowScreenGui = Root.PseudoWindowScreenGui :: any @@ -103,18 +103,18 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) PseudoWindow.Visible = true end end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Root) NumNonWindowChildren = 0 thisWidget.Instance:Destroy() end, - ChildAdded = function(thisWidget: Types.Widget, childWidget: Types.Widget) + ChildAdded = function(thisWidget: Types.Root, thisChild: Types.Widget) local Root = thisWidget.Instance :: any - if childWidget.type == "Window" then + if thisChild.type == "Window" then return thisWidget.Instance - elseif childWidget.type == "Tooltip" then + elseif thisChild.type == "Tooltip" then return Root.PopupScreenGui.TooltipContainer - elseif childWidget.type == "MenuBar" then + elseif thisChild.type == "MenuBar" then return Root.PopupScreenGui.MenuBarContainer else local PseudoWindowScreenGui = Root.PseudoWindowScreenGui :: any @@ -126,8 +126,8 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return PseudoWindow end end, - ChildDiscarded = function(thisWidget: Types.Widget, childWidget: Types.Widget) - if childWidget.type ~= "Window" and childWidget.type ~= "Tooltip" and childWidget.type ~= "MenuBar" then + ChildDiscarded = function(thisWidget: Types.Root, thisChild: Types.Widget) + if thisChild.type ~= "Window" and thisChild.type ~= "Tooltip" and thisChild.type ~= "MenuBar" then NumNonWindowChildren -= 1 if NumNonWindowChildren == 0 then local Root = thisWidget.Instance :: any diff --git a/lib/widgets/Table.lua b/lib/widgets/Table.lua index 348ccd8..1fe661b 100644 --- a/lib/widgets/Table.lua +++ b/lib/widgets/Table.lua @@ -3,11 +3,11 @@ local Types = require(script.Parent.Parent.Types) -- Tables need an overhaul. return function(Iris: Types.Internal, widgets: Types.WidgetUtility) - local tableWidgets: { [Types.ID]: Types.Widget } = {} + local tableWidgets: { [Types.ID]: Types.Table } = {} -- reset the cell index every frame. table.insert(Iris._postCycleCallbacks, function() - for _, thisWidget: Types.Widget in tableWidgets do + for _, thisWidget: Types.Table in tableWidgets do thisWidget.RowColumnIndex = 0 end end) @@ -27,7 +27,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.Table) tableWidgets[thisWidget.ID] = thisWidget thisWidget.InitialNumColumns = -1 @@ -51,7 +51,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Table end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Table) local Table = thisWidget.Instance :: Frame if thisWidget.arguments.BordersOuter == false then @@ -113,11 +113,11 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end end end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Table) tableWidgets[thisWidget.ID] = nil thisWidget.Instance:Destroy() end, - ChildAdded = function(thisWidget: Types.Widget) + ChildAdded = function(thisWidget: Types.Table, _thisChild: Types.Widget) if thisWidget.RowColumnIndex == 0 then thisWidget.RowColumnIndex = 1 end diff --git a/lib/widgets/Text.lua b/lib/widgets/Text.lua index a5cc2a0..f1840bb 100644 --- a/lib/widgets/Text.lua +++ b/lib/widgets/Text.lua @@ -16,7 +16,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.Text) local Text: TextLabel = Instance.new("TextLabel") Text.Name = "Iris_Text" Text.Size = UDim2.fromOffset(0, 0) @@ -30,7 +30,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Text end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Text) local Text = thisWidget.Instance :: TextLabel if thisWidget.arguments.Text == nil then error("Iris.Text Text Argument is required", 5) @@ -53,7 +53,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Text.Text = thisWidget.arguments.Text end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Text) thisWidget.Instance:Destroy() end, } :: Types.WidgetClass) @@ -70,7 +70,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.SeparatorText) local SeparatorText = Instance.new("Frame") SeparatorText.Name = "Iris_SeparatorText" SeparatorText.Size = UDim2.fromScale(1, 0) @@ -119,7 +119,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return SeparatorText end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.SeparatorText) local SeparatorText = thisWidget.Instance :: Frame local TextLabel: TextLabel = SeparatorText.TextLabel if thisWidget.arguments.Text == nil then @@ -127,7 +127,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end TextLabel.Text = thisWidget.arguments.Text end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.SeparatorText) thisWidget.Instance:Destroy() end, } :: Types.WidgetClass) diff --git a/lib/widgets/Tree.lua b/lib/widgets/Tree.lua index 1566b02..76dcec5 100644 --- a/lib/widgets/Tree.lua +++ b/lib/widgets/Tree.lua @@ -6,14 +6,14 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) hasChildren = true, Events = { ["collapsed"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.CollapsingHeader) end, + ["Get"] = function(thisWidget: Types.CollapsingHeader) return thisWidget.lastCollapsedTick == Iris._cycleTick end, }, ["uncollapsed"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.CollapsingHeader) end, + ["Get"] = function(thisWidget: Types.CollapsingHeader) return thisWidget.lastUncollapsedTick == Iris._cycleTick end, }, @@ -21,18 +21,18 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return thisWidget.Instance end), }, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.CollapsingHeader) thisWidget.Instance:Destroy() widgets.discardState(thisWidget) end, - ChildAdded = function(thisWidget: Types.Widget, _otherWidget: Types.Widget) - local ChildContainer = thisWidget.ChildContainer :: Frame + ChildAdded = function(thisWidget: Types.CollapsingHeader, _thisChild: Types.Widget) + local ChildContainer: Frame = thisWidget.ChildContainer :: Frame ChildContainer.Visible = thisWidget.state.isUncollapsed.value return ChildContainer end, - UpdateState = function(thisWidget: Types.Widget) + UpdateState = function(thisWidget: Types.CollapsingHeader) local isUncollapsed: boolean = thisWidget.state.isUncollapsed.value local Tree = thisWidget.Instance :: Frame local ChildContainer = thisWidget.ChildContainer :: Frame @@ -49,7 +49,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ChildContainer.Visible = isUncollapsed end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.CollapsingHeader) if thisWidget.state.isUncollapsed == nil then thisWidget.state.isUncollapsed = Iris._widgetState(thisWidget, "isUncollapsed", false) end @@ -65,7 +65,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ["SpanAvailWidth"] = 2, ["NoIndent"] = 3, }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.Tree) local Tree: Frame = Instance.new("Frame") Tree.Name = "Iris_Tree" Tree.Size = UDim2.new(Iris._config.ItemWidth, UDim.new(0, 0)) @@ -107,7 +107,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Button.Text = "" Button.AutoButtonColor = false - widgets.applyInteractionHighlights(thisWidget, "Background", Button, Header, { + widgets.applyInteractionHighlights("Background", Button, Header, { Color = Color3.fromRGB(0, 0, 0), Transparency = 1, HoveredColor = Iris._config.HeaderHoveredColor, @@ -147,14 +147,14 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) TextLabel.Parent = Button - widgets.applyButtonClick(thisWidget, Button, function() + widgets.applyButtonClick(Button, function() thisWidget.state.isUncollapsed:set(not thisWidget.state.isUncollapsed.value) end) thisWidget.ChildContainer = ChildContainer return Tree end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Tree) local Tree = thisWidget.Instance :: Frame local ChildContainer = thisWidget.ChildContainer :: Frame local Header = Tree.Header :: Frame @@ -187,7 +187,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Args = { ["Text"] = 1, }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.CollapsingHeader) local CollapsingHeader: Frame = Instance.new("Frame") CollapsingHeader.Name = "Iris_CollapsingHeader" CollapsingHeader.Size = UDim2.new(Iris._config.ItemWidth, UDim.new(0, 0)) @@ -238,7 +238,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) local ButtonUIListLayout: UIListLayout = widgets.UIListLayout(Button, Enum.FillDirection.Horizontal, UDim.new(0, 2 * Iris._config.FramePadding.X)) ButtonUIListLayout.VerticalAlignment = Enum.VerticalAlignment.Center - widgets.applyInteractionHighlights(thisWidget, "Background", Button, Button, { + widgets.applyInteractionHighlights("Background", Button, Button, { Color = Iris._config.HeaderColor, Transparency = Iris._config.HeaderTransparency, HoveredColor = Iris._config.HeaderHoveredColor, @@ -274,14 +274,14 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) TextLabel.Parent = Button - widgets.applyButtonClick(thisWidget, Button, function() + widgets.applyButtonClick(Button, function() thisWidget.state.isUncollapsed:set(not thisWidget.state.isUncollapsed.value) end) thisWidget.ChildContainer = ChildContainer return CollapsingHeader end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.CollapsingHeader) local Tree = thisWidget.Instance :: Frame local Header = Tree.Header :: Frame local Button = Header.Button :: TextButton diff --git a/lib/widgets/Window.lua b/lib/widgets/Window.lua index 01150ad..729a3de 100644 --- a/lib/widgets/Window.lua +++ b/lib/widgets/Window.lua @@ -27,7 +27,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ["Text"] = 1, }, Events = {}, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.Tooltip) thisWidget.parentWidget = Iris._rootWidget -- only allow root as parent local Tooltip: Frame = Instance.new("Frame") @@ -59,7 +59,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Tooltip end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Tooltip) local Tooltip = thisWidget.Instance :: Frame local TooltipText: TextLabel = Tooltip.TooltipText if thisWidget.arguments.Text == nil then @@ -68,17 +68,17 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) TooltipText.Text = thisWidget.arguments.Text relocateTooltips() end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Tooltip) thisWidget.Instance:Destroy() end, } :: Types.WidgetClass) local windowDisplayOrder: number = 0 -- incremental count which is used for determining focused windows ZIndex - local dragWindow: Types.Widget? -- window being dragged, may be nil + local dragWindow: Types.Window? -- window being dragged, may be nil local isDragging: boolean = false local moveDeltaCursorPosition: Vector2 -- cursor offset from drag origin (top left of window) - local resizeWindow: Types.Widget? -- window being resized, may be nil + local resizeWindow: Types.Window? -- window being resized, may be nil local isResizing = false local isInsideResize = false -- is cursor inside of the focused window resize outer padding local isInsideWindow = false -- is cursor inside of the focused window @@ -87,10 +87,10 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) local lastCursorPosition: Vector2 - local focusedWindow: Types.Widget? -- window with focus, may be nil + local focusedWindow: Types.Window? -- window with focus, may be nil local anyFocusedWindow: boolean = false -- is there any focused window? - local windowWidgets: { [Types.ID]: Types.Widget } = {} -- array of widget objects of type window + local windowWidgets: { [Types.ID]: Types.Window } = {} -- array of widget objects of type window local function quickSwapWindows() -- ctrl + tab swapping functionality @@ -99,9 +99,9 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end local lowest: number = 0xFFFF - local lowestWidget: Types.Widget + local lowestWidget: Types.Window - for _, widget: Types.Widget in windowWidgets do + for _, widget: Types.Window in windowWidgets do if widget.state.isOpened.value and not widget.arguments.NoNav then if widget.Instance:IsA("ScreenGui") then local value: number = widget.Instance.DisplayOrder @@ -123,7 +123,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Iris.SetFocusedWindow(lowestWidget) end - local function fitSizeToWindowBounds(thisWidget: Types.Widget, intentedSize: Vector2): Vector2 + local function fitSizeToWindowBounds(thisWidget: Types.Window, intentedSize: Vector2): Vector2 local windowSize: Vector2 = Vector2.new(thisWidget.state.position.value.X, thisWidget.state.position.value.Y) local minWindowSize: number = (Iris._config.TextSize + 2 * Iris._config.FramePadding.Y) * 2 local usableSize: Vector2 = widgets.getScreenSizeForWindow(thisWidget) @@ -133,7 +133,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Vector2.new(math.clamp(intentedSize.X, minWindowSize, math.max(maxWindowSize.X, minWindowSize)), math.clamp(intentedSize.Y, minWindowSize, math.max(maxWindowSize.Y, minWindowSize))) end - local function fitPositionToWindowBounds(thisWidget: Types.Widget, intendedPosition: Vector2): Vector2 + local function fitPositionToWindowBounds(thisWidget: Types.Window, intendedPosition: Vector2): Vector2 local thisWidgetInstance = thisWidget.Instance local usableSize: Vector2 = widgets.getScreenSizeForWindow(thisWidget) local safeAreaPadding: Vector2 = Vector2.new(Iris._config.WindowBorderSize + Iris._config.DisplaySafeAreaPadding.X, Iris._config.WindowBorderSize + Iris._config.DisplaySafeAreaPadding.Y) @@ -144,7 +144,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ) end - Iris.SetFocusedWindow = function(thisWidget: Types.Widget?) + Iris.SetFocusedWindow = function(thisWidget: Types.Window?) if focusedWindow == thisWidget then return end @@ -184,7 +184,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) WindowButton.UIStroke.Color = Iris._config.BorderActiveColor windowDisplayOrder += 1 - if thisWidget.usesScreenGUI then + if thisWidget.usesScreenGuis then Window.DisplayOrder = windowDisplayOrder + Iris._config.DisplayOrderOffset else Window.ZIndex = windowDisplayOrder + Iris._config.DisplayOrderOffset @@ -212,9 +212,14 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) if input.UserInputType == Enum.UserInputType.MouseButton1 then local inWindow: boolean = false 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 - widgets.GuiOffset, ResizeBorder.AbsolutePosition - widgets.GuiOffset + ResizeBorder.AbsoluteSize) then + for _, window: Types.Window in windowWidgets do + local Window = window.Instance :: Instance + if not Window then + continue + end + local WindowButton = Window.WindowButton :: TextButton + local ResizeBorder: TextButton = WindowButton.ResizeBorder + if ResizeBorder and widgets.isPosInsideRect(position, ResizeBorder.AbsolutePosition, ResizeBorder.AbsolutePosition + ResizeBorder.AbsoluteSize) then inWindow = true break end @@ -320,7 +325,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) dragWindow.state.position:set(Vector2.new(dragInstance.Position.X.Offset, dragInstance.Position.Y.Offset)) end if (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch) and isResizing and resizeWindow then - local Window = resizeWindow.Instance :: Frame + local Window = resizeWindow.Instance :: Instance isResizing = false resizeWindow.state.size:set(Window.WindowButton.AbsoluteSize) end @@ -348,26 +353,26 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) }, Events = { ["closed"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.Window) end, + ["Get"] = function(thisWidget: Types.Window) return thisWidget.lastClosedTick == Iris._cycleTick end, }, ["opened"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.Window) end, + ["Get"] = function(thisWidget: Types.Window) return thisWidget.lastOpenedTick == Iris._cycleTick end, }, ["collapsed"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.Window) end, + ["Get"] = function(thisWidget: Types.Window) return thisWidget.lastCollapsedTick == Iris._cycleTick end, }, ["uncollapsed"] = { - ["Init"] = function(_thisWidget: Types.Widget) end, - ["Get"] = function(thisWidget: Types.Widget) + ["Init"] = function(_thisWidget: Types.Window) end, + ["Get"] = function(thisWidget: Types.Window) return thisWidget.lastUncollapsedTick == Iris._cycleTick end, }, @@ -376,14 +381,14 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) return Window.WindowButton end), }, - Generate = function(thisWidget: Types.Widget) + Generate = function(thisWidget: Types.Window) thisWidget.parentWidget = Iris._rootWidget -- only allow root as parent - thisWidget.usesScreenGUI = Iris._config.UseScreenGUIs + thisWidget.usesScreenGuis = Iris._config.UseScreenGUIs windowWidgets[thisWidget.ID] = thisWidget local Window - if thisWidget.usesScreenGUI then + if thisWidget.usesScreenGuis then Window = Instance.new("ScreenGui") Window.ResetOnSpawn = false Window.ZIndexBehavior = Enum.ZIndexBehavior.Sibling @@ -420,7 +425,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) WindowButton.Parent = Window - widgets.applyInputBegan(thisWidget, WindowButton, function(input: InputObject) + widgets.applyInputBegan(WindowButton, function(input: InputObject) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Keyboard then return end @@ -478,7 +483,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.state.scrollDistance.value = ChildContainer.CanvasPosition.Y end) - widgets.applyInputBegan(thisWidget, ChildContainer, function(input: InputObject) + widgets.applyInputBegan(ChildContainer, function(input: InputObject) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Keyboard then return end @@ -510,7 +515,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) widgets.UIPadding(TitleBar, Vector2.xAxis * Iris._config.FramePadding.X) widgets.UIListLayout(TitleBar, Enum.FillDirection.Horizontal, UDim.new(0, Iris._config.FramePadding.X)).VerticalAlignment = Enum.VerticalAlignment.Center - widgets.applyInputBegan(thisWidget, TitleBar, function(input: InputObject) + widgets.applyInputBegan(TitleBar, function(input: InputObject) if input.UserInputType == Enum.UserInputType.Touch then if not thisWidget.arguments.NoMove then dragWindow = thisWidget @@ -538,11 +543,11 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) CollapseButton.Parent = TitleBar - widgets.applyButtonClick(thisWidget, CollapseButton, function() + widgets.applyButtonClick(CollapseButton, function() thisWidget.state.isUncollapsed:set(not thisWidget.state.isUncollapsed.value) end) - widgets.applyInteractionHighlights(thisWidget, "Background", CollapseButton, CollapseButton, { + widgets.applyInteractionHighlights("Background", CollapseButton, CollapseButton, { Color = Iris._config.ButtonColor, Transparency = 1, HoveredColor = Iris._config.ButtonHoveredColor, @@ -577,11 +582,11 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) widgets.UICorner(CloseButton) - widgets.applyButtonClick(thisWidget, CloseButton, function() + widgets.applyButtonClick(CloseButton, function() thisWidget.state.isOpened:set(false) end) - widgets.applyInteractionHighlights(thisWidget, "Background", CloseButton, CloseButton, { + widgets.applyInteractionHighlights("Background", CloseButton, CloseButton, { Color = Iris._config.ButtonColor, Transparency = 1, HoveredColor = Iris._config.ButtonHoveredColor, @@ -644,7 +649,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ResizeGrip.ZIndex = 3 ResizeGrip.Parent = WindowButton - widgets.applyInteractionHighlights(thisWidget, "Image", ResizeGrip, ResizeGrip, { + widgets.applyInteractionHighlights("Image", ResizeGrip, ResizeGrip, { Color = Iris._config.ButtonColor, Transparency = Iris._config.ButtonTransparency, HoveredColor = Iris._config.ButtonHoveredColor, @@ -653,7 +658,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ActiveTransparency = Iris._config.ButtonActiveTransparency, }) - widgets.applyButtonDown(thisWidget, ResizeGrip, function() + widgets.applyButtonDown(ResizeGrip, function() if not anyFocusedWindow or not (focusedWindow == thisWidget) then Iris.SetFocusedWindow(thisWidget) -- mitigating wrong focus when clicking on buttons inside of a window without clicking the window itself @@ -675,23 +680,23 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) ResizeBorder.ClipsDescendants = false ResizeBorder.Parent = WindowButton - widgets.applyMouseEnter(thisWidget, ResizeBorder, function() + widgets.applyMouseEnter(ResizeBorder, function() if focusedWindow == thisWidget then isInsideResize = true end end) - widgets.applyMouseLeave(thisWidget, ResizeBorder, function() + widgets.applyMouseLeave(ResizeBorder, function() if focusedWindow == thisWidget then isInsideResize = false end end) - widgets.applyMouseEnter(thisWidget, WindowButton, function() + widgets.applyMouseEnter(WindowButton, function() if focusedWindow == thisWidget then isInsideWindow = true end end) - widgets.applyMouseLeave(thisWidget, WindowButton, function() + widgets.applyMouseLeave(WindowButton, function() if focusedWindow == thisWidget then isInsideWindow = false end @@ -700,7 +705,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.ChildContainer = ChildContainer return Window end, - Update = function(thisWidget: Types.Widget) + Update = function(thisWidget: Types.Window) local Window = thisWidget.Instance :: GuiObject local ChildContainer = thisWidget.ChildContainer :: ScrollingFrame local WindowButton = Window.WindowButton :: TextButton @@ -752,7 +757,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) Title.Text = thisWidget.arguments.Title or "" end, - Discard = function(thisWidget: Types.Widget) + Discard = function(thisWidget: Types.Window) if focusedWindow == thisWidget then focusedWindow = nil anyFocusedWindow = false @@ -769,7 +774,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) thisWidget.Instance:Destroy() widgets.discardState(thisWidget) end, - ChildAdded = function(thisWidget: Types.Widget, thisChid: Types.Widget) + ChildAdded = function(thisWidget: Types.Window, thisChid: Types.Widget) local Window = thisWidget.Instance :: Frame local WindowButton = Window.WindowButton :: TextButton local Content = WindowButton.Content :: Frame @@ -781,7 +786,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end return thisWidget.ChildContainer end, - UpdateState = function(thisWidget: Types.Widget) + UpdateState = function(thisWidget: Types.Window) local stateSize: Vector2 = thisWidget.state.size.value local statePosition: Vector2 = thisWidget.state.position.value local stateIsUncollapsed: boolean = thisWidget.state.isUncollapsed.value @@ -800,7 +805,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) WindowButton.Position = UDim2.fromOffset(statePosition.X, statePosition.Y) if stateIsOpened then - if thisWidget.usesScreenGUI then + if thisWidget.usesScreenGuis then Window.Enabled = true WindowButton.Visible = true else @@ -809,7 +814,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end thisWidget.lastOpenedTick = Iris._cycleTick + 1 else - if thisWidget.usesScreenGUI then + if thisWidget.usesScreenGuis then Window.Enabled = false WindowButton.Visible = false else @@ -867,7 +872,7 @@ return function(Iris: Types.Internal, widgets: Types.WidgetUtility) end end end, - GenerateState = function(thisWidget: Types.Widget) + GenerateState = function(thisWidget: Types.Window) if thisWidget.state.size == nil then thisWidget.state.size = Iris._widgetState(thisWidget, "size", Vector2.new(400, 300)) end diff --git a/lib/widgets/init.lua b/lib/widgets/init.lua index e702e83..d68136a 100644 --- a/lib/widgets/init.lua +++ b/lib/widgets/init.lua @@ -20,7 +20,7 @@ return function(Iris: Types.Internal) } widgets.IS_STUDIO = widgets.RunService:IsStudio() - function widgets.getTime() + function widgets.getTime(): number -- time() always returns 0 in the context of plugins if widgets.IS_STUDIO then return os.clock() @@ -155,23 +155,23 @@ return function(Iris: Types.Internal) thisInstance.AutoLocalize = false end - function widgets.applyInteractionHighlights(thisWidget: Types.Widget, Property: string, Button: GuiButton, Highlightee: GuiObject, Colors: { [string]: any }) + function widgets.applyInteractionHighlights(Property: string, Button: GuiButton, Highlightee: GuiObject, Colors: { [string]: any }) local exitedButton: boolean = false - widgets.applyMouseEnter(thisWidget, Button, function() + widgets.applyMouseEnter(Button, function() Highlightee[Property .. "Color3"] = Colors.HoveredColor Highlightee[Property .. "Transparency"] = Colors.HoveredTransparency exitedButton = false end) - widgets.applyMouseLeave(thisWidget, Button, function() + widgets.applyMouseLeave(Button, function() Highlightee[Property .. "Color3"] = Colors.Color Highlightee[Property .. "Transparency"] = Colors.Transparency exitedButton = true end) - widgets.applyInputBegan(thisWidget, Button, function(input: InputObject) + widgets.applyInputBegan(Button, function(input: InputObject) if not (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Gamepad1) then return end @@ -179,7 +179,7 @@ return function(Iris: Types.Internal) Highlightee[Property .. "Transparency"] = Colors.ActiveTransparency end) - widgets.applyInputEnded(thisWidget, Button, function(input: InputObject) + widgets.applyInputEnded(Button, function(input: InputObject) if not (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Gamepad1) or exitedButton then return end @@ -196,9 +196,9 @@ return function(Iris: Types.Internal) Button.SelectionImageObject = Iris.SelectionImageObject end - function widgets.applyInteractionHighlightsWithMultiHighlightee(thisWidget: Types.Widget, Property: string, Button: GuiButton, Highlightees: { { GuiObject | { [string]: Color3 | number } } }) + function widgets.applyInteractionHighlightsWithMultiHighlightee(Property: string, Button: GuiButton, Highlightees: { { GuiObject | { [string]: Color3 | number } } }) local exitedButton: boolean = false - widgets.applyMouseEnter(thisWidget, Button, function() + widgets.applyMouseEnter(Button, function() for _, Highlightee in Highlightees do Highlightee[1][Property .. "Color3"] = Highlightee[2].HoveredColor Highlightee[1][Property .. "Transparency"] = Highlightee[2].HoveredTransparency @@ -207,7 +207,7 @@ return function(Iris: Types.Internal) end end) - widgets.applyMouseLeave(thisWidget, Button, function() + widgets.applyMouseLeave(Button, function() for _, Highlightee in Highlightees do Highlightee[1][Property .. "Color3"] = Highlightee[2].Color Highlightee[1][Property .. "Transparency"] = Highlightee[2].Transparency @@ -216,7 +216,7 @@ return function(Iris: Types.Internal) end end) - widgets.applyInputBegan(thisWidget, Button, function(input: InputObject) + widgets.applyInputBegan(Button, function(input: InputObject) if not (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Gamepad1) then return end @@ -226,7 +226,7 @@ return function(Iris: Types.Internal) end end) - widgets.applyInputEnded(thisWidget, Button, function(input: InputObject) + widgets.applyInputEnded(Button, function(input: InputObject) if not (input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Gamepad1) or exitedButton then return end @@ -263,44 +263,44 @@ return function(Iris: Types.Internal) end end - function widgets.applyButtonClick(_thisWidget: Types.Widget, thisInstance: GuiButton, callback: () -> ()) + function widgets.applyButtonClick(thisInstance: GuiButton, callback: () -> ()) thisInstance.MouseButton1Click:Connect(function() callback() end) end - function widgets.applyButtonDown(_thisWidget: Types.Widget, thisInstance: GuiButton, callback: (x: number, y: number) -> ()) + function widgets.applyButtonDown(thisInstance: GuiButton, callback: (x: number, y: number) -> ()) thisInstance.MouseButton1Down:Connect(function(...) callback(...) end) end - function widgets.applyMouseEnter(_thisWidget: Types.Widget, thisInstance: GuiObject, callback: () -> ()) + function widgets.applyMouseEnter(thisInstance: GuiObject, callback: () -> ()) thisInstance.MouseEnter:Connect(function(...) callback(...) end) end - function widgets.applyMouseLeave(_thisWidget: Types.Widget, thisInstance: GuiObject, callback: () -> ()) + function widgets.applyMouseLeave(thisInstance: GuiObject, callback: () -> ()) thisInstance.MouseLeave:Connect(function(...) callback(...) end) end - function widgets.applyInputBegan(_thisWidget: Types.Widget, thisInstance: GuiButton, callback: (input: InputObject) -> ()) + function widgets.applyInputBegan(thisInstance: GuiButton, callback: (input: InputObject) -> ()) thisInstance.InputBegan:Connect(function(...) callback(...) end) end - function widgets.applyInputEnded(_thisWidget: Types.Widget, thisInstance: GuiButton, callback: (input: InputObject) -> ()) + function widgets.applyInputEnded(thisInstance: GuiButton, callback: (input: InputObject) -> ()) thisInstance.InputEnded:Connect(function(...) callback(...) end) end - function widgets.discardState(thisWidget: Types.Widget) - for _, state: Types.State in thisWidget.state do + function widgets.discardState(thisWidget: Types.StateWidget) + for _, state: Types.State in thisWidget.state do state.ConnectedWidgets[thisWidget.ID] = nil end end @@ -314,17 +314,17 @@ return function(Iris: Types.Internal) widgets.EVENTS = { hover = function(pathToHovered: (thisWidget: Types.Widget) -> GuiObject) return { - ["Init"] = function(thisWidget: Types.Widget) + ["Init"] = function(thisWidget: Types.Widget & Types.Hovered) local hoveredGuiObject: GuiObject = pathToHovered(thisWidget) - widgets.applyMouseEnter(thisWidget, hoveredGuiObject, function() + widgets.applyMouseEnter(hoveredGuiObject, function() thisWidget.isHoveredEvent = true end) - widgets.applyMouseLeave(thisWidget, hoveredGuiObject, function() + widgets.applyMouseLeave(hoveredGuiObject, function() thisWidget.isHoveredEvent = false end) thisWidget.isHoveredEvent = false end, - ["Get"] = function(thisWidget: Types.Widget): boolean + ["Get"] = function(thisWidget: Types.Widget & Types.Hovered): boolean return thisWidget.isHoveredEvent end, } @@ -332,15 +332,15 @@ return function(Iris: Types.Internal) click = function(pathToClicked: (thisWidget: Types.Widget) -> GuiButton) return { - ["Init"] = function(thisWidget: Types.Widget) + ["Init"] = function(thisWidget: Types.Widget & Types.Clicked) local clickedGuiObject: GuiButton = pathToClicked(thisWidget) thisWidget.lastClickedTick = -1 - widgets.applyButtonClick(thisWidget, clickedGuiObject, function() + widgets.applyButtonClick(clickedGuiObject, function() thisWidget.lastClickedTick = Iris._cycleTick + 1 end) end, - ["Get"] = function(thisWidget: Types.Widget): boolean + ["Get"] = function(thisWidget: Types.Widget & Types.Clicked): boolean return thisWidget.lastClickedTick == Iris._cycleTick end, } @@ -348,7 +348,7 @@ return function(Iris: Types.Internal) rightClick = function(pathToClicked: (thisWidget: Types.Widget) -> GuiButton) return { - ["Init"] = function(thisWidget: Types.Widget) + ["Init"] = function(thisWidget: Types.Widget & Types.RightClicked) local clickedGuiObject: GuiButton = pathToClicked(thisWidget) thisWidget.lastRightClickedTick = -1 @@ -356,7 +356,7 @@ return function(Iris: Types.Internal) thisWidget.lastRightClickedTick = Iris._cycleTick + 1 end) end, - ["Get"] = function(thisWidget: Types.Widget): boolean + ["Get"] = function(thisWidget: Types.Widget & Types.RightClicked): boolean return thisWidget.lastRightClickedTick == Iris._cycleTick end, } @@ -364,13 +364,13 @@ return function(Iris: Types.Internal) doubleClick = function(pathToClicked: (thisWidget: Types.Widget) -> GuiButton) return { - ["Init"] = function(thisWidget: Types.Widget) + ["Init"] = function(thisWidget: Types.Widget & Types.DoubleClicked) local clickedGuiObject: GuiButton = pathToClicked(thisWidget) thisWidget.lastClickedTime = -1 thisWidget.lastClickedPosition = Vector2.zero thisWidget.lastDoubleClickedTick = -1 - widgets.applyButtonDown(thisWidget, clickedGuiObject, function(x: number, y: number) + widgets.applyButtonDown(clickedGuiObject, function(x: number, y: number) local currentTime: number = widgets.getTime() local isTimeValid: boolean = currentTime - thisWidget.lastClickedTime < Iris._config.MouseDoubleClickTime if isTimeValid and (Vector2.new(x, y) - thisWidget.lastClickedPosition).Magnitude < Iris._config.MouseDoubleClickMaxDist then @@ -381,7 +381,7 @@ return function(Iris: Types.Internal) end end) end, - ["Get"] = function(thisWidget: Types.Widget): boolean + ["Get"] = function(thisWidget: Types.Widget & Types.DoubleClicked): boolean return thisWidget.lastDoubleClickedTick == Iris._cycleTick end, } @@ -389,17 +389,17 @@ return function(Iris: Types.Internal) ctrlClick = function(pathToClicked: (thisWidget: Types.Widget) -> GuiButton) return { - ["Init"] = function(thisWidget: Types.Widget) + ["Init"] = function(thisWidget: Types.Widget & Types.CtrlClicked) local clickedGuiObject: GuiButton = pathToClicked(thisWidget) thisWidget.lastCtrlClickedTick = -1 - widgets.applyButtonClick(thisWidget, clickedGuiObject, function() + widgets.applyButtonClick(clickedGuiObject, function() if widgets.UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) or widgets.UserInputService:IsKeyDown(Enum.KeyCode.RightControl) then thisWidget.lastCtrlClickedTick = Iris._cycleTick + 1 end end) end, - ["Get"] = function(thisWidget: Types.Widget): boolean + ["Get"] = function(thisWidget: Types.Widget & Types.CtrlClicked): boolean return thisWidget.lastCtrlClickedTick == Iris._cycleTick end, }