summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-03-29 20:36:15 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-03-29 20:36:15 +0100
commit1963391ca63cb87bbb0ddd4854cea1a9c4f880fa (patch)
tree8a71e17daf048b78949f8cb562f612fb71a1e065
parent967eec1e52ea865e9ee718da4f78f678f7b03df9 (diff)
downloadserenity-1963391ca63cb87bbb0ddd4854cea1a9c4f880fa.zip
GTreeView: Add basic selection support.
-rw-r--r--LibGUI/GFileSystemModel.cpp34
-rw-r--r--LibGUI/GFileSystemModel.h2
-rw-r--r--LibGUI/GModelIndex.h10
-rw-r--r--LibGUI/GTreeView.cpp24
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();