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.
This commit is contained in:
Andreas Kling 2019-06-30 08:13:41 +02:00
parent ce0b615bef
commit b8ef5b5804
3 changed files with 27 additions and 9 deletions

View file

@ -33,6 +33,7 @@ public:
Function<void(const GModelIndex&)> on_activation;
Function<void(const GModelIndex&)> on_selection;
Function<void(const GModelIndex&, const GContextMenuEvent&)> on_context_menu_request;
Function<void(const GModelNotification&)> on_model_notification;
Function<OwnPtr<GModelEditingDelegate>(const GModelIndex&)> aid_create_editing_delegate;

View file

@ -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&)

View file

@ -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;