Merge pull request #116428 from Kazox61/virtual-joystick-styling

Add Styleboxes for Virtual Joystick
This commit is contained in:
Thaddeus Crews 2026-03-04 14:32:34 -06:00
commit 93bc47df38
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
4 changed files with 32 additions and 74 deletions

View file

@ -43,15 +43,9 @@
<member name="joystick_size" type="float" setter="set_joystick_size" getter="get_joystick_size" default="100.0">
The size of the joystick in pixels.
</member>
<member name="joystick_texture" type="Texture2D" setter="set_joystick_texture" getter="get_joystick_texture">
The texture to use for the joystick base. When [code]null[/code], a ring is drawn using the [theme_item ring_normal_color] and [theme_item ring_pressed_color].
</member>
<member name="tip_size" type="float" setter="set_tip_size" getter="get_tip_size" default="50.0">
The size of the joystick tip in pixels.
</member>
<member name="tip_texture" type="Texture2D" setter="set_tip_texture" getter="get_tip_texture">
The texture to use for the joystick tip. When [code]null[/code], a circle is drawn using the [theme_item tip_normal_color] and [theme_item tip_pressed_color].
</member>
<member name="visibility_mode" type="int" setter="set_visibility_mode" getter="get_visibility_mode" enum="VirtualJoystick.VisibilityMode" default="0">
The visibility mode to use.
</member>
@ -103,17 +97,17 @@
</constant>
</constants>
<theme_items>
<theme_item name="ring_normal_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
Default ring joystick [Color].
<theme_item name="normal_joystick" data_type="style" type="StyleBox">
Base joystick [StyleBox].
</theme_item>
<theme_item name="ring_pressed_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
Ring joystick [Color] when pressed.
<theme_item name="normal_tip" data_type="style" type="StyleBox">
Tip joystick [StyleBox].
</theme_item>
<theme_item name="tip_normal_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
Default Tip joystick [Color].
<theme_item name="pressed_joystick" data_type="style" type="StyleBox">
Base joystick [StyleBox] when pressed.
</theme_item>
<theme_item name="tip_pressed_color" data_type="color" type="Color" default="Color(0, 0, 0, 1)">
Tip joystick [Color] when pressed.
<theme_item name="pressed_tip" data_type="style" type="StyleBox">
Tip joystick [StyleBox] when pressed.
</theme_item>
</theme_items>
</class>

View file

@ -81,19 +81,11 @@ void VirtualJoystick::_notification(int p_what) {
return;
}
if (joystick_texture.is_valid()) {
Rect2 rect = Rect2(joystick_pos - Vector2(0.5, 0.5) * joystick_size, Vector2(joystick_size, joystick_size));
draw_texture_rect(joystick_texture, rect);
} else {
draw_circle(joystick_pos, joystick_size * 0.5, is_pressed ? theme_cache.ring_pressed_color : theme_cache.ring_normal_color, false, joystick_size * 0.05, true);
}
Rect2 rect_joystick = Rect2(joystick_pos - Vector2(0.5, 0.5) * joystick_size, Vector2(joystick_size, joystick_size));
draw_style_box(is_pressed ? theme_cache.pressed_joystick : theme_cache.normal_joystick, rect_joystick);
if (tip_texture.is_valid()) {
Rect2 rect = Rect2(tip_pos - Vector2(0.5, 0.5) * tip_size, Vector2(tip_size, tip_size));
draw_texture_rect(tip_texture, rect);
} else {
draw_circle(tip_pos, tip_size * 0.5, is_pressed ? theme_cache.tip_pressed_color : theme_cache.tip_normal_color, true, -1, true);
}
Rect2 rect_tip = Rect2(tip_pos - Vector2(0.5, 0.5) * tip_size, Vector2(tip_size, tip_size));
draw_style_box(is_pressed ? theme_cache.pressed_tip : theme_cache.normal_tip, rect_tip);
} break;
case NOTIFICATION_ENTER_TREE: {
@ -231,11 +223,6 @@ void VirtualJoystick::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_visibility_mode", "mode"), &VirtualJoystick::set_visibility_mode);
ClassDB::bind_method(D_METHOD("get_visibility_mode"), &VirtualJoystick::get_visibility_mode);
ClassDB::bind_method(D_METHOD("set_joystick_texture", "texture"), &VirtualJoystick::set_joystick_texture);
ClassDB::bind_method(D_METHOD("get_joystick_texture"), &VirtualJoystick::get_joystick_texture);
ClassDB::bind_method(D_METHOD("set_tip_texture", "texture"), &VirtualJoystick::set_tip_texture);
ClassDB::bind_method(D_METHOD("get_tip_texture"), &VirtualJoystick::get_tip_texture);
ADD_PROPERTY(PropertyInfo(Variant::INT, "joystick_mode", PROPERTY_HINT_ENUM, "Fixed,Dynamic,Following"), "set_joystick_mode", "get_joystick_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "joystick_size", PROPERTY_HINT_RANGE, "10,500,1"), "set_joystick_size", "get_joystick_size");
@ -251,9 +238,6 @@ void VirtualJoystick::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "visibility_mode", PROPERTY_HINT_ENUM, "Always,When Touched"), "set_visibility_mode", "get_visibility_mode");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "joystick_texture", PROPERTY_HINT_RESOURCE_TYPE, Texture2D::get_class_static()), "set_joystick_texture", "get_joystick_texture");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tip_texture", PROPERTY_HINT_RESOURCE_TYPE, Texture2D::get_class_static()), "set_tip_texture", "get_tip_texture");
ADD_SIGNAL(MethodInfo("pressed"));
ADD_SIGNAL(MethodInfo("tapped"));
ADD_SIGNAL(MethodInfo("released", PropertyInfo(Variant::VECTOR2, "input_vector")));
@ -266,10 +250,10 @@ void VirtualJoystick::_bind_methods() {
BIND_ENUM_CONSTANT(VISIBILITY_ALWAYS);
BIND_ENUM_CONSTANT(VISIBILITY_WHEN_TOUCHED);
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, VirtualJoystick, ring_normal_color);
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, VirtualJoystick, tip_normal_color);
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, VirtualJoystick, ring_pressed_color);
BIND_THEME_ITEM(Theme::DATA_TYPE_COLOR, VirtualJoystick, tip_pressed_color);
BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, VirtualJoystick, normal_joystick);
BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, VirtualJoystick, normal_tip);
BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, VirtualJoystick, pressed_joystick);
BIND_THEME_ITEM(Theme::DATA_TYPE_STYLEBOX, VirtualJoystick, pressed_tip);
}
Vector2 VirtualJoystick::get_joystick_position() const {
@ -381,27 +365,3 @@ void VirtualJoystick::set_visibility_mode(VisibilityMode p_mode) {
VirtualJoystick::VisibilityMode VirtualJoystick::get_visibility_mode() const {
return visibility;
}
void VirtualJoystick::set_joystick_texture(const Ref<Texture2D> &p_texture) {
if (joystick_texture == p_texture) {
return;
}
joystick_texture = p_texture;
queue_redraw();
}
Ref<Texture2D> VirtualJoystick::get_joystick_texture() const {
return joystick_texture;
}
void VirtualJoystick::set_tip_texture(const Ref<Texture2D> &p_texture) {
if (tip_texture == p_texture) {
return;
}
tip_texture = p_texture;
queue_redraw();
}
Ref<Texture2D> VirtualJoystick::get_tip_texture() const {
return tip_texture;
}

View file

@ -61,10 +61,10 @@ private:
VisibilityMode visibility = VISIBILITY_ALWAYS;
struct ThemeCache {
Color ring_normal_color;
Color tip_normal_color;
Color ring_pressed_color;
Color tip_pressed_color;
Ref<StyleBox> normal_joystick;
Ref<StyleBox> normal_tip;
Ref<StyleBox> pressed_joystick;
Ref<StyleBox> pressed_tip;
} theme_cache;
bool is_pressed = false;
@ -78,9 +78,6 @@ private:
Vector2 joystick_pos;
Vector2 tip_pos;
Ref<Texture2D> joystick_texture;
Ref<Texture2D> tip_texture;
void _update_joystick(const Vector2 &p_pos);
void _handle_input_actions();
void _reset();
@ -122,11 +119,6 @@ public:
void set_visibility_mode(VisibilityMode p_mode);
VisibilityMode get_visibility_mode() const;
void set_joystick_texture(const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_joystick_texture() const;
void set_tip_texture(const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_tip_texture() const;
};
VARIANT_ENUM_CAST(VirtualJoystick::JoystickMode);

View file

@ -669,6 +669,18 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("scroll_hint_vertical_color", "ScrollContainer", Color(0, 0, 0));
theme->set_color("scroll_hint_horizontal_color", "ScrollContainer", Color(0, 0, 0));
// Virtual Joystick
Ref<StyleBoxFlat> style_joystick = make_flat_stylebox(style_normal_color, 0, 0, 0, 0, 10000, false, 4 * scale);
style_joystick->set_corner_detail(24 * scale);
Ref<StyleBoxFlat> style_joystick_tip = make_flat_stylebox(style_normal_color, 0, 0, 0, 0, 10000);
style_joystick_tip->set_corner_detail(24 * scale);
theme->set_stylebox("normal_joystick", "VirtualJoystick", style_joystick);
theme->set_stylebox("normal_tip", "VirtualJoystick", style_joystick_tip);
theme->set_stylebox("pressed_joystick", "VirtualJoystick", style_joystick);
theme->set_stylebox("pressed_tip", "VirtualJoystick", style_joystick_tip);
// Window
theme->set_stylebox("embedded_border", "Window", sb_expand(make_flat_stylebox(style_popup_color, 10, 28, 10, 8), 8, 32, 8, 6));