소스 검색

GTreeView: Add basic selection support.

Andreas Kling 6 년 전
부모
커밋
1963391ca6
4개의 변경된 파일44개의 추가작업 그리고 26개의 파일을 삭제
  1. 17 17
      LibGUI/GFileSystemModel.cpp
  2. 1 1
      LibGUI/GFileSystemModel.h
  3. 9 1
      LibGUI/GModelIndex.h
  4. 17 7
      LibGUI/GTreeView.cpp

+ 17 - 17
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)

+ 1 - 1
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:

+ 9 - 1
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)

+ 17 - 7
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();