Skip to content

Editor: Add highlight around docks when dragging #106762

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

lodetrick
Copy link
Contributor

@lodetrick lodetrick commented May 23, 2025

Closes godotengine/godot-proposals#12489

Adds a highlight around docks when dragging that tells you whether you can drop a dock. Also increases the area to drop docks to the entire TabContainer.

There is multiple colors that the highlight could be depending on whether it is a valid dragging operation (say if you were trying to drag a vertical dock into the bottom panel), but currently no container is marked as horizontal so this won't go into effect.

Screen.Recording.2025-05-23.at.2.51.05.PM.mov

This PR also creates the EditorDockTabContainer class to contain the logic.
The primary issue that I ran into was that all the buttons and internal components in the docks stopped mouse input, so dragging and checking if the mouse was contained by the rect wouldn't work as expected (and in the case of the Scene Dock it would only work in the small margins in between buttons), which is why I pivoted to using input.

@lodetrick lodetrick requested review from a team as code owners May 23, 2025 22:46
@lodetrick lodetrick changed the title Improve editor dock dragging usability Add highlight around editor docks when dragging May 23, 2025
@lodetrick lodetrick changed the title Add highlight around editor docks when dragging Editor: Add highlight around docks when dragging May 24, 2025
@AThousandShips AThousandShips added this to the 4.x milestone May 24, 2025
Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

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

Tested locally, it works as expected. This is a nice usability improvement 🙂

My only concern is that the width of the drag border hint is a bit too wide by default. It also varies depending on the editor spacing preset chosen, and it'll be invisible with the Compact spacing preset:

Default

image

Spacious

image

Compact

image

I suggest using a fixed value that's identical to the standard focus outline (Math::round(2 * EDSCALE)).

@lodetrick
Copy link
Contributor Author

lodetrick commented May 24, 2025

Thanks for the tips! I changed the width to a constant, and removed the dock_margin variable because it was only used to keep track of the border width. I draw the highlight outside of the rect for it to not be obscured by the TabBar (I can't change the z-index of the TabBar because the tabbar background would draw over them), so it is slightly smaller on the edge of the window in the compact mode.

Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

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

Looks great now!

image

@lodetrick
Copy link
Contributor Author

Thanks for the tip on call_deferred(), that was really bugging me. I incorporated the rest of your suggestions into the code, and got rid of the unnecessary EditorDockTabContainer mentions.

@kitbdev
Copy link
Contributor

kitbdev commented May 28, 2025

The drop_data and other methods are intended to only be called from the Viewport, this is fighting with the drag and drop system, as can be seen with the cursor workaround.
I was imagining dynamically creating new Controls that cover the TabContainer's contents on drag start, this way we can have more drop targets than just in the TabContainers (eg. to move to dock slots with no tabs), the contents wouldn't receive their own can_drop, and it would work with the drag and drop system better.
Though I'm not sure if there are any problems with that approach, and I wanted to get a better idea of how floating docks could support it before trying it.

@lodetrick
Copy link
Contributor Author

lodetrick commented May 28, 2025

Thats a good idea, I'll play around with it. I think that floating docks right now are more about docks themselves rather than the TabContainers though, so I don't know if they should be supported.

@lodetrick
Copy link
Contributor Author

lodetrick commented May 28, 2025

Ok, I tried to create floating controls that would allow users to place docks in hidden TabContainers. The code for deciding on the rects was rather large. I am aware that when the bottom right dock slot of the left or right is unfilled it does look a bit weird. I'm curious what others think about this:

Screenshot 2025-05-28 at 4 11 30 AM

@lodetrick
Copy link
Contributor Author

There were a few visual changes, primarily that the dragging hints will only be shown when hoverred on, and the visual side of the rect is now fit to the TabContainer, but the interaction is not. The clip shows an example of this:

Screen.Recording.2025-05-28.at.10.45.16.AM.mov

int dock_hidden_size = 28 * EDSCALE;
int dock_hidden_offset = dock_hidden_size + 4 * EDSCALE;
Rect2 temp_dock_drag_rects[DOCK_SLOT_MAX];
temp_dock_drag_rects[DOCK_SLOT_LEFT_UL] = dock_slot[DOCK_SLOT_LEFT_UL]->get_global_rect();
Copy link
Contributor

Choose a reason for hiding this comment

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

This can just cover the contents, so the TabContainer drag and drop logic works the same as before, and dropping it on the contents just adds it to the end.
dock_slot[i]->get_current_tab_control()->get_global_rect();.

And this logic to set the rects should be from EditorDockManager's drag begin notification, so it only happens once instead of for each one.

Copy link
Contributor Author

@lodetrick lodetrick May 28, 2025

Choose a reason for hiding this comment

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

Unfortunately since EditorDockManager is an Object and not in the tree, it does not receive the drag notification. However, I already have safeguards against computing the information multiple times, it stores the output and has an early return if the output is already known for the current drag.

Although if I limit the drop rect to the child control, then the highlight won't appear when the mouse is over the tabbar unless I returned to using input(). What do you think about this?

Copy link
Contributor

Choose a reason for hiding this comment

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

If it doesn't get the notification, then it is fine. In the future we may want to move some dock management into a Control.

I think it's fine to not highlight when the mouse is over the TabBar, since it has its own drop highlight and it allows moving the tab to a different index.

Copy link
Contributor Author

@lodetrick lodetrick May 28, 2025

Choose a reason for hiding this comment

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

Actually thinking about it, I do think that we should override the TabBar drag and dropping. If we want to limit where the dock can be dropped (ie for different horizontal / vertical layouts), we need to change the behavior somewhat, and I think that this is the place. I might try and see if I can somehow update the TabBar's drop hint.

@lodetrick
Copy link
Contributor Author

It should be back to the original design from a user standpoint, but with a control as the backend, cleaning up the implementation a lot. There's a few changes that should be made once the EditorDock PR is merged, but until then it is good.

Comment on lines +63 to +64
int drop_tab = dock_manager->dock_slot[occupied_slot]->get_tab_bar()->get_closest_tab_idx_to_point(p_point);
dock_manager->_move_dock(dragged_dock, dock_manager->dock_slot[occupied_slot], drop_tab);
Copy link
Contributor

Choose a reason for hiding this comment

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

Dropping the tab on a dock should move it to the end by default, currently it never puts it at the end.
I think only when the tab is over the TabBar part should you be able to change the index.


for (int i = 0; i < DOCK_SLOT_MAX; i++) {
if (dock_slot[i]->is_visible_in_tree()) {
dock_drag_rects[i]->set_rect(dock_slot[i]->get_global_rect());
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm still not sure why the TabBar needs to be covered. For moving to closed slots in the future, it can either be on top of the TabBars or work around it, since dropping directly into the TabBar should probably always drop into the TabBar.
If it is needed for some reason, then the TabBar's tab drag index highlight should be recreated so you know what index the dock will be at when dropped.

@@ -7717,6 +7717,7 @@ EditorNode::EditorNode() {
editor_dock_manager->add_hsplit(main_hsplit);
editor_dock_manager->add_hsplit(right_hsplit);

// Register dock TabContainers.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// Register dock TabContainers.

This isn't really needed.

Comment on lines +226 to +229
dock_found = true;
}
}
if (!dock_found) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
dock_found = true;
}
}
if (!dock_found) {
break;
}
}
if (!dock_tab_dragged) {


set_as_top_level(true);
dock_drop_highlight.instantiate();
dock_drop_highlight->set_draw_center(false);
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this should draw a partially transparent center so it is more clear that it isn't for the dock's content?

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.

Improve editor dock dragging usability
5 participants