diff --git a/editor/gui/editor_spin_slider.cpp b/editor/gui/editor_spin_slider.cpp index 06e39d26c71..cc837b545f5 100644 --- a/editor/gui/editor_spin_slider.cpp +++ b/editor/gui/editor_spin_slider.cpp @@ -53,7 +53,15 @@ String EditorSpinSlider::get_tooltip(const Point2 &p_pos) const { } Size2 EditorSpinSlider::get_minimum_size() const { - return Size2(0, get_theme_constant(SNAME("inspector_property_height"), EditorStringName(Editor))); + Ref sb = get_theme_stylebox(CoreStringName(normal), SNAME("LineEdit")); + Ref font = get_theme_font(SceneStringName(font), SNAME("LineEdit")); + int font_size = get_theme_font_size(SceneStringName(font_size), SNAME("LineEdit")); + + Size2 ms = sb->get_minimum_size(); + ms.height += font->get_height(font_size); + ms.height = MAX(ms.height, get_theme_constant(SNAME("inspector_property_height"), EditorStringName(Editor))); + + return ms; } String EditorSpinSlider::get_text_value() const { @@ -280,9 +288,9 @@ void EditorSpinSlider::_value_input_gui_input(const Ref &p_event) { } break; case Key::ESCAPE: { value_input_closed_frame = Engine::get_singleton()->get_frames_drawn(); - if (value_input_popup) { + if (value_input) { value_input_focus_visible = value_input->has_focus(true); - value_input_popup->hide(); + value_input->hide(); } } break; default: @@ -300,14 +308,9 @@ void EditorSpinSlider::_update_value_input_stylebox() { // when it's edited. The LineEdit "focus" stylebox uses the "normal" stylebox's // default margins. Ref stylebox = get_theme_stylebox(CoreStringName(normal), SNAME("LineEdit"))->duplicate(); - // EditorSpinSliders with a label have more space on the left, so add an - // higher margin to match the location where the text begins. - // The margin values below were determined by empirical testing. - if (is_layout_rtl()) { - stylebox->set_content_margin(SIDE_RIGHT, (!get_label().is_empty() ? 23 : 16) * EDSCALE); - } else { - stylebox->set_content_margin(SIDE_LEFT, (!get_label().is_empty() ? 23 : 16) * EDSCALE); - } + // TODO: Handle this internally instead of relying on the theme. + int margin = get_theme_constant(get_label().is_empty() ? SNAME("line_edit_margin_empty") : SNAME("line_edit_margin"), SNAME("EditorSpinSlider")); + stylebox->set_content_margin(is_layout_rtl() ? SIDE_RIGHT : SIDE_LEFT, margin); value_input->add_theme_style_override(CoreStringName(normal), stylebox); } @@ -429,7 +432,7 @@ void EditorSpinSlider::_draw_spin_slider() { grabbing_spinner_mouse_pos = get_global_position() + grabber_rect.get_center(); - bool display_grabber = !read_only && (grabbing_grabber || mouse_over_spin || mouse_over_grabber) && !grabbing_spinner && !(value_input_popup && value_input_popup->is_visible()); + bool display_grabber = !read_only && (grabbing_grabber || mouse_over_spin || mouse_over_grabber) && !grabbing_spinner && !(value_input && value_input->is_visible()); if (grabber->is_visible() != display_grabber) { grabber->set_visible(display_grabber); } @@ -517,7 +520,7 @@ void EditorSpinSlider::_notification(int p_what) { } LineEdit *EditorSpinSlider::get_line_edit() { - _ensure_input_popup(); + _ensure_value_input(); return value_input; } @@ -604,24 +607,21 @@ void EditorSpinSlider::_evaluate_input_text() { set_value(v); } -//text_submitted signal void EditorSpinSlider::_value_input_submitted(const String &p_text) { value_input_closed_frame = Engine::get_singleton()->get_frames_drawn(); - if (value_input_popup) { + if (value_input) { value_input_focus_visible = value_input->has_focus(true); - value_input_popup->hide(); + value_input->hide(); } } -//modal_closed signal -void EditorSpinSlider::_value_input_closed() { +void EditorSpinSlider::_value_input_hidden() { _evaluate_input_text(); value_input_closed_frame = Engine::get_singleton()->get_frames_drawn(); } -//focus_exited signal void EditorSpinSlider::_value_focus_exited() { - // discontinue because the focus_exit was caused by right-click context menu + // Discontinue because the focus_exit was caused by right-click context menu. if (value_input->is_menu_visible()) { return; } @@ -632,15 +632,14 @@ void EditorSpinSlider::_value_focus_exited() { } _evaluate_input_text(); - // focus is not on the same element after the value_input was exited - // -> focus is on next element - // -> TAB was pressed - // -> modal_close was not called - // -> need to close/hide manually + // Focus is not on the same element after the value_input was hidden. + // -> Focus is on next element. + // -> TAB was pressed. + // -> Need to close/hide manually. if (!is_visible_in_tree() || value_input_closed_frame != Engine::get_singleton()->get_frames_drawn()) { // Hidden or something else took focus. - if (value_input_popup) { - value_input_popup->hide(); + if (value_input) { + value_input->hide(); } } else { // Enter or Esc was pressed. Keep showing the focus if already present. @@ -692,12 +691,11 @@ void EditorSpinSlider::_focus_entered(bool p_hide_focus) { return; } - _ensure_input_popup(); + _ensure_value_input(); value_input->set_text(get_text_value()); - value_input_popup->set_size(get_size()); value_input->set_focus_next(find_next_valid_focus()->get_path()); value_input->set_focus_previous(find_prev_valid_focus()->get_path()); - callable_mp((CanvasItem *)value_input_popup, &CanvasItem::show).call_deferred(); + callable_mp((CanvasItem *)value_input, &CanvasItem::show).call_deferred(); callable_mp((Control *)value_input, &Control::grab_focus).call_deferred(p_hide_focus); callable_mp(value_input, &LineEdit ::select_all).call_deferred(); emit_signal("value_focus_entered"); @@ -750,21 +748,18 @@ void EditorSpinSlider::_bind_methods() { BIND_THEME_ITEM_CUSTOM(Theme::DATA_TYPE_ICON, EditorSpinSlider, updown_disabled_icon, "updown_disabled"); } -void EditorSpinSlider::_ensure_input_popup() { - if (value_input_popup) { +void EditorSpinSlider::_ensure_value_input() { + if (value_input) { return; } - value_input_popup = memnew(Control); - value_input_popup->set_anchors_and_offsets_preset(PRESET_FULL_RECT); - add_child(value_input_popup); - value_input = memnew(LineEdit); value_input->set_emoji_menu_enabled(false); value_input->set_focus_mode(FOCUS_CLICK); - value_input_popup->add_child(value_input); + value_input->add_theme_constant_override(SNAME("minimum_character_width"), 0); + add_child(value_input); value_input->set_anchors_and_offsets_preset(PRESET_FULL_RECT); - value_input_popup->connect(SceneStringName(hidden), callable_mp(this, &EditorSpinSlider::_value_input_closed)); + value_input->connect(SceneStringName(hidden), callable_mp(this, &EditorSpinSlider::_value_input_hidden)); value_input->connect(SceneStringName(text_submitted), callable_mp(this, &EditorSpinSlider::_value_input_submitted)); value_input->connect(SceneStringName(focus_exited), callable_mp(this, &EditorSpinSlider::_value_focus_exited)); value_input->connect(SceneStringName(gui_input), callable_mp(this, &EditorSpinSlider::_value_input_gui_input)); diff --git a/editor/gui/editor_spin_slider.h b/editor/gui/editor_spin_slider.h index 90cbe096fa9..dbb8149f89b 100644 --- a/editor/gui/editor_spin_slider.h +++ b/editor/gui/editor_spin_slider.h @@ -62,7 +62,6 @@ class EditorSpinSlider : public Range { Vector2 grabbing_spinner_mouse_pos; double pre_grab_value = 0.0; - Control *value_input_popup = nullptr; LineEdit *value_input = nullptr; uint64_t value_input_closed_frame = 0; bool value_input_dirty = false; @@ -84,7 +83,7 @@ private: void _grab_end(); void _grabber_gui_input(const Ref &p_event); - void _value_input_closed(); + void _value_input_hidden(); void _value_input_submitted(const String &); void _value_focus_exited(); void _value_input_gui_input(const Ref &p_event); @@ -92,7 +91,7 @@ private: void _evaluate_input_text(); void _update_value_input_stylebox(); - void _ensure_input_popup(); + void _ensure_value_input(); void _draw_spin_slider(); struct ThemeCache { diff --git a/editor/themes/theme_classic.cpp b/editor/themes/theme_classic.cpp index 21eaeb6e437..83d5b4321e8 100644 --- a/editor/themes/theme_classic.cpp +++ b/editor/themes/theme_classic.cpp @@ -1760,10 +1760,16 @@ void ThemeClassic::populate_editor_styles(const Ref &p_theme, Edito editor_spin_label_bg->set_border_width_all(0); p_theme->set_stylebox("label_bg", "EditorSpinSlider", editor_spin_label_bg); - // TODO Use separate arrows instead like on SpinBox. Planned for a different PR. + // TODO: Use separate arrows instead like on SpinBox. Planned for a different PR. p_theme->set_icon("updown", "EditorSpinSlider", p_theme->get_icon(SNAME("GuiSpinboxUpdown"), EditorStringName(EditorIcons))); p_theme->set_icon("updown_disabled", "EditorSpinSlider", p_theme->get_icon(SNAME("GuiSpinboxUpdownDisabled"), EditorStringName(EditorIcons))); + // EditorSpinSliders with a label have more space on the left, so add an + // higher margin to match the location where the text begins. + // The margin values below were determined by empirical testing. + p_theme->set_constant("line_edit_margin", "EditorSpinSlider", 24 * EDSCALE); + p_theme->set_constant("line_edit_margin_empty", "EditorSpinSlider", 16 * EDSCALE); + // Launch Pad and Play buttons. Ref style_launch_pad = EditorThemeManager::make_flat_stylebox(p_config.dark_color_1, 2 * EDSCALE, 0, 2 * EDSCALE, 0, p_config.corner_radius); style_launch_pad->set_corner_radius_all(p_config.corner_radius * EDSCALE); diff --git a/editor/themes/theme_modern.cpp b/editor/themes/theme_modern.cpp index de9f5bab3df..6b193909741 100644 --- a/editor/themes/theme_modern.cpp +++ b/editor/themes/theme_modern.cpp @@ -1821,10 +1821,16 @@ void ThemeModern::populate_editor_styles(const Ref &p_theme, Editor editor_spin_label_bg->set_content_margin_all(p_config.base_margin * EDSCALE); p_theme->set_stylebox("label_bg", "EditorSpinSlider", editor_spin_label_bg); - // TODO Use separate arrows instead like on SpinBox. Planned for a different PR. + // TODO: Use separate arrows instead like on SpinBox. Planned for a different PR. p_theme->set_icon("updown", "EditorSpinSlider", p_theme->get_icon(SNAME("GuiSpinboxUpdown"), EditorStringName(EditorIcons))); p_theme->set_icon("updown_disabled", "EditorSpinSlider", p_theme->get_icon(SNAME("GuiSpinboxUpdownDisabled"), EditorStringName(EditorIcons))); + // EditorSpinSliders with a label have more space on the left, so add an + // higher margin to match the location where the text begins. + // The margin values below were determined by empirical testing. + p_theme->set_constant("line_edit_margin", "EditorSpinSlider", 28 * EDSCALE); + p_theme->set_constant("line_edit_margin_empty", "EditorSpinSlider", 20 * EDSCALE); + // Launch Pad and Play buttons. Ref style_launch_pad_movie = p_config.base_style->duplicate(); style_launch_pad_movie->set_content_margin_all(p_config.base_margin * EDSCALE);