From b8ef5b58044ee12d3b9e70a35a434f175c682957 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 30 Jun 2019 08:13:41 +0200 Subject: [PATCH] GTableView: Support per-index context menus. This patch adds an on_context_menu_request hook to GAbstractView which is currently only invoked by GTableView. We also pass along the entire context menu event, so that anyone using the hook can use it for menu placement etc. --- LibGUI/GAbstractView.h | 1 + LibGUI/GTableView.cpp | 31 +++++++++++++++++++++++-------- LibGUI/GTableView.h | 4 +++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/LibGUI/GAbstractView.h b/LibGUI/GAbstractView.h index 40bd04593a..348cabfdc3 100644 --- a/LibGUI/GAbstractView.h +++ b/LibGUI/GAbstractView.h @@ -33,6 +33,7 @@ public: Function on_activation; Function on_selection; + Function on_context_menu_request; Function on_model_notification; Function(const GModelIndex&)> aid_create_editing_delegate; diff --git a/LibGUI/GTableView.cpp b/LibGUI/GTableView.cpp index 8e096f3b43..5b2687261a 100644 --- a/LibGUI/GTableView.cpp +++ b/LibGUI/GTableView.cpp @@ -92,7 +92,7 @@ Rect GTableView::header_rect(int column_index) const return { x_offset, 0, column_width(column_index) + horizontal_padding() * 2, header_height() }; } -Point GTableView::adjusted_position(const Point& position) +Point GTableView::adjusted_position(const Point& position) const { return position.translated(horizontal_scrollbar().value() - frame_thickness(), vertical_scrollbar().value() - frame_thickness()); } @@ -136,20 +136,26 @@ void GTableView::mousedown_event(GMouseEvent& event) return; } - auto adjusted_position = this->adjusted_position(event.position()); + model()->set_selected_index(index_at_event_position(event.position())); + update(); +} + +GModelIndex GTableView::index_at_event_position(const Point& position) const +{ + if (!model()) + return {}; + + auto adjusted_position = this->adjusted_position(position); for (int row = 0, row_count = model()->row_count(); row < row_count; ++row) { if (!row_rect(row).contains(adjusted_position)) continue; for (int column = 0, column_count = model()->column_count(); column < column_count; ++column) { if (!content_rect(row, column).contains(adjusted_position)) continue; - model()->set_selected_index(model()->index(row, column)); - update(); - return; + return model()->index(row, column); } } - model()->set_selected_index({}); - update(); + return {}; } void GTableView::mousemove_event(GMouseEvent& event) @@ -448,7 +454,16 @@ void GTableView::context_menu_event(GContextMenuEvent& event) ensure_header_context_menu().popup(event.screen_position()); return; } - dbgprintf("GTableView::context_menu_event(): FIXME: Implement for table rows.\n"); + + auto index = index_at_event_position(event.position()); + if (!index.is_valid()) + return; + dbgprintf("context menu requested for index (%d,%d) '%s'\n", index.row(), index.column(), model()->data(index).to_string().characters()); + + model()->set_selected_index(index); + update(); + if (on_context_menu_request) + on_context_menu_request(index, event); } void GTableView::leave_event(CEvent&) diff --git a/LibGUI/GTableView.h b/LibGUI/GTableView.h index 3f63f94aab..6c6b02fa99 100644 --- a/LibGUI/GTableView.h +++ b/LibGUI/GTableView.h @@ -30,7 +30,7 @@ public: bool is_column_hidden(int) const; void set_column_hidden(int, bool); - Point adjusted_position(const Point&); + Point adjusted_position(const Point&) const; virtual Rect content_rect(const GModelIndex&) const override; @@ -47,6 +47,8 @@ private: virtual void leave_event(CEvent&) override; virtual void context_menu_event(GContextMenuEvent&) override; + GModelIndex index_at_event_position(const Point&) const; + Rect content_rect(int row, int column) const; void paint_headers(Painter&); int item_count() const;