mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:37:43 +00:00
GTableView: Make it possible to hide/show columns from a context menu.
Show a context menu when right clicking the headers of a GTableView, and allow the user to hide/show individual columns.
This commit is contained in:
parent
dbf7878998
commit
613c7b9856
4 changed files with 64 additions and 23 deletions
|
@ -3,7 +3,7 @@
|
||||||
#include <LibGUI/GButton.h>
|
#include <LibGUI/GButton.h>
|
||||||
#include <LibGUI/GMenuItem.h>
|
#include <LibGUI/GMenuItem.h>
|
||||||
|
|
||||||
GAction::GAction(const String& text, const String& custom_data, Function<void(const GAction&)> on_activation_callback, GWidget* widget)
|
GAction::GAction(const String& text, const String& custom_data, Function<void(GAction&)> on_activation_callback, GWidget* widget)
|
||||||
: on_activation(move(on_activation_callback))
|
: on_activation(move(on_activation_callback))
|
||||||
, m_text(text)
|
, m_text(text)
|
||||||
, m_custom_data(custom_data)
|
, m_custom_data(custom_data)
|
||||||
|
@ -11,12 +11,12 @@ GAction::GAction(const String& text, const String& custom_data, Function<void(co
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GAction::GAction(const String& text, Function<void(const GAction&)> on_activation_callback, GWidget* widget)
|
GAction::GAction(const String& text, Function<void(GAction&)> on_activation_callback, GWidget* widget)
|
||||||
: GAction(text, String(), move(on_activation_callback), widget)
|
: GAction(text, String(), move(on_activation_callback), widget)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GAction::GAction(const String& text, RetainPtr<GraphicsBitmap>&& icon, Function<void(const GAction&)> on_activation_callback, GWidget* widget)
|
GAction::GAction(const String& text, RetainPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> on_activation_callback, GWidget* widget)
|
||||||
: on_activation(move(on_activation_callback))
|
: on_activation(move(on_activation_callback))
|
||||||
, m_text(text)
|
, m_text(text)
|
||||||
, m_icon(move(icon))
|
, m_icon(move(icon))
|
||||||
|
@ -24,13 +24,13 @@ GAction::GAction(const String& text, RetainPtr<GraphicsBitmap>&& icon, Function<
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GAction::GAction(const String& text, const GShortcut& shortcut, Function<void(const GAction&)> on_activation_callback, GWidget* widget)
|
GAction::GAction(const String& text, const GShortcut& shortcut, Function<void(GAction&)> on_activation_callback, GWidget* widget)
|
||||||
: GAction(text, shortcut, nullptr, move(on_activation_callback), widget)
|
: GAction(text, shortcut, nullptr, move(on_activation_callback), widget)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GAction::GAction(const String& text, const GShortcut& shortcut, RetainPtr<GraphicsBitmap>&& icon, Function<void(const GAction&)> on_activation_callback, GWidget* widget)
|
GAction::GAction(const String& text, const GShortcut& shortcut, RetainPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> on_activation_callback, GWidget* widget)
|
||||||
: on_activation(move(on_activation_callback))
|
: on_activation(move(on_activation_callback))
|
||||||
, m_text(text)
|
, m_text(text)
|
||||||
, m_icon(move(icon))
|
, m_icon(move(icon))
|
||||||
|
|
|
@ -22,23 +22,23 @@ public:
|
||||||
ApplicationGlobal,
|
ApplicationGlobal,
|
||||||
WidgetLocal,
|
WidgetLocal,
|
||||||
};
|
};
|
||||||
static Retained<GAction> create(const String& text, Function<void(const GAction&)> callback, GWidget* widget = nullptr)
|
static Retained<GAction> create(const String& text, Function<void(GAction&)> callback, GWidget* widget = nullptr)
|
||||||
{
|
{
|
||||||
return adopt(*new GAction(text, move(callback), widget));
|
return adopt(*new GAction(text, move(callback), widget));
|
||||||
}
|
}
|
||||||
static Retained<GAction> create(const String& text, const String& custom_data, Function<void(const GAction&)> callback, GWidget* widget = nullptr)
|
static Retained<GAction> create(const String& text, const String& custom_data, Function<void(GAction&)> callback, GWidget* widget = nullptr)
|
||||||
{
|
{
|
||||||
return adopt(*new GAction(text, custom_data, move(callback), widget));
|
return adopt(*new GAction(text, custom_data, move(callback), widget));
|
||||||
}
|
}
|
||||||
static Retained<GAction> create(const String& text, RetainPtr<GraphicsBitmap>&& icon, Function<void(const GAction&)> callback, GWidget* widget = nullptr)
|
static Retained<GAction> create(const String& text, RetainPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> callback, GWidget* widget = nullptr)
|
||||||
{
|
{
|
||||||
return adopt(*new GAction(text, move(icon), move(callback), widget));
|
return adopt(*new GAction(text, move(icon), move(callback), widget));
|
||||||
}
|
}
|
||||||
static Retained<GAction> create(const String& text, const GShortcut& shortcut, Function<void(const GAction&)> callback, GWidget* widget = nullptr)
|
static Retained<GAction> create(const String& text, const GShortcut& shortcut, Function<void(GAction&)> callback, GWidget* widget = nullptr)
|
||||||
{
|
{
|
||||||
return adopt(*new GAction(text, shortcut, move(callback), widget));
|
return adopt(*new GAction(text, shortcut, move(callback), widget));
|
||||||
}
|
}
|
||||||
static Retained<GAction> create(const String& text, const GShortcut& shortcut, RetainPtr<GraphicsBitmap>&& icon, Function<void(const GAction&)> callback, GWidget* widget = nullptr)
|
static Retained<GAction> create(const String& text, const GShortcut& shortcut, RetainPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> callback, GWidget* widget = nullptr)
|
||||||
{
|
{
|
||||||
return adopt(*new GAction(text, shortcut, move(icon), move(callback), widget));
|
return adopt(*new GAction(text, shortcut, move(icon), move(callback), widget));
|
||||||
}
|
}
|
||||||
|
@ -71,11 +71,11 @@ public:
|
||||||
void unregister_menu_item(Badge<GMenuItem>, GMenuItem&);
|
void unregister_menu_item(Badge<GMenuItem>, GMenuItem&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GAction(const String& text, Function<void(const GAction&)> = nullptr, GWidget* = nullptr);
|
GAction(const String& text, Function<void(GAction&)> = nullptr, GWidget* = nullptr);
|
||||||
GAction(const String& text, const GShortcut&, Function<void(const GAction&)> = nullptr, GWidget* = nullptr);
|
GAction(const String& text, const GShortcut&, Function<void(GAction&)> = nullptr, GWidget* = nullptr);
|
||||||
GAction(const String& text, const GShortcut&, RetainPtr<GraphicsBitmap>&& icon, Function<void(const GAction&)> = nullptr, GWidget* = nullptr);
|
GAction(const String& text, const GShortcut&, RetainPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> = nullptr, GWidget* = nullptr);
|
||||||
GAction(const String& text, RetainPtr<GraphicsBitmap>&& icon, Function<void(const GAction&)> = nullptr, GWidget* = nullptr);
|
GAction(const String& text, RetainPtr<GraphicsBitmap>&& icon, Function<void(GAction&)> = nullptr, GWidget* = nullptr);
|
||||||
GAction(const String& text, const String& custom_data = String(), Function<void(const GAction&)> = nullptr, GWidget* = nullptr);
|
GAction(const String& text, const String& custom_data = String(), Function<void(GAction&)> = nullptr, GWidget* = nullptr);
|
||||||
|
|
||||||
template<typename Callback> void for_each_toolbar_button(Callback);
|
template<typename Callback> void for_each_toolbar_button(Callback);
|
||||||
template<typename Callback> void for_each_menu_item(Callback);
|
template<typename Callback> void for_each_menu_item(Callback);
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include <LibGUI/GPainter.h>
|
#include <LibGUI/GPainter.h>
|
||||||
#include <LibGUI/GTextBox.h>
|
#include <LibGUI/GTextBox.h>
|
||||||
#include <LibGUI/GWindow.h>
|
#include <LibGUI/GWindow.h>
|
||||||
|
#include <LibGUI/GMenu.h>
|
||||||
|
#include <LibGUI/GAction.h>
|
||||||
#include <Kernel/KeyCode.h>
|
#include <Kernel/KeyCode.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
|
|
||||||
|
@ -109,15 +111,15 @@ void GTableView::mousedown_event(GMouseEvent& event)
|
||||||
auto adjusted_position = this->adjusted_position(event.position());
|
auto adjusted_position = this->adjusted_position(event.position());
|
||||||
|
|
||||||
if (event.y() < header_height()) {
|
if (event.y() < header_height()) {
|
||||||
|
if (event.button() != GMouseButton::Left)
|
||||||
|
return;
|
||||||
for (int i = 0; i < model()->column_count(); ++i) {
|
for (int i = 0; i < model()->column_count(); ++i) {
|
||||||
if (event.button() == GMouseButton::Left) {
|
if (column_resize_grabbable_rect(i).contains(adjusted_position)) {
|
||||||
if (column_resize_grabbable_rect(i).contains(adjusted_position)) {
|
m_resizing_column = i;
|
||||||
m_resizing_column = i;
|
m_in_column_resize = true;
|
||||||
m_in_column_resize = true;
|
m_column_resize_original_width = column_width(i);
|
||||||
m_column_resize_original_width = column_width(i);
|
m_column_resize_origin = event.position();
|
||||||
m_column_resize_origin = event.position();
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
auto header_rect = this->header_rect(i);
|
auto header_rect = this->header_rect(i);
|
||||||
if (header_rect.contains(adjusted_position)) {
|
if (header_rect.contains(adjusted_position)) {
|
||||||
|
@ -413,6 +415,40 @@ void GTableView::doubleclick_event(GMouseEvent& event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GMenu& GTableView::ensure_header_context_menu()
|
||||||
|
{
|
||||||
|
// FIXME: This menu needs to be rebuilt if the model is swapped out,
|
||||||
|
// or if the column count/names change.
|
||||||
|
if (!m_header_context_menu) {
|
||||||
|
ASSERT(model());
|
||||||
|
m_header_context_menu = make<GMenu>("");
|
||||||
|
|
||||||
|
for (int column = 0; column < model()->column_count(); ++column) {
|
||||||
|
auto& column_data = this->column_data(column);
|
||||||
|
column_data.visibility_action = GAction::create(model()->column_name(column), [this, column] (GAction& action) {
|
||||||
|
action.set_checked(!action.is_checked());
|
||||||
|
set_column_hidden(column, !action.is_checked());
|
||||||
|
});
|
||||||
|
column_data.visibility_action->set_checkable(true);
|
||||||
|
column_data.visibility_action->set_checked(true);
|
||||||
|
|
||||||
|
m_header_context_menu->add_action(*column_data.visibility_action);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *m_header_context_menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GTableView::context_menu_event(GContextMenuEvent& event)
|
||||||
|
{
|
||||||
|
if (!model())
|
||||||
|
return;
|
||||||
|
if (event.position().y() < header_height()) {
|
||||||
|
ensure_header_context_menu().popup(event.screen_position());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dbgprintf("GTableView::context_menu_event(): FIXME: Implement for table rows.\n");
|
||||||
|
}
|
||||||
|
|
||||||
void GTableView::leave_event(CEvent&)
|
void GTableView::leave_event(CEvent&)
|
||||||
{
|
{
|
||||||
window()->set_override_cursor(GStandardCursor::None);
|
window()->set_override_cursor(GStandardCursor::None);
|
||||||
|
|
|
@ -45,6 +45,7 @@ private:
|
||||||
virtual void doubleclick_event(GMouseEvent&) override;
|
virtual void doubleclick_event(GMouseEvent&) override;
|
||||||
virtual void keydown_event(GKeyEvent&) override;
|
virtual void keydown_event(GKeyEvent&) override;
|
||||||
virtual void leave_event(CEvent&) override;
|
virtual void leave_event(CEvent&) override;
|
||||||
|
virtual void context_menu_event(GContextMenuEvent&) override;
|
||||||
|
|
||||||
Rect content_rect(int row, int column) const;
|
Rect content_rect(int row, int column) const;
|
||||||
void paint_headers(Painter&);
|
void paint_headers(Painter&);
|
||||||
|
@ -59,6 +60,7 @@ private:
|
||||||
int width { 0 };
|
int width { 0 };
|
||||||
bool has_initialized_width { false };
|
bool has_initialized_width { false };
|
||||||
bool visibility { true };
|
bool visibility { true };
|
||||||
|
RetainPtr<GAction> visibility_action;
|
||||||
};
|
};
|
||||||
ColumnData& column_data(int column) const;
|
ColumnData& column_data(int column) const;
|
||||||
|
|
||||||
|
@ -71,4 +73,7 @@ private:
|
||||||
Point m_column_resize_origin;
|
Point m_column_resize_origin;
|
||||||
int m_column_resize_original_width { 0 };
|
int m_column_resize_original_width { 0 };
|
||||||
int m_resizing_column { -1 };
|
int m_resizing_column { -1 };
|
||||||
|
|
||||||
|
GMenu& ensure_header_context_menu();
|
||||||
|
OwnPtr<GMenu> m_header_context_menu;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue