diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-03-29 20:36:15 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-03-29 20:36:15 +0100 |
commit | 1963391ca63cb87bbb0ddd4854cea1a9c4f880fa (patch) | |
tree | 8a71e17daf048b78949f8cb562f612fb71a1e065 | |
parent | 967eec1e52ea865e9ee718da4f78f678f7b03df9 (diff) | |
download | serenity-1963391ca63cb87bbb0ddd4854cea1a9c4f880fa.zip |
GTreeView: Add basic selection support.
-rw-r--r-- | LibGUI/GFileSystemModel.cpp | 34 | ||||
-rw-r--r-- | LibGUI/GFileSystemModel.h | 2 | ||||
-rw-r--r-- | LibGUI/GModelIndex.h | 10 | ||||
-rw-r--r-- | LibGUI/GTreeView.cpp | 24 |
4 files changed, 44 insertions, 26 deletions
diff --git a/LibGUI/GFileSystemModel.cpp b/LibGUI/GFileSystemModel.cpp index 49ceea9b9a..9dd7faf5c0 100644 --- a/LibGUI/GFileSystemModel.cpp +++ b/LibGUI/GFileSystemModel.cpp @@ -26,23 +26,6 @@ struct GFileSystemModel::Node { ASSERT_NOT_REACHED(); } - String full_path(const GFileSystemModel& model) const - { - Vector<String> lineage; - for (auto* ancestor = parent; ancestor; ancestor = ancestor->parent) { - lineage.append(ancestor->name); - } - StringBuilder builder; - builder.append(model.root_path()); - for (int i = lineage.size() - 1; i >= 0; --i) { - builder.append('/'); - builder.append(lineage[i]); - } - builder.append('/'); - builder.append(name); - return FileSystemPath(builder.to_string()).string(); - } - void traverse_if_needed(const GFileSystemModel& model) { if (type != Node::Directory || has_traversed) @@ -90,6 +73,23 @@ struct GFileSystemModel::Node { } type = S_ISDIR(st.st_mode) ? Node::Type::Directory : Node::Type::File; } + + String full_path(const GFileSystemModel& model) const + { + Vector<String> lineage; + for (auto* ancestor = parent; ancestor; ancestor = ancestor->parent) { + lineage.append(ancestor->name); + } + StringBuilder builder; + builder.append(model.root_path()); + for (int i = lineage.size() - 1; i >= 0; --i) { + builder.append('/'); + builder.append(lineage[i]); + } + builder.append('/'); + builder.append(name); + return FileSystemPath(builder.to_string()).string(); + } }; GFileSystemModel::GFileSystemModel(const String& root_path, Mode mode) diff --git a/LibGUI/GFileSystemModel.h b/LibGUI/GFileSystemModel.h index 09f137625a..be9cc6600f 100644 --- a/LibGUI/GFileSystemModel.h +++ b/LibGUI/GFileSystemModel.h @@ -20,7 +20,7 @@ public: virtual GVariant data(const GModelIndex&, Role = Role::Display) const override; virtual void update() override; virtual GModelIndex parent_index(const GModelIndex&) const override; - virtual GModelIndex index(int row, int column = 0, const GModelIndex& = GModelIndex()) const override; + virtual GModelIndex index(int row, int column = 0, const GModelIndex& parent = GModelIndex()) const override; virtual void activate(const GModelIndex&) override; private: diff --git a/LibGUI/GModelIndex.h b/LibGUI/GModelIndex.h index a303cf90d5..a568f1f63a 100644 --- a/LibGUI/GModelIndex.h +++ b/LibGUI/GModelIndex.h @@ -15,7 +15,15 @@ public: GModelIndex parent() const; - bool operator==(const GModelIndex& other) const { return m_row == other.m_row && m_column == other.m_column; } + bool operator==(const GModelIndex& other) const + { + return m_model == other.m_model && m_row == other.m_row && m_column == other.m_column && m_internal_data == other.m_internal_data; + } + + bool operator!=(const GModelIndex& other) const + { + return !(*this == other); + } private: GModelIndex(const GModel& model, int row, int column, void* internal_data) diff --git a/LibGUI/GTreeView.cpp b/LibGUI/GTreeView.cpp index 147282f94d..787faed370 100644 --- a/LibGUI/GTreeView.cpp +++ b/LibGUI/GTreeView.cpp @@ -144,16 +144,17 @@ void GTreeView::mousedown_event(GMouseEvent& event) auto& model = *this->model(); auto adjusted_position = event.position().translated(horizontal_scrollbar().value() - frame_thickness(), vertical_scrollbar().value() - frame_thickness()); auto index = index_at_content_position(adjusted_position); - if (!index.is_valid()) { - dbgprintf("GTV::mousedown: No valid index at %s (adjusted to: %s)\n", event.position().to_string().characters(), adjusted_position.to_string().characters()); + if (!index.is_valid()) return; + + if (model.selected_index() != index) { + model.set_selected_index(index); + update(); } - dbgprintf("GTV::mousedown: Index %d,%d {%p}] at %s (adjusted to: %s)\n", index.row(), index.column(), index.internal_data(), event.position().to_string().characters(), adjusted_position.to_string().characters()); - auto& metadata = ensure_metadata_for_index(index); if (model.row_count(index)) { + auto& metadata = ensure_metadata_for_index(index); metadata.open = !metadata.open; - dbgprintf("GTV::mousedown: toggle index %d,%d {%p} open: %d -> %d\n", index.row(), index.column(), index.internal_data(), !metadata.open, metadata.open); update(); } } @@ -174,7 +175,7 @@ void GTreeView::traverse_in_paint_order(Callback callback) const auto node_text = model.data(index, GModel::Role::Display).to_string(); Rect rect = { x_offset, y_offset, - toggle_size() + icon_spacing() + icon_size() + icon_spacing() + font().width(node_text), item_height() + icon_size() + icon_spacing() + font().width(node_text) + icon_spacing(), item_height() }; if (rect.intersects(visible_content_rect)) { if (callback(index, rect, indent_level) == IterationDecision::Abort) @@ -215,6 +216,15 @@ void GTreeView::paint_event(GPaintEvent& event) #ifdef DEBUG_ITEM_RECTS painter.fill_rect(rect, Color::LightGray); #endif + + Color background_color = Color::from_rgb(0xffffff); + Color text_color = Color::from_rgb(0x000000); + if (index == model.selected_index()) { + background_color = is_focused() ? Color::from_rgb(0x84351a) : Color::from_rgb(0x606060); + text_color = Color::from_rgb(0xffffff); + painter.fill_rect(rect, background_color); + } + Rect icon_rect = { rect.x(), rect.y(), icon_size(), icon_size() }; auto icon = model.data(index, GModel::Role::Icon); if (icon.is_icon()) { @@ -226,7 +236,7 @@ void GTreeView::paint_event(GPaintEvent& event) rect.width() - icon_size() - icon_spacing(), rect.height() }; auto node_text = model.data(index, GModel::Role::Display).to_string(); - painter.draw_text(text_rect, node_text, TextAlignment::CenterLeft, Color::Black); + painter.draw_text(text_rect, node_text, TextAlignment::CenterLeft, text_color); auto index_at_indent = index; for (int i = indent_level; i >= 0; --i) { auto parent_of_index_at_indent = index_at_indent.parent(); |