From 6e31c413b60e0896d7cd6e88755f24a8fbfdfa2a Mon Sep 17 00:00:00 2001 From: kobewi Date: Wed, 6 Dec 2023 23:10:32 +0100 Subject: [PATCH] Add descriptions for tile properties --- editor/editor_help.cpp | 7 +++- editor/editor_help.h | 4 ++- editor/editor_inspector.cpp | 21 ++++++++++- editor/editor_inspector.h | 4 +++ .../tiles/tile_set_atlas_source_editor.cpp | 35 +++++++++++++++++-- editor/plugins/tiles/tile_set_editor.cpp | 11 ++++-- ...le_set_scenes_collection_source_editor.cpp | 15 ++++++-- 7 files changed, 86 insertions(+), 11 deletions(-) diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 10ab733c2bd5..ced964737800 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -2659,6 +2659,10 @@ String EditorHelpBit::get_class_description(const StringName &p_class_name) cons } String EditorHelpBit::get_property_description(const StringName &p_class_name, const StringName &p_property_name) const { + if (!custom_description.is_empty()) { + return custom_description; + } + if (doc_property_cache.has(p_class_name) && doc_property_cache[p_class_name].has(p_property_name)) { return doc_property_cache[p_class_name][p_property_name]; } @@ -2906,8 +2910,9 @@ void EditorHelpTooltip::parse_tooltip(const String &p_text) { set_text(formatted_text); } -EditorHelpTooltip::EditorHelpTooltip(const String &p_text) { +EditorHelpTooltip::EditorHelpTooltip(const String &p_text, const String &p_custom_description) { tooltip_text = p_text; + custom_description = p_custom_description; get_rich_text()->set_custom_minimum_size(Size2(360 * EDSCALE, 0)); } diff --git a/editor/editor_help.h b/editor/editor_help.h index d2d05a860318..1dddcf742230 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -247,6 +247,8 @@ class EditorHelpBit : public MarginContainer { String text; protected: + String custom_description; + static void _bind_methods(); void _notification(int p_what); @@ -274,7 +276,7 @@ class EditorHelpTooltip : public EditorHelpBit { public: void parse_tooltip(const String &p_text); - EditorHelpTooltip(const String &p_text = String()); + EditorHelpTooltip(const String &p_text = String(), const String &p_custom_description = String()); }; #endif // EDITOR_HELP_H diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 3fa90b3d8191..fcd62f894397 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -909,7 +909,13 @@ Control *EditorProperty::make_custom_tooltip(const String &p_text) const { EditorHelpBit *tooltip = nullptr; if (has_doc_tooltip) { - tooltip = memnew(EditorHelpTooltip(p_text)); + String custom_description; + + const EditorInspector *inspector = get_parent_inspector(); + if (inspector) { + custom_description = inspector->get_custom_property_description(p_text); + } + tooltip = memnew(EditorHelpTooltip(p_text, custom_description)); } if (object->has_method("_get_property_warning")) { @@ -4070,6 +4076,19 @@ String EditorInspector::get_property_prefix() const { return property_prefix; } +void EditorInspector::add_custom_property_description(const String &p_class, const String &p_property, const String &p_description) { + const String key = vformat("property|%s|%s|", p_class, p_property); + custom_property_descriptions[key] = p_description; +} + +String EditorInspector::get_custom_property_description(const String &p_property) const { + HashMap::ConstIterator E = custom_property_descriptions.find(p_property); + if (E) { + return E->value; + } + return ""; +} + void EditorInspector::set_object_class(const String &p_class) { object_class = p_class; } diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index e36606c0805b..d82b17f404df 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -505,6 +505,7 @@ class EditorInspector : public ScrollContainer { HashMap> doc_path_cache; HashSet restart_request_props; + HashMap custom_property_descriptions; HashMap scroll_cache; @@ -612,6 +613,9 @@ class EditorInspector : public ScrollContainer { void set_property_prefix(const String &p_prefix); String get_property_prefix() const; + void add_custom_property_description(const String &p_class, const String &p_property, const String &p_description); + String get_custom_property_description(const String &p_property) const; + void set_object_class(const String &p_class); String get_object_class() const; diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index a3fc6aa5f7ef..43f490534a52 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -2406,7 +2406,36 @@ void TileSetAtlasSourceEditor::_auto_remove_tiles() { void TileSetAtlasSourceEditor::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_READY: { + atlas_source_inspector->edit(atlas_source_proxy_object); + atlas_source_inspector->add_custom_property_description("TileSetAtlasSourceProxyObject", "id", TTR("The tile's unique identifier within this TileSet. Each tile stores its source ID, so changing one may make tiles invalid.")); + atlas_source_inspector->add_custom_property_description("TileSetAtlasSourceProxyObject", "name", TTR("The human-readable name for the atlas. Use a descriptive name here for organizational purposes (such as \"terrain\", \"decoration\", etc.).")); + atlas_source_inspector->add_custom_property_description("TileSetAtlasSourceProxyObject", "texture", TTR("The image from which the tiles will be created.")); + atlas_source_inspector->add_custom_property_description("TileSetAtlasSourceProxyObject", "margins", TTR("The margins on the image's edges that should not be selectable as tiles (in pixels). Increasing this can be useful if you download a tilesheet image that has margins on the edges (e.g. for attribution).")); + atlas_source_inspector->add_custom_property_description("TileSetAtlasSourceProxyObject", "separation", TTR("The separation between each tile on the atlas in pixels. Increasing this can be useful if the tilesheet image you're using contains guides (such as outlines between every tile).")); + atlas_source_inspector->add_custom_property_description("TileSetAtlasSourceProxyObject", "texture_region_size", TTR("The size of each tile on the atlas in pixels. In most cases, this should match the tile size defined in the TileMap property (although this is not strictly necessary).")); + atlas_source_inspector->add_custom_property_description("TileSetAtlasSourceProxyObject", "use_texture_padding", TTR("If checked, adds a 1-pixel transparent edge around each tile to prevent texture bleeding when filtering is enabled. It's recommended to leave this enabled unless you're running into rendering issues due to texture padding.")); + + tile_inspector->edit(tile_proxy_object); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "atlas_coords", TTR("The position of the tile's top-left corner in the atlas. The position and size must be within the atlas and can't overlap another tile.\nEach painted tile has associated atlas coords, so changing this property may cause your TileMaps to not display properly.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "size_in_atlas", TTR("The unit size of the tile.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "animation_columns", TTR("Number of columns for the animation grid. If number of columns is lower than number of frames, the animation will automatically adjust row count.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "animation_separation", TTR("The space (in tiles) between each frame of the animation.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "animation_speed", TTR("Animation speed in frames per second.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "animation_mode", TTR("Determines how animation will start. In \"Default\" mode all tiles start animating at the same frame. In \"Random Start Times\" mode, each tile starts animation with a random offset.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "flip_h", TTR("If [code]true[/code], the tile is horizontally flipped.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "flip_v", TTR("If [code]true[/code], the tile is vertically flipped.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "transpose", TTR("If [code]true[/code], the tile is rotated 90 degrees [i]counter-clockwise[/i] and then flipped vertically. In practice, this means that to rotate a tile by 90 degrees clockwise without flipping it, you should enable [b]Flip H[/b] and [b]Transpose[/b]. To rotate a tile by 180 degrees clockwise, enable [b]Flip H[/b] and [b]Flip V[/b]. To rotate a tile by 270 degrees clockwise, enable [b]Flip V[/b] and [b]Transpose[/b].")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "texture_origin", TTR("The origin to use for drawing the tile. This can be used to visually offset the tile compared to the base tile.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "modulate", TTR("The color multiplier to use when rendering the tile.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "material", TTR("The material to use for this tile. This can be used to apply a different blend mode or custom shaders to a single tile.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "z_index", TTR("The sorting order for this tile. Higher values will make the tile render in front of others on the same layer. The index is relative to the TileMap's own Z index.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "y_sort_origin", TTR("The vertical offset to use for tile sorting based on its Y coordinate (in pixels). This allows using layers as if they were on different height for top-down games. Adjusting this can help alleviate issues with sorting certain tiles. Only effective if Y Sort Enabled is true on the TileMap layer the tile is placed on.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "terrain_set", TTR("The index of the terrain set this tile belongs to. [code]-1[/code] means it will not be used in terrains.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "terrain", TTR("The index of the terrain inside the terrain set this tile belongs to. [code]-1[/code] means it will not be used in terrains.")); + tile_inspector->add_custom_property_description("AtlasTileProxyObject", "probability", TTR("The relative probability of this tile appearing when painting with \"Place Random Tile\" enabled.")); + } break; + case NOTIFICATION_THEME_CHANGED: { tool_setup_atlas_source_button->set_icon(get_editor_theme_icon(SNAME("Tools"))); tool_select_button->set_icon(get_editor_theme_icon(SNAME("ToolSelect"))); @@ -2526,7 +2555,7 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { tile_inspector = memnew(EditorInspector); tile_inspector->set_v_size_flags(SIZE_EXPAND_FILL); tile_inspector->set_show_categories(true); - tile_inspector->edit(tile_proxy_object); + tile_inspector->set_use_doc_hints(true); tile_inspector->set_use_folding(true); tile_inspector->connect("property_selected", callable_mp(this, &TileSetAtlasSourceEditor::_inspector_property_selected)); middle_vbox_container->add_child(tile_inspector); @@ -2580,8 +2609,8 @@ TileSetAtlasSourceEditor::TileSetAtlasSourceEditor() { atlas_source_inspector = memnew(EditorInspector); atlas_source_inspector->set_v_size_flags(SIZE_EXPAND_FILL); atlas_source_inspector->set_show_categories(true); + atlas_source_inspector->set_use_doc_hints(true); atlas_source_inspector->add_inspector_plugin(memnew(TileSourceInspectorPlugin)); - atlas_source_inspector->edit(atlas_source_proxy_object); middle_vbox_container->add_child(atlas_source_inspector); // -- Right side -- diff --git a/editor/plugins/tiles/tile_set_editor.cpp b/editor/plugins/tiles/tile_set_editor.cpp index 5bde1f754bb2..e18dd35f2adc 100644 --- a/editor/plugins/tiles/tile_set_editor.cpp +++ b/editor/plugins/tiles/tile_set_editor.cpp @@ -987,7 +987,7 @@ void TileSourceInspectorPlugin::_show_id_edit_dialog(Object *p_for_source) { void TileSourceInspectorPlugin::_confirm_change_id() { edited_source->set("id", id_input->get_value()); - id_label->set_text(vformat(TTR("ID: %d"), edited_source->get("id"))); // Use get(), because the provided ID might've been invalid. + id_label->set_text(itos(edited_source->get("id"))); // Use get(), because the provided ID might've been invalid. } bool TileSourceInspectorPlugin::can_handle(Object *p_object) { @@ -1001,17 +1001,22 @@ bool TileSourceInspectorPlugin::parse_property(Object *p_object, const Variant:: return true; } + EditorProperty *ep = memnew(EditorProperty); + HBoxContainer *hbox = memnew(HBoxContainer); hbox->set_alignment(BoxContainer::ALIGNMENT_CENTER); - id_label = memnew(Label(vformat(TTR("ID: %d"), value))); + id_label = memnew(Label(itos(value))); + id_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); hbox->add_child(id_label); Button *button = memnew(Button(TTR("Edit"))); + button->set_h_size_flags(Control::SIZE_EXPAND_FILL); hbox->add_child(button); button->connect("pressed", callable_mp(this, &TileSourceInspectorPlugin::_show_id_edit_dialog).bind(p_object)); - add_custom_control(hbox); + ep->add_child(hbox); + add_property_editor(p_path, ep); return true; } return false; diff --git a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp index eaf7a2b50b37..a683ff58bf24 100644 --- a/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_scenes_collection_source_editor.cpp @@ -357,6 +357,17 @@ void TileSetScenesCollectionSourceEditor::_update_scenes_list() { void TileSetScenesCollectionSourceEditor::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_READY: { + scenes_collection_source_inspector->edit(scenes_collection_source_proxy_object); + scenes_collection_source_inspector->add_custom_property_description("TileSetScenesCollectionProxyObject", "id", TTR("The tile's unique identifier within this TileSet. Each tile stores its source ID, so changing one may make tiles invalid.")); + scenes_collection_source_inspector->add_custom_property_description("TileSetScenesCollectionProxyObject", "name", TTR("The human-readable name for the scene collection. Use a descriptive name here for organizational purposes (such as \"obstacles\", \"decoration\", etc.).")); + + tile_inspector->edit(tile_proxy_object); + tile_inspector->add_custom_property_description("SceneTileProxyObject", "id", TTR("ID of the scene tile in the collection. Each painted tile has associated ID, so changing this property may cause your TileMaps to not display properly.")); + tile_inspector->add_custom_property_description("SceneTileProxyObject", "scene", TTR("Absolute path to the scene associated with this tile.")); + tile_inspector->add_custom_property_description("SceneTileProxyObject", "display_placeholder", TTR("If [code]true[/code], a placeholder marker will be displayed on top of the scene's preview. The marker is displayed anyway if the scene has no valid preview.")); + } break; + case NOTIFICATION_THEME_CHANGED: { scene_tile_add_button->set_icon(get_editor_theme_icon(SNAME("Add"))); scene_tile_delete_button->set_icon(get_editor_theme_icon(SNAME("Remove"))); @@ -525,8 +536,8 @@ TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() { scenes_collection_source_inspector = memnew(EditorInspector); scenes_collection_source_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); + scenes_collection_source_inspector->set_use_doc_hints(true); scenes_collection_source_inspector->add_inspector_plugin(memnew(TileSourceInspectorPlugin)); - scenes_collection_source_inspector->edit(scenes_collection_source_proxy_object); middle_vbox_container->add_child(scenes_collection_source_inspector); // Tile inspector. @@ -541,7 +552,7 @@ TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() { tile_inspector = memnew(EditorInspector); tile_inspector->set_vertical_scroll_mode(ScrollContainer::SCROLL_MODE_DISABLED); - tile_inspector->edit(tile_proxy_object); + tile_inspector->set_use_doc_hints(true); tile_inspector->set_use_folding(true); middle_vbox_container->add_child(tile_inspector);