Skip to content

Commit

Permalink
Merge pull request #82051 from YeldhamDev/i_just_wanted_to_add_toolti…
Browse files Browse the repository at this point in the history
…ps_to_theme_items_man

Revamp how documentation tooltips work
  • Loading branch information
akien-mga committed Oct 4, 2023
2 parents d5db0e5 + ae91644 commit bb30c83
Show file tree
Hide file tree
Showing 10 changed files with 374 additions and 276 deletions.
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.
}

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

0 comments on commit bb30c83

Please sign in to comment.