diff options
author | Andreas Kling <kling@serenityos.org> | 2020-12-14 20:14:50 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-14 20:43:42 +0100 |
commit | b10255f93fbca3c916e4e8ae37a45a3866f97271 (patch) | |
tree | 65202465cf1634288b61e9b66d14c4243f028f86 /Applications | |
parent | 818f7777c8db01bab0cd13f1f6f542dab95e59a5 (diff) | |
download | serenity-b10255f93fbca3c916e4e8ae37a45a3866f97271.zip |
FileManager: Use GUI::BreadcrumbBar :^)
FileManager windows now alternate between the old-style location text
box and a new-style breadcrumb bar. The location bar shows up when you
try to edit the location (with Ctrl+L) and disappears once the textbox
loses focus.
The textbox and breadcrumb bar are mutually exclusive to keep it tidy.
Diffstat (limited to 'Applications')
-rw-r--r-- | Applications/FileManager/main.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/Applications/FileManager/main.cpp b/Applications/FileManager/main.cpp index d6bf574175..46cef00e49 100644 --- a/Applications/FileManager/main.cpp +++ b/Applications/FileManager/main.cpp @@ -40,6 +40,7 @@ #include <LibGUI/ActionGroup.h> #include <LibGUI/Application.h> #include <LibGUI/BoxLayout.h> +#include <LibGUI/BreadcrumbBar.h> #include <LibGUI/Clipboard.h> #include <LibGUI/Desktop.h> #include <LibGUI/FileIconProvider.h> @@ -301,6 +302,8 @@ int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_locatio auto& location_toolbar = toolbar_container.add<GUI::ToolBar>(); location_toolbar.layout()->set_margins({ 6, 3, 6, 3 }); + location_toolbar.set_visible(false); + auto& location_label = location_toolbar.add<GUI::Label>("Location: "); location_label.size_to_fit(); @@ -308,6 +311,15 @@ int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_locatio location_textbox.set_size_policy(GUI::SizePolicy::Fill, GUI::SizePolicy::Fixed); location_textbox.set_preferred_size(0, 22); + auto& breadcrumb_toolbar = toolbar_container.add<GUI::ToolBar>(Gfx::Orientation::Horizontal, 16); + breadcrumb_toolbar.layout()->set_margins({}); + auto& breadcrumb_bar = breadcrumb_toolbar.add<GUI::BreadcrumbBar>(); + + location_textbox.on_focusout = [&] { + location_toolbar.set_visible(false); + breadcrumb_toolbar.set_visible(true); + }; + auto& splitter = widget.add<GUI::HorizontalSplitter>(); auto& tree_view = splitter.add<GUI::TreeView>(); auto directories_model = GUI::FileSystemModel::create({}, GUI::FileSystemModel::Mode::DirectoriesOnly); @@ -326,6 +338,10 @@ int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_locatio auto& directory_view = splitter.add<DirectoryView>(DirectoryView::Mode::Normal); + location_textbox.on_escape_pressed = [&] { + directory_view.set_focus(true); + }; + // Open the root directory. FIXME: This is awkward. tree_view.toggle_index(directories_model->index(0, 0, {})); @@ -570,6 +586,8 @@ int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_locatio go_menu.add_action(go_home_action); go_menu.add_action(GUI::Action::create( "Go to location...", { Mod_Ctrl, Key_L }, [&](auto&) { + location_toolbar.set_visible(true); + breadcrumb_toolbar.set_visible(false); location_textbox.select_all(); location_textbox.set_focus(true); })); @@ -608,6 +626,54 @@ int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_locatio window->set_title(String::formatted("{} - File Manager", new_path)); location_textbox.set_text(new_path); + { + LexicalPath lexical_path(new_path); + + auto segment_index_of_new_path_in_breadcrumb_bar = [&]() -> Optional<size_t> { + for (size_t i = 0; i < breadcrumb_bar.segment_count(); ++i) { + if (breadcrumb_bar.segment_data(i) == new_path) + return i; + } + return {}; + }(); + + if (segment_index_of_new_path_in_breadcrumb_bar.has_value()) { + breadcrumb_bar.set_selected_segment(segment_index_of_new_path_in_breadcrumb_bar.value()); + } else { + breadcrumb_bar.clear_segments(); + + breadcrumb_bar.append_segment("/", GUI::FileIconProvider::icon_for_path("/").bitmap_for_size(16), "/"); + StringBuilder builder; + + for (auto& part : lexical_path.parts()) { + // NOTE: We rebuild the path as we go, so we have something to pass to GUI::FileIconProvider. + builder.append('/'); + builder.append(part); + + breadcrumb_bar.append_segment(part, GUI::FileIconProvider::icon_for_path(builder.string_view()).bitmap_for_size(16), builder.string_view()); + } + + breadcrumb_bar.set_selected_segment(breadcrumb_bar.segment_count() - 1); + + breadcrumb_bar.on_segment_click = [&directory_view, lexical_path](size_t segment_index) { + if (segment_index == 0) { + directory_view.open("/"); + return; + } + size_t part_index = segment_index - 1; + ASSERT(part_index < lexical_path.parts().size()); + + StringBuilder builder; + for (size_t i = 0; i <= part_index; ++i) { + builder.append('/'); + builder.append(lexical_path.parts()[i]); + } + + directory_view.open(builder.string_view()); + }; + } + } + if (!is_reacting_to_tree_view_selection_change) { auto new_index = directories_model->index(new_path, GUI::FileSystemModel::Column::Name); if (new_index.is_valid()) { |