123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- :article_outdated: True
- .. _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 to 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 important with controls, as it helps to
- organize them in proper layouts. For this, the
- :ref:`Control.size <class_Control_property_size>`
- property 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.focus_mode <class_Control_property_focus_mode>`
- property. When drawing, and if the control supports input focus, it is
- always desired to show some sort of indicator (highlight, box, etc.) to
- indicate that this is the currently focused control. To check for this
- status, the :ref:`Control.has_focus() <class_Control_method_has_focus>` method
- exists. Example
- .. tabs::
- .. code-tab:: gdscript GDScript
- func _draw():
- if has_focus():
- draw_selected()
- else:
- draw_normal()
- .. code-tab:: csharp
- public override void _Draw()
- {
- if (HasFocus())
- {
- DrawSelected()
- }
- else
- {
- DrawNormal();
- }
- }
- Sizing
- ------
- As mentioned before, size is 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 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_private_method__get_minimum_size>`,
- for example:
- .. tabs::
- .. code-tab:: gdscript GDScript
- func _get_minimum_size():
- return Vector2(30, 30)
- .. code-tab:: csharp
- public override Vector2 _GetMinimumSize()
- {
- return new Vector2(20, 20);
- }
- Alternatively, set it using a function:
- .. tabs::
- .. code-tab:: gdscript GDScript
- func _ready():
- set_custom_minimum_size(Vector2(30, 30))
- .. code-tab:: csharp
- public override void _Ready()
- {
- CustomMinimumSize = new Vector2(20, 20);
- }
- 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.focus_mode <class_Control_property_focus_mode>`.
- This function is
- :ref:`Control._gui_input() <class_Control_private_method__gui_input>`.
- Simply override it in your control. No processing needs to be set.
- .. tabs::
- .. code-tab:: gdscript GDScript
- extends Control
- func _gui_input(event):
- if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
- print("Left mouse button was pressed!")
- .. code-tab:: csharp
- public override void _GuiInput(InputEvent @event)
- {
- if (@event is InputEventMouseButton mbe && mbe.ButtonIndex == MouseButton.Left && mbe.Pressed)
- {
- GD.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 dedicated callback
- exists, but which can be checked with the _notification callback:
- .. tabs::
- .. code-tab:: gdscript GDScript
- func _notification(what):
- match what:
- NOTIFICATION_MOUSE_ENTER:
- pass # Mouse entered the area of this control.
- NOTIFICATION_MOUSE_EXIT:
- pass # Mouse exited the area of this control.
- NOTIFICATION_FOCUS_ENTER:
- pass # Control gained focus.
- NOTIFICATION_FOCUS_EXIT:
- pass # Control lost focus.
- NOTIFICATION_THEME_CHANGED:
- pass # Theme used to draw the control changed;
- # update and redraw is recommended if using a theme.
- NOTIFICATION_VISIBILITY_CHANGED:
- pass # Control became visible/invisible;
- # check new status with is_visible().
- NOTIFICATION_RESIZED:
- pass # Control changed size; check new size
- # with get_size().
- NOTIFICATION_MODAL_CLOSE:
- pass # For modal pop-ups, notification
- # that the pop-up was closed.
- .. code-tab:: csharp
- public override void _Notification(int what)
- {
- switch (what)
- {
- case NotificationMouseEnter:
- // Mouse entered the area of this control.
- break;
- case NotificationMouseExit:
- // Mouse exited the area of this control.
- break;
- case NotificationFocusEnter:
- // Control gained focus.
- break;
- case NotificationFocusExit:
- // Control lost focus.
- break;
- case NotificationThemeChanged:
- // Theme used to draw the control changed;
- // update and redraw is recommended if using a theme.
- break;
- case NotificationVisibilityChanged:
- // Control became visible/invisible;
- // check new status with is_visible().
- break;
- case NotificationResized:
- // Control changed size; check new size with get_size().
- break;
- case NotificationModalClose:
- // For modal pop-ups, notification that the pop-up was closed.
- break;
- }
- }
|