Building Studio Widgets

Building Studio Widgets

10 min

Roblox Studio gives you the power to create custom widgets and use them as Studio tools and extensions. These widgets behave as custom windows/panels in Studio and they can be docked inside your interface or floated as separate windows.

Creating a Widget GUI

All Studio widgets begin as DockWidgetPluginGui objects which can be filled with text labels, buttons, and more. To create an empty widget GUI, call the Plugin/CreateDockWidgetPluginGui|CreateDockWidgetPluginGui() function, passing in an ID and a DataType/DockWidgetPluginGuiInfo|DockWidgetPluginGuiInfo object.

Note the DataType/DockWidgetPluginGuiInfo|DockWidgetPluginGuiInfo.new() constructor expects its parameters in a specific order as follows:

# Property Type Description
1 InitialDockState enum One of the enum/InitialDockState|InitialDockState enumerations.
2 InitialEnabled boolean The initial enabled (visible) state of the widget GUI.
3 InitialEnabledShouldOverrideRestore boolean If true, the value of InitialEnabled will override the previously saved enabled state.
4 FloatingXSize integer The initial width of the GUI when InitialDockState is set to Enum.InitialDockState.Float.
5 FloatingYSize integer The initial height of the GUI when InitialDockState is set to Enum.InitialDockState.Float.
6 MinWidth integer The minimum width of the GUI, with some platform-specific variations.
7 MinHeight integer The minimum height of the GUI, with some platform-specific variations.

Customizing the GUI

Once created, a widget GUI can be customized with GUI objects like informative TextLabel|TextLabels, interactive ImageButton|ImageButtons, and more. For example, this code adds a basic TextButton to the GUI window:

Studio Color Themes

Effective Studio widgets should ideally match the Studio theme setting and dynamically adjust if the theme is changed. For instance, if a developer is using “Dark” theme, the widget’s background color, images, and text labels should look nice alongside Studio’s native theme colors.

The following addition uses a syncGuiColors() function which is initially called along with a table of GUI objects to sync. Inside the function, a nested setColors() function loops through the objects and syncs specific aspects of them using StudioTheme/GetColor|GetColor() with enum/StudioStyleGuideColor|StudioStyleGuideColor enums. On line 37, this setColors() function is immediately run to sync the Studio theme, then it’s connected to the Studio/ThemeChanged|ThemeChanged event to detect future theme changes.

Mouse Cursors

To improve the expected interaction with widget elements, system-specific mouse cursors can be set upon GUI events like GuiObject/MouseEnter|MouseEnter, GuiObject/MouseLeave|MouseLeave, GuiButton/MouseButton1Down|MouseButton1Down, etc. The following code shows how to connect a function to the GuiObject/MouseEnter|MouseEnter and GuiObject/MouseLeave|MouseLeave events of testButton to change the mouse cursor:

Look Asset Suggested Use
rbxasset://SystemCursors/Arrow Default clicking and selection.
rbxasset://SystemCursors/PointingHand Hovering over an active link/button.
rbxasset://SystemCursors/OpenHand Hovering over a draggable item.
rbxasset://SystemCursors/ClosedHand Dragging an item.
rbxasset://SystemCursors/IBeam Hovering in a text field.
rbxasset://SystemCursors/SizeNS Hovering over a vertical resize handle.
rbxasset://SystemCursors/SizeEW Hovering over a horizontal resize handle.
rbxasset://SystemCursors/SizeNESW Hovering over a corner resize handle.
rbxasset://SystemCursors/SizeNWSE Hovering over a corner resize handle.
rbxasset://SystemCursors/SizeAll Hovering over a multi-direction resize handle.
rbxasset://SystemCursors/SplitNS Hovering over a vertical "split" handle.
rbxasset://SystemCursors/SplitEW Hovering over a horizontal "split" handle.
rbxasset://SystemCursors/Forbidden Hovering over a locked/forbidden item.
rbxasset://SystemCursors/Wait Indicating an action is in progress.
rbxasset://SystemCursors/Busy Indicating the system is busy.
rbxasset://SystemCursors/Cross Hovering over a pinpoint selection area.

User Input in Widgets

UI elements such as TextBox and TextButton work as normal in Studio widgets and you can build interfaces just like you normally would on Roblox. However, UserInputService and ContextActionService will not work since these services expect the main game window to be in focus.

One workaround for generic input events is to create a transparent Frame and overlay it over the entire screen. When the user clicks on the frame, keyboard input will be captured in the GuiObject/InputBegan event on the frame until the user clicks away. Below is a sample code snippet that creates such a frame: