Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revamp how documentation tooltips work #82051

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 11 additions & 74 deletions editor/connections_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -835,35 +835,9 @@ ConnectDialog::~ConnectDialog() {

//////////////////////////////////////////

// Originally copied and adapted from EditorProperty, try to keep style in sync.
Control *ConnectionsDockTree::make_custom_tooltip(const String &p_text) const {
// `p_text` is expected to be something like this:
// - `class|Control||Control brief description.`;
// - `signal|gui_input|(event: InputEvent)|gui_input description.`;
// - `../../.. :: _on_gui_input()`.
// Note that the description can be empty or contain `|`.
PackedStringArray slices = p_text.split("|", true, 3);
if (slices.size() < 4) {
return nullptr; // Use default tooltip instead.
}
YeldhamDev marked this conversation as resolved.
Show resolved Hide resolved

String item_type = (slices[0] == "class") ? TTR("Class:") : TTR("Signal:");
String item_name = slices[1].strip_edges();
String item_params = slices[2].strip_edges();
String item_descr = slices[3].strip_edges();

String text = item_type + " [u][b]" + item_name + "[/b][/u]" + item_params + "\n";
if (item_descr.is_empty()) {
text += "[i]" + TTR("No description.") + "[/i]";
} else {
text += item_descr;
}

EditorHelpBit *help_bit = memnew(EditorHelpBit);
help_bit->get_rich_text()->set_custom_minimum_size(Size2(360 * EDSCALE, 1));
help_bit->set_text(text);

return help_bit;
// If it's not a doc tooltip, fallback to the default one.
return p_text.contains("::") ? nullptr : memnew(EditorHelpTooltip(p_text));
}

struct _ConnectionsDockMethodInfoSort {
Expand Down Expand Up @@ -1341,7 +1315,6 @@ void ConnectionsDock::update_tree() {
while (native_base != StringName()) {
String class_name;
String doc_class_name;
String class_brief;
Ref<Texture2D> class_icon;
List<MethodInfo> class_signals;

Expand All @@ -1355,21 +1328,8 @@ void ConnectionsDock::update_tree() {
if (doc_class_name.is_empty()) {
doc_class_name = script_base->get_path().trim_prefix("res://").quote();
}

// For a script class, the cache is filled each time.
if (!doc_class_name.is_empty()) {
if (descr_cache.has(doc_class_name)) {
descr_cache[doc_class_name].clear();
}
HashMap<String, DocData::ClassDoc>::ConstIterator F = doc_data->class_list.find(doc_class_name);
if (F) {
class_brief = F->value.brief_description;
for (int i = 0; i < F->value.signals.size(); i++) {
descr_cache[doc_class_name][F->value.signals[i].name] = F->value.signals[i].description;
}
} else {
doc_class_name = String();
}
if (!doc_class_name.is_empty() && !doc_data->class_list.find(doc_class_name)) {
doc_class_name = String();
}

class_icon = editor_data.get_script_icon(script_base);
Expand Down Expand Up @@ -1398,18 +1358,9 @@ void ConnectionsDock::update_tree() {
script_base = base;
} else {
class_name = native_base;
doc_class_name = class_name;

HashMap<String, DocData::ClassDoc>::ConstIterator F = doc_data->class_list.find(doc_class_name);
if (F) {
class_brief = DTR(F->value.brief_description);
// For a native class, the cache is filled once.
if (!descr_cache.has(doc_class_name)) {
for (int i = 0; i < F->value.signals.size(); i++) {
descr_cache[doc_class_name][F->value.signals[i].name] = DTR(F->value.signals[i].description);
}
}
} else {
doc_class_name = native_base;

if (!doc_data->class_list.find(doc_class_name)) {
doc_class_name = String();
}

Expand All @@ -1434,8 +1385,8 @@ void ConnectionsDock::update_tree() {

section_item = tree->create_item(root);
section_item->set_text(0, class_name);
// `|` separators used in `make_custom_tooltip()` for formatting.
section_item->set_tooltip_text(0, "class|" + class_name + "||" + class_brief);
// `|` separators used in `EditorHelpTooltip` for formatting.
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);
Expand Down Expand Up @@ -1466,22 +1417,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")));

// Set tooltip with the signal's documentation.
{
String descr;

HashMap<StringName, HashMap<StringName, String>>::ConstIterator G = descr_cache.find(doc_class_name);
if (G) {
HashMap<StringName, String>::ConstIterator F = G->value.find(signal_name);
if (F) {
descr = F->value;
}
}

// `|` separators used in `make_custom_tooltip()` for formatting.
signal_item->set_tooltip_text(0, "signal|" + String(signal_name) + "|" + signame.trim_prefix(mi.name) + "|" + descr);
}
// `|` separators used in `EditorHelpTooltip` for formatting.
signal_item->set_tooltip_text(0, "signal|" + doc_class_name + "|" + String(signal_name) + "|" + signame.trim_prefix(mi.name));

// List existing connections.
List<Object::Connection> existing_connections;
Expand Down
2 changes: 0 additions & 2 deletions editor/connections_dialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,6 @@ class ConnectionsDock : public VBoxContainer {
PopupMenu *slot_menu = nullptr;
LineEdit *search_box = nullptr;

HashMap<StringName, HashMap<StringName, String>> descr_cache;

void _filter_changed(const String &p_text);

void _make_or_edit_connection();
Expand Down
5 changes: 3 additions & 2 deletions editor/create_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,10 +500,11 @@ 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);

if (EditorHelp::get_doc_data()->class_list.has(p_type) && !DTR(EditorHelp::get_doc_data()->class_list[p_type].brief_description).is_empty()) {
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, DTR(EditorHelp::get_doc_data()->class_list[p_type].brief_description)));
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.
Expand Down
29 changes: 13 additions & 16 deletions editor/editor_build_profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,24 +646,21 @@ 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 class_name = md;
String class_description;

DocTools *dd = EditorHelp::get_doc_data();
HashMap<String, DocData::ClassDoc>::Iterator E = dd->class_list.find(class_name);
if (E) {
class_description = DTR(E->value.brief_description);
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->set_text(class_description);
} else if (md.get_type() == Variant::INT) {
int build_option_id = md;
String build_option_description = EditorBuildProfile::get_build_option_description(EditorBuildProfile::BuildOption(build_option_id));

description_bit->set_text(TTRGET(build_option_description));
return;
} else {
return;
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));
}
}

Expand Down
25 changes: 13 additions & 12 deletions editor/editor_feature_profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,21 +555,22 @@ 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 class_name = md;
String class_description;

DocTools *dd = EditorHelp::get_doc_data();
HashMap<String, DocData::ClassDoc>::Iterator E = dd->class_list.find(class_name);
if (E) {
class_description = DTR(E->value.brief_description);
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->set_text(class_description);
} else if (md.get_type() == Variant::INT) {
int feature_id = md;
String feature_description = EditorFeatureProfile::get_feature_description(EditorFeatureProfile::Feature(feature_id));
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_text(TTRGET(feature_description));
return;
} else {
return;
Expand Down
Loading