Iris
Iris; contains the all user-facing functions and properties.
A set of internal functions can be found in Iris.Internal
(only use if you understand).
In its simplest form, users may start Iris by using
Iris.Init()
Iris:Connect(function()
Iris.Window({"My First Window!"})
Iris.Text({"Hello, World"})
Iris.Button({"Save"})
Iris.InputNum({"Input"})
Iris.End()
end)
Types
ID
type
ID =
string
Widget
type
Widget =
{
type:
string
,
lastCycleTick:
number
,
ZIndex:
number
,
arguments:
{
[
string
]
:
any
}
}
Properties
Disabled
Iris.Disabled:
boolean
While Iris.Disabled is true, execution of Iris and connected functions will be paused. The widgets are not destroyed, they are just frozen so no changes will happen to them.
Args
Iris.Args:
{
[
string
]
:
{
[
string
]
:
any
}
}
Provides a list of every possible Argument for each type of widget to it's index.
For instance, Iris.Args.Window.NoResize
.
The Args table is useful for using widget Arguments without remembering their order.
Iris.Window({"My Window", [Iris.Args.Window.NoResize] = true})
TemplateConfig
Iris.TemplateConfig:
{
[
string
]
:
{
[
string
]
:
any
}
}
TemplateConfig provides a table of default styles and configurations which you may apply to your UI.
Functions
Init
Iris.
Init
(
eventConnection:
(
RBXScriptSignal
|
(
)
→
(
)
|
false
)
?
,
--
the event to determine an Iris cycle, defaulting to [Heartbeat]
allowMultipleInits:
boolean?
--
allows subsequent calls 'Iris.Init()' to do nothing rather than error about initialising again, defaulting to false
) →
Iris
Initializes Iris and begins rendering. Can only be called once. See Iris.Shutdown to stop Iris, or Iris.Disabled to temporarily disable Iris.
Once initialized, Iris:Connect can be used to create a widget.
If the eventConnection
is false
then Iris will not create a cycle loop and the user will need to call Internal._cycle every frame.
Shutdown
Iris.
Shutdown
(
) →
(
)
Shuts Iris down. This can only be called once, and Iris cannot be started once shut down.
Append
Inserts any Roblox Instance into Iris.
The parent of the inserted instance can either be determined by the _config.Parent
property or by the current parent widget from the stack.
End
Iris.
End
(
) →
(
)
Marks the end of any widgets which contain children. For example:
-- Widgets placed here **will not** be inside the tree
Iris.Text({"Above and outside the tree"})
-- A Tree widget can contain children.
-- We must therefore remember to call `Iris.End()`
Iris.Tree({"My First Tree"})
-- Widgets placed here **will** be inside the tree
Iris.Text({"Tree item 1"})
Iris.Text({"Tree item 2"})
Iris.End()
-- Widgets placed here **will not** be inside the tree
Iris.Text({"Below and outside the tree"})
Caution: Error
Seeing the error Callback has too few calls to Iris.End()
or Callback has too many calls to Iris.End()
?
Using the wrong amount of Iris.End()
calls in your code will lead to an error.
Each widget called which might have children should be paired with a call to Iris.End()
, even if the Widget doesnt currently have any children.
ForceRefresh
Iris.
ForceRefresh
(
) →
(
)
Destroys and regenerates all instances used by Iris. Useful if you want to propogate state changes.
Caution: Performance
Because this function Deletes and Initializes many instances, it may cause performance issues when used with many widgets. In no case should it be called every frame.
UpdateGlobalConfig
Iris.
UpdateGlobalConfig
(
deltaStyle:
{
[
string
]
:
any
}
--
a table containing the changes in style ex: {ItemWidth = UDim.new(0, 100)}
) →
(
)
Customizes the configuration which every widget will inherit from.
It can be used along with Iris.TemplateConfig to easily swap styles, for example:
Iris.UpdateGlobalConfig(Iris.TemplateConfig.colorLight) -- use light theme
Caution: Performance
This function internally calls Iris.ForceRefresh so that style changes are propogated.
As such, it may cause performance issues when used with many widgets. In no case should it be called every frame.
PushConfig
Iris.
PushConfig
(
deltaStyle:
{
[
string
]
:
any
}
--
a table containing the changes in style ex: {ItemWidth = UDim.new(0, 100)}
) →
(
)
Allows cascading of a style by allowing styles to be locally and hierarchically applied.
Each call to Iris.PushConfig must be paired with a call to Iris.PopConfig, for example:
Iris.Text({"boring text"})
Iris.PushConfig({TextColor = Color3.fromRGB(128, 0, 256)})
Iris.Text({"Colored Text!"})
Iris.PopConfig()
Iris.Text({"boring text"})
PopConfig
Iris.
PopConfig
(
) →
(
)
Ends a Iris.PushConfig style.
Each call to Iris.PopConfig should match a call to Iris.PushConfig.
PushId
Pushes an id onto the id stack for all future widgets. Use Iris.PopId to pop it off the stack.
PopID
Iris.
PopID
(
) →
(
)
Removes the most recent pushed id from the id stack.
SetNextWidgetID
Sets the id for the next widget. Useful for using Iris.Append on the same widget.
Iris.SetNextWidgetId("demo_window")
Iris.Window({ "Window" })
Iris.Text({ "Text one placed here." })
Iris.End()
-- later in the code
Iris.SetNextWidgetId("demo_window")
Iris.Window()
Iris.Text({ "Text two placed here." })
Iris.End()
-- both text widgets will be placed under the same window despite being called separately.
State<T>
StateConstructs a new State object. Subsequent ID calls will return the same object.
INFO
Iris.State allows you to create "references" to the same value while inside your UI drawing loop. For example:
Iris:Connect(function()
local myNumber = 5
myNumber = myNumber + 1
Iris.Text({"The number is: " .. myNumber})
end)
This is problematic. Each time the function is called, a new myNumber is initialized, instead of retrieving the old one. The above code will always display 6.
Iris.State solves this problem:
Iris:Connect(function()
local myNumber = Iris.State(5)
myNumber:set(myNumber:get() + 1)
Iris.Text({"The number is: " .. myNumber})
end)
In this example, the code will work properly, and increment every frame.
WeakState<T>
StateConstructs 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
VariableState<T>
StateIris.
VariableState<T>
(
variable:
T
,
--
the variable to track
callback:
(
T
)
→
(
)
--
a function which sets the new variable locally
) →
State
<
T
>
Returns a state object linked to a local variable.
The passed variable is used to check whether the state object should update. The callback method is used to change the local variable when the state changes.
The existence of such a function is to make working with local variables easier. Since Iris cannot directly manipulate the memory of the variable, like in C++, it must instead rely on the user updating it through the callback provided. Additionally, because the state value is not updated when created or called we cannot return the new value back, instead we require a callback for the user to update.
local myNumber = 5
local state = Iris.VariableState(myNumber, function(value)
myNumber = value
end)
Iris.DragNum({ "My number" }, { number = state })
This is how Dear ImGui does the same in C++ where we can just provide the memory location to the variable which is then updated directly.
static int myNumber = 5;
ImGui::DragInt("My number", &myNumber); // Here in C++, we can directly pass the variable.
Caution: Update Order
If the variable and state value are different when calling this, the variable value takes precedence.
Therefore, if you update the state using state.value = ...
then it will be overwritten by the variable value.
You must use state:set(...)
if you want the variable to update to the state's value.
TableState<K, V>
StateIris.
TableState<K, V>
(
table:
{
[
K
]
:
V
}
,
--
the table containing the value
key:
K
,
--
the key to the value in table
callback:
(
(
newValue:
V
)
→
false?
)
?
--
a function called when the state is changed
) →
State
<
V
>
Similar to Iris.VariableState but takes a table and key to modify a specific value and a callback to determine whether to update the value.
The passed table and key are used to check the value. The callback is called when the state changes value and determines whether we update the table. This is useful if we want to monitor a table value which needs to call other functions when changed.
Since tables are pass-by-reference, we can modify the table anywhere and it will update all other instances. Therefore, we don't need a callback by default.
local data = {
myNumber = 5
}
local state = Iris.TableState(data, "myNumber")
Iris.DragNum({ "My number" }, { number = state })
Here the data._started
should never be updated directly, only through the toggle
function. However, we still want to monitor the value and be able to change it.
Therefore, we use the callback to toggle the function for us and prevent Iris from updating the table value by returning false.
local data = {
_started = false
}
local function toggle(enabled: boolean)
data._started = enabled
if data._started then
start(...)
else
stop(...)
end
end
local state = Iris.TableState(data, "_started", function(stateValue: boolean)
toggle(stateValue)
return false
end)
Iris.Checkbox({ "Started" }, { isChecked = state })
Caution: Update Order
If the table value and state value are different when calling this, the table value value takes precedence.
Therefore, if you update the state using state.value = ...
then it will be overwritten by the table value.
You must use state:set(...)
if you want the table value to update to the state's value.
ComputedState<T, U>
Iris.
ComputedState<T, U>
(
onChangeCallback:
(
firstValue:
T
)
→
U
--
callback which should return a value transformed from the firstState value
) →
State
<
U
>
Constructs a new State object, but binds its value to the value of another State.
INFO
A common use case for this constructor is when a boolean State needs to be inverted:
Iris.ComputedState(otherState, function(newValue)
return not newValue
end)
ShowDemoWindow
Iris.
ShowDemoWindow
(
) →
(
)
ShowDemoWindow is a function which creates a Demonstration window. this window contains many useful utilities for coders, and serves as a refrence for using each part of the library. Ideally, the DemoWindow should always be available in your UI. It is the same as any other callback you would connect to Iris using Iris.Connect
Iris:Connect(Iris.ShowDemoWindow)
SetFocusedWindow
Iris.
SetFocusedWindow
(
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.
Connect
Iris:
Connect
(
callback:
(
)
→
(
)
--
the callback containg the Iris code
) →
(
)
→
(
)
--
call to disconnect it
Connects a function which will execute every Iris cycle. Iris.Init must be called before connecting.
A cycle is determined by the eventConnection
passed to Iris.Init (default to RunService.Heartbeat).
Multiple callbacks can be added to Iris from many different scripts or modules.