forked from AuroraMiddleware/gtk
Merge branch 'columnview-menu' into 'master'
columnview: Add header menus See merge request GNOME/gtk!2001
This commit is contained in:
commit
19da93b675
@ -300,7 +300,13 @@ do_listview_settings (GtkWidget *do_widget)
|
||||
GtkBuilderScope *scope;
|
||||
GtkBuilder *builder;
|
||||
GtkColumnViewColumn *name_column;
|
||||
GtkColumnViewColumn *type_column;
|
||||
GtkColumnViewColumn *default_column;
|
||||
GtkColumnViewColumn *summary_column;
|
||||
GtkColumnViewColumn *description_column;
|
||||
GtkSorter *sorter;
|
||||
GActionGroup *actions;
|
||||
GAction *action;
|
||||
|
||||
g_type_ensure (SETTINGS_TYPE_KEY);
|
||||
|
||||
@ -320,6 +326,32 @@ do_listview_settings (GtkWidget *do_widget)
|
||||
|
||||
listview = GTK_WIDGET (gtk_builder_get_object (builder, "listview"));
|
||||
columnview = GTK_WIDGET (gtk_builder_get_object (builder, "columnview"));
|
||||
type_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "type_column"));
|
||||
default_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "default_column"));
|
||||
summary_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "summary_column"));
|
||||
description_column = GTK_COLUMN_VIEW_COLUMN (gtk_builder_get_object (builder, "description_column"));
|
||||
|
||||
actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
|
||||
action = G_ACTION (g_property_action_new ("show-type", type_column, "visible"));
|
||||
g_action_map_add_action (G_ACTION_MAP (actions), action);
|
||||
g_object_unref (action);
|
||||
|
||||
action = G_ACTION (g_property_action_new ("show-default", default_column, "visible"));
|
||||
g_action_map_add_action (G_ACTION_MAP (actions), action);
|
||||
g_object_unref (action);
|
||||
|
||||
action = G_ACTION (g_property_action_new ("show-summary", summary_column, "visible"));
|
||||
g_action_map_add_action (G_ACTION_MAP (actions), action);
|
||||
g_object_unref (action);
|
||||
|
||||
action = G_ACTION (g_property_action_new ("show-description", description_column, "visible"));
|
||||
g_action_map_add_action (G_ACTION_MAP (actions), action);
|
||||
g_object_unref (action);
|
||||
|
||||
gtk_widget_insert_action_group (columnview, "columnview", actions);
|
||||
g_object_unref (actions);
|
||||
|
||||
model = create_settings_model (NULL, NULL);
|
||||
treemodel = gtk_tree_list_model_new (FALSE,
|
||||
model,
|
||||
|
@ -77,6 +77,7 @@
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn" id="name_column">
|
||||
<property name="title">Name</property>
|
||||
<property name="header-menu">header_menu</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
@ -103,6 +104,7 @@
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn">
|
||||
<property name="title">Value</property>
|
||||
<property name="header-menu">header_menu</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
@ -127,8 +129,9 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn">
|
||||
<object class="GtkColumnViewColumn" id="type_column">
|
||||
<property name="title">Type</property>
|
||||
<property name="header-menu">header_menu</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
@ -153,8 +156,9 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn">
|
||||
<object class="GtkColumnViewColumn" id="default_column">
|
||||
<property name="title">Default</property>
|
||||
<property name="header-menu">header_menu</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
@ -172,6 +176,68 @@
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]></property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn" id="summary_column">
|
||||
<property name="title">Summary</property>
|
||||
<property name="visible">0</property>
|
||||
<property name="header-menu">header_menu</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="width-chars">50</property>
|
||||
<property name="max-width-chars">50</property>
|
||||
<binding name="label">
|
||||
<lookup name="summary" type="SettingsKey">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]></property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkColumnViewColumn" id="description_column">
|
||||
<property name="title">Description</property>
|
||||
<property name="visible">0</property>
|
||||
<property name="header-menu">header_menu</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<property name="wrap">1</property>
|
||||
<property name="width-chars">50</property>
|
||||
<property name="max-width-chars">50</property>
|
||||
<binding name="label">
|
||||
<lookup name="description" type="SettingsKey">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]></property>
|
||||
</object>
|
||||
@ -187,4 +253,24 @@
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<menu id="header_menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Type</attribute>
|
||||
<attribute name="action">columnview.show-type</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Default value</attribute>
|
||||
<attribute name="action">columnview.show-default</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Summary</attribute>
|
||||
<attribute name="action">columnview.show-summary</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label" translatable="yes">Description</attribute>
|
||||
<attribute name="action">columnview.show-description</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
||||
|
@ -533,6 +533,9 @@ gtk_column_view_column_set_sorter
|
||||
gtk_column_view_column_get_sorter
|
||||
gtk_column_view_column_set_visible
|
||||
gtk_column_view_column_get_visible
|
||||
gtk_column_view_column_set_header_menu
|
||||
gtk_column_view_column_get_header_menu
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_COLUMN_VIEW_COLUMN
|
||||
GTK_COLUMN_VIEW_COLUMN_CLASS
|
||||
|
@ -63,6 +63,8 @@ struct _GtkColumnViewColumn
|
||||
|
||||
gboolean visible;
|
||||
|
||||
GMenuModel *menu;
|
||||
|
||||
/* This list isn't sorted - this is just caching for performance */
|
||||
GtkColumnViewCell *first_cell; /* no reference, just caching */
|
||||
};
|
||||
@ -80,6 +82,7 @@ enum
|
||||
PROP_TITLE,
|
||||
PROP_SORTER,
|
||||
PROP_VISIBLE,
|
||||
PROP_HEADER_MENU,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
@ -99,6 +102,7 @@ gtk_column_view_column_dispose (GObject *object)
|
||||
g_clear_object (&self->factory);
|
||||
g_clear_object (&self->sorter);
|
||||
g_clear_pointer (&self->title, g_free);
|
||||
g_clear_object (&self->menu);
|
||||
|
||||
G_OBJECT_CLASS (gtk_column_view_column_parent_class)->dispose (object);
|
||||
}
|
||||
@ -133,6 +137,10 @@ gtk_column_view_column_get_property (GObject *object,
|
||||
g_value_set_boolean (value, self->visible);
|
||||
break;
|
||||
|
||||
case PROP_HEADER_MENU:
|
||||
g_value_set_object (value, self->menu);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
@ -165,6 +173,10 @@ gtk_column_view_column_set_property (GObject *object,
|
||||
gtk_column_view_column_set_visible (self, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_HEADER_MENU:
|
||||
gtk_column_view_column_set_header_menu (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
@ -240,6 +252,18 @@ gtk_column_view_column_class_init (GtkColumnViewColumnClass *klass)
|
||||
TRUE,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* GtkColumnViewColumn:header-menu:
|
||||
*
|
||||
* Menu model used to create the context menu for the column header.
|
||||
*/
|
||||
properties[PROP_HEADER_MENU] =
|
||||
g_param_spec_object ("header-menu",
|
||||
P_("Header menu"),
|
||||
P_("Menu to use on the title of this column"),
|
||||
G_TYPE_MENU_MODEL,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
@ -723,3 +747,44 @@ gtk_column_view_column_get_visible (GtkColumnViewColumn *self)
|
||||
|
||||
return self->visible;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_column_view_column_set_header_menu:
|
||||
* @self: a #GtkColumnViewColumn
|
||||
* @menu: (allow-none): a #GMenuModel, or %NULL
|
||||
*
|
||||
* Sets the menu model that is used to create the context menu
|
||||
* for the column header.
|
||||
*/
|
||||
void
|
||||
gtk_column_view_column_set_header_menu (GtkColumnViewColumn *self,
|
||||
GMenuModel *menu)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self));
|
||||
g_return_if_fail (menu == NULL || G_IS_MENU_MODEL (menu));
|
||||
|
||||
if (!g_set_object (&self->menu, menu))
|
||||
return;
|
||||
|
||||
if (self->header)
|
||||
gtk_column_view_title_update (GTK_COLUMN_VIEW_TITLE (self->header));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HEADER_MENU]);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_column_view_column_get_header_menu:
|
||||
* @self: a #GtkColumnViewColumn
|
||||
*
|
||||
* Gets the menu model that is used to create the context menu
|
||||
* for the column header.
|
||||
*
|
||||
* Returns: the #GMenuModel, or %NULL
|
||||
*/
|
||||
GMenuModel *
|
||||
gtk_column_view_column_get_header_menu (GtkColumnViewColumn *self)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self), NULL);
|
||||
|
||||
return self->menu;
|
||||
}
|
||||
|
@ -78,6 +78,12 @@ void gtk_column_view_column_set_visible (GtkColu
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_column_view_column_get_visible (GtkColumnViewColumn *self);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_column_view_column_set_header_menu (GtkColumnViewColumn *self,
|
||||
GMenuModel *menu);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GMenuModel * gtk_column_view_column_get_header_menu (GtkColumnViewColumn *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_COLUMN_VIEW_COLUMN_H__ */
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "gtkbox.h"
|
||||
#include "gtkimage.h"
|
||||
#include "gtkgestureclick.h"
|
||||
#include "gtkpopovermenu.h"
|
||||
#include "gtknative.h"
|
||||
|
||||
struct _GtkColumnViewTitle
|
||||
{
|
||||
@ -40,6 +42,7 @@ struct _GtkColumnViewTitle
|
||||
GtkWidget *box;
|
||||
GtkWidget *title;
|
||||
GtkWidget *sort;
|
||||
GtkWidget *popup_menu;
|
||||
};
|
||||
|
||||
struct _GtkColumnViewTitleClass
|
||||
@ -70,10 +73,14 @@ gtk_column_view_title_size_allocate (GtkWidget *widget,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
GtkColumnViewTitle *self = GTK_COLUMN_VIEW_TITLE (widget);
|
||||
GtkWidget *child = gtk_widget_get_first_child (widget);
|
||||
|
||||
if (child)
|
||||
gtk_widget_allocate (child, width, height, baseline, NULL);
|
||||
|
||||
if (self->popup_menu)
|
||||
gtk_native_check_resize (GTK_NATIVE (self->popup_menu));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -82,6 +89,7 @@ gtk_column_view_title_dispose (GObject *object)
|
||||
GtkColumnViewTitle *self = GTK_COLUMN_VIEW_TITLE (object);
|
||||
|
||||
g_clear_pointer (&self->box, gtk_widget_unparent);
|
||||
g_clear_pointer (&self->popup_menu, gtk_widget_unparent);
|
||||
|
||||
g_clear_object (&self->column);
|
||||
|
||||
@ -112,13 +120,8 @@ gtk_column_view_title_resize_func (GtkWidget *widget)
|
||||
}
|
||||
|
||||
static void
|
||||
click_pressed_cb (GtkGestureClick *gesture,
|
||||
guint n_press,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
GtkWidget *widget)
|
||||
activate_sort (GtkColumnViewTitle *self)
|
||||
{
|
||||
GtkColumnViewTitle *self = GTK_COLUMN_VIEW_TITLE (widget);
|
||||
GtkSorter *sorter;
|
||||
GtkColumnView *view;
|
||||
GtkColumnViewSorter *view_sorter;
|
||||
@ -132,6 +135,56 @@ click_pressed_cb (GtkGestureClick *gesture,
|
||||
gtk_column_view_sorter_add_column (view_sorter, self->column);
|
||||
}
|
||||
|
||||
static void
|
||||
show_menu (GtkColumnViewTitle *self,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
if (!self->popup_menu)
|
||||
{
|
||||
GMenuModel *model;
|
||||
|
||||
model = gtk_column_view_column_get_header_menu (self->column);
|
||||
if (!model)
|
||||
return;
|
||||
|
||||
self->popup_menu = gtk_popover_menu_new_from_model (model);
|
||||
gtk_widget_set_parent (self->popup_menu, GTK_WIDGET (self));
|
||||
gtk_popover_set_position (GTK_POPOVER (self->popup_menu), GTK_POS_BOTTOM);
|
||||
|
||||
gtk_popover_set_has_arrow (GTK_POPOVER (self->popup_menu), FALSE);
|
||||
gtk_widget_set_halign (self->popup_menu, GTK_ALIGN_START);
|
||||
}
|
||||
|
||||
if (x != -1 && y != -1)
|
||||
{
|
||||
GdkRectangle rect = { x, y, 1, 1 };
|
||||
gtk_popover_set_pointing_to (GTK_POPOVER (self->popup_menu), &rect);
|
||||
}
|
||||
else
|
||||
gtk_popover_set_pointing_to (GTK_POPOVER (self->popup_menu), NULL);
|
||||
|
||||
gtk_popover_popup (GTK_POPOVER (self->popup_menu));
|
||||
}
|
||||
|
||||
static void
|
||||
click_released_cb (GtkGestureClick *gesture,
|
||||
guint n_press,
|
||||
double x,
|
||||
double y,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkColumnViewTitle *self = GTK_COLUMN_VIEW_TITLE (widget);
|
||||
guint button;
|
||||
|
||||
button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
|
||||
|
||||
if (button == GDK_BUTTON_PRIMARY)
|
||||
activate_sort (self);
|
||||
else if (button == GDK_BUTTON_SECONDARY)
|
||||
show_menu (self, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_column_view_title_init (GtkColumnViewTitle *self)
|
||||
{
|
||||
@ -150,7 +203,8 @@ gtk_column_view_title_init (GtkColumnViewTitle *self)
|
||||
gtk_box_append (GTK_BOX (self->box), self->sort);
|
||||
|
||||
gesture = gtk_gesture_click_new ();
|
||||
g_signal_connect (gesture, "pressed", G_CALLBACK (click_pressed_cb), self);
|
||||
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), 0);
|
||||
g_signal_connect (gesture, "released", G_CALLBACK (click_released_cb), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (gesture));
|
||||
}
|
||||
|
||||
@ -199,6 +253,8 @@ gtk_column_view_title_update (GtkColumnViewTitle *self)
|
||||
}
|
||||
else
|
||||
gtk_widget_hide (self->sort);
|
||||
|
||||
g_clear_pointer (&self->popup_menu, gtk_widget_unparent);
|
||||
}
|
||||
|
||||
GtkColumnViewColumn *
|
||||
|
Loading…
Reference in New Issue
Block a user