godot icon indicating copy to clipboard operation
godot copied to clipboard

Redesign Quick Open

Open stijn-h opened this issue 3 years ago • 39 comments

Closes https://github.com/godotengine/godot-proposals/issues/3788

2024-10-1

Features:

  • dynamic switching between list and grid view
  • support for filtering files from addons
  • history of recently opened files

stijn-h avatar Jan 13 '22 23:01 stijn-h

Still not decided on what kind of design to go with. Current one is most standard, but might have problems with long file paths.

For long file paths, ellipsis () can be used, with only the end of the path showing. Label has built-in support for automatic ellipsis in master, but I'm not sure if it can be used with right-aligned text to show only the end of a string. If this doesn't work, then you'll have to implement ellipsis manually.

Calinou avatar Jan 14 '22 00:01 Calinou

This PR is ready for review! There are a few gui/theme issues I can't figure out, but these aren't blocking issues and fixing it could increase the scope too much (for me at least), so I think it's better if they are be fixed later.

  • Good way to implement padding (and other things) in AcceptDialog, see https://github.com/godotengine/godot-proposals/issues/3832
  • Labels in list view could be better, see: #56915
  • On popup, sizing/positioning is sometimes wrong, probably related to some internal sizing override.
  • Currently all arrow keys are redirected to the results container to allow keyboard selection in grid view. I think it's better that way, but perhaps there is a way to switch focus off of the label and only then redirect the input.

I also looked into making the dialog a singleton. It makes some sense given that we allocate all these nodes for the results on startup. However, that only works if only one object subscribed to the quick open signal at any moment.

stijn-h avatar Feb 06 '22 16:02 stijn-h

The current looks of this dialog goes very against the overall visual style of the Godot editor:

  • The place holding the main contents should be the dark area, but instead it's the bottom part.
  • The icon for changing the view mode is at the bottom, when it would better placed to the right of the search bar.
  • The text of the items in list mode seem to be truncated for no good reason.
  • I think the bottom text should rather be a tooltip when hovering an item.
  • Not really a big fan of windows resizing by themselves.
  • There are no borders.

YeldhamDev avatar Feb 06 '22 19:02 YeldhamDev

What's the status of this? The remarks from the previous comment should be addressed. Also the PR needs rebase.

KoBeWi avatar Apr 08 '22 19:04 KoBeWi

What's the status of this?

The new dialog is functional, although there are still some things I don't like in the code. I've already mentioned a few styling issues, and I don't know how to fix them. Any help with theming/UI issues, or code review would be appreciated.

stijn-h avatar Apr 30 '22 17:04 stijn-h

The current looks of this dialog goes very against the overall visual style of the Godot editor:

To me, it's kind of clear that Godot's design might be lacking, which is why I redesigned this dialog in the first place. I designed it precisely without caring about what 'style' Godot has, only caring about what a Quick Open dialog needs.

  • The place holding the main contents should be the dark area, but instead it's the bottom part.

I'm okay with making the results part darker, but I think the bottom part should still be even darker. Here is what it looks like (ignore the white dialog border, I think it happened after rebasing, maybe a theme update?).

image

  • The icon for changing the view mode is at the bottom, when it would better placed to the right of the search bar.

No, that would not be better. It would no longer be a simple search bar, and even on it's own, that place is not a better location. There is free space at the bottom, and putting it there also doesn't break the simple design of search bar + search results.

  • The text of the items in list mode seem to be truncated for no good reason.

There is a good reason, as I've explained in the post above.

  • I think the bottom text should rather be a tooltip when hovering an item.

No.

  • Not really a big fan of windows resizing by themselves.

I don't think it works well with Godot's separate windows, but I have seen this style work in other software. It's up for debate whether we want to keep this or not.

  • There are no borders.

So?

stijn-h avatar Apr 30 '22 17:04 stijn-h

To me, it's kind of clear that Godot's design might be lacking, which is why I redesigned this dialog in the first place. I designed it precisely without caring about what 'style' Godot has, only caring about what a Quick Open dialog needs.

If you think Godot's overall UI design needs changes that's completely fine, but this sort of thing needs to be done as a whole and with proper discussion on what said changes should be (the proposals repository would be the perfect place for that).

Having a section of the editor look and act differently from the rest just adds confusion to the user, who expects things to behave consistently across the editor.

YeldhamDev avatar Apr 30 '22 18:04 YeldhamDev

If you think Godot's overall UI design needs changes that's completely fine, but this sort of thing needs to be done as a whole and with proper discussion on what said changes should be (the proposals repository would be the perfect place for that).

Top down, bottom up. Both is possible, but I have no interest in getting bogged down in discussions over what 'design rules' Godot should follow. I think it's more effective to try to design a small isolated component, and maybe others can take that further.

Actually, I think that because of this top down approach, Godot's style (which was supposed to have gotten a complete overhaul in 4.0 btw) has remained so stagnant, even when there is so much room for improvement.

stijn-h avatar Apr 30 '22 21:04 stijn-h

@stijn-h Just want to say that I think this change is brilliant.

I'd like to salvage this PR and apply the suggested modifications to get this merged. I personally agree with your stance on the UX but it's more important to me that this gets into the engine.

Let me know what you think.

realkotob avatar Jan 01 '23 06:01 realkotob

@stijn-h Just want to say that I think this change is brilliant.

I'd like to salvage this PR and apply the suggested modifications to get this merged. I personally agree with your stance on the UX but it's more important to me that this gets into the engine.

Let me know what you think.

Thanks, the current version is actually already a stripped down version of what i originally had in mind to get it merged quicker. But, other than the new merge conflicts, the only problem i had was fixing the supposed memory leaks. I think it had something to do with the label nodes. If you want to help with that it would be appreciated!

stijn-h avatar Jan 01 '23 09:01 stijn-h

@stijn-h Ok that is great! I will look into the memory leaks!

realkotob avatar Jan 01 '23 10:01 realkotob

@stijn-h I could not reproduce the memory leak when using the new quick open dialog, can you send me a minimum reproduction project or tell me how to reproduce it?

I found 2 leaks at exit but I don't think these are what you were referring to.

Relevant part of the logs:
leaks Report Version: 4.0, multi-line stacks
Process 77278: 177136 nodes malloced for 22779 KB
Process 77278: 2 leaks for 432 total leaked bytes.

STACK OF 1 INSTANCE OF 'ROOT LEAK: <malloc in RendererRD::TextureStorage::canvas_texture_get_uniform_set(RID, RenderingServer::CanvasItemTextureFilter, RenderingServer::CanvasItemTextureRepeat, RID, int, RID&, Vector2i&, Color&, bool&, bool&)>':
15  dyld                                  0x182f77e50 start + 2544
14  godot.macos.editor.arm64              0x104f04754 main + 404
13  godot.macos.editor.arm64              0x104ede6f4 OS_MacOS::run() + 116
12  godot.macos.editor.arm64              0x104f2fbd8 Main::iteration() + 988
11  godot.macos.editor.arm64              0x1083ee82c RenderingServerDefault::_draw(bool, double) + 328
10  godot.macos.editor.arm64              0x108379930 RendererViewport::draw_viewports() + 1968
9   godot.macos.editor.arm64              0x108378670 RendererViewport::_draw_viewport(RendererViewport::Viewport*) + 5632
8   godot.macos.editor.arm64              0x1083351a4 RendererCanvasCull::render_canvas(RID, RendererCanvasCull::Canvas*, Transform2D const&, RendererCanvasRender::Light*, RendererCanvasRender::Light*, Rect2 const&, RenderingServer::CanvasItemTextureFilter, RenderingServer::CanvasItemTextureRepeat, bool, bool, unsigned int) + 356
7   godot.macos.editor.arm64              0x1083329f0 RendererCanvasCull::_render_canvas_item_tree(RID, RendererCanvasCull::Canvas::ChildItem*, int, RendererCanvasCull::Item*, Transform2D const&, Rect2 const&, Color const&, RendererCanvasRender::Light*, RendererCanvasRender::Light*, RenderingServer::CanvasItemTextureFilter, RenderingServer::CanvasItemTextureRepeat, bool, unsigned int) + 580
6   godot.macos.editor.arm64              0x1084da2e8 RendererCanvasRenderRD::canvas_render_items(RID, RendererCanvasRender::Item*, Color const&, RendererCanvasRender::Light*, RendererCanvasRender::Light*, Transform2D const&, RenderingServer::CanvasItemTextureFilter, RenderingServer::CanvasItemTextureRepeat, bool, bool&) + 2728
5   godot.macos.editor.arm64              0x1084d965c RendererCanvasRenderRD::_render_items(RID, int, Transform2D const&, RendererCanvasRender::Light*, bool) + 884
4   godot.macos.editor.arm64              0x1084d6ddc RendererCanvasRenderRD::_render_item(long long, RID, RendererCanvasRender::Item const*, long long, Transform2D const&, RendererCanvasRender::Item*&, RendererCanvasRender::Light*, RendererCanvasRenderRD::PipelineVariants*) + 4888
3   godot.macos.editor.arm64              0x1084d8400 RendererCanvasRenderRD::_bind_canvas_texture(long long, RID, RenderingServer::CanvasItemTextureFilter, RenderingServer::CanvasItemTextureRepeat, RID&, RendererCanvasRenderRD::PushConstant&, Vector2&) + 164
2   godot.macos.editor.arm64              0x1086492bc RendererRD::TextureStorage::canvas_texture_get_uniform_set(RID, RenderingServer::CanvasItemTextureFilter, RenderingServer::CanvasItemTextureRepeat, RID, int, RID&, Vector2i&, Color&, bool&, bool&) + 216
1   godot.macos.editor.arm64              0x108a7e6c8 operator new(unsigned long, char const*) + 24
0   libsystem_malloc.dylib                0x18310ac20 _malloc_zone_malloc_instrumented_or_legacy + 128 
====
    1 (320 bytes) ROOT LEAK: <malloc in RendererRD::TextureStorage::canvas_texture_get_uniform_set(RID, RenderingServer::CanvasItemTextureFilter, RenderingServer::CanvasItemTextureRepeat, RID, int, RID&, Vector2i&, Color&, bool&, bool&) 0x2ab481bd0> [320]

STACK OF 1 INSTANCE OF 'ROOT LEAK: <CGEventSource>':
9   dyld                                  0x182f77e50 start + 2544
8   godot.macos.editor.arm64              0x104f04730 main + 368
7   godot.macos.editor.arm64              0x104f1822c Main::setup(char const*, int, char**, bool) + 36252
6   godot.macos.editor.arm64              0x104f1f524 Main::setup2(unsigned long long) + 1416
5   godot.macos.editor.arm64              0x104ef75e8 DisplayServerMacOS::create_func(String const&, DisplayServer::WindowMode, DisplayServer::VSyncMode, unsigned int, Vector2i const*, Vector2i const&, Error&) + 108
4   godot.macos.editor.arm64              0x104ef8a00 DisplayServerMacOS::DisplayServerMacOS(String const&, DisplayServer::WindowMode, DisplayServer::VSyncMode, unsigned int, Vector2i const*, Vector2i const&, Error&) + 392
3   com.apple.SkyLight                    0x188151238 SLEventSourceCreate + 296
2   com.apple.SkyLight                    0x188014434 SLTypeCreateInstance + 96
1   com.apple.CoreFoundation              0x183302934 _CFRuntimeCreateInstance + 756
0   libsystem_malloc.dylib                0x18310ac20 _malloc_zone_malloc_instrumented_or_legacy + 128 
====
    1 (112 bytes) ROOT LEAK: <CGEventSource 0x123968920> [112]

Using leaks -atExit -- ~/Personal/godot/bin/godot.macos.editor.arm64 -e

realkotob avatar Jan 01 '23 11:01 realkotob

I could not reproduce the memory leak when using the new quick open dialog, can you send me a minimum reproduction project or tell me how to reproduce it?

Well, seems like I fixed it after all. Anyway, I should've been more specific. The CI build failed because asan detected memory leaks. You could see it in the list of checks.

Click if you're interested about the issue and the solution

This is the old log: https://github.com/godotengine/godot/actions/runs/3818883371/jobs/6496060823

You can see in the logs that asan reports "direct leaks" on lines where a Label node is allocated in the QuickOpenResult item classes.

The new dialog works by creating a bunch of results upfront, then hiding them if they are not necessary. But in the CI test, the dialog was never opened, and so the result nodes were never added as a child to either the list view or grid view, and thus none of them were freed. As a fix, I added a deconstructor that frees all the nodes. Still not sure why there were only direct leaks in the label nodes, but maybe Im misunderstanding the tool.

Anyway, to given an update on what the design currently looks like:

List view was changed because I could not get the path next to the filename to work the way I wanted to. This is probably easier to read anyway. lijst3

Grid view now uses FlowContainer, which makes it possible to resize the window and have the columns update automatically. I also removed redirecting the left right arrow key events to the result container, because it interfered with moving the cursor in the searchbox. grid

All the issues I had found myself are solved, and so are I think most other issues that were raised. The PR was already open, but now that the CI has succeeded I think it's possible to review (although it will have to wait for 4.1 I guess).

stijn-h avatar Jan 01 '23 23:01 stijn-h

@stijn-h Awesome! Glad you figured it out and thanks for the detailed update.

I'm excited for this to happen 👍

realkotob avatar Jan 02 '23 03:01 realkotob

The merge might need to wait for 4.1, but the PR can be reviewed now.

I did a quick test and a few remarks:

  • is this intended that the dialog is empty when there is no search text? It should just display everything
  • the names in grid view are tiny image
  • same with paths in list view image While this is likely ok, the path at the bottom should be bigger.
  • "Search files by name" is a bit misleading, because it searches by the whole path

Overall the new dialog looks good to me.

EDIT: Some more notes:

  • why the class was moved to an entirely new file?
  • I wonder if include_addons shouldn't be toggleable with a button inside the dialog 🤔

KoBeWi avatar Jan 03 '23 14:01 KoBeWi

why the class was moved to an entirely new file?

@KoBeWi Not OP but I'm guessing because this dialog is likely to be expanded in the future and it'd be good to have it separate for neatness sake.

I wonder if include_addons shouldn't be toggleable with a button inside the dialog 🤔

Like for example if we end up adding a few more filters like this to the dialog it'll end up needing to be moved to a new file anyway.

realkotob avatar Jan 03 '23 18:01 realkotob

But it was already separate. The file was renamed.

KoBeWi avatar Jan 03 '23 19:01 KoBeWi

@KoBeWi Oh yeah I misunderstood my bad 🙏

realkotob avatar Jan 03 '23 20:01 realkotob

is this intended that the dialog is empty when there is no search text? It should just display everything

It will show all possible results at the start if the amount of possible results is below some threshold. If there is tons of files I feel like showing a bunch of them is just noise. We could do something with recently opened files here, but I don't consider that a must have feature.

the names in grid view are tiny

I think you're using a different editor scale? I've tried to improve the scaling in the latest commit. I think it looks a bit bad at 75% now, so we could stop scaling down from 100%. The text is supposed to be tiny though in grid view (8px at 100%), since there is just not much room for text.

"Search files by name" is a bit misleading, because it searches by the whole path

It still felt more natural to me than something like "Search files...".

why the class was moved to an entirely new file?

I renamed the file because I renamed the dialog class to be more consistent with how other dialogs are named. If people think having the git history is more valuable, then I can change it back. I guess if we are going to make the names consistent, this would be a good point to do it, since the whole thing is rewritten.

I wonder if include_addons shouldn't be toggleable with a button inside the dialog

I personally think this is only useful in edge case scenarios, and it also isn't a must-have feature. But I decided to try and implement in the current design to see how much it would affect the design and code. Maybe people like it this way, or they find it distracting.

stijn-h avatar Jan 03 '23 22:01 stijn-h

It still felt more natural to me than something like "Search files...".

Can say "Search files by name and path"

YuriSizov avatar Jan 03 '23 23:01 YuriSizov

Setting up a dev environment and rebasing went easier than expected, only had to downgrade scons to 4.3.0. But build times seem to have gone down quite a bit, which is very nice. I think this PR is ready now, there are some extra features that could be added, but they are not crucial.

stijn-h avatar Dec 03 '23 10:12 stijn-h

was there a reason for renaming it to remove the "Editor" part? AFAIK we've preferred to keep that prefix to distinguish things.

I am not sure about it, but I did it because most dialogs in the editor folder don't have the prefix, except for things like EditorFileDialog.

stijn-h avatar Dec 03 '23 12:12 stijn-h

We could do something with recently opened files here

Showing X recently opened files would be nice actually, but yeah, it's not that important. The empty space looks awkward though, it should at least have some label like "Start searching to see results" or something.

I see the text is still too small. Personally I don't mind, but it should be bigger from usability standpoint. If you are worried about space, you can make the dialog bigger.

Also the addons button should have text. Right now it gives false impression that it switches view, while they are 2 separate buttons. The text can be "Include Addons" to be shorter.

EDIT: Also maybe the layout button should display the current layout mode, like in filesystem. It's more intuitive.

KoBeWi avatar Dec 03 '23 16:12 KoBeWi

it should at least have some label like "Start searching to see results" or something.

Added.

text is still too small.

Yes, forgot to fix it. I don't know if it is big enough, but I tried to make everything a bit bigger across the board. It does make the icons stand out even more, because they are so small (why don't we make them bigger?).

Also the addons button should have text. Right now it gives false impression that it switches view, while they are 2 separate buttons. The text can be "Include Addons" to be shorter.

I see your point, but it also cuts away space for the file path details. So it would be a compromise either way. I added a separator between the buttons instead, maybe that is good enough.

Also maybe the layout button should display the current layout mode, like in filesystem. It's more intuitive.

Where is this? The file dialog uses two buttons. And in the file dock, we have only one toggle button, and it uses the same design of showing the action, rather than the current state: afbeelding

I think it makes more sense this way.

Aside from that I changed the base path in list view to include "res://" again. This creates a more consistent feel with files in the root folder. Otherwise, it felt like these results are not clearly separated, like you can see here: https://github.com/godotengine/godot/pull/56772#issuecomment-1368566007 I haven't heard anyone complain about it, and it is a bit redundant, but I think I prefer it like this.

afbeelding

stijn-h avatar Dec 03 '23 21:12 stijn-h

I added a separator between the buttons instead, maybe that is good enough.

A nameless button looks awkward, but it's slightly better now.

Where is this? The file dialog uses two buttons. And in the file dock, we have only one toggle button, and it uses the same design of showing the action, rather than the current state:

https://github.com/godotengine/godot/assets/2223172/1dde873a-2b93-4719-ae99-c400aa200ea7

Are you on top of some old version?

KoBeWi avatar Dec 04 '23 13:12 KoBeWi

Ah I just noticed that the new dialog no longer allows to open multiple files. idk how many people relied on it (not me), but technically it's a functionality regression. Also opening something instantly makes it more prone to missclicks.

KoBeWi avatar Dec 04 '23 13:12 KoBeWi

Keyboard navigation is broken i grid mode. Up/down move selection left/right, left/right keys have no effect.

KoBeWi avatar Dec 04 '23 17:12 KoBeWi

Are you on top of some old version?

No, you can see it in your video. The split mode works like you said. But the icon in the filter files part, which actually has the exact same grid/list view logic as here in this dialog ,does not work that way.

I just noticed that the new dialog no longer allows to open multiple files. Also opening something instantly makes it more prone to missclicks.

You want a quick open dialog to be fast, and distraction free. You have a file you want to open and want to get there the quickest way. Whether you want to edit a scene, or select a texture for a sprite. Having to click multiple times does the opposite. Look at other code editors and what they do. How realistic are your use cases, and are they worth compromising for?

Keyboard navigation is broken i grid mode. Up/down move selection left/right, left/right keys have no effect.

It used to be there, I think I removed it after moving to flow container. But it's not broken, because if the grid eats up left/right keys you cant move the cursor in the searchbox anymore. That felt bad to me. Maybe you can do something with focus, but I don't know how to shift focus to the grid and back.

stijn-h avatar Dec 04 '23 20:12 stijn-h

You want a quick open dialog to be fast, and distraction free. You have a file you want to open and want to get there the quickest way. Whether you want to edit a scene, or select a texture for a sprite. Having to click multiple times does the opposite. Look at other code editors and what they do. How realistic are your use cases, and are they worth compromising for?

Opening is one thing, but this also affects instancing scenes. Some users might not be happy with that.

KoBeWi avatar Dec 05 '23 13:12 KoBeWi

@stijn-h I realize this PR has been pending for quite some time now, but are there any plans to address the latest feedback here and try to bring this across the finish line?

Judging from a quick rebase it looks like there may be some issues with the theming, as some of the text is black for me (although I haven't seen the previous iterations beyond what's been shown in this thread):

image

I'm assuming this also needs to switch over to the tokenized search that was introduced in #88660.

And for whatever it's worth, I do agree with the feedback/sentiment about the removal of multi-file selection being somewhat unfortunate, for things like the scene instancing. I also found the single-click selection a bit surprising/jarring in this type of dialog in general.

Anyway, if you're too busy or otherwise unable to move this forward, let us know and perhaps someone else (like myself) could step in instead. This is a sorely needed UX improvement.

mihe avatar May 31 '24 10:05 mihe