From 9d9a31384e10c557a6e6da5fc4d7b56951f7d2bc Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 21 May 2020 13:36:08 +0200 Subject: [PATCH] LibGUI: Allow expand/collapse subtrees in TreeView with Alt+Left/Right This makes TreeView a lot more keyboard friendly. --- Libraries/LibGUI/TreeView.cpp | 42 +++++++++++++++++++++++++++++++++++ Libraries/LibGUI/TreeView.h | 4 ++++ 2 files changed, 46 insertions(+) diff --git a/Libraries/LibGUI/TreeView.cpp b/Libraries/LibGUI/TreeView.cpp index 1af3799c32..0f6320734b 100644 --- a/Libraries/LibGUI/TreeView.cpp +++ b/Libraries/LibGUI/TreeView.cpp @@ -109,6 +109,38 @@ void TreeView::doubleclick_event(MouseEvent& event) } } +void TreeView::set_open_state_of_all_in_subtree(const ModelIndex& root, bool open) +{ + if (root.is_valid()) + ensure_metadata_for_index(root).open = open; + int row_count = model()->row_count(root); + int column = model()->tree_column(); + for (int row = 0; row < row_count; ++row) { + auto index = model()->index(row, column, root); + set_open_state_of_all_in_subtree(index, open); + } +} + +void TreeView::expand_tree(const ModelIndex& root) +{ + if (!model()) + return; + set_open_state_of_all_in_subtree(root, true); + update_column_sizes(); + update_content_size(); + update(); +} + +void TreeView::collapse_tree(const ModelIndex& root) +{ + if (!model()) + return; + set_open_state_of_all_in_subtree(root, false); + update_column_sizes(); + update_content_size(); + update(); +} + void TreeView::toggle_index(const ModelIndex& index) { ASSERT(model()->row_count(index)); @@ -426,6 +458,11 @@ void TreeView::keydown_event(KeyEvent& event) if (event.key() == KeyCode::Key_Left) { if (cursor_index.is_valid() && model()->row_count(cursor_index)) { + if (event.alt()) { + collapse_tree(cursor_index); + return; + } + auto& metadata = ensure_metadata_for_index(cursor_index); if (metadata.open) { open_tree_node(false, metadata); @@ -441,6 +478,11 @@ void TreeView::keydown_event(KeyEvent& event) if (event.key() == KeyCode::Key_Right) { if (cursor_index.is_valid() && model()->row_count(cursor_index)) { + if (event.alt()) { + expand_tree(cursor_index); + return; + } + auto& metadata = ensure_metadata_for_index(cursor_index); if (!metadata.open) { open_tree_node(true, metadata); diff --git a/Libraries/LibGUI/TreeView.h b/Libraries/LibGUI/TreeView.h index 618bca040b..4ec708d4ab 100644 --- a/Libraries/LibGUI/TreeView.h +++ b/Libraries/LibGUI/TreeView.h @@ -41,6 +41,9 @@ public: virtual int item_count() const override; virtual void toggle_index(const ModelIndex&) override; + void expand_tree(const ModelIndex& root = {}); + void collapse_tree(const ModelIndex& root = {}); + protected: TreeView(); @@ -69,6 +72,7 @@ private: struct MetadataForIndex; MetadataForIndex& ensure_metadata_for_index(const ModelIndex&) const; + void set_open_state_of_all_in_subtree(const ModelIndex& root, bool open); mutable HashMap> m_view_metadata;