Skip to content

Commit

Permalink
Fix connecting a signal with a double click is too difficult
Browse files Browse the repository at this point in the history
  • Loading branch information
Hilderin committed Aug 2, 2024
1 parent 3978628 commit f8d4fad
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 10 deletions.
27 changes: 24 additions & 3 deletions editor/connections_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -899,9 +899,30 @@ Control *ConnectionsDockTree::make_custom_tooltip(const String &p_text) const {
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.
// Show the custom tooltip only if it is not already visible. With the parameter p_popup_flag set to false,
// the editor does not lose focus when showing the tooltip, and the Viewport will
// retrigger make_custom_tooltip every few seconds even if the custom tooltip is displayed.
if (!EditorHelpBitTooltip::is_tooltip_visible()) {
EditorHelpBit *help_bit = memnew(EditorHelpBit(p_text));
EditorHelpBitTooltip::show_tooltip(help_bit, const_cast<ConnectionsDockTree *>(this), false);
}

return _invisible_tooltip;
}

ConnectionsDockTree::ConnectionsDockTree() {
// Make the standard tooltip invisible.
// Ensure that the control is not visible so the default tooltip would
// not show at the same time as the custom one. The control is created only one time
// because the viewport will try to recreate the tooltip each couple of seconds
// add recall make_custom_tooltip each time because it thinks that there's not tooltip.
// This prevent to recreate a new control each time not nothing.
_invisible_tooltip = memnew(Control);
_invisible_tooltip->set_visible(false);
}

ConnectionsDockTree::~ConnectionsDockTree() {
memdelete(_invisible_tooltip);
}

struct _ConnectionsDockMethodInfoSort {
Expand Down
8 changes: 8 additions & 0 deletions editor/connections_dialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,15 @@ class ConnectDialog : public ConfirmationDialog {

// Custom `Tree` needed to use `EditorHelpBit` to display signal documentation.
class ConnectionsDockTree : public Tree {
private:
Control *_invisible_tooltip;

protected:
virtual Control *make_custom_tooltip(const String &p_text) const;

public:
ConnectionsDockTree();
~ConnectionsDockTree();
};

class ConnectionsDock : public VBoxContainer {
Expand Down
27 changes: 25 additions & 2 deletions editor/editor_help.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ const Vector<String> packed_array_types = {
DocTools *EditorHelp::doc = nullptr;
DocTools *EditorHelp::ext_doc = nullptr;

bool EditorHelpBitTooltip::_is_tooltip_visible = false;

static bool _attempt_doc_load(const String &p_class) {
// Docgen always happens in the outer-most class: it also generates docs for inner classes.
String outer_class = p_class.get_slice(".", 0);
Expand Down Expand Up @@ -3778,7 +3780,11 @@ void EditorHelpBitTooltip::_safe_queue_free() {
void EditorHelpBitTooltip::_target_gui_input(const Ref<InputEvent> &p_event) {
const Ref<InputEventMouse> mouse_event = p_event;
if (mouse_event.is_valid()) {
_start_timer();
if (!_first_mouse_event_done) {
_first_mouse_event_done = true;
} else {
_start_timer();
}
}
}

Expand All @@ -3790,6 +3796,9 @@ void EditorHelpBitTooltip::_notification(int p_what) {
case NOTIFICATION_WM_MOUSE_EXIT:
_start_timer();
break;
case NOTIFICATION_EXIT_TREE:
_is_tooltip_visible = false;
break;
}
}

Expand All @@ -3811,14 +3820,22 @@ void EditorHelpBitTooltip::_input_from_window(const Ref<InputEvent> &p_event) {
}
}

void EditorHelpBitTooltip::show_tooltip(EditorHelpBit *p_help_bit, Control *p_target) {
void EditorHelpBitTooltip::show_tooltip(EditorHelpBit *p_help_bit, Control *p_target, bool p_popup_flag) {
ERR_FAIL_NULL(p_help_bit);
EditorHelpBitTooltip *tooltip = memnew(EditorHelpBitTooltip(p_target));
p_help_bit->connect("request_hide", callable_mp(tooltip, &EditorHelpBitTooltip::_safe_queue_free));
tooltip->add_child(p_help_bit);
p_target->get_viewport()->add_child(tooltip);
p_help_bit->update_content_height();
// When FLAG_POPUP is false, it prevents the editor from losing focus when displaying the tooltip.
// This way, double-clicks are still available when showing tooltips.
tooltip->set_flag(Window::FLAG_POPUP, p_popup_flag);
tooltip->popup_under_cursor();
_is_tooltip_visible = true;
}

bool EditorHelpBitTooltip::is_tooltip_visible() {
return _is_tooltip_visible;
}

// Copy-paste from `Viewport::_gui_show_tooltip()`.
Expand Down Expand Up @@ -3858,6 +3875,12 @@ void EditorHelpBitTooltip::popup_under_cursor() {
r.position.y = vr.position.y;
}

// Reset the flag for the first mouse event.
// When FLAG_POPUP is false, there's always a first _target_gui_input event
// triggered when opening the popup and it's important to discard it,
// otherwise, the timer would be starter and the tooltip would close.
_first_mouse_event_done = false;

set_flag(Window::FLAG_NO_FOCUS, true);
popup(r);
}
Expand Down
5 changes: 4 additions & 1 deletion editor/editor_help.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,9 +325,11 @@ class EditorHelpBit : public VBoxContainer {
class EditorHelpBitTooltip : public PopupPanel {
GDCLASS(EditorHelpBitTooltip, PopupPanel);

static bool _is_tooltip_visible;
Timer *timer = nullptr;
int _pushing_input = 0;
bool _need_free = false;
bool _first_mouse_event_done = false;

void _start_timer();
void _safe_queue_free();
Expand All @@ -338,7 +340,8 @@ class EditorHelpBitTooltip : public PopupPanel {
virtual void _input_from_window(const Ref<InputEvent> &p_event) override;

public:
static void show_tooltip(EditorHelpBit *p_help_bit, Control *p_target);
static void show_tooltip(EditorHelpBit *p_help_bit, Control *p_target, bool p_popup_flag = true);
static bool is_tooltip_visible();

void popup_under_cursor();

Expand Down
15 changes: 11 additions & 4 deletions scene/main/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1457,17 +1457,24 @@ void Viewport::_gui_show_tooltip() {
return;
}

// 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(gui.tooltip_text);

// When the custom control is not visible, don't show any tooltip.
// This way, the custom tooltip from ConnectionsDockTree can create
// its own tooltip without conflicting with the default one, even an empty tooltip.
if (base_tooltip && !base_tooltip->is_visible()) {
return;
}

// Popup window which houses the tooltip content.
PopupPanel *panel = memnew(PopupPanel);
panel->set_theme_type_variation(SNAME("TooltipPanel"));

// Ensure no opaque background behind the panel as its StyleBox can be partially transparent (e.g. corners).
panel->set_transparent_background(true);

// 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(gui.tooltip_text);

// If no custom tooltip is given, use a default implementation.
if (!base_tooltip) {
gui.tooltip_label = memnew(Label);
Expand Down

0 comments on commit f8d4fad

Please sign in to comment.