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

Tooltips: Improve code clarity and docs #43280

Merged
merged 1 commit into from
Nov 3, 2020

Conversation

akien-mga
Copy link
Member

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.


Supersedes #43273.

My aim initially was to re-add flexibility to Control._make_custom_tooltip in what kind of tooltip popup will be created. In 3.2 you can pass any Control to be used as is, while in master popups derive Window, and thus the custom tooltip Control created by the user is wrapped in a TooltipPanel of type PopupPanel.

I thought some users might want more flexibility here, so I tried to make TooltipPanel part of the public API, and make it so it's no longer used by default in Viewport but should be returned by users in _make_custom_tooltip, if they want it (otherwise they could use another Window-derived control for a popup window, or even another type of Control for some in-game tooltip hints). But since Popup/PopupPanel now inherit Window, they're no longer Control so we have a type mismatch. In the end, I'm not sure the flexibility I was pursuing really corresponds to actual use cases that users have (it came from my own use case in https://github.com/akien-mga/godot-debug-watermark, but I think I can work with styling TooltipPanel as documented in this PR), so I prefer to wait for user feedback before exploring a potentially more flexible API.

@akien-mga akien-mga added enhancement documentation cherrypick:3.x Considered for cherry-picking into a future 3.x release topic:gui labels Nov 2, 2020
@akien-mga akien-mga added this to the 4.0 milestone Nov 2, 2020
@akien-mga akien-mga requested a review from a team as a code owner November 2, 2020 19:15
@akien-mga
Copy link
Member Author

CC @rxlecky as this is partly based on our discussion on #39677.

Comment on lines +1008 to +1015
[csharp]
var styleBox = new StyleBoxFlat();
styleBox.SetBgColor(new Color(1, 1, 0));
styleBox.SetBorderWidthAll(2);
// We assume here that the `Theme` property has been assigned a custom Theme beforehand.
Theme.SetStyleBox("panel", "TooltipPanel", styleBox);
Theme.SetColor("font_color", "TooltipLabel", new Color(0, 1, 1));
[/csharp]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tested my C# conversion yet. If anyone wants to give it a try and confirm that it works, that'd be welcome.

Note that you have to have a valid Theme, which can presumably be created with:

Theme = new Theme();
Theme.CopyDefaultTheme();

tooltip = tooltip.strip_edges();
if (tooltip.length() == 0) {
return; // bye
String tooltip_text = _gui_get_tooltip(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice clean up on this one, especially the confusing variable names. I wasn't sure when tooltip refers to the control and when to the string when I was looking at that code. Since you are making changes to that function, I'd also rename the which variable to something more descriptive. Perhaps tooltip_text_source? Or tooltip_text_source_node, since tooltip_text_source_control would be a bit confusing, haha.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about renaming which but since it's only used in local code (and a helper method) I didn't feel it was so problematic. But here goes, I renamed it to tooltip_owner.

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 = which->make_custom_tooltip(tooltip_text);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps should be named base_tooltip_control just to follow suit.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this would be really useful as it's only used locally and it's clear from it's type declaration. This would also open the door to renaming make_custom_tooltip and tons of tooltip-related methods which can either be about tooltip widgets or tooltip texts in the existing API.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. you are right. Better not go down the rabbit hole.

@rxlecky
Copy link
Contributor

rxlecky commented Nov 2, 2020

Changes look good to me all in all. The docs are definitely clearer now and the extra section on theming tooltips is great, I didn't know that.

Also, I'd like to bring up my argument from #39677 (comment) and say that if user returns a custom tooltip Control with visible = false and there is an edge case that causes unexpected behaviour under that conditions, we should just show empty TooltipPanel. That is more of an expected behaviour than showing a tooltip which is half-cropped by window edge. I, as a user, would consider that behaviour an engine bug, rather than user error. Even though the docs are now explicitly flagging this, there will be many people who won't read it and will instead report issues about supposedly bugged tooltips.

I feel like there are three main ways we can communicate with the user, in order of accessibility:

  1. Behaviour
  2. Output console
  3. Documentation

If we make the first point of contact, behaviour, confusing by showing unexpected, half-cropped tooltip, we haven't communicated the cause of the problem to the user very well. If we instead show empty tooltip panel, the user might either get a hint that their tooltip is not set to visible or it will prompt them to read the documentation where they will find answer to why tooltip is empty.

@akien-mga
Copy link
Member Author

Also, I'd like to bring up my argument from #39677 (comment) and say that if user returns a custom tooltip Control with visible = false and there is an edge case that causes unexpected behaviour under that conditions, we should just show empty TooltipPanel. That is more of an expected behaviour than showing a tooltip which is half-cropped by window edge. I, as a user, would consider that behaviour an engine bug, rather than user error. Even though the docs are now explicitly flagging this, there will be many people who won't read it and will instead report issues about supposedly bugged tooltips.

In the master branch, this is actually what happens. It's only the TooltipPanel created by the engine that gets show()-ed, the Control you pass from make_custom_tooltip() is not impacted. So if it's not visible, you will indeed see an empty panel (contrarily to 3.2 where show() is called on the custom Control).

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 godotengine#39677.
@rxlecky
Copy link
Contributor

rxlecky commented Nov 3, 2020

Oh, sorry, didn't realize that. That's good then. Perhaps we should replicate that behaviour in 3.2 when backporting this change.

@akien-mga akien-mga merged commit 0fc84b7 into godotengine:master Nov 3, 2020
@akien-mga akien-mga deleted the custom-tooltips-cleanup branch November 3, 2020 12:09
@akien-mga
Copy link
Member Author

Cherry-picked for 3.2.4.

Perhaps we should replicate that behaviour in 3.2 when backporting this change.

I chose not to as this could be considered a breaking change. IMO the fact that I was the one to report this issue even though I don't work on any serious Godot project apart from the engine itself shows that there are probably not too many users affected by this, so the documentation change should be enough for those.

@akien-mga akien-mga removed the cherrypick:3.x Considered for cherry-picking into a future 3.x release label Nov 11, 2020
gui.tooltip_control,
gui.tooltip_control->get_global_transform().xform_inv(gui.last_mouse_pos),
&tooltip_owner);
tooltip_text.strip_edges();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I introduced a bug here, this doesn't do anything as it's not assigned.

akien-mga added a commit to akien-mga/godot that referenced this pull request Jan 5, 2021
akien-mga added a commit to akien-mga/godot that referenced this pull request Jan 5, 2021
Fixes godotengine#43940, was a regression from godotengine#43280.

(cherry picked from commit a4af940)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Custom tooltip placement bug when using _make_custom_tooltip
2 participants