Просмотр исходного кода

GItemView: Add context menu support

Also, use the model_column() internally for selection as well as for
painting to keep things consistent.

Note that we always fire the on_context_menu_request hook, even if you
didn't click on an item. In those cases, you get a GModelIndex().
Andreas Kling 5 лет назад
Родитель
Сommit
bf23f1e8bc
2 измененных файлов с 43 добавлено и 14 удалено
  1. 41 14
      Libraries/LibGUI/GItemView.cpp
  2. 2 0
      Libraries/LibGUI/GItemView.h

+ 41 - 14
Libraries/LibGUI/GItemView.cpp

@@ -66,24 +66,51 @@ Rect GItemView::item_rect(int item_index) const
     };
     };
 }
 }
 
 
+int GItemView::item_at_event_position(const Point& position) const
+{
+    // FIXME: Since all items are the same size, just compute the clicked item index
+    //        instead of iterating over everything.
+    auto adjusted_position = position.translated(0, vertical_scrollbar().value());
+    for (int i = 0; i < item_count(); ++i) {
+        if (item_rect(i).contains(adjusted_position))
+            return i;
+    }
+    return -1;
+}
+
 void GItemView::mousedown_event(GMouseEvent& event)
 void GItemView::mousedown_event(GMouseEvent& event)
 {
 {
+    int item_index = item_at_event_position(event.position());
+
     if (event.button() == GMouseButton::Left) {
     if (event.button() == GMouseButton::Left) {
-        // FIXME: Since all items are the same size, just compute the clicked item index
-        //        instead of iterating over everything.
-        auto adjusted_position = event.position().translated(0, vertical_scrollbar().value());
-        for (int i = 0; i < item_count(); ++i) {
-            if (item_rect(i).contains(adjusted_position)) {
-                auto index = model()->index(i, 0);
-                if (event.modifiers() & Mod_Ctrl)
-                    selection().toggle(index);
-                else
-                    selection().set(index);
-                return;
-            }
+        if (item_index == -1) {
+            selection().clear();
+        } else {
+            auto index = model()->index(item_index, m_model_column);
+            if (event.modifiers() & Mod_Ctrl)
+                selection().toggle(index);
+            else
+                selection().set(index);
         }
         }
-        selection().clear();
     }
     }
+
+    GAbstractView::mousedown_event(event);
+}
+
+void GItemView::context_menu_event(GContextMenuEvent& event)
+{
+    if (!model())
+        return;
+    auto item_index = item_at_event_position(event.position());
+    GModelIndex index;
+    if (item_index != -1) {
+        index = model()->index(item_index, m_model_column);
+        selection().add(index);
+        update();
+    }
+    if (on_context_menu_request)
+        on_context_menu_request(index, event);
+    GAbstractView::context_menu_event(event);
 }
 }
 
 
 void GItemView::doubleclick_event(GMouseEvent& event)
 void GItemView::doubleclick_event(GMouseEvent& event)
@@ -112,7 +139,7 @@ void GItemView::paint_event(GPaintEvent& event)
     const Font& font = column_metadata.font ? *column_metadata.font : this->font();
     const Font& font = column_metadata.font ? *column_metadata.font : this->font();
 
 
     for (int item_index = 0; item_index < model()->row_count(); ++item_index) {
     for (int item_index = 0; item_index < model()->row_count(); ++item_index) {
-        bool is_selected_item = selection().contains(model()->index(item_index));
+        bool is_selected_item = selection().contains(model()->index(item_index, m_model_column));
         Color background_color;
         Color background_color;
         if (is_selected_item) {
         if (is_selected_item) {
             background_color = is_focused() ? Color::from_rgb(0x84351a) : Color::from_rgb(0x606060);
             background_color = is_focused() ? Color::from_rgb(0x84351a) : Color::from_rgb(0x606060);

+ 2 - 0
Libraries/LibGUI/GItemView.h

@@ -30,9 +30,11 @@ private:
     virtual void mousedown_event(GMouseEvent&) override;
     virtual void mousedown_event(GMouseEvent&) override;
     virtual void keydown_event(GKeyEvent&) override;
     virtual void keydown_event(GKeyEvent&) override;
     virtual void doubleclick_event(GMouseEvent&) override;
     virtual void doubleclick_event(GMouseEvent&) override;
+    virtual void context_menu_event(GContextMenuEvent&) override;
 
 
     int item_count() const;
     int item_count() const;
     Rect item_rect(int item_index) const;
     Rect item_rect(int item_index) const;
+    int item_at_event_position(const Point&) const;
     void update_content_size();
     void update_content_size();
 
 
     int m_horizontal_padding { 5 };
     int m_horizontal_padding { 5 };