mirror of
https://github.com/godotengine/godot
synced 2024-09-05 09:38:46 +00:00
Editor: Display deprecated/experimental messages in tooltips
This commit is contained in:
parent
3b1806182a
commit
a714cb9f65
|
@ -47,6 +47,7 @@
|
|||
#include "scene/gui/check_box.h"
|
||||
#include "scene/gui/label.h"
|
||||
#include "scene/gui/line_edit.h"
|
||||
#include "scene/gui/margin_container.h"
|
||||
#include "scene/gui/option_button.h"
|
||||
#include "scene/gui/popup_menu.h"
|
||||
#include "scene/gui/spin_box.h"
|
||||
|
@ -872,7 +873,13 @@ ConnectDialog::~ConnectDialog() {
|
|||
|
||||
Control *ConnectionsDockTree::make_custom_tooltip(const String &p_text) const {
|
||||
// If it's not a doc tooltip, fallback to the default one.
|
||||
return p_text.contains("::") ? nullptr : memnew(EditorHelpTooltip(p_text));
|
||||
if (p_text.contains("::")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EditorHelpBit *help_bit = memnew(EditorHelpBit(p_text));
|
||||
EditorHelpBitTooltip::show_tooltip(help_bit, const_cast<ConnectionsDockTree *>(this));
|
||||
return memnew(Control); // Make the standard tooltip invisible.
|
||||
}
|
||||
|
||||
struct _ConnectionsDockMethodInfoSort {
|
||||
|
@ -1458,8 +1465,8 @@ void ConnectionsDock::update_tree() {
|
|||
|
||||
section_item = tree->create_item(root);
|
||||
section_item->set_text(0, class_name);
|
||||
// `|` separators used in `EditorHelpTooltip` for formatting.
|
||||
section_item->set_tooltip_text(0, "class|" + doc_class_name + "||");
|
||||
// `|` separators used in `EditorHelpBit`.
|
||||
section_item->set_tooltip_text(0, "class|" + doc_class_name + "|");
|
||||
section_item->set_icon(0, class_icon);
|
||||
section_item->set_selectable(0, false);
|
||||
section_item->set_editable(0, false);
|
||||
|
@ -1490,8 +1497,8 @@ void ConnectionsDock::update_tree() {
|
|||
sinfo["args"] = argnames;
|
||||
signal_item->set_metadata(0, sinfo);
|
||||
signal_item->set_icon(0, get_editor_theme_icon(SNAME("Signal")));
|
||||
// `|` separators used in `EditorHelpTooltip` for formatting.
|
||||
signal_item->set_tooltip_text(0, "signal|" + doc_class_name + "|" + String(signal_name) + "|" + signame.trim_prefix(mi.name));
|
||||
// `|` separators used in `EditorHelpBit`.
|
||||
signal_item->set_tooltip_text(0, "signal|" + doc_class_name + "|" + String(signal_name));
|
||||
|
||||
// List existing connections.
|
||||
List<Object::Connection> existing_connections;
|
||||
|
|
|
@ -191,7 +191,7 @@ public:
|
|||
|
||||
//////////////////////////////////////////
|
||||
|
||||
// Custom `Tree` needed to use `EditorHelpTooltip` to display signal documentation.
|
||||
// Custom `Tree` needed to use `EditorHelpBit` to display signal documentation.
|
||||
class ConnectionsDockTree : public Tree {
|
||||
virtual Control *make_custom_tooltip(const String &p_text) const;
|
||||
};
|
||||
|
|
|
@ -202,8 +202,7 @@ void CreateDialog::_update_search() {
|
|||
select_type(_top_result(candidates, search_text));
|
||||
} else {
|
||||
favorite->set_disabled(true);
|
||||
help_bit->set_text(vformat(TTR("No results for \"%s\"."), search_text));
|
||||
help_bit->get_rich_text()->set_self_modulate(Color(1, 1, 1, 0.5));
|
||||
help_bit->set_custom_text(String(), String(), vformat(TTR("No results for \"%s\"."), search_text.replace("[", "[lb]")));
|
||||
get_ok_button()->set_disabled(true);
|
||||
search_options->deselect_all();
|
||||
}
|
||||
|
@ -502,17 +501,7 @@ void CreateDialog::select_type(const String &p_type, bool p_center_on_item) {
|
|||
to_select->select(0);
|
||||
search_options->scroll_to_item(to_select, p_center_on_item);
|
||||
|
||||
String text = help_bit->get_class_description(p_type);
|
||||
if (!text.is_empty()) {
|
||||
// Display both class name and description, since the help bit may be displayed
|
||||
// far away from the location (especially if the dialog was resized to be taller).
|
||||
help_bit->set_text(vformat("[b]%s[/b]: %s", p_type, text));
|
||||
help_bit->get_rich_text()->set_self_modulate(Color(1, 1, 1, 1));
|
||||
} else {
|
||||
// Use nested `vformat()` as translators shouldn't interfere with BBCode tags.
|
||||
help_bit->set_text(vformat(TTR("No description available for %s."), vformat("[b]%s[/b]", p_type)));
|
||||
help_bit->get_rich_text()->set_self_modulate(Color(1, 1, 1, 0.5));
|
||||
}
|
||||
help_bit->parse_symbol("class|" + p_type + "|");
|
||||
|
||||
favorite->set_disabled(false);
|
||||
favorite->set_pressed(favorite_list.has(p_type));
|
||||
|
@ -837,6 +826,7 @@ CreateDialog::CreateDialog() {
|
|||
vbc->add_margin_child(TTR("Matches:"), search_options, true);
|
||||
|
||||
help_bit = memnew(EditorHelpBit);
|
||||
help_bit->set_content_height_limits(64 * EDSCALE, 64 * EDSCALE);
|
||||
help_bit->connect("request_hide", callable_mp(this, &CreateDialog::_hide_requested));
|
||||
vbc->add_margin_child(TTR("Description:"), help_bit);
|
||||
|
||||
|
|
|
@ -593,6 +593,10 @@ void EditorBuildProfileManager::_action_confirm() {
|
|||
}
|
||||
}
|
||||
|
||||
void EditorBuildProfileManager::_hide_requested() {
|
||||
_cancel_pressed(); // From AcceptDialog.
|
||||
}
|
||||
|
||||
void EditorBuildProfileManager::_fill_classes_from(TreeItem *p_parent, const String &p_class, const String &p_selected) {
|
||||
TreeItem *class_item = class_list->create_item(p_parent);
|
||||
class_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
|
||||
|
@ -646,21 +650,10 @@ void EditorBuildProfileManager::_class_list_item_selected() {
|
|||
|
||||
Variant md = item->get_metadata(0);
|
||||
if (md.get_type() == Variant::STRING || md.get_type() == Variant::STRING_NAME) {
|
||||
String text = description_bit->get_class_description(md);
|
||||
if (!text.is_empty()) {
|
||||
// Display both class name and description, since the help bit may be displayed
|
||||
// far away from the location (especially if the dialog was resized to be taller).
|
||||
description_bit->set_text(vformat("[b]%s[/b]: %s", md, text));
|
||||
description_bit->get_rich_text()->set_self_modulate(Color(1, 1, 1, 1));
|
||||
} else {
|
||||
// Use nested `vformat()` as translators shouldn't interfere with BBCode tags.
|
||||
description_bit->set_text(vformat(TTR("No description available for %s."), vformat("[b]%s[/b]", md)));
|
||||
description_bit->get_rich_text()->set_self_modulate(Color(1, 1, 1, 0.5));
|
||||
}
|
||||
description_bit->parse_symbol("class|" + md.operator String() + "|");
|
||||
} else if (md.get_type() == Variant::INT) {
|
||||
String build_option_description = EditorBuildProfile::get_build_option_description(EditorBuildProfile::BuildOption((int)md));
|
||||
description_bit->set_text(vformat("[b]%s[/b]: %s", TTR(item->get_text(0)), TTRGET(build_option_description)));
|
||||
description_bit->get_rich_text()->set_self_modulate(Color(1, 1, 1, 1));
|
||||
description_bit->set_custom_text(TTR(item->get_text(0)), String(), TTRGET(build_option_description));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -864,7 +857,8 @@ EditorBuildProfileManager::EditorBuildProfileManager() {
|
|||
main_vbc->add_margin_child(TTR("Configure Engine Compilation Profile:"), class_list, true);
|
||||
|
||||
description_bit = memnew(EditorHelpBit);
|
||||
description_bit->set_custom_minimum_size(Size2(0, 80) * EDSCALE);
|
||||
description_bit->set_content_height_limits(80 * EDSCALE, 80 * EDSCALE);
|
||||
description_bit->connect("request_hide", callable_mp(this, &EditorBuildProfileManager::_hide_requested));
|
||||
main_vbc->add_margin_child(TTR("Description:"), description_bit, false);
|
||||
|
||||
confirm_dialog = memnew(ConfirmationDialog);
|
||||
|
|
|
@ -150,6 +150,7 @@ class EditorBuildProfileManager : public AcceptDialog {
|
|||
|
||||
void _profile_action(int p_action);
|
||||
void _action_confirm();
|
||||
void _hide_requested();
|
||||
|
||||
void _update_edited_profile();
|
||||
void _fill_classes_from(TreeItem *p_parent, const String &p_class, const String &p_selected);
|
||||
|
|
|
@ -493,6 +493,10 @@ void EditorFeatureProfileManager::_profile_selected(int p_what) {
|
|||
_update_selected_profile();
|
||||
}
|
||||
|
||||
void EditorFeatureProfileManager::_hide_requested() {
|
||||
_cancel_pressed(); // From AcceptDialog.
|
||||
}
|
||||
|
||||
void EditorFeatureProfileManager::_fill_classes_from(TreeItem *p_parent, const String &p_class, const String &p_selected) {
|
||||
TreeItem *class_item = class_list->create_item(p_parent);
|
||||
class_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
|
||||
|
@ -555,22 +559,10 @@ void EditorFeatureProfileManager::_class_list_item_selected() {
|
|||
|
||||
Variant md = item->get_metadata(0);
|
||||
if (md.get_type() == Variant::STRING || md.get_type() == Variant::STRING_NAME) {
|
||||
String text = description_bit->get_class_description(md);
|
||||
if (!text.is_empty()) {
|
||||
// Display both class name and description, since the help bit may be displayed
|
||||
// far away from the location (especially if the dialog was resized to be taller).
|
||||
description_bit->set_text(vformat("[b]%s[/b]: %s", md, text));
|
||||
description_bit->get_rich_text()->set_self_modulate(Color(1, 1, 1, 1));
|
||||
} else {
|
||||
// Use nested `vformat()` as translators shouldn't interfere with BBCode tags.
|
||||
description_bit->set_text(vformat(TTR("No description available for %s."), vformat("[b]%s[/b]", md)));
|
||||
description_bit->get_rich_text()->set_self_modulate(Color(1, 1, 1, 0.5));
|
||||
}
|
||||
description_bit->parse_symbol("class|" + md.operator String() + "|");
|
||||
} else if (md.get_type() == Variant::INT) {
|
||||
String feature_description = EditorFeatureProfile::get_feature_description(EditorFeatureProfile::Feature((int)md));
|
||||
description_bit->set_text(vformat("[b]%s[/b]: %s", TTR(item->get_text(0)), TTRGET(feature_description)));
|
||||
description_bit->get_rich_text()->set_self_modulate(Color(1, 1, 1, 1));
|
||||
|
||||
description_bit->set_custom_text(TTR(item->get_text(0)), String(), TTRGET(feature_description));
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
|
@ -991,8 +983,9 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() {
|
|||
property_list_vbc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
|
||||
description_bit = memnew(EditorHelpBit);
|
||||
description_bit->set_content_height_limits(80 * EDSCALE, 80 * EDSCALE);
|
||||
description_bit->connect("request_hide", callable_mp(this, &EditorFeatureProfileManager::_hide_requested));
|
||||
property_list_vbc->add_margin_child(TTR("Description:"), description_bit, false);
|
||||
description_bit->set_custom_minimum_size(Size2(0, 80) * EDSCALE);
|
||||
|
||||
property_list = memnew(Tree);
|
||||
property_list_vbc->add_margin_child(TTR("Extra Options:"), property_list, true);
|
||||
|
|
|
@ -142,6 +142,7 @@ class EditorFeatureProfileManager : public AcceptDialog {
|
|||
|
||||
void _profile_action(int p_action);
|
||||
void _profile_selected(int p_what);
|
||||
void _hide_requested();
|
||||
|
||||
String current_profile;
|
||||
void _update_profile_list(const String &p_select_profile = String());
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -35,9 +35,9 @@
|
|||
#include "editor/code_editor.h"
|
||||
#include "editor/doc_tools.h"
|
||||
#include "editor/editor_plugin.h"
|
||||
#include "scene/gui/margin_container.h"
|
||||
#include "scene/gui/menu_button.h"
|
||||
#include "scene/gui/panel_container.h"
|
||||
#include "scene/gui/popup.h"
|
||||
#include "scene/gui/rich_text_label.h"
|
||||
#include "scene/gui/split_container.h"
|
||||
#include "scene/gui/tab_container.h"
|
||||
|
@ -251,53 +251,91 @@ public:
|
|||
~EditorHelp();
|
||||
};
|
||||
|
||||
class EditorHelpBit : public MarginContainer {
|
||||
GDCLASS(EditorHelpBit, MarginContainer);
|
||||
class EditorHelpBit : public VBoxContainer {
|
||||
GDCLASS(EditorHelpBit, VBoxContainer);
|
||||
|
||||
inline static HashMap<StringName, String> doc_class_cache;
|
||||
inline static HashMap<StringName, HashMap<StringName, String>> doc_property_cache;
|
||||
inline static HashMap<StringName, HashMap<StringName, String>> doc_method_cache;
|
||||
inline static HashMap<StringName, HashMap<StringName, String>> doc_signal_cache;
|
||||
inline static HashMap<StringName, HashMap<StringName, String>> doc_theme_item_cache;
|
||||
struct DocType {
|
||||
String type;
|
||||
String enumeration;
|
||||
bool is_bitfield = false;
|
||||
};
|
||||
|
||||
RichTextLabel *rich_text = nullptr;
|
||||
struct ArgumentData {
|
||||
String name;
|
||||
DocType doc_type;
|
||||
String default_value;
|
||||
};
|
||||
|
||||
struct HelpData {
|
||||
String description;
|
||||
String deprecated_message;
|
||||
String experimental_message;
|
||||
DocType doc_type; // For method return type.
|
||||
Vector<ArgumentData> arguments; // For methods and signals.
|
||||
};
|
||||
|
||||
inline static HashMap<StringName, HelpData> doc_class_cache;
|
||||
inline static HashMap<StringName, HashMap<StringName, HelpData>> doc_property_cache;
|
||||
inline static HashMap<StringName, HashMap<StringName, HelpData>> doc_method_cache;
|
||||
inline static HashMap<StringName, HashMap<StringName, HelpData>> doc_signal_cache;
|
||||
inline static HashMap<StringName, HashMap<StringName, HelpData>> doc_theme_item_cache;
|
||||
|
||||
RichTextLabel *title = nullptr;
|
||||
RichTextLabel *content = nullptr;
|
||||
|
||||
String symbol_class_name;
|
||||
String symbol_type;
|
||||
String symbol_visible_type;
|
||||
String symbol_name;
|
||||
|
||||
HelpData help_data;
|
||||
|
||||
float content_min_height = 0.0;
|
||||
float content_max_height = 0.0;
|
||||
|
||||
static HelpData _get_class_help_data(const StringName &p_class_name);
|
||||
static HelpData _get_property_help_data(const StringName &p_class_name, const StringName &p_property_name);
|
||||
static HelpData _get_method_help_data(const StringName &p_class_name, const StringName &p_method_name);
|
||||
static HelpData _get_signal_help_data(const StringName &p_class_name, const StringName &p_signal_name);
|
||||
static HelpData _get_theme_item_help_data(const StringName &p_class_name, const StringName &p_theme_item_name);
|
||||
|
||||
void _add_type_to_title(const DocType &p_doc_type);
|
||||
void _update_labels();
|
||||
void _go_to_help(const String &p_what);
|
||||
void _meta_clicked(const String &p_select);
|
||||
|
||||
String text;
|
||||
|
||||
protected:
|
||||
String doc_class_name;
|
||||
String custom_description;
|
||||
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
String get_class_description(const StringName &p_class_name) const;
|
||||
String get_property_description(const StringName &p_class_name, const StringName &p_property_name) const;
|
||||
String get_method_description(const StringName &p_class_name, const StringName &p_method_name) const;
|
||||
String get_signal_description(const StringName &p_class_name, const StringName &p_signal_name) const;
|
||||
String get_theme_item_description(const StringName &p_class_name, const StringName &p_theme_item_name) const;
|
||||
void parse_symbol(const String &p_symbol);
|
||||
void set_custom_text(const String &p_type, const String &p_name, const String &p_description);
|
||||
void prepend_description(const String &p_text);
|
||||
|
||||
RichTextLabel *get_rich_text() { return rich_text; }
|
||||
void set_text(const String &p_text);
|
||||
void set_content_height_limits(float p_min, float p_max);
|
||||
void update_content_height();
|
||||
|
||||
EditorHelpBit();
|
||||
EditorHelpBit(const String &p_symbol = String());
|
||||
};
|
||||
|
||||
class EditorHelpTooltip : public EditorHelpBit {
|
||||
GDCLASS(EditorHelpTooltip, EditorHelpBit);
|
||||
// Standard tooltips do not allow you to hover over them.
|
||||
// This class is intended as a temporary workaround.
|
||||
class EditorHelpBitTooltip : public PopupPanel {
|
||||
GDCLASS(EditorHelpBitTooltip, PopupPanel);
|
||||
|
||||
String tooltip_text;
|
||||
Timer *timer = nullptr;
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
virtual void _input_from_window(const Ref<InputEvent> &p_event) override;
|
||||
|
||||
public:
|
||||
void parse_tooltip(const String &p_text);
|
||||
static void show_tooltip(EditorHelpBit *p_help_bit, Control *p_target);
|
||||
|
||||
EditorHelpTooltip(const String &p_text = String(), const String &p_custom_description = String());
|
||||
void popup_under_cursor();
|
||||
|
||||
EditorHelpBitTooltip(Control *p_target);
|
||||
};
|
||||
|
||||
#if defined(MODULE_GDSCRIPT_ENABLED) || defined(MODULE_MONO_ENABLED)
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "editor/plugins/script_editor_plugin.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
#include "editor/themes/editor_theme_manager.h"
|
||||
#include "scene/gui/margin_container.h"
|
||||
#include "scene/gui/spin_box.h"
|
||||
#include "scene/gui/texture_rect.h"
|
||||
#include "scene/property_utils.h"
|
||||
|
@ -916,34 +917,35 @@ void EditorProperty::_update_pin_flags() {
|
|||
}
|
||||
|
||||
Control *EditorProperty::make_custom_tooltip(const String &p_text) const {
|
||||
EditorHelpBit *tooltip = nullptr;
|
||||
|
||||
if (has_doc_tooltip) {
|
||||
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));
|
||||
}
|
||||
|
||||
String custom_warning;
|
||||
if (object->has_method("_get_property_warning")) {
|
||||
String warn = object->call("_get_property_warning", property);
|
||||
if (!warn.is_empty()) {
|
||||
String prev_text;
|
||||
if (tooltip == nullptr) {
|
||||
tooltip = memnew(EditorHelpBit());
|
||||
tooltip->set_text(p_text);
|
||||
tooltip->get_rich_text()->set_custom_minimum_size(Size2(360 * EDSCALE, 0));
|
||||
} else {
|
||||
prev_text = tooltip->get_rich_text()->get_text() + "\n";
|
||||
}
|
||||
tooltip->set_text(prev_text + "[b][color=" + get_theme_color(SNAME("warning_color")).to_html(false) + "]" + warn + "[/color][/b]");
|
||||
}
|
||||
custom_warning = object->call("_get_property_warning", property);
|
||||
}
|
||||
|
||||
return tooltip;
|
||||
if (has_doc_tooltip || !custom_warning.is_empty()) {
|
||||
EditorHelpBit *help_bit = memnew(EditorHelpBit);
|
||||
|
||||
if (has_doc_tooltip) {
|
||||
help_bit->parse_symbol(p_text);
|
||||
|
||||
const EditorInspector *inspector = get_parent_inspector();
|
||||
if (inspector) {
|
||||
const String custom_description = inspector->get_custom_property_description(p_text);
|
||||
if (!custom_description.is_empty()) {
|
||||
help_bit->prepend_description(custom_description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!custom_warning.is_empty()) {
|
||||
help_bit->prepend_description("[b][color=" + get_theme_color(SNAME("warning_color")).to_html(false) + "]" + custom_warning + "[/color][/b]");
|
||||
}
|
||||
|
||||
EditorHelpBitTooltip::show_tooltip(help_bit, const_cast<EditorProperty *>(this));
|
||||
return memnew(Control); // Make the standard tooltip invisible.
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void EditorProperty::menu_option(int p_option) {
|
||||
|
@ -1178,7 +1180,14 @@ void EditorInspectorCategory::_notification(int p_what) {
|
|||
}
|
||||
|
||||
Control *EditorInspectorCategory::make_custom_tooltip(const String &p_text) const {
|
||||
return doc_class_name.is_empty() ? nullptr : memnew(EditorHelpTooltip(p_text));
|
||||
// If it's not a doc tooltip, fallback to the default one.
|
||||
if (doc_class_name.is_empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EditorHelpBit *help_bit = memnew(EditorHelpBit(p_text));
|
||||
EditorHelpBitTooltip::show_tooltip(help_bit, const_cast<EditorInspectorCategory *>(this));
|
||||
return memnew(Control); // Make the standard tooltip invisible.
|
||||
}
|
||||
|
||||
Size2 EditorInspectorCategory::get_minimum_size() const {
|
||||
|
@ -2887,8 +2896,8 @@ void EditorInspector::update_tree() {
|
|||
category->doc_class_name = doc_name;
|
||||
|
||||
if (use_doc_hints) {
|
||||
// `|` separator used in `EditorHelpTooltip` for formatting.
|
||||
category->set_tooltip_text("class|" + doc_name + "||");
|
||||
// `|` separators used in `EditorHelpBit`.
|
||||
category->set_tooltip_text("class|" + doc_name + "|");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3368,15 +3377,15 @@ void EditorInspector::update_tree() {
|
|||
ep->connect("object_id_selected", callable_mp(this, &EditorInspector::_object_id_selected), CONNECT_DEFERRED);
|
||||
|
||||
if (use_doc_hints) {
|
||||
// `|` separator used in `EditorHelpTooltip` for formatting.
|
||||
// `|` separators used in `EditorHelpBit`.
|
||||
if (theme_item_name.is_empty()) {
|
||||
if (p.usage & PROPERTY_USAGE_INTERNAL) {
|
||||
ep->set_tooltip_text("internal_property|" + classname + "|" + property_prefix + p.name + "|");
|
||||
ep->set_tooltip_text("internal_property|" + classname + "|" + property_prefix + p.name);
|
||||
} else {
|
||||
ep->set_tooltip_text("property|" + classname + "|" + property_prefix + p.name + "|");
|
||||
ep->set_tooltip_text("property|" + classname + "|" + property_prefix + p.name);
|
||||
}
|
||||
} else {
|
||||
ep->set_tooltip_text("theme_item|" + classname + "|" + theme_item_name + "|");
|
||||
ep->set_tooltip_text("theme_item|" + classname + "|" + theme_item_name);
|
||||
}
|
||||
ep->has_doc_tooltip = true;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ class ConfirmationDialog;
|
|||
class EditorInspector;
|
||||
class EditorValidationPanel;
|
||||
class LineEdit;
|
||||
class MarginContainer;
|
||||
class OptionButton;
|
||||
class PanelContainer;
|
||||
class PopupMenu;
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "editor/inspector_dock.h"
|
||||
#include "editor/themes/editor_scale.h"
|
||||
#include "scene/gui/button.h"
|
||||
#include "scene/gui/margin_container.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
|
||||
bool EditorPropertyArrayObject::_set(const StringName &p_name, const Variant &p_value) {
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
class Button;
|
||||
class EditorSpinSlider;
|
||||
class MarginContainer;
|
||||
|
||||
class EditorPropertyArrayObject : public RefCounted {
|
||||
GDCLASS(EditorPropertyArrayObject, RefCounted);
|
||||
|
|
|
@ -2267,7 +2267,9 @@ ThemeTypeDialog::ThemeTypeDialog() {
|
|||
///////////////////////
|
||||
|
||||
Control *ThemeItemLabel::make_custom_tooltip(const String &p_text) const {
|
||||
return memnew(EditorHelpTooltip(p_text));
|
||||
EditorHelpBit *help_bit = memnew(EditorHelpBit(p_text));
|
||||
EditorHelpBitTooltip::show_tooltip(help_bit, const_cast<ThemeItemLabel *>(this));
|
||||
return memnew(Control); // Make the standard tooltip invisible.
|
||||
}
|
||||
|
||||
VBoxContainer *ThemeTypeEditor::_create_item_list(Theme::DataType p_data_type) {
|
||||
|
@ -2436,8 +2438,8 @@ HBoxContainer *ThemeTypeEditor::_create_property_control(Theme::DataType p_data_
|
|||
item_name->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
item_name->set_clip_text(true);
|
||||
item_name->set_text(p_item_name);
|
||||
// `|` separators used in `EditorHelpTooltip` for formatting.
|
||||
item_name->set_tooltip_text("theme_item|" + edited_type + "|" + p_item_name + "|");
|
||||
// `|` separators used in `EditorHelpBit`.
|
||||
item_name->set_tooltip_text("theme_item|" + edited_type + "|" + p_item_name);
|
||||
item_name->set_mouse_filter(Control::MOUSE_FILTER_STOP);
|
||||
item_name_container->add_child(item_name);
|
||||
|
||||
|
|
|
@ -321,7 +321,7 @@ public:
|
|||
ThemeTypeDialog();
|
||||
};
|
||||
|
||||
// Custom `Label` needed to use `EditorHelpTooltip` to display theme item documentation.
|
||||
// Custom `Label` needed to use `EditorHelpBit` to display theme item documentation.
|
||||
class ThemeItemLabel : public Label {
|
||||
virtual Control *make_custom_tooltip(const String &p_text) const;
|
||||
};
|
||||
|
|
|
@ -87,7 +87,7 @@ void PropertySelector::_update_search() {
|
|||
}
|
||||
|
||||
search_options->clear();
|
||||
help_bit->set_text("");
|
||||
help_bit->set_custom_text(String(), String(), String());
|
||||
|
||||
TreeItem *root = search_options->create_item();
|
||||
|
||||
|
@ -353,7 +353,7 @@ void PropertySelector::_confirmed() {
|
|||
}
|
||||
|
||||
void PropertySelector::_item_selected() {
|
||||
help_bit->set_text("");
|
||||
help_bit->set_custom_text(String(), String(), String());
|
||||
|
||||
TreeItem *item = search_options->get_selected();
|
||||
if (!item) {
|
||||
|
@ -372,25 +372,21 @@ void PropertySelector::_item_selected() {
|
|||
|
||||
String text;
|
||||
while (!class_type.is_empty()) {
|
||||
text = properties ? help_bit->get_property_description(class_type, name) : help_bit->get_method_description(class_type, name);
|
||||
if (!text.is_empty()) {
|
||||
break;
|
||||
if (properties) {
|
||||
if (ClassDB::has_property(class_type, name, true)) {
|
||||
help_bit->parse_symbol("property|" + class_type + "|" + name);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (ClassDB::has_method(class_type, name, true)) {
|
||||
help_bit->parse_symbol("method|" + class_type + "|" + name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// It may be from a parent class, keep looking.
|
||||
class_type = ClassDB::get_parent_class(class_type);
|
||||
}
|
||||
|
||||
if (!text.is_empty()) {
|
||||
// Display both property name and description, since the help bit may be displayed
|
||||
// far away from the location (especially if the dialog was resized to be taller).
|
||||
help_bit->set_text(vformat("[b]%s[/b]: %s", name, text));
|
||||
help_bit->get_rich_text()->set_self_modulate(Color(1, 1, 1, 1));
|
||||
} else {
|
||||
// Use nested `vformat()` as translators shouldn't interfere with BBCode tags.
|
||||
help_bit->set_text(vformat(TTR("No description available for %s."), vformat("[b]%s[/b]", name)));
|
||||
help_bit->get_rich_text()->set_self_modulate(Color(1, 1, 1, 0.5));
|
||||
}
|
||||
}
|
||||
|
||||
void PropertySelector::_hide_requested() {
|
||||
|
@ -569,8 +565,7 @@ PropertySelector::PropertySelector() {
|
|||
search_options->set_hide_folding(true);
|
||||
|
||||
help_bit = memnew(EditorHelpBit);
|
||||
vbc->add_margin_child(TTR("Description:"), help_bit);
|
||||
help_bit->get_rich_text()->set_fit_content(false);
|
||||
help_bit->get_rich_text()->set_custom_minimum_size(Size2(help_bit->get_rich_text()->get_minimum_size().x, 135 * EDSCALE));
|
||||
help_bit->set_content_height_limits(80 * EDSCALE, 80 * EDSCALE);
|
||||
help_bit->connect("request_hide", callable_mp(this, &PropertySelector::_hide_requested));
|
||||
vbc->add_margin_child(TTR("Description:"), help_bit);
|
||||
}
|
||||
|
|
|
@ -2158,6 +2158,28 @@ void EditorThemeManager::_populate_editor_styles(const Ref<EditorTheme> &p_theme
|
|||
p_theme->set_constant("text_highlight_v_padding", "EditorHelp", 2 * EDSCALE);
|
||||
}
|
||||
|
||||
// EditorHelpBitTitle.
|
||||
{
|
||||
Ref<StyleBoxFlat> style = p_config.tree_panel_style->duplicate();
|
||||
style->set_bg_color(p_config.dark_theme ? style->get_bg_color().lightened(0.04) : style->get_bg_color().darkened(0.04));
|
||||
style->set_border_color(p_config.dark_theme ? style->get_border_color().lightened(0.04) : style->get_border_color().darkened(0.04));
|
||||
style->set_corner_radius(CORNER_BOTTOM_LEFT, 0);
|
||||
style->set_corner_radius(CORNER_BOTTOM_RIGHT, 0);
|
||||
|
||||
p_theme->set_type_variation("EditorHelpBitTitle", "RichTextLabel");
|
||||
p_theme->set_stylebox("normal", "EditorHelpBitTitle", style);
|
||||
}
|
||||
|
||||
// EditorHelpBitContent.
|
||||
{
|
||||
Ref<StyleBoxFlat> style = p_config.tree_panel_style->duplicate();
|
||||
style->set_corner_radius(CORNER_TOP_LEFT, 0);
|
||||
style->set_corner_radius(CORNER_TOP_RIGHT, 0);
|
||||
|
||||
p_theme->set_type_variation("EditorHelpBitContent", "RichTextLabel");
|
||||
p_theme->set_stylebox("normal", "EditorHelpBitContent", style);
|
||||
}
|
||||
|
||||
// Asset Library.
|
||||
p_theme->set_stylebox("bg", "AssetLib", p_config.base_empty_style);
|
||||
p_theme->set_stylebox("panel", "AssetLib", p_config.content_panel_style);
|
||||
|
|
Loading…
Reference in a new issue