User Interface
April 13, 2020(edited August 15, 2022)

This addon is meant to provide custom user interface Control nodes. You can install only the controls that you want to use and activating the addon will make those available for use.


As mentioned, this is a base class for custom control implementations within Godot. The idea is to provide means to deal with the theme system while exposing to the inspector the various possibilities to override the theme entries relevant to the implemented Control. The problem that this class attempts to solve follows.

When we try to retrieve a theme object/value, the default behavior is that the control instance will check if there is a valid Theme object assigned to it. If not, it will go recursively through its parents until one is found or the root is reached. If still none is found, the default Theme object is used to retrieve the desired style name with the specified type category.

While this is very interesting for providing really easy means to style an entire application/game by simply applying a theme resource to a parent node, it also imposes a limitation for custom controls, specially when implemented in pure GDScript. The major problem is that we don't have access to the default Theme object in order to insert default entries in it.

Another problem is that if we do like I did in the past (you can see in the FancyLineEdit and the Inventory widgets), which is to create a theme object if one does not exist and create the entries within the obtained theme, then we pollute it with category/values that may never be used. What if we decide the control is not exactly for the project and remove it? The style entries will remain within the theme resource unless we manually clean it up!

This base class attempts to solve this problem while also "automatically" exposing to the inspector the possibility to easily override the style values of a given instance, much like any core Control.

Based on this information it should be clear that this "addon" is primarily meant to those wanting to create new custom Controls with pure GDScript. Any future UI control I release as part of this addon pack will derive from this class. Unfortunately I can't change previous Controls without breaking compatibility so those will remain the way they are, at least until the pack is ported to Godot 4.


This control is meant to be used as input for consoles and/or chat boxes, thus not all of the functionalities of the LineEdit control are implemented in it.

It allows images to be rendered within the box, automatically scaling them based on the used font height. Depending on how the image is built it should result in something that matches the rendered text.

Text can be formatted, that is, colored as well as decorated (bold, italic, underline...).

The basic idea of this control is to configure a few rules that will automatically change how the entered text is rendered.


This addon actually incorporates two Control nodes, both derived from InventoryCore (which is not meant for direct usage):

Some of the features (besides what was already mentioned above) that are available:


The TabularBox widget offers means to edit and view data in a tabular way, that is, through rows and columns. The information shown is based on a data source, which is the main interaction point between logic and the widget itself. The Control offers several features to customize the behavior. It also provides a system to expand to different "types of columns" that would allow custom viewing/storing of the data.

This Control depends on the CustomControlBase.


The ExpandablePanel is a widget that attaches itself to one of the four borders of its parent Control. It also can handle multiple "pages" of content. The panel can "shrink into the border" or expand into the viewport in order to hide or show the desired content page.

Expanding or shrinking can even be animated. The animation can also be affected by a curve if so desired.

This Control depends on the CustomControlBase.


When you expose numerical properties to the Inspector panel, depending on the settings of that property the editor will display a slider instead of the spin buttons. On both cases the input is still box is displayed. Unfortunately that control is not fully exposed to scripting, meaning that we can't use it.

The slider is particularly useful when we have a very well defined value range for a given property. So I decided to implement one such control, which would display spin buttons when the range is not fully defined, while hiding those buttons to show a slider otherwise. The image bellow displays two instances of the SpinSlider Control, one which does not define a range (top) and the other with both minimum and maximum values defined:


One important aspect of the SpinSlider in comparison to the core (EditorSpinSlider) Control (the one used only in the editor) is in how the widget "decides" when to use the spin buttons or the slider. In the EditorSpinSlider, the buttons will be shown whenever the Step property is set to 1. Otherwise the slider is shown. However, in the SpinSlider the buttons will be shown whenever the range is not fully defined. That is, to get the slider to show up, both minimum and maximum values must be defined.