Skip to content

Commit

Permalink
Code Editor: Add documentation tooltips
Browse files Browse the repository at this point in the history
  • Loading branch information
dalexeev committed Dec 11, 2024
1 parent 2136c6c commit 1a1075c
Show file tree
Hide file tree
Showing 26 changed files with 1,016 additions and 370 deletions.
33 changes: 0 additions & 33 deletions core/doc_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,28 +105,6 @@ void DocData::argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const
}
}

void DocData::property_doc_from_scriptmemberinfo(DocData::PropertyDoc &p_property, const ScriptMemberInfo &p_memberinfo) {
p_property.name = p_memberinfo.propinfo.name;
p_property.description = p_memberinfo.doc_string;

if (p_memberinfo.propinfo.type == Variant::OBJECT) {
p_property.type = p_memberinfo.propinfo.class_name;
} else if (p_memberinfo.propinfo.type == Variant::NIL && p_memberinfo.propinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
p_property.type = "Variant";
} else {
p_property.type = Variant::get_type_name(p_memberinfo.propinfo.type);
}

p_property.setter = p_memberinfo.setter;
p_property.getter = p_memberinfo.getter;

if (p_memberinfo.has_default_value && p_memberinfo.default_value.get_type() != Variant::OBJECT) {
p_property.default_value = get_default_value_string(p_memberinfo.default_value);
}

p_property.overridden = false;
}

void DocData::method_doc_from_methodinfo(DocData::MethodDoc &p_method, const MethodInfo &p_methodinfo, const String &p_desc) {
p_method.name = p_methodinfo.name;
p_method.description = p_desc;
Expand Down Expand Up @@ -170,14 +148,3 @@ void DocData::method_doc_from_methodinfo(DocData::MethodDoc &p_method, const Met
p_method.arguments.push_back(argument);
}
}

void DocData::constant_doc_from_variant(DocData::ConstantDoc &p_const, const StringName &p_name, const Variant &p_value, const String &p_desc) {
p_const.name = p_name;
p_const.value = p_value;
p_const.is_value_valid = (p_value.get_type() != Variant::OBJECT);
p_const.description = p_desc;
}

void DocData::signal_doc_from_methodinfo(DocData::MethodDoc &p_signal, const MethodInfo &p_methodinfo, const String &p_desc) {
return method_doc_from_methodinfo(p_signal, p_methodinfo, p_desc);
}
20 changes: 7 additions & 13 deletions core/doc_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,6 @@
#include "core/io/xml_parser.h"
#include "core/variant/variant.h"

struct ScriptMemberInfo {
PropertyInfo propinfo;
String doc_string;
StringName setter;
StringName getter;

bool has_default_value = false;
Variant default_value;
};

class DocData {
public:
struct ArgumentDoc {
Expand Down Expand Up @@ -276,6 +266,7 @@ class DocData {
String name;
String value;
bool is_value_valid = false;
String type;
String enumeration;
bool is_bitfield = false;
String description;
Expand All @@ -302,6 +293,10 @@ class DocData {
doc.is_value_valid = p_dict["is_value_valid"];
}

if (p_dict.has("type")) {
doc.type = p_dict["type"];
}

if (p_dict.has("enumeration")) {
doc.enumeration = p_dict["enumeration"];
if (p_dict.has("is_bitfield")) {
Expand Down Expand Up @@ -352,6 +347,8 @@ class DocData {

dict["is_value_valid"] = p_doc.is_value_valid;

dict["type"] = p_doc.type;

if (!p_doc.enumeration.is_empty()) {
dict["enumeration"] = p_doc.enumeration;
dict["is_bitfield"] = p_doc.is_bitfield;
Expand Down Expand Up @@ -981,10 +978,7 @@ class DocData {

static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo);
static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo);
static void property_doc_from_scriptmemberinfo(DocData::PropertyDoc &p_property, const ScriptMemberInfo &p_memberinfo);
static void method_doc_from_methodinfo(DocData::MethodDoc &p_method, const MethodInfo &p_methodinfo, const String &p_desc);
static void constant_doc_from_variant(DocData::ConstantDoc &p_const, const StringName &p_name, const Variant &p_value, const String &p_desc);
static void signal_doc_from_methodinfo(DocData::MethodDoc &p_signal, const MethodInfo &p_methodinfo, const String &p_desc);
};

#endif // DOC_DATA_H
36 changes: 29 additions & 7 deletions core/object/script_language.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ class Script : public Resource {
virtual Error reload(bool p_keep_state = false) = 0;

#ifdef TOOLS_ENABLED
virtual StringName get_doc_class_name() const = 0;
virtual Vector<DocData::ClassDoc> get_documentation() const = 0;
virtual String get_class_icon_path() const = 0;
virtual PropertyInfo get_class_category() const;
Expand Down Expand Up @@ -181,7 +182,7 @@ class Script : public Resource {
virtual int get_member_line(const StringName &p_member) const { return -1; }

virtual void get_constants(HashMap<StringName, Variant> *p_constants) {}
virtual void get_members(HashSet<StringName> *p_constants) {}
virtual void get_members(HashSet<StringName> *p_members) {}

virtual bool is_placeholder_fallback_enabled() const { return false; }

Expand Down Expand Up @@ -340,25 +341,46 @@ class ScriptLanguage : public Object {
virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<CodeCompletionOption> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; }

enum LookupResultType {
LOOKUP_RESULT_SCRIPT_LOCATION,
LOOKUP_RESULT_SCRIPT_LOCATION, // Use if none of the options below apply.
LOOKUP_RESULT_CLASS,
LOOKUP_RESULT_CLASS_CONSTANT,
LOOKUP_RESULT_CLASS_PROPERTY,
LOOKUP_RESULT_CLASS_METHOD,
LOOKUP_RESULT_CLASS_SIGNAL,
LOOKUP_RESULT_CLASS_ENUM,
LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE,
LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE, // Deprecated.
LOOKUP_RESULT_CLASS_ANNOTATION,
LOOKUP_RESULT_MAX
LOOKUP_RESULT_LOCAL_CONSTANT,
LOOKUP_RESULT_LOCAL_VARIABLE,
LOOKUP_RESULT_MAX,
};

struct LookupResult {
LookupResultType type;
Ref<Script> script;

// For `CLASS_*`.
String class_name;
String class_member;
String class_path;
int location;

// For `LOCAL_*`.
String description;
bool is_deprecated = false;
String deprecated_message;
bool is_experimental = false;
String experimental_message;

// For `LOCAL_*`.
String doc_type;
String enumeration;
bool is_bitfield = false;

// For `LOCAL_*`.
String value;

// `SCRIPT_LOCATION` and `LOCAL_*` must have, `CLASS_*` can have.
Ref<Script> script;
String script_path;
int location = -1;
};

virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) { return ERR_UNAVAILABLE; }
Expand Down
5 changes: 4 additions & 1 deletion core/object/script_language_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ void ScriptExtension::_bind_methods() {
GDVIRTUAL_BIND(_set_source_code, "code");
GDVIRTUAL_BIND(_reload, "keep_state");

GDVIRTUAL_BIND(_get_doc_class_name);
GDVIRTUAL_BIND(_get_documentation);
GDVIRTUAL_BIND(_get_class_icon_path);

Expand Down Expand Up @@ -169,8 +170,10 @@ void ScriptLanguageExtension::_bind_methods() {
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_METHOD);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_SIGNAL);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_ENUM);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE); // Deprecated.
BIND_ENUM_CONSTANT(LOOKUP_RESULT_CLASS_ANNOTATION);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_LOCAL_CONSTANT);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_LOCAL_VARIABLE);
BIND_ENUM_CONSTANT(LOOKUP_RESULT_MAX);

BIND_ENUM_CONSTANT(LOCATION_LOCAL);
Expand Down
40 changes: 28 additions & 12 deletions core/object/script_language_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,16 @@ class ScriptExtension : public Script {
EXBIND1(set_source_code, const String &)
EXBIND1R(Error, reload, bool)

GDVIRTUAL0RC_REQUIRED(StringName, _get_doc_class_name)
GDVIRTUAL0RC_REQUIRED(TypedArray<Dictionary>, _get_documentation)
GDVIRTUAL0RC(String, _get_class_icon_path)
#ifdef TOOLS_ENABLED
virtual StringName get_doc_class_name() const override {
StringName ret;
GDVIRTUAL_CALL(_get_doc_class_name, ret);
return ret;
}

virtual Vector<DocData::ClassDoc> get_documentation() const override {
TypedArray<Dictionary> doc;
GDVIRTUAL_CALL(_get_documentation, doc);
Expand Down Expand Up @@ -454,22 +461,31 @@ class ScriptLanguageExtension : public ScriptLanguage {
virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) override {
Dictionary ret;
GDVIRTUAL_CALL(_lookup_code, p_code, p_symbol, p_path, p_owner, ret);
if (!ret.has("result")) {
return ERR_UNAVAILABLE;
}

ERR_FAIL_COND_V(!ret.has("result"), ERR_UNAVAILABLE);
const Error result = Error(int(ret["result"]));

ERR_FAIL_COND_V(!ret.has("type"), ERR_UNAVAILABLE);
r_result.type = LookupResultType(int(ret["type"]));
ERR_FAIL_COND_V(!ret.has("script"), ERR_UNAVAILABLE);
r_result.script = ret["script"];
ERR_FAIL_COND_V(!ret.has("class_name"), ERR_UNAVAILABLE);
r_result.class_name = ret["class_name"];
ERR_FAIL_COND_V(!ret.has("class_path"), ERR_UNAVAILABLE);
r_result.class_path = ret["class_path"];
ERR_FAIL_COND_V(!ret.has("location"), ERR_UNAVAILABLE);
r_result.location = ret["location"];

Error result = Error(int(ret["result"]));
r_result.class_name = ret.get("class_name", "");
r_result.class_member = ret.get("class_member", "");

r_result.description = ret.get("description", "");
r_result.is_deprecated = ret.get("is_deprecated", false);
r_result.deprecated_message = ret.get("deprecated_message", "");
r_result.is_deprecated = ret.get("is_deprecated", false);
r_result.experimental_message = ret.get("experimental_message", "");

r_result.doc_type = ret.get("doc_type", "");
r_result.enumeration = ret.get("enumeration", "");
r_result.is_bitfield = ret.get("is_bitfield", false);

r_result.script = ret.get("script", Ref<Script>());
r_result.script_path = ret.get("script_path", "");
r_result.location = ret.get("location", -1);

r_result.value = ret.get("value", "");

return result;
}
Expand Down
13 changes: 13 additions & 0 deletions doc/classes/CodeEdit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,9 @@
<member name="symbol_lookup_on_click" type="bool" setter="set_symbol_lookup_on_click_enabled" getter="is_symbol_lookup_on_click_enabled" default="false">
Set when a validated word from [signal symbol_validate] is clicked, the [signal symbol_lookup] should be emitted.
</member>
<member name="symbol_tooltip_on_hover" type="bool" setter="set_symbol_tooltip_on_hover_enabled" getter="is_symbol_tooltip_on_hover_enabled" default="false">
Set when a word is hovered, the [signal symbol_hovered] should be emitted.
</member>
<member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" overrides="TextEdit" enum="Control.TextDirection" default="1" />
</members>
<signals>
Expand All @@ -601,6 +604,15 @@
Emitted when the user requests code completion. This signal will not be sent if [method _request_code_completion] is overridden or [member code_completion_enabled] is [code]false[/code].
</description>
</signal>
<signal name="symbol_hovered">
<param index="0" name="symbol" type="String" />
<param index="1" name="line" type="int" />
<param index="2" name="column" type="int" />
<description>
Emitted when the user hovers over a symbol. Unlike [signal Control.mouse_entered], this signal is not emitted immediately, but when the cursor is over the symbol for [member ProjectSettings.gui/timers/tooltip_delay_sec] seconds.
[b]Note:[/b] [member symbol_tooltip_on_hover] must be [code]true[/code] for this signal to be emitted.
</description>
</signal>
<signal name="symbol_lookup">
<param index="0" name="symbol" type="String" />
<param index="1" name="line" type="int" />
Expand All @@ -613,6 +625,7 @@
<param index="0" name="symbol" type="String" />
<description>
Emitted when the user hovers over a symbol. The symbol should be validated and responded to, by calling [method set_symbol_lookup_word_as_valid].
[b]Note:[/b] [member symbol_lookup_on_click] must be [code]true[/code] for this signal to be emitted.
</description>
</signal>
</signals>
Expand Down
5 changes: 5 additions & 0 deletions doc/classes/ScriptExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<description>
</description>
</method>
<method name="_get_doc_class_name" qualifiers="virtual const">
<return type="StringName" />
<description>
</description>
</method>
<method name="_get_documentation" qualifiers="virtual const">
<return type="Dictionary[]" />
<description>
Expand Down
8 changes: 6 additions & 2 deletions doc/classes/ScriptLanguageExtension.xml
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,15 @@
</constant>
<constant name="LOOKUP_RESULT_CLASS_ENUM" value="6" enum="LookupResultType">
</constant>
<constant name="LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE" value="7" enum="LookupResultType">
<constant name="LOOKUP_RESULT_CLASS_TBD_GLOBALSCOPE" value="7" enum="LookupResultType" deprecated="">
</constant>
<constant name="LOOKUP_RESULT_CLASS_ANNOTATION" value="8" enum="LookupResultType">
</constant>
<constant name="LOOKUP_RESULT_MAX" value="9" enum="LookupResultType">
<constant name="LOOKUP_RESULT_LOCAL_CONSTANT" value="9" enum="LookupResultType">
</constant>
<constant name="LOOKUP_RESULT_LOCAL_VARIABLE" value="10" enum="LookupResultType">
</constant>
<constant name="LOOKUP_RESULT_MAX" value="11" enum="LookupResultType">
</constant>
<constant name="LOCATION_LOCAL" value="0" enum="CodeCompletionLocation">
The option is local to the location of the code completion query - e.g. a local variable. Subsequent value of location represent options from the outer class, the exact value represent how far they are (in terms of inner classes).
Expand Down
2 changes: 1 addition & 1 deletion editor/create_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,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->set_content_height_limits(80 * EDSCALE, 80 * EDSCALE);
help_bit->connect("request_hide", callable_mp(this, &CreateDialog::_hide_requested));
vbc->add_margin_child(TTR("Description:"), help_bit);

Expand Down
7 changes: 6 additions & 1 deletion editor/doc_tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,7 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
constant.name = E;
constant.value = itos(ClassDB::get_integer_constant(name, E));
constant.is_value_valid = true;
constant.type = "int";
constant.enumeration = ClassDB::get_integer_constant_enum(name, E);
constant.is_bitfield = ClassDB::is_enum_bitfield(name, constant.enumeration);
c.constants.push_back(constant);
Expand Down Expand Up @@ -920,6 +921,7 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
constant.name = F;
constant.value = itos(Variant::get_enum_value(Variant::Type(i), E, F));
constant.is_value_valid = true;
constant.type = "int";
constant.enumeration = E;
c.constants.push_back(constant);
}
Expand All @@ -934,6 +936,7 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
Variant value = Variant::get_constant_value(Variant::Type(i), E);
constant.value = value.get_type() == Variant::INT ? itos(value) : value.get_construct_string().replace("\n", " ");
constant.is_value_valid = true;
constant.type = Variant::get_type_name(value.get_type());
c.constants.push_back(constant);
}
}
Expand All @@ -951,14 +954,15 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) {
DocData::ConstantDoc cd;
cd.name = CoreConstants::get_global_constant_name(i);
cd.type = "int";
cd.enumeration = CoreConstants::get_global_constant_enum(i);
cd.is_bitfield = CoreConstants::is_global_constant_bitfield(i);
if (!CoreConstants::get_ignore_value_in_docs(i)) {
cd.value = itos(CoreConstants::get_global_constant_value(i));
cd.is_value_valid = true;
} else {
cd.is_value_valid = false;
}
cd.enumeration = CoreConstants::get_global_constant_enum(i);
c.constants.push_back(cd);
}

Expand Down Expand Up @@ -1077,6 +1081,7 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
cd.name = E.first;
cd.value = E.second;
cd.is_value_valid = true;
cd.type = Variant::get_type_name(E.second.get_type());
c.constants.push_back(cd);
}

Expand Down
Loading

0 comments on commit 1a1075c

Please sign in to comment.