Add descriptions for tile properties

This commit is contained in:
kobewi 2023-12-06 23:10:32 +01:00
parent 2f73a059ce
commit 6e31c413b6
7 changed files with 86 additions and 11 deletions

View file

@ -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));
}

View file

@ -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 @@ protected:
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

View file

@ -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<String, String>::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;
}

View file

@ -505,6 +505,7 @@ class EditorInspector : public ScrollContainer {
HashMap<StringName, HashMap<StringName, String>> doc_path_cache;
HashSet<StringName> restart_request_props;
HashMap<String, String> custom_property_descriptions;
HashMap<ObjectID, int> scroll_cache;
@ -612,6 +613,9 @@ public:
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;

View file

@ -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 --

View file

@ -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;

View file

@ -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);