diff options
Diffstat (limited to 'scene/gui')
34 files changed, 520 insertions, 337 deletions
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 5ef2557383..52fcea2a71 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -61,37 +61,7 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) { bool button_masked = mouse_button.is_valid() && ((1 << (mouse_button->get_button_index() - 1)) & button_mask) > 0; if (button_masked || ui_accept) { - if (p_event->is_pressed()) { - status.press_attempt = true; - status.pressing_inside = true; - emit_signal("button_down"); - } - - if (status.press_attempt && status.pressing_inside) { - if (toggle_mode) { - if ((p_event->is_pressed() && action_mode == ACTION_MODE_BUTTON_PRESS) || (!p_event->is_pressed() && action_mode == ACTION_MODE_BUTTON_RELEASE)) { - if (action_mode == ACTION_MODE_BUTTON_PRESS) { - status.press_attempt = false; - status.pressing_inside = false; - } - status.pressed = !status.pressed; - _unpress_group(); - _toggled(status.pressed); - _pressed(); - } - } else { - if (!p_event->is_pressed()) { - _pressed(); - } - } - } - - if (!p_event->is_pressed()) { // pressed state should be correct with button_up signal - emit_signal("button_up"); - status.press_attempt = false; - } - - update(); + on_action_event(p_event); return; } @@ -177,6 +147,41 @@ void BaseButton::_toggled(bool p_pressed) { emit_signal("toggled", p_pressed); } +void BaseButton::on_action_event(Ref<InputEvent> p_event) { + + if (p_event->is_pressed()) { + status.press_attempt = true; + status.pressing_inside = true; + emit_signal("button_down"); + } + + if (status.press_attempt && status.pressing_inside) { + if (toggle_mode) { + if ((p_event->is_pressed() && action_mode == ACTION_MODE_BUTTON_PRESS) || (!p_event->is_pressed() && action_mode == ACTION_MODE_BUTTON_RELEASE)) { + if (action_mode == ACTION_MODE_BUTTON_PRESS) { + status.press_attempt = false; + status.pressing_inside = false; + } + status.pressed = !status.pressed; + _unpress_group(); + _toggled(status.pressed); + _pressed(); + } + } else { + if (!p_event->is_pressed()) { + _pressed(); + } + } + } + + if (!p_event->is_pressed()) { // pressed state should be correct with button_up signal + emit_signal("button_up"); + status.press_attempt = false; + } + + update(); +} + void BaseButton::pressed() { } @@ -216,9 +221,7 @@ void BaseButton::set_pressed(bool p_pressed) { if (p_pressed) { _unpress_group(); } - if (toggle_mode) { - _toggled(status.pressed); - } + _toggled(status.pressed); update(); } @@ -337,9 +340,6 @@ bool BaseButton::is_keep_pressed_outside() const { void BaseButton::set_shortcut(const Ref<ShortCut> &p_shortcut) { - if (shortcut.is_null() == p_shortcut.is_null()) - return; - shortcut = p_shortcut; set_process_unhandled_input(shortcut.is_valid()); } @@ -350,17 +350,12 @@ Ref<ShortCut> BaseButton::get_shortcut() const { void BaseButton::_unhandled_input(Ref<InputEvent> p_event) { - if (!is_disabled() && is_visible_in_tree() && p_event->is_pressed() && !p_event->is_echo() && shortcut.is_valid() && shortcut->is_shortcut(p_event)) { + if (!is_disabled() && is_visible_in_tree() && !p_event->is_echo() && shortcut.is_valid() && shortcut->is_shortcut(p_event)) { if (get_viewport()->get_modal_stack_top() && !get_viewport()->get_modal_stack_top()->is_a_parent_of(this)) return; //ignore because of modal window - if (is_toggle_mode()) { - set_pressed(!is_pressed()); - emit_signal("toggled", is_pressed()); - } - - emit_signal("pressed"); + on_action_event(p_event); } } diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h index abb3f58d6b..ffccdd69d6 100644 --- a/scene/gui/base_button.h +++ b/scene/gui/base_button.h @@ -74,6 +74,8 @@ private: void _pressed(); void _toggled(bool p_pressed); + void on_action_event(Ref<InputEvent> p_event); + protected: virtual void pressed(); virtual void toggled(bool p_pressed); @@ -138,7 +140,7 @@ VARIANT_ENUM_CAST(BaseButton::ActionMode) class ButtonGroup : public Resource { - GDCLASS(ButtonGroup, Resource) + GDCLASS(ButtonGroup, Resource); friend class BaseButton; Set<BaseButton *> buttons; diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp index cc37d4cf7d..b7d2131ee9 100644 --- a/scene/gui/box_container.cpp +++ b/scene/gui/box_container.cpp @@ -91,7 +91,6 @@ void BoxContainer::_resort() { int stretch_diff = stretch_max - stretch_min; if (stretch_diff < 0) { //avoid negative stretch space - stretch_max = stretch_min; stretch_diff = 0; } diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index bca3471091..b197971b61 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -93,6 +93,28 @@ void ColorPicker::set_focus_on_line_edit() { void ColorPicker::_update_controls() { + const char *rgb[3] = { "R", "G", "B" }; + const char *hsv[3] = { "H", "S", "V" }; + + if (hsv_mode_enabled) { + for (int i = 0; i < 3; i++) + labels[i]->set_text(hsv[i]); + } else { + for (int i = 0; i < 3; i++) + labels[i]->set_text(rgb[i]); + } + + if (hsv_mode_enabled) { + set_raw_mode(false); + btn_raw->set_disabled(true); + } else if (raw_mode_enabled) { + set_hsv_mode(false); + btn_hsv->set_disabled(true); + } else { + btn_raw->set_disabled(false); + btn_hsv->set_disabled(false); + } + if (edit_alpha) { values[3]->show(); scroll[3]->show(); @@ -104,7 +126,7 @@ void ColorPicker::_update_controls() { } } -void ColorPicker::set_pick_color(const Color &p_color) { +void ColorPicker::_set_pick_color(const Color &p_color, bool p_update_sliders) { color = p_color; if (color != last_hsv) { @@ -117,7 +139,12 @@ void ColorPicker::set_pick_color(const Color &p_color) { if (!is_inside_tree()) return; - _update_color(); + _update_color(p_update_sliders); +} + +void ColorPicker::set_pick_color(const Color &p_color) { + + _set_pick_color(p_color, true); //because setters can't have more arguments } void ColorPicker::set_edit_alpha(bool p_show) { @@ -142,11 +169,18 @@ void ColorPicker::_value_changed(double) { if (updating) return; - for (int i = 0; i < 4; i++) { - color.components[i] = scroll[i]->get_value() / (raw_mode_enabled ? 1.0 : 255.0); + if (hsv_mode_enabled) { + color.set_hsv(scroll[0]->get_value() / 360.0, + scroll[1]->get_value() / 100.0, + scroll[2]->get_value() / 100.0, + scroll[3]->get_value() / 255.0); + } else { + for (int i = 0; i < 4; i++) { + color.components[i] = scroll[i]->get_value() / (raw_mode_enabled ? 1.0 : 255.0); + } } - set_pick_color(color); + _set_pick_color(color, false); emit_signal("color_changed", color); } @@ -167,22 +201,40 @@ void ColorPicker::_html_entered(const String &p_html) { emit_signal("color_changed", color); } -void ColorPicker::_update_color() { +void ColorPicker::_update_color(bool p_update_sliders) { updating = true; - for (int i = 0; i < 4; i++) { - if (raw_mode_enabled) { - scroll[i]->set_step(0.01); - scroll[i]->set_max(100); - if (i == 3) - scroll[i]->set_max(1); - scroll[i]->set_value(color.components[i]); + if (p_update_sliders) { + + if (hsv_mode_enabled) { + for (int i = 0; i < 4; i++) { + scroll[i]->set_step(1.0); + } + + scroll[0]->set_max(359); + scroll[0]->set_value(h * 360.0); + scroll[1]->set_max(100); + scroll[1]->set_value(s * 100.0); + scroll[2]->set_max(100); + scroll[2]->set_value(v * 100.0); + scroll[3]->set_max(255); + scroll[3]->set_value(color.components[3] * 255.0); } else { - scroll[i]->set_step(1); - const float byte_value = color.components[i] * 255.0; - scroll[i]->set_max(next_power_of_2(MAX(255, byte_value)) - 1); - scroll[i]->set_value(byte_value); + for (int i = 0; i < 4; i++) { + if (raw_mode_enabled) { + scroll[i]->set_step(0.01); + scroll[i]->set_max(100); + if (i == 3) + scroll[i]->set_max(1); + scroll[i]->set_value(color.components[i]); + } else { + scroll[i]->set_step(1); + const float byte_value = color.components[i] * 255.0; + scroll[i]->set_max(next_power_of_2(MAX(255, byte_value)) - 1); + scroll[i]->set_value(byte_value); + } + } } } @@ -272,13 +324,33 @@ PoolColorArray ColorPicker::get_presets() const { return arr; } +void ColorPicker::set_hsv_mode(bool p_enabled) { + + if (hsv_mode_enabled == p_enabled || raw_mode_enabled) + return; + hsv_mode_enabled = p_enabled; + if (btn_hsv->is_pressed() != p_enabled) + btn_hsv->set_pressed(p_enabled); + + if (!is_inside_tree()) + return; + + _update_controls(); + _update_color(); +} + +bool ColorPicker::is_hsv_mode() const { + + return hsv_mode_enabled; +} + void ColorPicker::set_raw_mode(bool p_enabled) { - if (raw_mode_enabled == p_enabled) + if (raw_mode_enabled == p_enabled || hsv_mode_enabled) return; raw_mode_enabled = p_enabled; - if (btn_mode->is_pressed() != p_enabled) - btn_mode->set_pressed(p_enabled); + if (btn_raw->is_pressed() != p_enabled) + btn_raw->set_pressed(p_enabled); if (!is_inside_tree()) return; @@ -592,6 +664,8 @@ void ColorPicker::_bind_methods() { ClassDB::bind_method(D_METHOD("set_pick_color", "color"), &ColorPicker::set_pick_color); ClassDB::bind_method(D_METHOD("get_pick_color"), &ColorPicker::get_pick_color); + ClassDB::bind_method(D_METHOD("set_hsv_mode", "mode"), &ColorPicker::set_hsv_mode); + ClassDB::bind_method(D_METHOD("is_hsv_mode"), &ColorPicker::is_hsv_mode); ClassDB::bind_method(D_METHOD("set_raw_mode", "mode"), &ColorPicker::set_raw_mode); ClassDB::bind_method(D_METHOD("is_raw_mode"), &ColorPicker::is_raw_mode); ClassDB::bind_method(D_METHOD("set_deferred_mode", "mode"), &ColorPicker::set_deferred_mode); @@ -623,6 +697,7 @@ void ColorPicker::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_pick_color", "get_pick_color"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "edit_alpha"), "set_edit_alpha", "is_editing_alpha"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hsv_mode"), "set_hsv_mode", "is_hsv_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "raw_mode"), "set_raw_mode", "is_raw_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deferred_mode"), "set_deferred_mode", "is_deferred_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "presets_enabled"), "set_presets_enabled", "are_presets_enabled"); @@ -639,6 +714,7 @@ ColorPicker::ColorPicker() : updating = true; edit_alpha = true; text_is_constructor = false; + hsv_mode_enabled = false; raw_mode_enabled = false; deferred_mode_enabled = false; changing_color = false; @@ -689,13 +765,12 @@ ColorPicker::ColorPicker() : VBoxContainer *vbr = memnew(VBoxContainer); add_child(vbr); vbr->set_h_size_flags(SIZE_EXPAND_FILL); - const char *lt[4] = { "R", "G", "B", "A" }; for (int i = 0; i < 4; i++) { HBoxContainer *hbc = memnew(HBoxContainer); - labels[i] = memnew(Label(lt[i])); + labels[i] = memnew(Label()); labels[i]->set_custom_minimum_size(Size2(get_constant("label_width"), 0)); labels[i]->set_v_size_flags(SIZE_SHRINK_CENTER); hbc->add_child(labels[i]); @@ -719,14 +794,20 @@ ColorPicker::ColorPicker() : vbr->add_child(hbc); } + labels[3]->set_text("A"); HBoxContainer *hhb = memnew(HBoxContainer); vbr->add_child(hhb); - btn_mode = memnew(CheckButton); - hhb->add_child(btn_mode); - btn_mode->set_text(TTR("Raw Mode")); - btn_mode->connect("toggled", this, "set_raw_mode"); + btn_hsv = memnew(CheckButton); + hhb->add_child(btn_hsv); + btn_hsv->set_text(TTR("HSV")); + btn_hsv->connect("toggled", this, "set_hsv_mode"); + + btn_raw = memnew(CheckButton); + hhb->add_child(btn_raw); + btn_raw->set_text(TTR("Raw")); + btn_raw->connect("toggled", this, "set_raw_mode"); text_type = memnew(Button); hhb->add_child(text_type); diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index b5ddf2d0c2..3af27a9856 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -58,7 +58,8 @@ private: Button *bt_add_preset; List<Color> presets; ToolButton *btn_pick; - CheckButton *btn_mode; + CheckButton *btn_hsv; + CheckButton *btn_raw; HSlider *scroll[4]; SpinBox *values[4]; Label *labels[4]; @@ -70,6 +71,7 @@ private: Color color; bool raw_mode_enabled; + bool hsv_mode_enabled; bool deferred_mode_enabled; bool updating; bool changing_color; @@ -81,7 +83,7 @@ private: void _html_entered(const String &p_html); void _value_changed(double); void _update_controls(); - void _update_color(); + void _update_color(bool p_update_sliders = true); void _update_presets(); void _update_text_value(); void _text_type_toggled(); @@ -106,6 +108,7 @@ public: void set_edit_alpha(bool p_show); bool is_editing_alpha() const; + void _set_pick_color(const Color &p_color, bool p_update_sliders); void set_pick_color(const Color &p_color); Color get_pick_color() const; @@ -113,6 +116,9 @@ public: void erase_preset(const Color &p_color); PoolColorArray get_presets() const; + void set_hsv_mode(bool p_enabled); + bool is_hsv_mode() const; + void set_raw_mode(bool p_enabled); bool is_raw_mode() const; diff --git a/scene/gui/color_rect.h b/scene/gui/color_rect.h index d7f9ef275d..7a7bbe1029 100644 --- a/scene/gui/color_rect.h +++ b/scene/gui/color_rect.h @@ -34,7 +34,7 @@ #include "scene/gui/control.h" class ColorRect : public Control { - GDCLASS(ColorRect, Control) + GDCLASS(ColorRect, Control); Color color; diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index 1f9bfb9936..c9cf5f8308 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -177,7 +177,7 @@ String Container::get_configuration_warning() const { if (warning != String()) { warning += "\n"; } - warning += TTR("Container by itself serves no purpose unless a script configures it's children placement behavior.\nIf you don't intend to add a script, then please use a plain 'Control' node instead."); + warning += TTR("Container by itself serves no purpose unless a script configures its children placement behavior.\nIf you don't intend to add a script, then please use a plain 'Control' node instead."); } return warning; } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 76275c2420..eccd42cb9f 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -29,23 +29,23 @@ /*************************************************************************/ #include "control.h" -#include "core/project_settings.h" -#include "scene/main/canvas_layer.h" -#include "scene/main/viewport.h" -#include "servers/visual_server.h" #include "core/message_queue.h" #include "core/os/keyboard.h" #include "core/os/os.h" #include "core/print_string.h" +#include "core/project_settings.h" #include "scene/gui/label.h" #include "scene/gui/panel.h" +#include "scene/main/canvas_layer.h" +#include "scene/main/viewport.h" #include "scene/scene_string_names.h" +#include "servers/visual_server.h" + #ifdef TOOLS_ENABLED #include "editor/editor_settings.h" #include "editor/plugins/canvas_item_editor_plugin.h" #endif -#include <stdio.h> Dictionary Control::_edit_get_state() const { @@ -1042,55 +1042,37 @@ int Control::get_constant(const StringName &p_name, const StringName &p_type) co bool Control::has_icon_override(const StringName &p_name) const { const Ref<Texture> *tex = data.icon_override.getptr(p_name); - if (tex) - return true; - else - return false; + return tex != NULL; } bool Control::has_shader_override(const StringName &p_name) const { const Ref<Shader> *sdr = data.shader_override.getptr(p_name); - if (sdr) - return true; - else - return false; + return sdr != NULL; } bool Control::has_stylebox_override(const StringName &p_name) const { const Ref<StyleBox> *style = data.style_override.getptr(p_name); - if (style) - return true; - else - return false; + return style != NULL; } bool Control::has_font_override(const StringName &p_name) const { const Ref<Font> *font = data.font_override.getptr(p_name); - if (font) - return true; - else - return false; + return font != NULL; } bool Control::has_color_override(const StringName &p_name) const { const Color *color = data.color_override.getptr(p_name); - if (color) - return true; - else - return false; + return color != NULL; } bool Control::has_constant_override(const StringName &p_name) const { const int *constant = data.constant_override.getptr(p_name); - if (constant) - return true; - else - return false; + return constant != NULL; } bool Control::has_icon(const StringName &p_name, const StringName &p_type) const { @@ -1749,6 +1731,9 @@ Rect2 Control::_compute_child_rect(const float p_anchors[4], const float p_margi void Control::_compute_anchors(Rect2 p_rect, const float p_margins[4], float (&r_anchors)[4]) { Size2 parent_rect_size = get_parent_anchorable_rect().size; + ERR_FAIL_COND(parent_rect_size.x == 0.0); + ERR_FAIL_COND(parent_rect_size.y == 0.0); + r_anchors[0] = (p_rect.position.x - p_margins[0]) / parent_rect_size.x; r_anchors[1] = (p_rect.position.y - p_margins[1]) / parent_rect_size.y; r_anchors[2] = (p_rect.position.x + p_rect.size.x - p_margins[2]) / parent_rect_size.x; @@ -1994,10 +1979,7 @@ Control *Control::find_next_valid_focus() const { break; } - if (next_child) { - - from = next_child; - } else { + if (!next_child) { next_child = _next_control(from); if (!next_child) { //nothing else.. go up and find either window or subwindow @@ -2267,6 +2249,7 @@ Ref<Theme> Control::get_theme() const { void Control::set_tooltip(const String &p_tooltip) { data.tooltip = p_tooltip; + update_configuration_warning(); } String Control::get_tooltip(const Point2 &p_pos) const { @@ -2558,6 +2541,7 @@ void Control::set_mouse_filter(MouseFilter p_filter) { ERR_FAIL_INDEX(p_filter, 3); data.mouse_filter = p_filter; + update_configuration_warning(); } Control::MouseFilter Control::get_mouse_filter() const { @@ -2721,6 +2705,20 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List } } } + +String Control::get_configuration_warning() const { + String warning = CanvasItem::get_configuration_warning(); + + if (data.mouse_filter == MOUSE_FILTER_IGNORE && data.tooltip != "") { + if (warning != String()) { + warning += "\n"; + } + warning += TTR("The Hint Tooltip won't be displayed as the control's Mouse Filter is set to \"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"."); + } + + return warning; +} + void Control::set_clip_contents(bool p_clip) { data.clip_contents = p_clip; diff --git a/scene/gui/control.h b/scene/gui/control.h index a6f9a442ae..1a59a6d2e4 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -139,8 +139,8 @@ private: bool operator()(const Control *p_a, const Control *p_b) const { if (p_a->get_canvas_layer() == p_b->get_canvas_layer()) return p_b->is_greater_than(p_a); - else - return p_a->get_canvas_layer() < p_b->get_canvas_layer(); + + return p_a->get_canvas_layer() < p_b->get_canvas_layer(); } }; @@ -487,6 +487,7 @@ public: bool is_visibility_clip_disabled() const; virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const; + virtual String get_configuration_warning() const; Control(); ~Control(); diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp index 89f3d509d0..4da11b671e 100644 --- a/scene/gui/dialogs.cpp +++ b/scene/gui/dialogs.cpp @@ -406,12 +406,20 @@ void AcceptDialog::set_hide_on_ok(bool p_hide) { hide_on_ok = p_hide; } - bool AcceptDialog::get_hide_on_ok() const { return hide_on_ok; } +void AcceptDialog::set_autowrap(bool p_autowrap) { + + label->set_autowrap(p_autowrap); +} +bool AcceptDialog::has_autowrap() { + + return label->has_autowrap(); +} + void AcceptDialog::register_text_enter(Node *p_line_edit) { ERR_FAIL_NULL(p_line_edit); @@ -530,6 +538,8 @@ void AcceptDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("_custom_action"), &AcceptDialog::_custom_action); ClassDB::bind_method(D_METHOD("set_text", "text"), &AcceptDialog::set_text); ClassDB::bind_method(D_METHOD("get_text"), &AcceptDialog::get_text); + ClassDB::bind_method(D_METHOD("set_autowrap", "autowrap"), &AcceptDialog::set_autowrap); + ClassDB::bind_method(D_METHOD("has_autowrap"), &AcceptDialog::has_autowrap); ADD_SIGNAL(MethodInfo("confirmed")); ADD_SIGNAL(MethodInfo("custom_action", PropertyInfo(Variant::STRING, "action"))); @@ -537,6 +547,7 @@ void AcceptDialog::_bind_methods() { ADD_GROUP("Dialog", "dialog"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "dialog_text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dialog_hide_on_ok"), "set_hide_on_ok", "get_hide_on_ok"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dialog_autowrap"), "set_autowrap", "has_autowrap"); } bool AcceptDialog::swap_ok_cancel = false; @@ -555,7 +566,6 @@ AcceptDialog::AcceptDialog() { label->set_anchor(MARGIN_BOTTOM, ANCHOR_END); label->set_begin(Point2(margin, margin)); label->set_end(Point2(-margin, -button_margin - 10)); - //label->set_autowrap(true); add_child(label); hbc = memnew(HBoxContainer); diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h index 4b89ac54c5..c1a7f26a85 100644 --- a/scene/gui/dialogs.h +++ b/scene/gui/dialogs.h @@ -145,6 +145,9 @@ public: void set_text(String p_text); String get_text() const; + void set_autowrap(bool p_autowrap); + bool has_autowrap(); + AcceptDialog(); ~AcceptDialog(); }; diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index bdb1342019..04fb991f78 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -48,8 +48,9 @@ void FileDialog::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { - refresh->set_icon(get_icon("reload")); dir_up->set_icon(get_icon("parent_folder")); + refresh->set_icon(get_icon("reload")); + show_hidden->set_icon(get_icon("toggle_hidden")); } if (p_what == NOTIFICATION_POPUP_HIDE) { @@ -301,11 +302,8 @@ bool FileDialog::_is_open_should_be_disabled() { Dictionary d = ti->get_metadata(0); // Opening a file, but selected a folder? Forbidden. - if (((mode == MODE_OPEN_FILE || mode == MODE_OPEN_FILES) && d["dir"]) || // Flipped case, also forbidden. - (mode == MODE_OPEN_DIR && !d["dir"])) - return true; - - return false; + return ((mode == MODE_OPEN_FILE || mode == MODE_OPEN_FILES) && d["dir"]) || // Flipped case, also forbidden. + (mode == MODE_OPEN_DIR && !d["dir"]); } void FileDialog::_go_up() { @@ -383,6 +381,18 @@ void FileDialog::_tree_item_activated() { } } +void FileDialog::update_file_name() { + int idx = filter->get_selected() - 1; + if ((idx == -1 && filter->get_item_count() == 2) || (filter->get_item_count() > 2 && idx >= 0 && idx < filter->get_item_count() - 2)) { + if (idx == -1) idx += 1; + String filter_str = filters[idx]; + String file_str = file->get_text(); + String base_name = file_str.get_basename(); + file_str = base_name + "." + filter_str.strip_edges().to_lower(); + file->set_text(file_str); + } +} + void FileDialog::update_file_list() { tree->clear(); @@ -393,20 +403,19 @@ void FileDialog::update_file_list() { List<String> files; List<String> dirs; - bool isdir; - bool ishidden; - bool show_hidden = show_hidden_files; + bool is_dir; + bool is_hidden; String item; - while ((item = dir_access->get_next(&isdir)) != "") { + while ((item = dir_access->get_next(&is_dir)) != "") { if (item == "." || item == "..") continue; - ishidden = dir_access->current_is_hidden(); + is_hidden = dir_access->current_is_hidden(); - if (show_hidden || !ishidden) { - if (!isdir) + if (show_hidden_files || !is_hidden) { + if (!is_dir) files.push_back(item); else dirs.push_back(item); @@ -509,6 +518,7 @@ void FileDialog::update_file_list() { void FileDialog::_filter_selected(int) { + update_file_name(); update_file_list(); } @@ -800,6 +810,7 @@ void FileDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("_select_drive"), &FileDialog::_select_drive); ClassDB::bind_method(D_METHOD("_make_dir"), &FileDialog::_make_dir); ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &FileDialog::_make_dir_confirm); + ClassDB::bind_method(D_METHOD("_update_file_name"), &FileDialog::update_file_name); ClassDB::bind_method(D_METHOD("_update_file_list"), &FileDialog::update_file_list); ClassDB::bind_method(D_METHOD("_update_dir"), &FileDialog::update_dir); ClassDB::bind_method(D_METHOD("_go_up"), &FileDialog::_go_up); @@ -873,6 +884,13 @@ FileDialog::FileDialog() { refresh->connect("pressed", this, "_update_file_list"); hbc->add_child(refresh); + show_hidden = memnew(ToolButton); + show_hidden->set_toggle_mode(true); + show_hidden->set_pressed(is_showing_hidden_files()); + show_hidden->set_tooltip(RTR("Toggle Hidden Files")); + show_hidden->connect("toggled", this, "set_show_hidden_files"); + hbc->add_child(show_hidden); + drives = memnew(OptionButton); hbc->add_child(drives); drives->connect("item_selected", this, "_select_drive"); diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 85edac0b12..191af5fef3 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -90,6 +90,7 @@ private: ToolButton *dir_up; ToolButton *refresh; + ToolButton *show_hidden; Vector<String> filters; @@ -101,6 +102,7 @@ private: bool invalidated; void update_dir(); + void update_file_name(); void update_file_list(); void update_filters(); diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp index cfbc9d6d18..75f5f79873 100644 --- a/scene/gui/gradient_edit.cpp +++ b/scene/gui/gradient_edit.cpp @@ -29,10 +29,17 @@ /*************************************************************************/ #include "gradient_edit.h" + #include "core/os/keyboard.h" -#include "editor/editor_scale.h" +#ifdef TOOLS_ENABLED +#include "editor/editor_scale.h" #define SPACING (3 * EDSCALE) +#define POINT_WIDTH (8 * EDSCALE) +#else +#define SPACING 3 +#define POINT_WIDTH 8 +#endif GradientEdit::GradientEdit() { grabbed = -1; diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h index 662278a17b..6f31107729 100644 --- a/scene/gui/gradient_edit.h +++ b/scene/gui/gradient_edit.h @@ -36,8 +36,6 @@ #include "scene/resources/default_theme/theme_data.h" #include "scene/resources/gradient.h" -#define POINT_WIDTH (8 * EDSCALE) - class GradientEdit : public Control { GDCLASS(GradientEdit, Control); diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index dabff08fea..f238aeb392 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -479,7 +479,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { connecting_color = gn->get_connection_input_color(j); connecting_target = false; connecting_to = pos; - just_disconnected = true; + just_disconnected = false; return; } @@ -550,11 +550,18 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) { emit_signal("connection_request", from, from_slot, to, to_slot); } else if (!just_disconnected) { + String from = connecting_from; int from_slot = connecting_index; Vector2 ofs = Vector2(mb->get_position().x, mb->get_position().y); - emit_signal("connection_to_empty", from, from_slot, ofs); + + if (!connecting_out) { + emit_signal("connection_from_empty", from, from_slot, ofs); + } else { + emit_signal("connection_to_empty", from, from_slot, ofs); + } } + connecting = false; top_layer->update(); update(); @@ -1292,6 +1299,7 @@ void GraphEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("duplicate_nodes_request")); ADD_SIGNAL(MethodInfo("node_selected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::VECTOR2, "release_position"))); + ADD_SIGNAL(MethodInfo("connection_from_empty", PropertyInfo(Variant::STRING, "to"), PropertyInfo(Variant::INT, "to_slot"), PropertyInfo(Variant::VECTOR2, "release_position"))); ADD_SIGNAL(MethodInfo("delete_nodes_request")); ADD_SIGNAL(MethodInfo("_begin_node_move")); ADD_SIGNAL(MethodInfo("_end_node_move")); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index e3e9368a12..510f1b18ad 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -247,11 +247,11 @@ void Label::_notification(int p_what) { n = String::char_uppercase(n); } - float move = font->draw_char(ci, Point2(x_ofs_shadow, y_ofs) + shadow_ofs, c, n, font_color_shadow, false); + float move = drawer.draw_char(ci, Point2(x_ofs_shadow, y_ofs) + shadow_ofs, c, n, font_color_shadow); if (use_outline) { - font->draw_char(ci, Point2(x_ofs_shadow, y_ofs) + Vector2(-shadow_ofs.x, shadow_ofs.y), c, n, font_color_shadow, false); - font->draw_char(ci, Point2(x_ofs_shadow, y_ofs) + Vector2(shadow_ofs.x, -shadow_ofs.y), c, n, font_color_shadow, false); - font->draw_char(ci, Point2(x_ofs_shadow, y_ofs) + Vector2(-shadow_ofs.x, -shadow_ofs.y), c, n, font_color_shadow, false); + drawer.draw_char(ci, Point2(x_ofs_shadow, y_ofs) + Vector2(-shadow_ofs.x, shadow_ofs.y), c, n, font_color_shadow); + drawer.draw_char(ci, Point2(x_ofs_shadow, y_ofs) + Vector2(shadow_ofs.x, -shadow_ofs.y), c, n, font_color_shadow); + drawer.draw_char(ci, Point2(x_ofs_shadow, y_ofs) + Vector2(-shadow_ofs.x, -shadow_ofs.y), c, n, font_color_shadow); } x_ofs_shadow += move; chars_total_shadow++; @@ -470,7 +470,6 @@ void Label::regenerate_word_cache() { wc->word_len = i - word_pos; wc->space_count = space_count; current_word_size = char_width; - space_count = 0; word_pos = i; } } diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 58bdde1ffd..7a015f77db 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -539,7 +539,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { if (handled) { accept_event(); - } else if (!k->get_alt() && !k->get_command()) { + } else if (!k->get_command()) { if (k->get_unicode() >= 32 && k->get_scancode() != KEY_DELETE) { if (editable) { @@ -623,10 +623,7 @@ bool LineEdit::_is_over_clear_button(const Point2 &p_pos) const { } Ref<Texture> icon = Control::get_icon("clear"); int x_ofs = get_stylebox("normal")->get_offset().x; - if (p_pos.x > get_size().width - icon->get_width() - x_ofs) { - return true; - } - return false; + return p_pos.x > get_size().width - icon->get_width() - x_ofs; } void LineEdit::_notification(int p_what) { @@ -650,6 +647,11 @@ void LineEdit::_notification(int p_what) { set_cursor_position(get_cursor_position()); } break; + case NOTIFICATION_TRANSLATION_CHANGED: { + placeholder_translated = tr(placeholder); + update_placeholder_width(); + update(); + } break; case MainLoop::NOTIFICATION_WM_FOCUS_IN: { window_has_focus = true; draw_caret = true; @@ -675,10 +677,8 @@ void LineEdit::_notification(int p_what) { RID ci = get_canvas_item(); Ref<StyleBox> style = get_stylebox("normal"); - float disabled_alpha = 1.0; // used to set the disabled input text color if (!is_editable()) { style = get_stylebox("read_only"); - disabled_alpha = .5; draw_caret = false; } @@ -724,20 +724,19 @@ void LineEdit::_notification(int p_what) { int font_ascent = font->get_ascent(); Color selection_color = get_color("selection_color"); - Color font_color = get_color("font_color"); + Color font_color = is_editable() ? get_color("font_color") : get_color("font_color_uneditable"); Color font_color_selected = get_color("font_color_selected"); Color cursor_color = get_color("cursor_color"); - const String &t = using_placeholder ? placeholder : text; + const String &t = using_placeholder ? placeholder_translated : text; // draw placeholder color if (using_placeholder) font_color.a *= placeholder_alpha; - font_color.a *= disabled_alpha; bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled; if (right_icon.is_valid() || display_clear_icon) { Ref<Texture> r_icon = display_clear_icon ? Control::get_icon("clear") : right_icon; - Color color_icon(1, 1, 1, disabled_alpha * .9); + Color color_icon(1, 1, 1, !is_editable() ? .5 * .9 : .9); if (display_clear_icon) { if (clear_button_status.press_attempt && clear_button_status.pressing_inside) { color_icon = get_color("clear_button_color_pressed"); @@ -1148,16 +1147,9 @@ String LineEdit::get_text() const { void LineEdit::set_placeholder(String p_text) { - placeholder = tr(p_text); - if ((max_length <= 0) || (placeholder.length() <= max_length)) { - Ref<Font> font = get_font("font"); - cached_placeholder_width = 0; - if (font != NULL) { - for (int i = 0; i < placeholder.length(); i++) { - cached_placeholder_width += font->get_char_size(placeholder[i]).width; - } - } - } + placeholder = p_text; + placeholder_translated = tr(placeholder); + update_placeholder_width(); update(); } @@ -1546,6 +1538,18 @@ void LineEdit::_emit_text_change() { text_changed_dirty = false; } +void LineEdit::update_placeholder_width() { + if ((max_length <= 0) || (placeholder_translated.length() <= max_length)) { + Ref<Font> font = get_font("font"); + cached_placeholder_width = 0; + if (font != NULL) { + for (int i = 0; i < placeholder_translated.length(); i++) { + cached_placeholder_width += font->get_char_size(placeholder_translated[i]).width; + } + } + } +} + void LineEdit::_clear_redo() { _create_undo_state(); if (undo_stack_pos == NULL) { diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 3b29780dc0..3002f6f637 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -72,6 +72,7 @@ private: String undo_text; String text; String placeholder; + String placeholder_translated; String secret_character; float placeholder_alpha; String ime_text; @@ -126,6 +127,8 @@ private: void _emit_text_change(); bool expand_to_text_length; + void update_placeholder_width(); + bool caret_blink_enabled; bool draw_caret; bool window_has_focus; diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index 7027fceb84..58671655dc 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -86,24 +86,7 @@ void OptionButton::_focused(int p_which) { void OptionButton::_selected(int p_which) { - int selid = -1; - for (int i = 0; i < popup->get_item_count(); i++) { - - bool is_clicked = popup->get_item_id(i) == p_which; - if (is_clicked) { - selid = i; - break; - } - } - - if (selid == -1 && p_which >= 0 && p_which < popup->get_item_count()) { - _select(p_which, true); - } else { - - ERR_FAIL_COND(selid == -1); - - _select(selid, true); - } + _select(p_which, true); } void OptionButton::pressed() { @@ -299,7 +282,7 @@ void OptionButton::_set_items(const Array &p_items) { void OptionButton::get_translatable_strings(List<String> *p_strings) const { - return popup->get_translatable_strings(p_strings); + popup->get_translatable_strings(p_strings); } void OptionButton::_bind_methods() { @@ -355,7 +338,7 @@ OptionButton::OptionButton() { popup->set_pass_on_modal_close_click(false); popup->set_notify_transform(true); popup->set_allow_search(true); - popup->connect("id_pressed", this, "_selected"); + popup->connect("index_pressed", this, "_selected"); popup->connect("id_focused", this, "_focused"); popup->connect("popup_hide", this, "set_pressed", varray(false)); } diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index fdb1b65f77..492e379440 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -141,7 +141,7 @@ void Popup::popup_centered(const Size2 &p_size) { rect.size = p_size == Size2() ? get_size() : p_size; rect.position = ((window_size - rect.size) / 2.0).floor(); - popup(rect); + _popup(rect, true); } void Popup::popup_centered_ratio(float p_screen_ratio) { @@ -151,18 +151,29 @@ void Popup::popup_centered_ratio(float p_screen_ratio) { rect.size = (window_size * p_screen_ratio).floor(); rect.position = ((window_size - rect.size) / 2.0).floor(); - popup(rect); + _popup(rect, true); } void Popup::popup(const Rect2 &p_bounds) { + _popup(p_bounds); +} + +void Popup::_popup(const Rect2 &p_bounds, const bool p_centered) { + emit_signal("about_to_show"); show_modal(exclusive); // Fit the popup into the optionally provided bounds. if (!p_bounds.has_no_area()) { - set_position(p_bounds.position); set_size(p_bounds.size); + + // check if p_bounds.size was using an outdated cached values + if (p_centered && p_bounds.size != get_size()) { + set_position(p_bounds.position - ((get_size() - p_bounds.size) / 2.0).floor()); + } else { + set_position(p_bounds.position); + } } _fix_size(); diff --git a/scene/gui/popup.h b/scene/gui/popup.h index 6615c51ec5..d6d96dfe64 100644 --- a/scene/gui/popup.h +++ b/scene/gui/popup.h @@ -43,6 +43,9 @@ class Popup : public Control { bool exclusive; bool popped_up; +private: + void _popup(const Rect2 &p_bounds = Rect2(), const bool p_centered = false); + protected: virtual void _post_popup() {} diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp index c24e62c8cb..d00acaf08a 100644 --- a/scene/gui/range.cpp +++ b/scene/gui/range.cpp @@ -63,7 +63,7 @@ void Range::Shared::emit_value_changed() { void Range::_changed_notify(const char *p_what) { - emit_signal("changed", shared->val); + emit_signal("changed"); update(); _change_notify(p_what); } @@ -79,6 +79,7 @@ void Range::Shared::emit_changed(const char *p_what) { } void Range::set_value(double p_val) { + if (shared->step > 0) p_val = Math::round(p_val / shared->step) * shared->step; @@ -303,22 +304,27 @@ bool Range::is_ratio_exp() const { } void Range::set_allow_greater(bool p_allow) { + shared->allow_greater = p_allow; } bool Range::is_greater_allowed() const { + return shared->allow_greater; } void Range::set_allow_lesser(bool p_allow) { + shared->allow_lesser = p_allow; } bool Range::is_lesser_allowed() const { + return shared->allow_lesser; } Range::Range() { + shared = memnew(Shared); shared->min = 0; shared->max = 100; diff --git a/scene/gui/reference_rect.cpp b/scene/gui/reference_rect.cpp index 553e133946..052c8ccd05 100644 --- a/scene/gui/reference_rect.cpp +++ b/scene/gui/reference_rect.cpp @@ -38,26 +38,41 @@ void ReferenceRect::_notification(int p_what) { if (!is_inside_tree()) return; - if (Engine::get_singleton()->is_editor_hint()) + if (Engine::get_singleton()->is_editor_hint() || !editor_only) draw_rect(Rect2(Point2(), get_size()), border_color, false); } } -void ReferenceRect::set_border_color(const Color &color) { - border_color = color; +void ReferenceRect::set_border_color(const Color &p_color) { + border_color = p_color; + update(); } Color ReferenceRect::get_border_color() const { return border_color; } +void ReferenceRect::set_editor_only(const bool &p_enabled) { + editor_only = p_enabled; + update(); +} + +bool ReferenceRect::get_editor_only() const { + return editor_only; +} + void ReferenceRect::_bind_methods() { ClassDB::bind_method(D_METHOD("get_border_color"), &ReferenceRect::get_border_color); ClassDB::bind_method(D_METHOD("set_border_color", "color"), &ReferenceRect::set_border_color); + ClassDB::bind_method(D_METHOD("get_editor_only"), &ReferenceRect::get_editor_only); + ClassDB::bind_method(D_METHOD("set_editor_only", "enabled"), &ReferenceRect::set_editor_only); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "border_color"), "set_border_color", "get_border_color"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "get_editor_only"); } ReferenceRect::ReferenceRect() { border_color = Color(1, 0, 0); + editor_only = true; } diff --git a/scene/gui/reference_rect.h b/scene/gui/reference_rect.h index de3ccaeeca..7a88333cf2 100644 --- a/scene/gui/reference_rect.h +++ b/scene/gui/reference_rect.h @@ -37,6 +37,7 @@ class ReferenceRect : public Control { GDCLASS(ReferenceRect, Control); Color border_color; + bool editor_only; protected: void _notification(int p_what); @@ -45,8 +46,11 @@ protected: public: ReferenceRect(); - void set_border_color(const Color &color); + void set_border_color(const Color &p_color); Color get_border_color() const; + + void set_editor_only(const bool &p_enabled); + bool get_editor_only() const; }; #endif // REFERENCE_RECT_H diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index da452e3f10..5b91299de6 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -307,6 +307,25 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & switch (it->type) { + case ITEM_ALIGN: { + + ItemAlign *align_it = static_cast<ItemAlign *>(it); + + align = align_it->align; + + } break; + case ITEM_INDENT: { + + if (it != l.from) { + ItemIndent *indent_it = static_cast<ItemIndent *>(it); + + int indent = indent_it->level * tab_size * cfont->get_char_size(' ').width; + margin += indent; + begin += indent; + wofs += indent; + } + + } break; case ITEM_TEXT: { ItemText *text = static_cast<ItemText *>(it); @@ -440,14 +459,13 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & if (p_font_color_shadow.a > 0) { float x_ofs_shadow = align_ofs + pofs; float y_ofs_shadow = y + lh - line_descent; - float move = font->draw_char(ci, Point2(x_ofs_shadow, y_ofs_shadow) + shadow_ofs, c[i], c[i + 1], p_font_color_shadow); + font->draw_char(ci, Point2(x_ofs_shadow, y_ofs_shadow) + shadow_ofs, c[i], c[i + 1], p_font_color_shadow); if (p_shadow_as_outline) { font->draw_char(ci, Point2(x_ofs_shadow, y_ofs_shadow) + Vector2(-shadow_ofs.x, shadow_ofs.y), c[i], c[i + 1], p_font_color_shadow); font->draw_char(ci, Point2(x_ofs_shadow, y_ofs_shadow) + Vector2(shadow_ofs.x, -shadow_ofs.y), c[i], c[i + 1], p_font_color_shadow); font->draw_char(ci, Point2(x_ofs_shadow, y_ofs_shadow) + Vector2(-shadow_ofs.x, -shadow_ofs.y), c[i], c[i + 1], p_font_color_shadow); } - x_ofs_shadow += move; } if (selected) { @@ -592,7 +610,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int & //assign actual widths for (int i = 0; i < table->columns.size(); i++) { table->columns.write[i].width = table->columns[i].min_width; - if (table->columns[i].expand) + if (table->columns[i].expand && total_ratio > 0) table->columns.write[i].width += table->columns[i].expand_ratio * remaining_width / total_ratio; table->total_width += table->columns[i].width + hseparation; } @@ -928,84 +946,80 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) { return; if (b->get_button_index() == BUTTON_LEFT) { + if (b->is_pressed() && !b->is_doubleclick()) { + scroll_updated = false; + int line = 0; + Item *item = NULL; - if (true) { + bool outside; + _find_click(main, b->get_position(), &item, &line, &outside); - if (b->is_pressed() && !b->is_doubleclick()) { - scroll_updated = false; - int line = 0; - Item *item = NULL; + if (item) { - bool outside; - _find_click(main, b->get_position(), &item, &line, &outside); - - if (item) { + if (selection.enabled) { - if (selection.enabled) { + selection.click = item; + selection.click_char = line; - selection.click = item; - selection.click_char = line; + // Erase previous selection. + if (selection.active) { + selection.from = NULL; + selection.from_char = '\0'; + selection.to = NULL; + selection.to_char = '\0'; + selection.active = false; - // Erase previous selection. - if (selection.active) { - selection.from = NULL; - selection.from_char = '\0'; - selection.to = NULL; - selection.to_char = '\0'; - selection.active = false; - - update(); - } + update(); } } - } else if (b->is_pressed() && b->is_doubleclick() && selection.enabled) { + } + } else if (b->is_pressed() && b->is_doubleclick() && selection.enabled) { - //doubleclick: select word - int line = 0; - Item *item = NULL; - bool outside; + //doubleclick: select word + int line = 0; + Item *item = NULL; + bool outside; - _find_click(main, b->get_position(), &item, &line, &outside); + _find_click(main, b->get_position(), &item, &line, &outside); - while (item && item->type != ITEM_TEXT) { + while (item && item->type != ITEM_TEXT) { - item = _get_next_item(item, true); - } + item = _get_next_item(item, true); + } - if (item && item->type == ITEM_TEXT) { + if (item && item->type == ITEM_TEXT) { - String itext = static_cast<ItemText *>(item)->text; + String itext = static_cast<ItemText *>(item)->text; - int beg, end; - if (select_word(itext, line, beg, end)) { + int beg, end; + if (select_word(itext, line, beg, end)) { - selection.from = item; - selection.to = item; - selection.from_char = beg; - selection.to_char = end - 1; - selection.active = true; - update(); - } + selection.from = item; + selection.to = item; + selection.from_char = beg; + selection.to_char = end - 1; + selection.active = true; + update(); } - } else if (!b->is_pressed()) { + } + } else if (!b->is_pressed()) { - selection.click = NULL; + selection.click = NULL; - if (!b->is_doubleclick() && !scroll_updated) { - int line = 0; - Item *item = NULL; + if (!b->is_doubleclick() && !scroll_updated) { + int line = 0; + Item *item = NULL; - bool outside; - _find_click(main, b->get_position(), &item, &line, &outside); + bool outside; + _find_click(main, b->get_position(), &item, &line, &outside); - if (item) { + if (item) { - Variant meta; - if (!outside && _find_meta(item, &meta)) { - //meta clicked + Variant meta; + if (!outside && _find_meta(item, &meta)) { + //meta clicked - emit_signal("meta_clicked", meta); - } + emit_signal("meta_clicked", meta); } } } @@ -1294,6 +1308,23 @@ bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item) return false; } +bool RichTextLabel::_find_layout_subitem(Item *from, Item *to) { + + if (from && from != to) { + if (from->type != ITEM_FONT && from->type != ITEM_COLOR && from->type != ITEM_UNDERLINE && from->type != ITEM_STRIKETHROUGH) + return true; + + for (List<Item *>::Element *E = from->subitems.front(); E; E = E->next()) { + bool layout = _find_layout_subitem(E->get(), to); + + if (layout) + return true; + } + } + + return false; +} + void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) { if (p_frame->first_invalid_line == p_frame->lines.size()) @@ -1411,9 +1442,13 @@ void RichTextLabel::_add_item(Item *p_item, bool p_enter, bool p_ensure_newline) if (p_enter) current = p_item; - if (p_ensure_newline && current_frame->lines[current_frame->lines.size() - 1].from) { - _invalidate_current_line(current_frame); - current_frame->lines.resize(current_frame->lines.size() + 1); + if (p_ensure_newline) { + Item *from = current_frame->lines[current_frame->lines.size() - 1].from; + // only create a new line for Item types that generate content/layout, ignore those that represent formatting/styling + if (_find_layout_subitem(from, p_item)) { + _invalidate_current_line(current_frame); + current_frame->lines.resize(current_frame->lines.size() + 1); + } } if (current_frame->lines[current_frame->lines.size() - 1].from == NULL) { diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 114c6103e2..21d099c37a 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -286,6 +286,7 @@ private: bool _find_underline(Item *p_item); bool _find_strikethrough(Item *p_item); bool _find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item = NULL); + bool _find_layout_subitem(Item *from, Item *to); void _update_scroll(); void _scroll_changed(double); diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp index 686d1c96cc..a7c15151ae 100644 --- a/scene/gui/scroll_bar.cpp +++ b/scene/gui/scroll_bar.cpp @@ -439,27 +439,26 @@ double ScrollBar::get_grabber_size() const { } double ScrollBar::get_area_size() const { - - if (orientation == VERTICAL) { - - double area = get_size().height; - area -= get_stylebox("scroll")->get_minimum_size().height; - area -= get_icon("increment")->get_height(); - area -= get_icon("decrement")->get_height(); - area -= get_grabber_min_size(); - return area; - - } else if (orientation == HORIZONTAL) { - - double area = get_size().width; - area -= get_stylebox("scroll")->get_minimum_size().width; - area -= get_icon("increment")->get_width(); - area -= get_icon("decrement")->get_width(); - area -= get_grabber_min_size(); - return area; - } else { - - return 0; + switch (orientation) { + case VERTICAL: { + double area = get_size().height; + area -= get_stylebox("scroll")->get_minimum_size().height; + area -= get_icon("increment")->get_height(); + area -= get_icon("decrement")->get_height(); + area -= get_grabber_min_size(); + return area; + } break; + case HORIZONTAL: { + double area = get_size().width; + area -= get_stylebox("scroll")->get_minimum_size().width; + area -= get_icon("increment")->get_width(); + area -= get_icon("decrement")->get_width(); + area -= get_grabber_min_size(); + return area; + } break; + default: { + return 0.0; + } } } diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index a1034937b5..d83ae47671 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -140,19 +140,17 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) { _cancel_drag(); } - if (true) { - drag_speed = Vector2(); - drag_accum = Vector2(); - last_drag_accum = Vector2(); - drag_from = Vector2(h_scroll->get_value(), v_scroll->get_value()); - drag_touching = OS::get_singleton()->has_touchscreen_ui_hint(); - drag_touching_deaccel = false; - beyond_deadzone = false; + drag_speed = Vector2(); + drag_accum = Vector2(); + last_drag_accum = Vector2(); + drag_from = Vector2(h_scroll->get_value(), v_scroll->get_value()); + drag_touching = OS::get_singleton()->has_touchscreen_ui_hint(); + drag_touching_deaccel = false; + beyond_deadzone = false; + time_since_motion = 0; + if (drag_touching) { + set_physics_process_internal(true); time_since_motion = 0; - if (drag_touching) { - set_physics_process_internal(true); - time_since_motion = 0; - } } } else { diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h index 3c1ca09a9f..97838e19a3 100644 --- a/scene/gui/split_container.h +++ b/scene/gui/split_container.h @@ -35,7 +35,7 @@ class SplitContainer : public Container { - GDCLASS(SplitContainer, Container) + GDCLASS(SplitContainer, Container); public: enum DraggerVisibility { diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index 36571cc878..7b0836cd28 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -892,6 +892,8 @@ void Tabs::ensure_tab_visible(int p_idx) { } Rect2 Tabs::get_tab_rect(int p_tab) const { + + ERR_FAIL_INDEX_V(p_tab, tabs.size(), Rect2()); return Rect2(tabs[p_tab].ofs_cache, 0, tabs[p_tab].size_cache, get_size().height); } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 6203b15992..a6e3d644f6 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -662,10 +662,8 @@ void TextEdit::_notification(int p_what) { int xmargin_end = size.width - cache.style_normal->get_margin(MARGIN_RIGHT); //let's do it easy for now: cache.style_normal->draw(ci, Rect2(Point2(), size)); - float readonly_alpha = 1.0; // used to set the input text color when in read-only mode if (readonly) { cache.style_readonly->draw(ci, Rect2(Point2(), size)); - readonly_alpha = .5; draw_caret = false; } if (has_focus()) @@ -675,8 +673,7 @@ void TextEdit::_notification(int p_what) { int visible_rows = get_visible_rows() + 1; - Color color = cache.font_color; - color.a *= readonly_alpha; + Color color = readonly ? cache.font_color_readonly : cache.font_color; if (syntax_coloring) { if (cache.background_color.a > 0.01) { @@ -684,6 +681,13 @@ void TextEdit::_notification(int p_what) { } } + if (line_length_guideline) { + int x = xmargin_beg + cache.font->get_char_size('0').width * line_length_guideline_col - cursor.x_ofs; + if (x > xmargin_beg && x < xmargin_end) { + VisualServer::get_singleton()->canvas_item_add_line(ci, Point2(x, 0), Point2(x, size.height), cache.line_length_guideline_color); + } + } + int brace_open_match_line = -1; int brace_open_match_column = -1; bool brace_open_matching = false; @@ -871,10 +875,7 @@ void TextEdit::_notification(int p_what) { color_map = _get_line_syntax_highlighting(line); } // ensure we at least use the font color - Color current_color = cache.font_color; - if (readonly) { - current_color.a *= readonly_alpha; - } + Color current_color = readonly ? cache.font_color_readonly : cache.font_color; bool underlined = false; @@ -1061,10 +1062,7 @@ void TextEdit::_notification(int p_what) { if (syntax_coloring) { if (color_map.has(last_wrap_column + j)) { - current_color = color_map[last_wrap_column + j].color; - if (readonly) { - current_color.a *= readonly_alpha; - } + current_color = readonly ? cache.font_color_readonly : color_map[last_wrap_column + j].color; } color = current_color; } @@ -1178,7 +1176,7 @@ void TextEdit::_notification(int p_what) { if (brace_open_mismatch) color = cache.brace_mismatch_color; - drawer.draw_char(ci, Point2i(char_ofs + char_margin + ofs_x, yofs + ascent), '_', str[j + 1], in_selection && override_selected_font_color ? cache.font_selected_color : color); + drawer.draw_char(ci, Point2i(char_ofs + char_margin + ofs_x, yofs + ascent), '_', str[j + 1], in_selection && override_selected_font_color ? cache.font_color_selected : color); } if ((brace_close_match_line == line && brace_close_match_column == last_wrap_column + j) || @@ -1186,7 +1184,7 @@ void TextEdit::_notification(int p_what) { if (brace_close_mismatch) color = cache.brace_mismatch_color; - drawer.draw_char(ci, Point2i(char_ofs + char_margin + ofs_x, yofs + ascent), '_', str[j + 1], in_selection && override_selected_font_color ? cache.font_selected_color : color); + drawer.draw_char(ci, Point2i(char_ofs + char_margin + ofs_x, yofs + ascent), '_', str[j + 1], in_selection && override_selected_font_color ? cache.font_color_selected : color); } } @@ -1252,29 +1250,28 @@ void TextEdit::_notification(int p_what) { if (cursor.column == last_wrap_column + j && cursor.line == line && cursor_wrap_index == line_wrap_index && block_caret && draw_caret && !insert_mode) { color = cache.caret_background_color; } else if (!syntax_coloring && block_caret) { - color = cache.font_color; - color.a *= readonly_alpha; + color = readonly ? cache.font_color_readonly : cache.font_color; } if (str[j] >= 32) { int yofs = ofs_y + (get_row_height() - cache.font->get_height()) / 2; - int w = drawer.draw_char(ci, Point2i(char_ofs + char_margin + ofs_x, yofs + ascent), str[j], str[j + 1], in_selection && override_selected_font_color ? cache.font_selected_color : color); + int w = drawer.draw_char(ci, Point2i(char_ofs + char_margin + ofs_x, yofs + ascent), str[j], str[j + 1], in_selection && override_selected_font_color ? cache.font_color_selected : color); if (underlined) { float line_width = 1.0; #ifdef TOOLS_ENABLED line_width *= EDSCALE; #endif - draw_rect(Rect2(char_ofs + char_margin + ofs_x, yofs + ascent + 2, w, line_width), in_selection && override_selected_font_color ? cache.font_selected_color : color); + draw_rect(Rect2(char_ofs + char_margin + ofs_x, yofs + ascent + 2, w, line_width), in_selection && override_selected_font_color ? cache.font_color_selected : color); } } else if (draw_tabs && str[j] == '\t') { int yofs = (get_row_height() - cache.tab_icon->get_height()) / 2; - cache.tab_icon->draw(ci, Point2(char_ofs + char_margin + ofs_x, ofs_y + yofs), in_selection && override_selected_font_color ? cache.font_selected_color : color); + cache.tab_icon->draw(ci, Point2(char_ofs + char_margin + ofs_x, ofs_y + yofs), in_selection && override_selected_font_color ? cache.font_color_selected : color); } if (draw_spaces && str[j] == ' ') { int yofs = (get_row_height() - cache.space_icon->get_height()) / 2; - cache.space_icon->draw(ci, Point2(char_ofs + char_margin + ofs_x, ofs_y + yofs), in_selection && override_selected_font_color ? cache.font_selected_color : color); + cache.space_icon->draw(ci, Point2(char_ofs + char_margin + ofs_x, ofs_y + yofs), in_selection && override_selected_font_color ? cache.font_color_selected : color); } char_ofs += char_w; @@ -1349,13 +1346,6 @@ void TextEdit::_notification(int p_what) { } } - if (line_length_guideline) { - int x = xmargin_beg + cache.font->get_char_size('0').width * line_length_guideline_col - cursor.x_ofs; - if (x > xmargin_beg && x < xmargin_end) { - VisualServer::get_singleton()->canvas_item_add_line(ci, Point2(x, 0), Point2(x, size.height), cache.line_length_guideline_color); - } - } - bool completion_below = false; if (completion_active) { // code completion box @@ -1603,7 +1593,6 @@ void TextEdit::_consume_pair_symbol(CharType ch) { insert_text_at_cursor(ch_pair); cursor_set_column(cursor_position_to_move); - return; } void TextEdit::_consume_backspace_for_pair_symbol(int prev_line, int prev_column) { @@ -4078,7 +4067,7 @@ void TextEdit::cursor_set_line(int p_row, bool p_adjust_viewport, bool p_can_be_ cursor.line = p_row; int n_col = get_char_pos_for_line(cursor.last_fit_x, p_row, p_wrap_index); - if (is_wrap_enabled() && p_wrap_index < times_line_wraps(p_row)) { + if (n_col != 0 && is_wrap_enabled() && p_wrap_index < times_line_wraps(p_row)) { Vector<String> rows = get_wrap_rows_text(p_row); int row_end_col = 0; for (int i = 0; i < p_wrap_index + 1; i++) { @@ -4554,7 +4543,8 @@ void TextEdit::_update_caches() { cache.line_number_color = get_color("line_number_color"); cache.safe_line_number_color = get_color("safe_line_number_color"); cache.font_color = get_color("font_color"); - cache.font_selected_color = get_color("font_selected_color"); + cache.font_color_selected = get_color("font_color_selected"); + cache.font_color_readonly = get_color("font_color_readonly"); cache.keyword_color = get_color("keyword_color"); cache.function_color = get_color("function_color"); cache.member_variable_color = get_color("member_variable_color"); @@ -4682,6 +4672,8 @@ bool TextEdit::has_keyword_color(String p_keyword) const { } Color TextEdit::get_keyword_color(String p_keyword) const { + + ERR_FAIL_COND_V(!keywords.has(p_keyword), Color()); return keywords[p_keyword]; } @@ -4825,14 +4817,18 @@ void TextEdit::deselect() { void TextEdit::select(int p_from_line, int p_from_column, int p_to_line, int p_to_column) { - if (p_from_line >= text.size()) + if (p_from_line < 0) + p_from_line = 0; + else if (p_from_line >= text.size()) p_from_line = text.size() - 1; if (p_from_column >= text[p_from_line].length()) p_from_column = text[p_from_line].length(); if (p_from_column < 0) p_from_column = 0; - if (p_to_line >= text.size()) + if (p_to_line < 0) + p_to_line = 0; + else if (p_to_line >= text.size()) p_to_line = text.size() - 1; if (p_to_column >= text[p_to_line].length()) p_to_column = text[p_to_line].length(); @@ -5402,11 +5398,7 @@ bool TextEdit::is_line_comment(int p_line) const { for (int i = 0; i < line_length - 1; i++) { if (_is_symbol(text[p_line][i]) && cri_map.has(i)) { const Text::ColorRegionInfo &cri = cri_map[i]; - if (color_regions[cri.region].begin_key == "#" || color_regions[cri.region].begin_key == "//") { - return true; - } else { - return false; - } + return color_regions[cri.region].begin_key == "#" || color_regions[cri.region].begin_key == "//"; } else if (_is_whitespace(text[p_line][i])) { continue; } else { @@ -5455,9 +5447,7 @@ bool TextEdit::is_folded(int p_line) const { ERR_FAIL_INDEX_V(p_line, text.size(), false); if (p_line + 1 >= text.size()) return false; - if (!is_line_hidden(p_line) && is_line_hidden(p_line + 1)) - return true; - return false; + return !is_line_hidden(p_line) && is_line_hidden(p_line + 1); } Vector<int> TextEdit::get_folded_lines() const { @@ -5611,7 +5601,7 @@ void TextEdit::undo() { TextOperation op = undo_stack_pos->get(); _do_text_op(op, true); - if (op.from_line != op.to_line || op.to_column != op.from_column + 1) + if (op.type != TextOperation::TYPE_INSERT && (op.from_line != op.to_line || op.to_column != op.from_column + 1)) select(op.from_line, op.from_column, op.to_line, op.to_column); current_op.version = op.prev_version; @@ -6342,14 +6332,14 @@ int TextEdit::get_info_gutter_width() const { return info_gutter_width; } -void TextEdit::set_hiding_enabled(int p_enabled) { +void TextEdit::set_hiding_enabled(bool p_enabled) { if (!p_enabled) unhide_all_lines(); hiding_enabled = p_enabled; update(); } -int TextEdit::is_hiding_enabled() const { +bool TextEdit::is_hiding_enabled() const { return hiding_enabled; } @@ -6450,6 +6440,7 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_text"), &TextEdit::get_text); ClassDB::bind_method(D_METHOD("get_line", "line"), &TextEdit::get_line); + ClassDB::bind_method(D_METHOD("center_viewport_to_cursor"), &TextEdit::center_viewport_to_cursor); ClassDB::bind_method(D_METHOD("cursor_set_column", "column", "adjust_viewport"), &TextEdit::cursor_set_column, DEFVAL(true)); ClassDB::bind_method(D_METHOD("cursor_set_line", "line", "adjust_viewport", "can_be_hidden", "wrap_index"), &TextEdit::cursor_set_line, DEFVAL(true), DEFVAL(true), DEFVAL(0)); diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 68e590f1e6..30956ccb23 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -40,7 +40,7 @@ class SyntaxHighlighter; class TextEdit : public Control { - GDCLASS(TextEdit, Control) + GDCLASS(TextEdit, Control); public: struct HighlighterInfo { @@ -184,7 +184,8 @@ private: Color line_number_color; Color safe_line_number_color; Color font_color; - Color font_selected_color; + Color font_color_selected; + Color font_color_readonly; Color keyword_color; Color number_color; Color function_color; @@ -697,8 +698,8 @@ public: void set_info_gutter_width(int p_gutter_width); int get_info_gutter_width() const; - void set_hiding_enabled(int p_enabled); - int is_hiding_enabled() const; + void set_hiding_enabled(bool p_enabled); + bool is_hiding_enabled() const; void set_tooltip_request_func(Object *p_obj, const StringName &p_function, const Variant &p_udata); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 2007ae2669..c2493ab321 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -39,7 +39,7 @@ #include "scene/main/viewport.h" #ifdef TOOLS_ENABLED -#include "editor/editor_node.h" +#include "editor/editor_scale.h" #endif #include <limits.h> @@ -318,7 +318,7 @@ void TreeItem::set_custom_draw(int p_column, Object *p_object, const StringName void TreeItem::set_collapsed(bool p_collapsed) { - if (collapsed == p_collapsed) + if (collapsed == p_collapsed || !tree) return; collapsed = p_collapsed; TreeItem *ci = tree->selected_item; @@ -344,8 +344,7 @@ void TreeItem::set_collapsed(bool p_collapsed) { } _changed_notify(); - if (tree) - tree->emit_signal("item_collapsed", this); + tree->emit_signal("item_collapsed", this); } bool TreeItem::is_collapsed() { @@ -1129,6 +1128,8 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 for (int j = p_item->cells[i].buttons.size() - 1; j >= 0; j--) { Ref<Texture> b = p_item->cells[i].buttons[j].texture; Size2 s = b->get_size() + cache.button_pressed->get_minimum_size(); + if (s.height < label_h) + s.height = label_h; Point2i o = Point2i(ofs + w - s.width, p_pos.y) - cache.offset + p_draw_ofs; @@ -1930,8 +1931,6 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool edited_col = col; bool on_arrow = x > col_width - cache.select_arrow->get_width(); - bring_up_editor = false; - custom_popup_rect = Rect2i(get_global_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h - cache.offset.y), Size2(get_column_width(col), item_h)); if (on_arrow || !p_item->cells[col].custom_button) { @@ -3164,10 +3163,7 @@ bool Tree::is_anything_selected() { void Tree::clear() { - if (blocked > 0) { - - ERR_FAIL_COND(blocked > 0); - } + ERR_FAIL_COND(blocked > 0); if (pressing_for_editor) { if (range_drag_enabled) { @@ -3721,6 +3717,10 @@ String Tree::get_tooltip(const Point2 &p_pos) const { const TreeItem::Cell &c = it->cells[col]; int col_width = get_column_width(col); + + for (int i = 0; i < col; i++) + pos.x -= get_column_width(i); + for (int j = c.buttons.size() - 1; j >= 0; j--) { Ref<Texture> b = c.buttons[j].texture; Size2 size = b->get_size() + cache.button_pressed->get_minimum_size(); |