Improve docs structure
Change Step by Step in Getting Started Remove Engine Features category, move into a new Tutorials top-level section
83
tutorials/gui/bbcode_in_richtextlabel.rst
Normal file
@@ -0,0 +1,83 @@
|
||||
.. _doc_bbcode_in_richtextlabel:
|
||||
|
||||
BBCode in RichTextLabel
|
||||
=======================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
:ref:`class_RichTextLabel` allows to display complex text markup in a control.
|
||||
It has a built-in API for generating the markup, but can also parse a BBCode.
|
||||
|
||||
Note that the BBCode tags can also be used to some extent in the
|
||||
:ref:`XML source of the class reference <doc_updating_the_class_reference>`.
|
||||
|
||||
Setting up
|
||||
----------
|
||||
|
||||
For RichTextLabel to work properly, it must be set up. This means loading
|
||||
the intended fonts in the relevant properties:
|
||||
|
||||
.. image:: img/rtl_setup.png
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
| Command | Tag | Description |
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
| **bold** | ``[b]{text}[/b]`` | Makes {text} bold. |
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
| **italics** | ``[i]{text}[/i]`` | Makes {text} italics. |
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
| **underline** | ``[u]{text}[/u]`` | Makes {text} underline. |
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
| **code** | ``[code]{text}[/code]`` | Makes {text} monospace. |
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
| **center** | ``[center]{text}[/center]`` | Makes {text} centered. |
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
| **right** | ``[right]{text}[/right]`` | Makes {text} right-aligned. |
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
| **fill** | ``[fill]{text}[/fill]`` | Makes {text} fill width. |
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
| **indent** | ``[indent]{text}[/indent]`` | Increase indent level of {text}. |
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
| **url** | ``[url]{url}[/url]`` | Show {url} as such. |
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
| **url (ref)** | ``[url=<url>]{text}[/url]`` | Makes {text} reference <url>. |
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
| **image** | ``[img]{path}[/img]`` | Insert image at resource {path}. |
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
| **font** | ``[font=<path>]{text}[/font]`` | Use custom font at <path> for {text}. |
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
| **color** | ``[color=<code/name>]{text}[/color]`` | Change {text} color, use # format such as #ff00ff or name. |
|
||||
+-----------------+--------------------------------------------+--------------------------------------------------------------+
|
||||
|
||||
Built-in color names
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
List of valid color names for the [color=<name>] tag:
|
||||
|
||||
- aqua
|
||||
- black
|
||||
- blue
|
||||
- fuchsia
|
||||
- gray
|
||||
- green
|
||||
- lime
|
||||
- maroon
|
||||
- navy
|
||||
- purple
|
||||
- red
|
||||
- silver
|
||||
- teal
|
||||
- white
|
||||
- yellow
|
||||
|
||||
Hexadecimal color codes
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For opaque RGB colors, any valid 6-digit hexadecimal code is supported, e.g. ``[color=#ffffff]white[/color]``.
|
||||
|
||||
For transparent RGB colors, any 8-digit hexadecimal code can be used, e.g. ``[color=#88ffffff]translucent white[/color]``.
|
||||
In this case, note that the alpha channel is the **first** component of the color code, not the last one.
|
||||
143
tutorials/gui/custom_gui_controls.rst
Normal file
@@ -0,0 +1,143 @@
|
||||
.. _doc_custom_gui_controls:
|
||||
|
||||
Custom GUI controls
|
||||
===================
|
||||
|
||||
So many controls...
|
||||
-------------------
|
||||
|
||||
Yet there are never enough. Creating your own custom controls that act
|
||||
just the way you want them is an obsession of almost every GUI
|
||||
programmer. Godot provides plenty of them, but they may not work exactly
|
||||
the way you want. Before contacting the developers with a pull-request
|
||||
to support diagonal scrollbars, at least it will be good to know how to
|
||||
create these controls easily from script.
|
||||
|
||||
Drawing
|
||||
-------
|
||||
|
||||
For drawing, it is recommended to check the :ref:`doc_custom_drawing_in_2d` tutorial.
|
||||
The same applies. Some functions are worth mentioning due to their
|
||||
usefulness when drawing, so they will be detailed next:
|
||||
|
||||
Checking control size
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Unlike 2D nodes, "size" is very important with controls, as it helps to
|
||||
organize them in proper layouts. For this, the
|
||||
:ref:`Control.get_size() <class_Control_get_size>`
|
||||
method is provided. Checking it during _draw() is vital to ensure
|
||||
everything is kept in-bounds.
|
||||
|
||||
Checking focus
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Some controls (such as buttons or text editors) might provide input
|
||||
focus for keyboard or joypad input. Examples of this are entering text
|
||||
or pressing a button. This is controlled with the
|
||||
:ref:`Control.set_focus_mode() <class_Control_set_focus_mode>`
|
||||
function. When drawing, and if the control supports input focus, it is
|
||||
always desired to show some sort of indicator (highight, box, etc) to
|
||||
indicate that this is the currently focused control. To check for this
|
||||
status, the :ref:`Control.has_focus() <class_Control_has_focus>`
|
||||
exists. Example
|
||||
|
||||
::
|
||||
|
||||
func _draw():
|
||||
if (has_focus()):
|
||||
draw_selected()
|
||||
else:
|
||||
draw_normal()
|
||||
|
||||
Sizing
|
||||
------
|
||||
|
||||
As mentioned before, size is very important to controls. This allows
|
||||
them to lay out properly, when set into grids, containers, or anchored.
|
||||
Controls most of the time provide a *minimum size* to help to properly
|
||||
lay them out. For example, if controls are placed vertically on top of
|
||||
each other using a :ref:`VBoxContainer <class_VBoxContainer>`,
|
||||
the minimum size will make sure your custom control is not squished by
|
||||
the other controls in the container.
|
||||
|
||||
To provide this callback, just override
|
||||
:ref:`Control.get_minimum_size() <class_Control_get_minimum_size>`,
|
||||
for example:
|
||||
|
||||
::
|
||||
|
||||
func get_minimum_size():
|
||||
return Vector2(30,30)
|
||||
|
||||
Or alternatively, set it via function:
|
||||
|
||||
::
|
||||
|
||||
func _ready():
|
||||
set_custom_minimum_size( Vector2(30,30) )
|
||||
|
||||
Input
|
||||
-----
|
||||
|
||||
Controls provide a few helpers to make managing input events much easier
|
||||
than regular nodes.
|
||||
|
||||
Input events
|
||||
~~~~~~~~~~~~
|
||||
|
||||
There are a few tutorials about input before this one, but it's worth
|
||||
mentioning that controls have a special input method that only works
|
||||
when:
|
||||
|
||||
- The mouse pointer is over the control.
|
||||
- The button was pressed over this control (control always
|
||||
captures input until button is released)
|
||||
- Control provides keyboard/joypad focus via
|
||||
:ref:`Control.set_focus_mode() <class_Control_set_focus_mode>`.
|
||||
|
||||
This function is
|
||||
:ref:`Control._gui_input() <class_Control__gui_input>`.
|
||||
Simply override it in your control. No processing needs to be set.
|
||||
|
||||
::
|
||||
|
||||
extends Control
|
||||
|
||||
func _gui_input(ev):
|
||||
if (ev is InputEventMouseButton and ev.button_index==BUTTON_LEFT and ev.pressed):
|
||||
print("Left mouse button was pressed!")
|
||||
|
||||
For more information about events themselves, check the :ref:`doc_inputevent`
|
||||
tutorial.
|
||||
|
||||
Notifications
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Controls also have many useful notifications for which no callback
|
||||
exists, but can be checked with the _notification callback:
|
||||
|
||||
::
|
||||
|
||||
func _notification(what):
|
||||
|
||||
if (what==NOTIFICATION_MOUSE_ENTER):
|
||||
pass # mouse entered the area of this control
|
||||
elif (what==NOTIFICATION_MOUSE_EXIT):
|
||||
pass # mouse exited the area of this control
|
||||
elif (what==NOTIFICATION_FOCUS_ENTER):
|
||||
pass # control gained focus
|
||||
elif (what==NOTIFICATION_FOCUS_EXIT):
|
||||
pass # control lost focus
|
||||
elif (what==NOTIFICATION_THEME_CHANGED):
|
||||
pass # theme used to draw the control changed
|
||||
# update and redraw is recommended if using a theme
|
||||
elif (what==NOTIFICATION_VISIBILITY_CHANGED):
|
||||
pass # control became visible/invisible
|
||||
# check new status with is_visible()
|
||||
elif (what==NOTIFICATION_RESIZED):
|
||||
pass # control changed size, check new size
|
||||
# with get_size()
|
||||
elif (what==NOTIFICATION_MODAL_CLOSED):
|
||||
pass # for modal popups, notification
|
||||
# that the popup was closed
|
||||
BIN
tutorials/gui/files/skin_assets.zip
Normal file
161
tutorials/gui/gui_skinning.rst
Normal file
@@ -0,0 +1,161 @@
|
||||
.. _doc_gui_skinning:
|
||||
|
||||
GUI skinning
|
||||
============
|
||||
|
||||
Oh beautiful GUI!
|
||||
-----------------
|
||||
|
||||
This tutorial is about advanced skinning of an user interface. Most
|
||||
games generally don't need this, as they end up just relying on
|
||||
:ref:`Label <class_Label>`, :ref:`TextureRect <class_TextureRect>`,
|
||||
:ref:`TextureButton <class_TextureButton>` and
|
||||
:ref:`TextureProgress <class_TextureProgress>`.
|
||||
|
||||
However, many types of games often need complex user interfaces, like
|
||||
MMOs, traditional RPGs, Simulators, Strategy, etc. These kind of
|
||||
interfaces are also common in some games that include editors to create
|
||||
content, or interfaces for network connectivity.
|
||||
|
||||
Godot user interface uses these kind of controls with the default theme,
|
||||
but they can be skinned to resemble pretty much any kind of user
|
||||
interface.
|
||||
|
||||
Theme
|
||||
-----
|
||||
|
||||
The GUI is skinned through the :ref:`Theme <class_Theme>`
|
||||
resource. Theme contains all the information required to change the
|
||||
entire visual styling of all controls. Theme options are named, so it's
|
||||
not obvious which name changes what (specialy from code), but several
|
||||
tools are provided. The ultimate place to look at what each theme option
|
||||
is for each control, which will always be more up to date than any
|
||||
documentation is the file `scene/resources/default_theme/default_theme.cpp
|
||||
<https://github.com/godotengine/godot/blob/master/scene/resources/default_theme/default_theme.cpp>`__.
|
||||
The rest of this document will explain the different tools used to
|
||||
customize the theme.
|
||||
|
||||
A Theme can be applied to any control in the scene. As a result, all
|
||||
children and grand-children controls will use that same theme too
|
||||
(unless another theme is specified further down the tree). If a value is
|
||||
not found in a theme, it will be searched in themes higher up in the
|
||||
hierarchy towards the root. If nothing was found, the default theme is
|
||||
used. This system allows for flexible overriding of themes in complex
|
||||
user interfaces.
|
||||
|
||||
Theme options
|
||||
-------------
|
||||
|
||||
Each kind of option in a theme can be:
|
||||
|
||||
- **An integer constant**: A single numerical constant. Generally used
|
||||
to define spacing between compoments or alignment.
|
||||
- **A Color**: A single color, with or without transparency. Colors are
|
||||
usually applied to fonts and icons.
|
||||
- **A Texture**: A single image. Textures are not often used, but when
|
||||
they are they represent handles to pick or icons in a complex control
|
||||
(such as file dialog).
|
||||
- **A Font**: Every control that uses text can be assigned the fonts
|
||||
used to draw strings.
|
||||
- **A StyleBox**: Stylebox is a resource that defines how to draw a
|
||||
panel in varying sizes (more information on them later).
|
||||
|
||||
Every option is associated to:
|
||||
|
||||
- A name (the name of the option)
|
||||
- A Control (the name of the control)
|
||||
|
||||
An example usage:
|
||||
|
||||
::
|
||||
|
||||
var t = Theme.new()
|
||||
t.set_color("font_color","Label",Color(1.0,1.0,1.0))
|
||||
|
||||
var l = Label.new()
|
||||
l.set_theme(t)
|
||||
|
||||
In the example above, a new theme is created. The "font_color" option
|
||||
is changed and then applied to a label. As a result, the label (and all
|
||||
children and grand children labels) will use that color.
|
||||
|
||||
It is possible to override those options without using the theme
|
||||
directly and only for a specific control by using the override API in
|
||||
:ref:`Control.add_color_override() <class_Control_add_color_override>`:
|
||||
|
||||
::
|
||||
|
||||
var l = Label.new()
|
||||
l.add_color_override("font_color",Color(1.0,1.0,1.0))
|
||||
|
||||
In the inline help of Godot (in the script tab) you can check which theme options
|
||||
are overrideable, or check the :ref:`Control <class_Control>` class reference.
|
||||
|
||||
Customizing a control
|
||||
---------------------
|
||||
|
||||
If only a few controls need to be skinned, it is often not necessary to
|
||||
create a new theme. Controls offer their theme options as special kinds
|
||||
of properties. If checked, overriding will take place:
|
||||
|
||||
.. image:: img/themecheck.png
|
||||
|
||||
As can be see in the image above, theme options have little check-boxes.
|
||||
If checked, they can be used to override the value of the theme just for
|
||||
that control.
|
||||
|
||||
Creating a theme
|
||||
----------------
|
||||
|
||||
The simplest way to create a theme is to edit a theme resource. Create a
|
||||
Theme from the resource menu, the editor will appear immediately.
|
||||
Following to this, save it (to, as example, mytheme.thm):
|
||||
|
||||
.. image:: img/themecheck.png
|
||||
|
||||
This will create an empty theme that can later be loaded and assigned to
|
||||
controls.
|
||||
|
||||
Example: theming a button
|
||||
--------------------------
|
||||
|
||||
Take some assets (:download:`skin_assets.zip <files/skin_assets.zip>`),
|
||||
go to the "theme" menu and select "Add Class Item":
|
||||
|
||||
.. image:: img/themeci.png
|
||||
|
||||
A menu will appear promting the type of control to create. Select
|
||||
"Button":
|
||||
|
||||
.. image:: img/themeci2.png
|
||||
|
||||
Immediately, all button theme options will appear in the property
|
||||
editor, where they can be edited:
|
||||
|
||||
.. image:: img/themeci3.png
|
||||
|
||||
Select the "normal" stylebox and create a new "StyleBoxTexture", then
|
||||
edit it. A texture stylebox basically contains a texture and the size of
|
||||
the margins that will not stretch when the texture is stretched. This is
|
||||
called "3x3" stretching:
|
||||
|
||||
.. image:: img/sb1.png
|
||||
|
||||
Repeat the steps and add the other assets. There is no hover or disabled
|
||||
image in the example files, so use the same stylebox as in normal. Set
|
||||
the supplied font as the button font and change the font color to black.
|
||||
Soon, your button will look different and retro:
|
||||
|
||||
.. image:: img/sb2.png
|
||||
|
||||
Save this theme to the .thm file. Go to the 2D editor and create a few
|
||||
buttons:
|
||||
|
||||
.. image:: img/skinbuttons1.png
|
||||
|
||||
Now, go to the root node of the scene and locate the "theme" property,
|
||||
replace it by the theme that was just created. It should look like this:
|
||||
|
||||
.. image:: img/skinbuttons2.png
|
||||
|
||||
Congratulations! You have created a reusable GUI Theme!
|
||||
BIN
tutorials/gui/img/anchors.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
tutorials/gui/img/margin.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
tutorials/gui/img/marginaround.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
tutorials/gui/img/marginend.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
tutorials/gui/img/rtl_setup.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
tutorials/gui/img/sb1.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
tutorials/gui/img/sb2.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
tutorials/gui/img/skinbuttons1.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
tutorials/gui/img/skinbuttons2.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
tutorials/gui/img/themecheck.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
tutorials/gui/img/themeci.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
tutorials/gui/img/themeci2.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
tutorials/gui/img/themeci3.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
13
tutorials/gui/index.rst
Normal file
@@ -0,0 +1,13 @@
|
||||
GUI
|
||||
===
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:name: toc-learn-features-gui
|
||||
|
||||
gui_skinning
|
||||
custom_gui_controls
|
||||
size_and_anchors
|
||||
bbcode_in_richtextlabel
|
||||
|
||||
.. gui_containers
|
||||
40
tutorials/gui/size_and_anchors.rst
Normal file
@@ -0,0 +1,40 @@
|
||||
.. _doc_size_and_anchors:
|
||||
|
||||
Size and anchors
|
||||
----------------
|
||||
|
||||
If a game was always going to be run on the same device and at the same
|
||||
resolution, positioning controls would be a simple matter of setting the
|
||||
position and size of each one of them. Unfortunately, that is rarely the
|
||||
case.
|
||||
|
||||
Only TVs nowadays have a standard resolution and aspect ratio.
|
||||
Everything else, from computer monitors to tablets, portable consoles
|
||||
and mobile phones have different resolutions and aspect ratios.
|
||||
|
||||
There are several ways to handle this, but for now let's just imagine
|
||||
that the screen resolution has changed and the controls need to be
|
||||
re-positioned. Some will need to follow the bottom of the screen, others
|
||||
the top of the screen, or maybe the right or left margins.
|
||||
|
||||
.. image:: img/anchors.png
|
||||
|
||||
This is done by editing the *margin* properties of controls. Each
|
||||
control has four margins: left, right, bottom and top. By default all of
|
||||
them represent a distance in pixels relative to the top-left corner of
|
||||
the parent control or (in case there is no parent control) the viewport.
|
||||
|
||||
.. image:: img/margin.png
|
||||
|
||||
When horizontal (left,right) and/or vertical (top,bottom) anchors are
|
||||
changed to END, the margin values become relative to the bottom-right
|
||||
corner of the parent control or viewport.
|
||||
|
||||
.. image:: img/marginend.png
|
||||
|
||||
Here the control is set to expand its bottom-right corner with that of
|
||||
the parent, so when re-sizing the parent, the control will always cover
|
||||
it, leaving a 20 pixel margin:
|
||||
|
||||
.. image:: img/marginaround.png
|
||||
|
||||