columnview: add a (private) focus-column

Make setting the focus column scroll to it, too.
This commit is contained in:
Benjamin Otte
2023-03-23 03:35:04 +01:00
parent 8e17abb8fe
commit 78e72ad1de
3 changed files with 89 additions and 6 deletions

View File

@@ -21,6 +21,7 @@
#include "gtkcolumnviewprivate.h"
#include "gtkadjustment.h"
#include "gtkboxlayout.h"
#include "gtkbuildable.h"
#include "gtkcolumnviewcolumnprivate.h"
@@ -31,9 +32,8 @@
#include "gtkmain.h"
#include "gtkprivate.h"
#include "gtkscrollable.h"
#include "gtkwidgetprivate.h"
#include "gtksizerequest.h"
#include "gtkadjustment.h"
#include "gtkwidgetprivate.h"
#include "gtkgesturedrag.h"
#include "gtkeventcontrollermotion.h"
#include "gtkdragsourceprivate.h"
@@ -166,6 +166,8 @@ struct _GtkColumnView
GListStore *columns;
GtkColumnViewColumn *focus_column;
GtkWidget *header;
GtkListView *listview;
@@ -495,6 +497,8 @@ gtk_column_view_dispose (GObject *object)
g_object_unref (column);
}
g_assert (self->focus_column == NULL);
g_clear_pointer (&self->header, gtk_widget_unparent);
g_clear_pointer ((GtkWidget **) &self->listview, gtk_widget_unparent);
@@ -1547,6 +1551,20 @@ gtk_column_view_remove_column (GtkColumnView *self,
gtk_column_view_sorter_remove_column (GTK_COLUMN_VIEW_SORTER (self->sorter), column);
gtk_column_view_column_set_column_view (column, NULL);
g_list_store_remove (self->columns, i);
if (self->focus_column == column)
{
GtkColumnViewColumn *item;
if (i < g_list_model_get_n_items (G_LIST_MODEL (self->columns)))
item = g_list_model_get_item (G_LIST_MODEL (self->columns), i);
else if (i > 0)
item = g_list_model_get_item (G_LIST_MODEL (self->columns), i - 1);
else
item = NULL;
gtk_column_view_set_focus_column (self, item);
}
}
/**
@@ -1603,6 +1621,43 @@ gtk_column_view_insert_column (GtkColumnView *self,
g_object_unref (column);
}
static void
gtk_column_view_scroll_to_column (GtkColumnView *self,
GtkColumnViewColumn *column)
{
int col_x, col_width, adj_x, adj_width;
gtk_column_view_column_get_header_allocation (column, &col_x, &col_width);
adj_x = gtk_adjustment_get_value (self->hadjustment);
adj_width = gtk_adjustment_get_page_size (self->hadjustment);
if (col_x < adj_x)
gtk_adjustment_set_value (self->hadjustment, col_x);
else if (col_x + col_width > adj_x + adj_width)
gtk_adjustment_set_value (self->hadjustment, adj_x + adj_width - col_width);
}
void
gtk_column_view_set_focus_column (GtkColumnView *self,
GtkColumnViewColumn *column)
{
g_assert (column == NULL || gtk_column_view_column_get_column_view (column) == self);
if (self->focus_column == column)
return;
self->focus_column = column;
if (column)
gtk_column_view_scroll_to_column (self, column);
}
GtkColumnViewColumn *
gtk_column_view_get_focus_column (GtkColumnView *self)
{
return self->focus_column;
}
void
gtk_column_view_measure_across (GtkColumnView *self,
int *minimum,

View File

@@ -38,4 +38,8 @@ void gtk_column_view_distribute_width (GtkColumnView
int width,
GtkRequestedSize *sizes);
void gtk_column_view_set_focus_column (GtkColumnView *self,
GtkColumnViewColumn *focus_column);
GtkColumnViewColumn * gtk_column_view_get_focus_column (GtkColumnView *self);
#endif /* __GTK_COLUMN_VIEW_PRIVATE_H__ */

View File

@@ -53,6 +53,17 @@ gtk_column_view_row_widget_is_header (GtkColumnViewRowWidget *self)
return gtk_widget_get_css_name (GTK_WIDGET (self)) == g_intern_static_string ("header");
}
static GtkColumnViewColumn *
gtk_column_view_row_child_get_column (GtkWidget *child)
{
if (GTK_IS_COLUMN_VIEW_CELL (child))
return gtk_column_view_cell_get_column (GTK_COLUMN_VIEW_CELL (child));
else
return gtk_column_view_title_get_column (GTK_COLUMN_VIEW_TITLE (child));
g_return_val_if_reached (NULL);
}
static void
gtk_column_view_row_widget_update (GtkListItemBase *base,
guint position,
@@ -192,6 +203,21 @@ gtk_column_view_row_widget_grab_focus (GtkWidget *widget)
return GTK_WIDGET_CLASS (gtk_column_view_row_widget_parent_class)->grab_focus (widget);
}
static void
gtk_column_view_row_widget_set_focus_child (GtkWidget *widget,
GtkWidget *child)
{
GtkColumnViewRowWidget *self = GTK_COLUMN_VIEW_ROW_WIDGET (widget);
GTK_WIDGET_CLASS (gtk_column_view_row_widget_parent_class)->set_focus_child (widget, child);
if (child)
{
gtk_column_view_set_focus_column (gtk_column_view_row_widget_get_column_view (self),
gtk_column_view_row_child_get_column (child));
}
}
static void
gtk_column_view_row_widget_root (GtkWidget *widget)
{
@@ -341,10 +367,7 @@ gtk_column_view_row_widget_allocate (GtkWidget *widget,
if (!gtk_widget_should_layout (child))
continue;
if (GTK_IS_COLUMN_VIEW_CELL (child))
column = gtk_column_view_cell_get_column (GTK_COLUMN_VIEW_CELL (child));
else
column = gtk_column_view_title_get_column (GTK_COLUMN_VIEW_TITLE (child));
column = gtk_column_view_row_child_get_column (child);
gtk_column_view_column_get_header_allocation (column, &col_x, &col_width);
gtk_widget_measure (child, GTK_ORIENTATION_HORIZONTAL, -1, &min, NULL, NULL, NULL);
@@ -388,6 +411,7 @@ gtk_column_view_row_widget_class_init (GtkColumnViewRowWidgetClass *klass)
widget_class->focus = gtk_column_view_row_widget_focus;
widget_class->grab_focus = gtk_column_view_row_widget_grab_focus;
widget_class->set_focus_child = gtk_column_view_row_widget_set_focus_child;
widget_class->measure = gtk_column_view_row_widget_measure;
widget_class->size_allocate = gtk_column_view_row_widget_allocate;
widget_class->root = gtk_column_view_row_widget_root;