From b619a47416ef062c757fdd92addcff18be7a684e Mon Sep 17 00:00:00 2001 From: jmb462 Date: Mon, 20 Dec 2021 21:30:05 +0100 Subject: [PATCH] Renaming layers from the inspector via a popup menu. --- editor/editor_properties.cpp | 517 +++++++++++++++++++---------------- editor/editor_properties.h | 44 ++- 2 files changed, 324 insertions(+), 237 deletions(-) diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index f0d2d51922e..bce553661c7 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -791,261 +791,293 @@ EditorPropertyFlags::EditorPropertyFlags() { ///////////////////// LAYERS ///////////////////////// -class EditorPropertyLayersGrid : public Control { - GDCLASS(EditorPropertyLayersGrid, Control); +void EditorPropertyLayersGrid::_rename_pressed(int p_menu) { + // Show rename popup for active layer. + if (renamed_layer_index == -1) { + return; + } + String name = names[renamed_layer_index]; + rename_dialog->set_title(vformat(TTR("Renaming layer %d:"), renamed_layer_index + 1)); + rename_dialog_text->set_text(name); + rename_dialog_text->select(0, name.length()); + rename_dialog->popup_centered(Size2(300, 80) * EDSCALE); + rename_dialog_text->grab_focus(); +} -private: - Vector flag_rects; - Rect2 expand_rect; - bool expand_hovered = false; - bool expanded = false; - int expansion_rows = 0; - int hovered_index = -1; - bool read_only = false; +void EditorPropertyLayersGrid::_rename_operation_confirm() { + String new_name = rename_dialog_text->get_text().strip_edges(); + if (new_name.length() == 0) { + EditorNode::get_singleton()->show_warning(TTR("No name provided.")); + return; + } else if (new_name.find("/") != -1 || new_name.find("\\") != -1 || new_name.find(":") != -1) { + EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters.")); + return; + } + names.set(renamed_layer_index, new_name); + tooltips.set(renamed_layer_index, new_name + "\n" + vformat(TTR("Bit %d, value %d"), renamed_layer_index, 1 << renamed_layer_index)); + emit_signal(SNAME("rename_confirmed"), renamed_layer_index, new_name); +} - Size2 get_grid_size() const { - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); - int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); - return Vector2(0, font->get_height(font_size) * 3); +EditorPropertyLayersGrid::EditorPropertyLayersGrid() { + rename_dialog = memnew(ConfirmationDialog); + VBoxContainer *rename_dialog_vb = memnew(VBoxContainer); + rename_dialog->add_child(rename_dialog_vb); + rename_dialog_text = memnew(LineEdit); + rename_dialog_vb->add_margin_child(TTR("Name:"), rename_dialog_text); + rename_dialog->get_ok_button()->set_text(TTR("Rename")); + add_child(rename_dialog); + rename_dialog->register_text_enter(rename_dialog_text); + rename_dialog->connect("confirmed", callable_mp(this, &EditorPropertyLayersGrid::_rename_operation_confirm)); + layer_rename = memnew(PopupMenu); + layer_rename->add_item(TTR("Rename layer"), 0); + add_child(layer_rename); + layer_rename->connect("id_pressed", callable_mp(this, &EditorPropertyLayersGrid::_rename_pressed)); +} + +Size2 EditorPropertyLayersGrid::get_grid_size() const { + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); + return Vector2(0, font->get_height(font_size) * 3); +} + +void EditorPropertyLayersGrid::set_read_only(bool p_read_only) { + read_only = p_read_only; +} + +Size2 EditorPropertyLayersGrid::get_minimum_size() const { + Size2 min_size = get_grid_size(); + + // Add extra rows when expanded. + if (expanded) { + const int bsize = (min_size.height * 80 / 100) / 2; + for (int i = 0; i < expansion_rows; ++i) { + min_size.y += 2 * (bsize + 1) + 3; + } } -public: - uint32_t value = 0; - int layer_group_size = 0; - int layer_count = 0; - Vector names; - Vector tooltips; + return min_size; +} - void set_read_only(bool p_read_only) { - read_only = p_read_only; +String EditorPropertyLayersGrid::get_tooltip(const Point2 &p_pos) const { + for (int i = 0; i < flag_rects.size(); i++) { + if (i < tooltips.size() && flag_rects[i].has_point(p_pos)) { + return tooltips[i]; + } } + return String(); +} - virtual Size2 get_minimum_size() const override { - Size2 min_size = get_grid_size(); - - // Add extra rows when expanded. - if (expanded) { - const int bsize = (min_size.height * 80 / 100) / 2; - for (int i = 0; i < expansion_rows; ++i) { - min_size.y += 2 * (bsize + 1) + 3; - } +void EditorPropertyLayersGrid::gui_input(const Ref &p_ev) { + if (read_only) { + return; + } + const Ref mm = p_ev; + if (mm.is_valid()) { + bool expand_was_hovered = expand_hovered; + expand_hovered = expand_rect.has_point(mm->get_position()); + if (expand_hovered != expand_was_hovered) { + update(); } - return min_size; - } - - virtual String get_tooltip(const Point2 &p_pos) const override { - for (int i = 0; i < flag_rects.size(); i++) { - if (i < tooltips.size() && flag_rects[i].has_point(p_pos)) { - return tooltips[i]; - } - } - return String(); - } - - void gui_input(const Ref &p_ev) override { - if (read_only) { - return; - } - const Ref mm = p_ev; - if (mm.is_valid()) { - bool expand_was_hovered = expand_hovered; - expand_hovered = expand_rect.has_point(mm->get_position()); - if (expand_hovered != expand_was_hovered) { - update(); - } - - if (!expand_hovered) { - for (int i = 0; i < flag_rects.size(); i++) { - if (flag_rects[i].has_point(mm->get_position())) { - // Used to highlight the hovered flag in the layers grid. - hovered_index = i; - update(); - return; - } + if (!expand_hovered) { + for (int i = 0; i < flag_rects.size(); i++) { + if (flag_rects[i].has_point(mm->get_position())) { + // Used to highlight the hovered flag in the layers grid. + hovered_index = i; + update(); + return; } } + } - // Remove highlight when no square is hovered. + // Remove highlight when no square is hovered. + if (hovered_index != -1) { + hovered_index = -1; + update(); + } + + return; + } + + const Ref mb = p_ev; + if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { + if (hovered_index >= 0) { + // Toggle the flag. + // We base our choice on the hovered flag, so that it always matches the hovered flag. + if (value & (1 << hovered_index)) { + value &= ~(1 << hovered_index); + } else { + value |= (1 << hovered_index); + } + + emit_signal(SNAME("flag_changed"), value); + update(); + } else if (expand_hovered) { + expanded = !expanded; + update_minimum_size(); + update(); + } + } + if (mb.is_valid() && mb->get_button_index() == MouseButton::RIGHT && mb->is_pressed()) { + if (hovered_index >= 0) { + renamed_layer_index = hovered_index; + layer_rename->set_position(get_screen_position() + mb->get_position()); + layer_rename->reset_size(); + layer_rename->popup(); + } + } +} + +void EditorPropertyLayersGrid::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_DRAW: { + Size2 grid_size = get_grid_size(); + grid_size.x = get_size().x; + + flag_rects.clear(); + + int prev_expansion_rows = expansion_rows; + expansion_rows = 0; + + const int bsize = (grid_size.height * 80 / 100) / 2; + const int h = bsize * 2 + 1; + + Color color = get_theme_color(read_only ? SNAME("disabled_highlight_color") : SNAME("highlight_color"), SNAME("Editor")); + + Color text_color = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_color"), SNAME("Editor")); + text_color.a *= 0.5; + + Color text_color_on = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_hover_color"), SNAME("Editor")); + text_color_on.a *= 0.7; + + const int vofs = (grid_size.height - h) / 2; + + int layer_index = 0; + int block_index = 0; + + Point2 arrow_pos; + + Point2 block_ofs(4, vofs); + + while (true) { + Point2 ofs = block_ofs; + + for (int i = 0; i < 2; i++) { + for (int j = 0; j < layer_group_size; j++) { + const bool on = value & (1 << layer_index); + Rect2 rect2 = Rect2(ofs, Size2(bsize, bsize)); + + color.a = on ? 0.6 : 0.2; + if (layer_index == hovered_index) { + // Add visual feedback when hovering a flag. + color.a += 0.15; + } + + draw_rect(rect2, color); + flag_rects.push_back(rect2); + + Ref font = get_theme_font(SNAME("font"), SNAME("Label")); + int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); + Vector2 offset; + offset.y = rect2.size.y * 0.75; + + draw_string(font, rect2.position + offset, itos(layer_index + 1), HORIZONTAL_ALIGNMENT_CENTER, rect2.size.x, font_size, on ? text_color_on : text_color); + + ofs.x += bsize + 1; + + ++layer_index; + } + + ofs.x = block_ofs.x; + ofs.y += bsize + 1; + } + + if (layer_index >= layer_count) { + if (!flag_rects.is_empty() && (expansion_rows == 0)) { + const Rect2 &last_rect = flag_rects[flag_rects.size() - 1]; + arrow_pos = last_rect.get_end(); + } + break; + } + + int block_size_x = layer_group_size * (bsize + 1); + block_ofs.x += block_size_x + 3; + + if (block_ofs.x + block_size_x + 12 > grid_size.width) { + // Keep last valid cell position for the expansion icon. + if (!flag_rects.is_empty() && (expansion_rows == 0)) { + const Rect2 &last_rect = flag_rects[flag_rects.size() - 1]; + arrow_pos = last_rect.get_end(); + } + ++expansion_rows; + + if (expanded) { + // Expand grid to next line. + block_ofs.x = 4; + block_ofs.y += 2 * (bsize + 1) + 3; + } else { + // Skip remaining blocks. + break; + } + } + + ++block_index; + } + + if ((expansion_rows != prev_expansion_rows) && expanded) { + update_minimum_size(); + } + + if ((expansion_rows == 0) && (layer_index == layer_count)) { + // Whole grid was drawn, no need for expansion icon. + break; + } + + Ref arrow = get_theme_icon(SNAME("arrow"), SNAME("Tree")); + ERR_FAIL_COND(arrow.is_null()); + + Color arrow_color = get_theme_color(SNAME("highlight_color"), SNAME("Editor")); + arrow_color.a = expand_hovered ? 1.0 : 0.6; + + arrow_pos.x += 2.0; + arrow_pos.y -= arrow->get_height(); + + Rect2 arrow_draw_rect(arrow_pos, arrow->get_size()); + expand_rect = arrow_draw_rect; + if (expanded) { + arrow_draw_rect.size.y *= -1.0; // Flip arrow vertically when expanded. + } + + RID ci = get_canvas_item(); + arrow->draw_rect(ci, arrow_draw_rect, false, arrow_color); + + } break; + + case NOTIFICATION_MOUSE_EXIT: { + if (expand_hovered) { + expand_hovered = false; + update(); + } if (hovered_index != -1) { hovered_index = -1; update(); } + } break; - return; - } - - const Ref mb = p_ev; - if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) { - if (hovered_index >= 0) { - // Toggle the flag. - // We base our choice on the hovered flag, so that it always matches the hovered flag. - if (value & (1 << hovered_index)) { - value &= ~(1 << hovered_index); - } else { - value |= (1 << hovered_index); - } - - emit_signal(SNAME("flag_changed"), value); - update(); - } else if (expand_hovered) { - expanded = !expanded; - update_minimum_size(); - update(); - } - } + default: + break; } +} - void _notification(int p_what) { - switch (p_what) { - case NOTIFICATION_DRAW: { - Size2 grid_size = get_grid_size(); - grid_size.x = get_size().x; +void EditorPropertyLayersGrid::set_flag(uint32_t p_flag) { + value = p_flag; + update(); +} - flag_rects.clear(); - - int prev_expansion_rows = expansion_rows; - expansion_rows = 0; - - const int bsize = (grid_size.height * 80 / 100) / 2; - const int h = bsize * 2 + 1; - - Color color = get_theme_color(read_only ? SNAME("disabled_highlight_color") : SNAME("highlight_color"), SNAME("Editor")); - - Color text_color = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_color"), SNAME("Editor")); - text_color.a *= 0.5; - - Color text_color_on = get_theme_color(read_only ? SNAME("disabled_font_color") : SNAME("font_hover_color"), SNAME("Editor")); - text_color_on.a *= 0.7; - - const int vofs = (grid_size.height - h) / 2; - - int layer_index = 0; - int block_index = 0; - - Point2 arrow_pos; - - Point2 block_ofs(4, vofs); - - while (true) { - Point2 ofs = block_ofs; - - for (int i = 0; i < 2; i++) { - for (int j = 0; j < layer_group_size; j++) { - const bool on = value & (1 << layer_index); - Rect2 rect2 = Rect2(ofs, Size2(bsize, bsize)); - - color.a = on ? 0.6 : 0.2; - if (layer_index == hovered_index) { - // Add visual feedback when hovering a flag. - color.a += 0.15; - } - - draw_rect(rect2, color); - flag_rects.push_back(rect2); - - Ref font = get_theme_font(SNAME("font"), SNAME("Label")); - int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Label")); - Vector2 offset; - offset.y = rect2.size.y * 0.75; - - draw_string(font, rect2.position + offset, itos(layer_index + 1), HORIZONTAL_ALIGNMENT_CENTER, rect2.size.x, font_size, on ? text_color_on : text_color); - - ofs.x += bsize + 1; - - ++layer_index; - } - - ofs.x = block_ofs.x; - ofs.y += bsize + 1; - } - - if (layer_index >= layer_count) { - if (!flag_rects.is_empty() && (expansion_rows == 0)) { - const Rect2 &last_rect = flag_rects[flag_rects.size() - 1]; - arrow_pos = last_rect.get_end(); - } - break; - } - - int block_size_x = layer_group_size * (bsize + 1); - block_ofs.x += block_size_x + 3; - - if (block_ofs.x + block_size_x + 12 > grid_size.width) { - // Keep last valid cell position for the expansion icon. - if (!flag_rects.is_empty() && (expansion_rows == 0)) { - const Rect2 &last_rect = flag_rects[flag_rects.size() - 1]; - arrow_pos = last_rect.get_end(); - } - ++expansion_rows; - - if (expanded) { - // Expand grid to next line. - block_ofs.x = 4; - block_ofs.y += 2 * (bsize + 1) + 3; - } else { - // Skip remaining blocks. - break; - } - } - - ++block_index; - } - - if ((expansion_rows != prev_expansion_rows) && expanded) { - update_minimum_size(); - } - - if ((expansion_rows == 0) && (layer_index == layer_count)) { - // Whole grid was drawn, no need for expansion icon. - break; - } - - Ref arrow = get_theme_icon(SNAME("arrow"), SNAME("Tree")); - ERR_FAIL_COND(arrow.is_null()); - - Color arrow_color = get_theme_color(SNAME("highlight_color"), SNAME("Editor")); - arrow_color.a = expand_hovered ? 1.0 : 0.6; - - arrow_pos.x += 2.0; - arrow_pos.y -= arrow->get_height(); - - Rect2 arrow_draw_rect(arrow_pos, arrow->get_size()); - expand_rect = arrow_draw_rect; - if (expanded) { - arrow_draw_rect.size.y *= -1.0; // Flip arrow vertically when expanded. - } - - RID ci = get_canvas_item(); - arrow->draw_rect(ci, arrow_draw_rect, false, arrow_color); - - } break; - - case NOTIFICATION_MOUSE_EXIT: { - if (expand_hovered) { - expand_hovered = false; - update(); - } - if (hovered_index != -1) { - hovered_index = -1; - update(); - } - } break; - - default: - break; - } - } - - void set_flag(uint32_t p_flag) { - value = p_flag; - update(); - } - - static void _bind_methods() { - ADD_SIGNAL(MethodInfo("flag_changed", PropertyInfo(Variant::INT, "flag"))); - } -}; +void EditorPropertyLayersGrid::_bind_methods() { + ADD_SIGNAL(MethodInfo("flag_changed", PropertyInfo(Variant::INT, "flag"))); + ADD_SIGNAL(MethodInfo("rename_confirmed", PropertyInfo(Variant::INT, "layer_id"), PropertyInfo(Variant::STRING, "new_name"))); +} void EditorPropertyLayers::_set_read_only(bool p_read_only) { button->set_disabled(p_read_only); @@ -1063,7 +1095,7 @@ void EditorPropertyLayers::update_property() { } void EditorPropertyLayers::setup(LayerType p_layer_type) { - String basename; + layer_type = p_layer_type; int layer_group_size = 0; int layer_count = 0; switch (p_layer_type) { @@ -1127,6 +1159,13 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) { grid->layer_count = layer_count; } +void EditorPropertyLayers::set_layer_name(int p_index, const String &p_name) { + if (ProjectSettings::get_singleton()->has_setting(basename + vformat("/layer_%d", p_index + 1))) { + ProjectSettings::get_singleton()->set(basename + vformat("/layer_%d", p_index + 1), p_name); + ProjectSettings::get_singleton()->save(); + } +} + void EditorPropertyLayers::_button_pressed() { int layer_count = grid->layer_count; int layer_group_size = grid->layer_group_size; @@ -1159,6 +1198,10 @@ void EditorPropertyLayers::_menu_pressed(int p_menu) { _grid_changed(grid->value); } +void EditorPropertyLayers::_refresh_names() { + setup(layer_type); +} + void EditorPropertyLayers::_bind_methods() { } @@ -1168,6 +1211,7 @@ EditorPropertyLayers::EditorPropertyLayers() { add_child(hb); grid = memnew(EditorPropertyLayersGrid); grid->connect("flag_changed", callable_mp(this, &EditorPropertyLayers::_grid_changed)); + grid->connect("rename_confirmed", callable_mp(this, &EditorPropertyLayers::set_layer_name)); grid->set_h_size_flags(SIZE_EXPAND_FILL); hb->add_child(grid); @@ -1184,6 +1228,7 @@ EditorPropertyLayers::EditorPropertyLayers() { layers->set_hide_on_checkable_item_selection(false); layers->connect("id_pressed", callable_mp(this, &EditorPropertyLayers::_menu_pressed)); layers->connect("popup_hide", callable_mp((BaseButton *)button, &BaseButton::set_pressed), varray(false)); + EditorNode::get_singleton()->connect("project_settings_changed", callable_mp(this, &EditorPropertyLayers::_refresh_names)); } ///////////////////// INT ///////////////////////// diff --git a/editor/editor_properties.h b/editor/editor_properties.h index fdb0360d6be..9a16a78ff8a 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -279,7 +279,46 @@ public: EditorPropertyFlags(); }; -class EditorPropertyLayersGrid; +///////////////////// LAYERS ///////////////////////// + +class EditorPropertyLayersGrid : public Control { + GDCLASS(EditorPropertyLayersGrid, Control); + +private: + Vector flag_rects; + Rect2 expand_rect; + bool expand_hovered = false; + bool expanded = false; + int expansion_rows = 0; + int hovered_index = -1; + bool read_only = false; + int renamed_layer_index = -1; + PopupMenu *layer_rename; + ConfirmationDialog *rename_dialog; + LineEdit *rename_dialog_text; + + void _rename_pressed(int p_menu); + void _rename_operation_confirm(); + Size2 get_grid_size() const; + +protected: + void _notification(int p_what); + static void _bind_methods(); + +public: + uint32_t value = 0; + int layer_group_size = 0; + int layer_count = 0; + Vector names; + Vector tooltips; + + void set_read_only(bool p_read_only); + virtual Size2 get_minimum_size() const override; + virtual String get_tooltip(const Point2 &p_pos) const override; + void gui_input(const Ref &p_ev) override; + void set_flag(uint32_t p_flag); + EditorPropertyLayersGrid(); +}; class EditorPropertyLayers : public EditorProperty { GDCLASS(EditorPropertyLayers, EditorProperty); @@ -297,12 +336,14 @@ public: private: EditorPropertyLayersGrid *grid; void _grid_changed(uint32_t p_grid); + String basename; LayerType layer_type; PopupMenu *layers; Button *button; void _button_pressed(); void _menu_pressed(int p_menu); + void _refresh_names(); protected: virtual void _set_read_only(bool p_read_only) override; @@ -310,6 +351,7 @@ protected: public: void setup(LayerType p_layer_type); + void set_layer_name(int p_index, const String &p_name); virtual void update_property() override; EditorPropertyLayers(); };