You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-21 14:57:09 +00:00
Tooltips: Improve code clarity and docs
The return type for `_make_custom_tooltip` is clarified as Control, and users should make sure to return a visible node for proper size calculations. Moreover in the current master branch, a PopupPanel will be added as parent to the provided tooltip to make it a sub-window. Clarifies documentation for `Control._make_custom_tooltip`, and shows how to use the (until now undocumented) "TooltipPanel" and "TooltipLabel" theme types to style tooltips. Fixes #39677.
This commit is contained in:
@@ -161,6 +161,11 @@ ViewportTexture::~ViewportTexture() {
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
// Aliases used to provide custom styles to tooltips in the default
|
||||
// theme and editor theme.
|
||||
// TooltipPanel is also used for custom tooltips, while TooltipLabel
|
||||
// is only relevant for default tooltips.
|
||||
|
||||
class TooltipPanel : public PopupPanel {
|
||||
GDCLASS(TooltipPanel, PopupPanel);
|
||||
|
||||
@@ -175,6 +180,8 @@ public:
|
||||
TooltipLabel() {}
|
||||
};
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
Viewport::GUI::GUI() {
|
||||
embed_subwindows_hint = false;
|
||||
embedding_subwindows = false;
|
||||
@@ -188,7 +195,7 @@ Viewport::GUI::GUI() {
|
||||
mouse_over = nullptr;
|
||||
drag_mouse_over = nullptr;
|
||||
|
||||
tooltip = nullptr;
|
||||
tooltip_control = nullptr;
|
||||
tooltip_popup = nullptr;
|
||||
tooltip_label = nullptr;
|
||||
}
|
||||
@@ -1465,7 +1472,7 @@ void Viewport::_gui_sort_roots() {
|
||||
}
|
||||
|
||||
void Viewport::_gui_cancel_tooltip() {
|
||||
gui.tooltip = nullptr;
|
||||
gui.tooltip_control = nullptr;
|
||||
gui.tooltip_timer = -1;
|
||||
if (gui.tooltip_popup) {
|
||||
gui.tooltip_popup->queue_delete();
|
||||
@@ -1474,21 +1481,23 @@ void Viewport::_gui_cancel_tooltip() {
|
||||
}
|
||||
}
|
||||
|
||||
String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_which) {
|
||||
String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_tooltip_owner) {
|
||||
Vector2 pos = p_pos;
|
||||
String tooltip;
|
||||
|
||||
while (p_control) {
|
||||
tooltip = p_control->get_tooltip(pos);
|
||||
|
||||
if (r_which) {
|
||||
*r_which = p_control;
|
||||
if (r_tooltip_owner) {
|
||||
*r_tooltip_owner = p_control;
|
||||
}
|
||||
|
||||
if (tooltip != String()) {
|
||||
// If we found a tooltip, we stop here.
|
||||
if (!tooltip.empty()) {
|
||||
break;
|
||||
}
|
||||
pos = p_control->get_transform().xform(pos);
|
||||
|
||||
// Otherwise, we check parent controls unless some conditions prevent it.
|
||||
|
||||
if (p_control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
|
||||
break;
|
||||
@@ -1497,6 +1506,9 @@ String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Cont
|
||||
break;
|
||||
}
|
||||
|
||||
// Transform cursor pos for parent control.
|
||||
pos = p_control->get_transform().xform(pos);
|
||||
|
||||
p_control = p_control->get_parent_control();
|
||||
}
|
||||
|
||||
@@ -1504,34 +1516,40 @@ String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Cont
|
||||
}
|
||||
|
||||
void Viewport::_gui_show_tooltip() {
|
||||
if (!gui.tooltip) {
|
||||
if (!gui.tooltip_control) {
|
||||
return;
|
||||
}
|
||||
|
||||
Control *which = nullptr;
|
||||
String tooltip = _gui_get_tooltip(gui.tooltip, gui.tooltip->get_global_transform().xform_inv(gui.last_mouse_pos), &which);
|
||||
tooltip = tooltip.strip_edges();
|
||||
if (tooltip.length() == 0) {
|
||||
return; // bye
|
||||
// Get the Control under cursor and the relevant tooltip text, if any.
|
||||
Control *tooltip_owner = nullptr;
|
||||
String tooltip_text = _gui_get_tooltip(
|
||||
gui.tooltip_control,
|
||||
gui.tooltip_control->get_global_transform().xform_inv(gui.last_mouse_pos),
|
||||
&tooltip_owner);
|
||||
tooltip_text.strip_edges();
|
||||
if (tooltip_text.empty()) {
|
||||
return; // Nothing to show.
|
||||
}
|
||||
|
||||
// Remove previous popup if we change something.
|
||||
if (gui.tooltip_popup) {
|
||||
memdelete(gui.tooltip_popup);
|
||||
gui.tooltip_popup = nullptr;
|
||||
gui.tooltip_label = nullptr;
|
||||
}
|
||||
|
||||
if (!which) {
|
||||
if (!tooltip_owner) {
|
||||
return;
|
||||
}
|
||||
|
||||
Control *rp = which;
|
||||
|
||||
Control *base_tooltip = which->make_custom_tooltip(tooltip);
|
||||
// Controls can implement `make_custom_tooltip` to provide their own tooltip.
|
||||
// This should be a Control node which will be added as child to a TooltipPanel.
|
||||
Control *base_tooltip = tooltip_owner->make_custom_tooltip(tooltip_text);
|
||||
|
||||
// If no custom tooltip is given, use a default implementation.
|
||||
if (!base_tooltip) {
|
||||
gui.tooltip_label = memnew(TooltipLabel);
|
||||
gui.tooltip_label->set_text(tooltip);
|
||||
gui.tooltip_label->set_text(tooltip_text);
|
||||
base_tooltip = gui.tooltip_label;
|
||||
}
|
||||
|
||||
@@ -1545,10 +1563,7 @@ void Viewport::_gui_show_tooltip() {
|
||||
|
||||
gui.tooltip_popup = panel;
|
||||
|
||||
rp->add_child(gui.tooltip_popup);
|
||||
|
||||
//if (gui.tooltip) // Avoids crash when rapidly switching controls.
|
||||
// gui.tooltip_popup->set_scale(gui.tooltip->get_global_transform().get_scale());
|
||||
tooltip_owner->add_child(gui.tooltip_popup);
|
||||
|
||||
Point2 tooltip_offset = ProjectSettings::get_singleton()->get("display/mouse_cursor/tooltip_position_offset");
|
||||
Rect2 r(gui.tooltip_pos + tooltip_offset, gui.tooltip_popup->get_contents_minimum_size());
|
||||
@@ -1897,8 +1912,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
|
||||
}
|
||||
|
||||
_gui_cancel_tooltip();
|
||||
//gui.tooltip_popup->hide();
|
||||
|
||||
} else {
|
||||
if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == BUTTON_LEFT) {
|
||||
if (gui.drag_mouse_over) {
|
||||
@@ -2052,8 +2065,8 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
|
||||
bool is_tooltip_shown = false;
|
||||
|
||||
if (gui.tooltip_popup) {
|
||||
if (can_tooltip && gui.tooltip) {
|
||||
String tooltip = _gui_get_tooltip(over, gui.tooltip->get_global_transform().xform_inv(mpos));
|
||||
if (can_tooltip && gui.tooltip_control) {
|
||||
String tooltip = _gui_get_tooltip(over, gui.tooltip_control->get_global_transform().xform_inv(mpos));
|
||||
|
||||
if (tooltip.length() == 0) {
|
||||
_gui_cancel_tooltip();
|
||||
@@ -2078,14 +2091,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
|
||||
}
|
||||
|
||||
if (can_tooltip && !is_tooltip_shown) {
|
||||
gui.tooltip = over;
|
||||
gui.tooltip_pos = over->get_screen_transform().xform(pos); //(parent_xform * get_transform()).affine_inverse().xform(pos);
|
||||
gui.tooltip_control = over;
|
||||
gui.tooltip_pos = over->get_screen_transform().xform(pos);
|
||||
gui.tooltip_timer = gui.tooltip_delay;
|
||||
}
|
||||
}
|
||||
|
||||
//pos = gui.focus_inv_xform.xform(pos);
|
||||
|
||||
mm->set_position(pos);
|
||||
|
||||
Control::CursorShape cursor_shape = Control::CURSOR_ARROW;
|
||||
@@ -2436,7 +2447,7 @@ void Viewport::_gui_hide_control(Control *p_control) {
|
||||
if (gui.drag_mouse_over == p_control) {
|
||||
gui.drag_mouse_over = nullptr;
|
||||
}
|
||||
if (gui.tooltip == p_control) {
|
||||
if (gui.tooltip_control == p_control) {
|
||||
_gui_cancel_tooltip();
|
||||
}
|
||||
}
|
||||
@@ -2459,8 +2470,8 @@ void Viewport::_gui_remove_control(Control *p_control) {
|
||||
if (gui.drag_mouse_over == p_control) {
|
||||
gui.drag_mouse_over = nullptr;
|
||||
}
|
||||
if (gui.tooltip == p_control) {
|
||||
gui.tooltip = nullptr;
|
||||
if (gui.tooltip_control == p_control) {
|
||||
gui.tooltip_control = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3579,14 +3590,13 @@ Viewport::Viewport() {
|
||||
|
||||
disable_input = false;
|
||||
|
||||
//window tooltip
|
||||
// Window tooltip.
|
||||
gui.tooltip_timer = -1;
|
||||
|
||||
//gui.tooltip_timer->force_parent_owned();
|
||||
gui.tooltip_delay = GLOBAL_DEF("gui/timers/tooltip_delay_sec", 0.5);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/tooltip_delay_sec", PropertyInfo(Variant::FLOAT, "gui/timers/tooltip_delay_sec", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater")); // No negative numbers
|
||||
|
||||
gui.tooltip = nullptr;
|
||||
gui.tooltip_control = nullptr;
|
||||
gui.tooltip_label = nullptr;
|
||||
gui.drag_preview = nullptr;
|
||||
gui.drag_attempted = false;
|
||||
|
||||
Reference in New Issue
Block a user