Compare commits
114 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 463dffe48d | |||
| d42c26b117 | |||
| 12d45c01b0 | |||
| fc3f4aafe5 | |||
| ffd8b19a87 | |||
| 20c4a4bb21 | |||
| f8647b02eb | |||
| 4b11e73be6 | |||
| 4de3e99fbe | |||
| c81e04755d | |||
| e4466dd4fe | |||
| 19e7d412e3 | |||
| 80c27061c6 | |||
| bd5c558646 | |||
| ad40630008 | |||
| f07ba4ac5b | |||
| 391add73ec | |||
| a21562f270 | |||
| 124607d1e8 | |||
| 9756cb9482 | |||
| 92f93a603b | |||
| e7cd3d4633 | |||
| 5780ec4bf1 | |||
| ec14c1f605 | |||
| c09fada79e | |||
| 9e6b4e82c9 | |||
| 4be2e804ae | |||
| 1056e9976a | |||
| 851bb61455 | |||
| 3aadc29af4 | |||
| 3d55b74197 | |||
| 19b1fcfee3 | |||
| 98cfbd3712 | |||
| 112f49b23c | |||
| 4d36fdc176 | |||
| 31d79b07b7 | |||
| 2405e2711e | |||
| 1527407c3d | |||
| f524a9315b | |||
| a5f22897f9 | |||
| 03840fb687 | |||
| 6e65c16b60 | |||
| 23e4d05383 | |||
| 489e9e0934 | |||
| 3acc014499 | |||
| 3ebe30bf32 | |||
| 996f011ed8 | |||
| 0611370a5f | |||
| 1be850d806 | |||
| b903d8ee33 | |||
| 8fd968e5bf | |||
| 366e8da927 | |||
| 203d612afd | |||
| 135580108a | |||
| 4515604511 | |||
| ad4a81e9df | |||
| 95e5472ade | |||
| 06ff4a8b6f | |||
| 1f0904d3df | |||
| 35a88c1440 | |||
| d1f4068b94 | |||
| 7e73da5f73 | |||
| c789a39660 | |||
| 3c6045e300 | |||
| 9389768a17 | |||
| 412006ad23 | |||
| ea456b80da | |||
| 152eabbaba | |||
| 9be0b3d76f | |||
| 27644dc573 | |||
| 41595cf336 | |||
| 8f3fb4109f | |||
| 417a70b096 | |||
| 6f82fd8b2e | |||
| 53d43dff46 | |||
| 3ef8af3be9 | |||
| fe6507f875 | |||
| 9b0d87c5a7 | |||
| a515fca63f | |||
| b6baa15e0a | |||
| 955ae40cd6 | |||
| dee9e40ad3 | |||
| a933a9bc79 | |||
| 6a4a082660 | |||
| a7cdcdf92c | |||
| a7a0a34da1 | |||
| 299bd5fa93 | |||
| c25e948375 | |||
| a03e531772 | |||
| 1420408858 | |||
| 4414e7ec7b | |||
| 217f9ea3b8 | |||
| ab7b9d882e | |||
| 4a19bab5b3 | |||
| 27d6276212 | |||
| d8d5cc9788 | |||
| 2687a2eb8d | |||
| c0bbfd950d | |||
| d541aed165 | |||
| c2ac141031 | |||
| cdee8270e2 | |||
| 6581d66652 | |||
| 7dbeee5d50 | |||
| 01e89f9142 | |||
| dafb7054a1 | |||
| 04bace1982 | |||
| 90701cb655 | |||
| ccccaa2681 | |||
| 421e9c3502 | |||
| ef031e1a9d | |||
| 9b62da10e6 | |||
| aa6f5dae5a | |||
| 0b1efebb39 | |||
| bbea1cc841 |
@@ -0,0 +1,282 @@
|
||||
/* Constraints/Simple
|
||||
*
|
||||
* GtkConstraintLayout provides a layout manager that uses relations
|
||||
* between widgets (also known as "constraints") to compute the position
|
||||
* and size of each child.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_DECLARE_FINAL_TYPE (SimpleGrid, simple_grid, SIMPLE, GRID, GtkWidget)
|
||||
|
||||
struct _SimpleGrid
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *button1, *button2;
|
||||
GtkWidget *button3;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (SimpleGrid, simple_grid, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
simple_grid_destroy (GtkWidget *widget)
|
||||
{
|
||||
SimpleGrid *self = SIMPLE_GRID (widget);
|
||||
|
||||
g_clear_pointer (&self->button1, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button2, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button3, gtk_widget_destroy);
|
||||
|
||||
GTK_WIDGET_CLASS (simple_grid_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
simple_grid_class_init (SimpleGridClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->destroy = simple_grid_destroy;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
||||
}
|
||||
|
||||
/* Layout:
|
||||
*
|
||||
* +-----------------------------+
|
||||
* | +-----------+ +-----------+ |
|
||||
* | | Child 1 | | Child 2 | |
|
||||
* | +-----------+ +-----------+ |
|
||||
* | +-------------------------+ |
|
||||
* | | Child 3 | |
|
||||
* | +-------------------------+ |
|
||||
* +-----------------------------+
|
||||
*
|
||||
* Constraints:
|
||||
*
|
||||
* super.start = child1.start - 8
|
||||
* child1.width = child2.width
|
||||
* child1.end = child2.start - 12
|
||||
* child2.end = super.end - 8
|
||||
* super.start = child3.start - 8
|
||||
* child3.end = super.end - 8
|
||||
* super.top = child1.top - 8
|
||||
* super.top = child2.top - 8
|
||||
* child1.bottom = child3.top - 12
|
||||
* child2.bottom = child3.top - 12
|
||||
* child3.height = child1.height
|
||||
* child3.height = child2.height
|
||||
* child3.bottom = super.bottom - 8
|
||||
*
|
||||
*/
|
||||
static void
|
||||
build_constraints (SimpleGrid *self,
|
||||
GtkConstraintLayout *manager)
|
||||
{
|
||||
GtkConstraintGuide *guide;
|
||||
|
||||
guide = g_object_new (GTK_TYPE_CONSTRAINT_GUIDE,
|
||||
"min-width", 10,
|
||||
"min-height", 10,
|
||||
"nat-width", 100,
|
||||
"nat-height", 10,
|
||||
NULL);
|
||||
gtk_constraint_layout_add_guide (manager, guide);
|
||||
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->button1),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
GTK_CONSTRAINT_RELATION_LE,
|
||||
200.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
guide,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (guide,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
-12.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
-12.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button1,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
self->button2,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (self->button3,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
}
|
||||
|
||||
static void
|
||||
simple_grid_init (SimpleGrid *self)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
|
||||
self->button1 = gtk_button_new_with_label ("Child 1");
|
||||
gtk_widget_set_parent (self->button1, widget);
|
||||
gtk_widget_set_name (self->button1, "button1");
|
||||
|
||||
self->button2 = gtk_button_new_with_label ("Child 2");
|
||||
gtk_widget_set_parent (self->button2, widget);
|
||||
gtk_widget_set_name (self->button2, "button2");
|
||||
|
||||
self->button3 = gtk_button_new_with_label ("Child 3");
|
||||
gtk_widget_set_parent (self->button3, widget);
|
||||
gtk_widget_set_name (self->button3, "button3");
|
||||
|
||||
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_constraints (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *header, *box, *grid, *button;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
grid = g_object_new (simple_grid_get_type (), NULL);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
gtk_widget_set_vexpand (grid, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (box), grid);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gtk_widget_destroy), window);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
/* Constraints/Interactive
|
||||
*
|
||||
* Demonstrate how constraints can be updates during
|
||||
* user interaction.
|
||||
*/
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
G_DECLARE_FINAL_TYPE (InteractiveGrid, interactive_grid, INTERACTIVE, GRID, GtkWidget)
|
||||
|
||||
struct _InteractiveGrid
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
GtkWidget *button1, *button2;
|
||||
GtkWidget *button3;
|
||||
GtkConstraintGuide *guide;
|
||||
GtkConstraint *constraint;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (InteractiveGrid, interactive_grid, GTK_TYPE_WIDGET)
|
||||
|
||||
static void
|
||||
interactive_grid_destroy (GtkWidget *widget)
|
||||
{
|
||||
InteractiveGrid *self = INTERACTIVE_GRID (widget);
|
||||
|
||||
g_clear_pointer (&self->button1, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button2, gtk_widget_destroy);
|
||||
g_clear_pointer (&self->button3, gtk_widget_destroy);
|
||||
|
||||
GTK_WIDGET_CLASS (interactive_grid_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
interactive_grid_class_init (InteractiveGridClass *klass)
|
||||
{
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->destroy = interactive_grid_destroy;
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_CONSTRAINT_LAYOUT);
|
||||
}
|
||||
|
||||
static void
|
||||
build_constraints (InteractiveGrid *self,
|
||||
GtkConstraintLayout *manager)
|
||||
{
|
||||
self->guide = g_object_new (GTK_TYPE_CONSTRAINT_GUIDE, NULL);
|
||||
gtk_constraint_layout_add_guide (manager, self->guide);
|
||||
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->button1),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button1),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->guide),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->guide),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->button3),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->guide),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->button1),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button2),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->button1),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_TARGET (self->button2),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
1.0,
|
||||
0.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
gtk_constraint_layout_add_constraint (manager,
|
||||
gtk_constraint_new (GTK_CONSTRAINT_TARGET (self->button3),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
NULL,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
1.0,
|
||||
-8.0,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED));
|
||||
}
|
||||
|
||||
static void
|
||||
drag_cb (GtkGestureDrag *drag,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
InteractiveGrid *self)
|
||||
{
|
||||
GtkConstraintLayout *layout = GTK_CONSTRAINT_LAYOUT (gtk_widget_get_layout_manager (GTK_WIDGET (self)));
|
||||
double x, y;
|
||||
|
||||
if (self->constraint)
|
||||
{
|
||||
gtk_constraint_layout_remove_constraint (layout, self->constraint);
|
||||
g_clear_object (&self->constraint);
|
||||
}
|
||||
|
||||
gtk_gesture_drag_get_start_point (drag, &x, &y);
|
||||
self->constraint = gtk_constraint_new_constant (GTK_CONSTRAINT_TARGET (self->guide),
|
||||
GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
x + offset_x,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
gtk_constraint_layout_add_constraint (layout, g_object_ref (self->constraint));
|
||||
gtk_widget_queue_allocate (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
interactive_grid_init (InteractiveGrid *self)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (self);
|
||||
GtkGesture *drag;
|
||||
|
||||
self->button1 = gtk_button_new_with_label ("Child 1");
|
||||
gtk_widget_set_parent (self->button1, widget);
|
||||
gtk_widget_set_name (self->button1, "button1");
|
||||
|
||||
self->button2 = gtk_button_new_with_label ("Child 2");
|
||||
gtk_widget_set_parent (self->button2, widget);
|
||||
gtk_widget_set_name (self->button2, "button2");
|
||||
|
||||
self->button3 = gtk_button_new_with_label ("Child 3");
|
||||
gtk_widget_set_parent (self->button3, widget);
|
||||
gtk_widget_set_name (self->button3, "button3");
|
||||
|
||||
GtkLayoutManager *manager = gtk_widget_get_layout_manager (GTK_WIDGET (self));
|
||||
build_constraints (self, GTK_CONSTRAINT_LAYOUT (manager));
|
||||
|
||||
drag = gtk_gesture_drag_new ();
|
||||
g_signal_connect (drag, "drag-update", G_CALLBACK (drag_cb), self);
|
||||
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (drag));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_constraints2 (GtkWidget *do_widget)
|
||||
{
|
||||
static GtkWidget *window;
|
||||
|
||||
if (!window)
|
||||
{
|
||||
GtkWidget *header, *box, *grid, *button;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_display (GTK_WINDOW (window), gtk_widget_get_display (do_widget));
|
||||
|
||||
header = gtk_header_bar_new ();
|
||||
gtk_header_bar_set_title (GTK_HEADER_BAR (header), "Constraints");
|
||||
gtk_header_bar_set_show_title_buttons (GTK_HEADER_BAR (header), FALSE);
|
||||
gtk_window_set_titlebar (GTK_WINDOW (window), header);
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
grid = g_object_new (interactive_grid_get_type (), NULL);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
gtk_widget_set_vexpand (grid, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (box), grid);
|
||||
|
||||
button = gtk_button_new_with_label ("Close");
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
gtk_widget_set_hexpand (grid, TRUE);
|
||||
g_signal_connect_swapped (button, "clicked",
|
||||
G_CALLBACK (gtk_widget_destroy), window);
|
||||
}
|
||||
|
||||
if (!gtk_widget_get_visible (window))
|
||||
gtk_widget_show (window);
|
||||
else
|
||||
gtk_widget_destroy (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
@@ -150,6 +150,8 @@
|
||||
<file>clipboard.c</file>
|
||||
<file>colorsel.c</file>
|
||||
<file>combobox.c</file>
|
||||
<file>constraints.c</file>
|
||||
<file>constraints2.c</file>
|
||||
<file>css_accordion.c</file>
|
||||
<file>css_basics.c</file>
|
||||
<file>css_blendmodes.c</file>
|
||||
|
||||
@@ -8,6 +8,8 @@ demos = files([
|
||||
'clipboard.c',
|
||||
'colorsel.c',
|
||||
'combobox.c',
|
||||
'constraints.c',
|
||||
'constraints2.c',
|
||||
'css_accordion.c',
|
||||
'css_basics.c',
|
||||
'css_blendmodes.c',
|
||||
|
||||
@@ -1128,6 +1128,7 @@ gdk_monitor_get_width_mm
|
||||
gdk_monitor_get_height_mm
|
||||
gdk_monitor_get_manufacturer
|
||||
gdk_monitor_get_model
|
||||
gdk_monitor_get_connector
|
||||
gdk_monitor_get_scale_factor
|
||||
gdk_monitor_get_refresh_rate
|
||||
GdkSubpixelLayout
|
||||
|
||||
@@ -258,9 +258,11 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Actions are added to their relevant scope (application or
|
||||
window) either using the GActionMap interface, or by using
|
||||
gtk_widget_insert_action_group().
|
||||
Actions are added to their relevant scope (application,
|
||||
window or widget) either using the GActionMap interface,
|
||||
or by using gtk_widget_insert_action_group(). Actions that
|
||||
will be the same for all instances of a widget class can
|
||||
be added globally using gtk_widget_class_install_action().
|
||||
</para>
|
||||
|
||||
</refsect2>
|
||||
@@ -317,8 +319,8 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Another of obtaining widgets that are connected to actions is
|
||||
to create a menu using a GMenu menu model. GMenu provides an
|
||||
Another way of obtaining widgets that are connected to actions
|
||||
is to create a menu using a GMenu menu model. GMenu provides an
|
||||
abstract way to describe typical menus: nested groups of items
|
||||
where each item can have a label, and icon, and an action.
|
||||
</para>
|
||||
@@ -364,6 +366,25 @@
|
||||
(typically a GtkWindow, GtkDialog or GtkPopover)
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>clipboard.cut, clipboard.copy, clipboard.paste</term>
|
||||
<listitem><para>Clipboard operations on entries, text view
|
||||
and labels, typically used in the context menu
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>selection.delete, selection.select-all</term>
|
||||
<listitem><para>Selection operations on entries, text view
|
||||
and labels
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>color.select, color.customize</term>
|
||||
<listitem><para>Operations on colors in GtkColorChooserWidget.
|
||||
These actions are unusual in that they have the non-trivial
|
||||
parameter type (dddd).
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
|
||||
@@ -4549,10 +4549,6 @@ gtk_widget_get_opacity
|
||||
gtk_widget_set_opacity
|
||||
gtk_widget_get_overflow
|
||||
gtk_widget_set_overflow
|
||||
gtk_widget_insert_action_group
|
||||
gtk_widget_list_action_prefixes
|
||||
gtk_widget_activate_action
|
||||
gtk_widget_activate_default
|
||||
gtk_widget_measure
|
||||
gtk_widget_snapshot_child
|
||||
gtk_widget_get_next_sibling
|
||||
@@ -4629,6 +4625,17 @@ gtk_widget_class_set_connect_func
|
||||
gtk_widget_observe_children
|
||||
gtk_widget_observe_controllers
|
||||
|
||||
<SUBSECTION Actions>
|
||||
gtk_widget_insert_action_group
|
||||
gtk_widget_activate_action
|
||||
gtk_widget_activate_action_variant
|
||||
gtk_widget_activate_default
|
||||
GtkWidgetActionActivateFunc
|
||||
gtk_widget_class_install_action
|
||||
gtk_widget_class_install_property_action
|
||||
gtk_widget_class_query_action
|
||||
gtk_widget_action_set_enabled
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_WIDGET
|
||||
GTK_IS_WIDGET
|
||||
@@ -5195,7 +5202,6 @@ GtkBindingSet
|
||||
GtkBindingEntry
|
||||
GtkBindingSignal
|
||||
GtkBindingArg
|
||||
gtk_binding_entry_add_signall
|
||||
gtk_binding_set_new
|
||||
gtk_binding_set_by_class
|
||||
gtk_binding_set_find
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <gtk/gtkunixprint.h>
|
||||
|
||||
gtk_about_dialog_get_type
|
||||
gtk_accel_group_get_type
|
||||
gtk_accel_label_get_type
|
||||
|
||||
@@ -234,7 +234,7 @@ gdk_content_formats_unref (GdkContentFormats *formats)
|
||||
* This is meant for debugging and logging.
|
||||
*
|
||||
* The form of the representation may change at any time and is
|
||||
* not guranteed to stay identical.
|
||||
* not guaranteed to stay identical.
|
||||
**/
|
||||
void
|
||||
gdk_content_formats_print (GdkContentFormats *formats,
|
||||
|
||||
@@ -49,6 +49,7 @@ enum {
|
||||
PROP_DISPLAY,
|
||||
PROP_MANUFACTURER,
|
||||
PROP_MODEL,
|
||||
PROP_CONNECTOR,
|
||||
PROP_SCALE_FACTOR,
|
||||
PROP_GEOMETRY,
|
||||
PROP_WORKAREA,
|
||||
@@ -100,6 +101,10 @@ gdk_monitor_get_property (GObject *object,
|
||||
g_value_set_string (value, monitor->model);
|
||||
break;
|
||||
|
||||
case PROP_CONNECTOR:
|
||||
g_value_set_string (value, monitor->connector);
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
g_value_set_int (value, monitor->scale_factor);
|
||||
break;
|
||||
@@ -165,6 +170,7 @@ gdk_monitor_finalize (GObject *object)
|
||||
{
|
||||
GdkMonitor *monitor = GDK_MONITOR (object);
|
||||
|
||||
g_free (monitor->connector);
|
||||
g_free (monitor->manufacturer);
|
||||
g_free (monitor->model);
|
||||
|
||||
@@ -198,6 +204,12 @@ gdk_monitor_class_init (GdkMonitorClass *class)
|
||||
"The model name",
|
||||
NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
props[PROP_CONNECTOR] =
|
||||
g_param_spec_string ("connector",
|
||||
"Connector",
|
||||
"The connector name",
|
||||
NULL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
props[PROP_SCALE_FACTOR] =
|
||||
g_param_spec_int ("scale-factor",
|
||||
"Scale factor",
|
||||
@@ -369,6 +381,22 @@ gdk_monitor_get_height_mm (GdkMonitor *monitor)
|
||||
return monitor->height_mm;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_connector:
|
||||
* @monitor: a #GdkMonitor
|
||||
*
|
||||
* Gets the name of the monitor's connector, if available.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): the name of the connector
|
||||
*/
|
||||
const char *
|
||||
gdk_monitor_get_connector (GdkMonitor *monitor)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_MONITOR (monitor), NULL);
|
||||
|
||||
return monitor->connector;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_monitor_get_manufacturer:
|
||||
* @monitor: a #GdkMonitor
|
||||
@@ -504,6 +532,16 @@ gdk_monitor_set_model (GdkMonitor *monitor,
|
||||
g_object_notify (G_OBJECT (monitor), "model");
|
||||
}
|
||||
|
||||
void
|
||||
gdk_monitor_set_connector (GdkMonitor *monitor,
|
||||
const char *connector)
|
||||
{
|
||||
g_free (monitor->connector);
|
||||
monitor->connector = g_strdup (connector);
|
||||
|
||||
g_object_notify (G_OBJECT (monitor), "connector");
|
||||
}
|
||||
|
||||
void
|
||||
gdk_monitor_set_position (GdkMonitor *monitor,
|
||||
int x,
|
||||
|
||||
@@ -80,6 +80,8 @@ const char * gdk_monitor_get_manufacturer (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const char * gdk_monitor_get_model (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const char * gdk_monitor_get_connector (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_monitor_get_scale_factor (GdkMonitor *monitor);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gdk_monitor_get_refresh_rate (GdkMonitor *monitor);
|
||||
|
||||
@@ -36,6 +36,7 @@ struct _GdkMonitor {
|
||||
GdkDisplay *display;
|
||||
char *manufacturer;
|
||||
char *model;
|
||||
char *connector;
|
||||
GdkRectangle geometry;
|
||||
int width_mm;
|
||||
int height_mm;
|
||||
@@ -58,6 +59,8 @@ void gdk_monitor_set_manufacturer (GdkMonitor *monitor,
|
||||
const char *manufacturer);
|
||||
void gdk_monitor_set_model (GdkMonitor *monitor,
|
||||
const char *model);
|
||||
void gdk_monitor_set_connector (GdkMonitor *monitor,
|
||||
const char *connector);
|
||||
void gdk_monitor_set_position (GdkMonitor *monitor,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
@@ -531,8 +531,11 @@ gdk_registry_handle_global (void *data,
|
||||
}
|
||||
else if (strcmp(interface, "zxdg_output_manager_v1") == 0)
|
||||
{
|
||||
display_wayland->xdg_output_manager_version = MIN (version, 2);
|
||||
display_wayland->xdg_output_manager =
|
||||
wl_registry_bind (registry, id, &zxdg_output_manager_v1_interface, 1);
|
||||
wl_registry_bind (display_wayland->wl_registry, id,
|
||||
&zxdg_output_manager_v1_interface,
|
||||
display_wayland->xdg_output_manager_version);
|
||||
gdk_wayland_display_init_xdg_output (display_wayland);
|
||||
_gdk_wayland_display_async_roundtrip (display_wayland);
|
||||
}
|
||||
@@ -2222,6 +2225,7 @@ apply_monitor_change (GdkWaylandMonitor *monitor)
|
||||
|
||||
gdk_monitor_set_position (GDK_MONITOR (monitor), monitor->x, monitor->y);
|
||||
gdk_monitor_set_size (GDK_MONITOR (monitor), monitor->width, monitor->height);
|
||||
gdk_monitor_set_connector (GDK_MONITOR (monitor), monitor->name);
|
||||
monitor->wl_output_done = FALSE;
|
||||
monitor->xdg_output_done = FALSE;
|
||||
|
||||
@@ -2272,10 +2276,36 @@ xdg_output_handle_done (void *data,
|
||||
apply_monitor_change (monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_name (void *data,
|
||||
struct zxdg_output_v1 *xdg_output,
|
||||
const char *name)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle name xdg-output %d", monitor->id));
|
||||
|
||||
monitor->name = g_strdup (name);
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_description (void *data,
|
||||
struct zxdg_output_v1 *xdg_output,
|
||||
const char *description)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *) data;
|
||||
|
||||
GDK_NOTE (MISC,
|
||||
g_message ("handle description xdg-output %d", monitor->id));
|
||||
}
|
||||
|
||||
static const struct zxdg_output_v1_listener xdg_output_listener = {
|
||||
xdg_output_handle_logical_position,
|
||||
xdg_output_handle_logical_size,
|
||||
xdg_output_handle_done,
|
||||
xdg_output_handle_name,
|
||||
xdg_output_handle_description,
|
||||
};
|
||||
|
||||
static void
|
||||
|
||||
@@ -137,6 +137,7 @@ struct _GdkWaylandDisplay
|
||||
int seat_version;
|
||||
int data_device_manager_version;
|
||||
int gtk_shell_version;
|
||||
int xdg_output_manager_version;
|
||||
|
||||
uint32_t server_decoration_mode;
|
||||
|
||||
|
||||
@@ -391,13 +391,13 @@ find_eglconfig_for_surface (GdkSurface *surface,
|
||||
attrs[i++] = EGL_RGB_BUFFER;
|
||||
|
||||
attrs[i++] = EGL_RED_SIZE;
|
||||
attrs[i++] = 1;
|
||||
attrs[i++] = 8;
|
||||
attrs[i++] = EGL_GREEN_SIZE;
|
||||
attrs[i++] = 1;
|
||||
attrs[i++] = 8;
|
||||
attrs[i++] = EGL_BLUE_SIZE;
|
||||
attrs[i++] = 1;
|
||||
attrs[i++] = 8;
|
||||
attrs[i++] = EGL_ALPHA_SIZE;
|
||||
attrs[i++] = 1;
|
||||
attrs[i++] = 8;
|
||||
|
||||
attrs[i++] = EGL_NONE;
|
||||
g_assert (i < MAX_EGL_ATTRS);
|
||||
|
||||
@@ -35,6 +35,8 @@ gdk_wayland_monitor_finalize (GObject *object)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)object;
|
||||
|
||||
g_free (monitor->name);
|
||||
|
||||
wl_output_destroy (monitor->output);
|
||||
|
||||
G_OBJECT_CLASS (gdk_wayland_monitor_parent_class)->finalize (object);
|
||||
|
||||
@@ -37,6 +37,7 @@ struct _GdkWaylandMonitor {
|
||||
int32_t y;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
char *name;
|
||||
gboolean wl_output_done;
|
||||
gboolean xdg_output_done;
|
||||
};
|
||||
|
||||
@@ -821,7 +821,7 @@ gdk_x11_drop_finish (GdkDrop *drop,
|
||||
|
||||
if (gdk_drop_get_drag (drop))
|
||||
{
|
||||
gdk_x11_drag_handle_status (display, &xev);
|
||||
gdk_x11_drag_handle_finished (display, &xev);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -432,6 +432,7 @@ init_randr15 (GdkX11Screen *x11_screen, gboolean *changed)
|
||||
gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh_rate);
|
||||
gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), x11_screen->surface_scale);
|
||||
gdk_monitor_set_model (GDK_MONITOR (monitor), name);
|
||||
gdk_monitor_set_connector (GDK_MONITOR (monitor), name);
|
||||
g_free (name);
|
||||
|
||||
if (rr_monitors[i].primary)
|
||||
|
||||
+2
-2
@@ -99,7 +99,7 @@ gsk_render_node_new (const GskRenderNodeClass *node_class, gsize extra_size)
|
||||
*
|
||||
* Acquires a reference on the given #GskRenderNode.
|
||||
*
|
||||
* Returns: (transfer none): the #GskRenderNode with an additional reference
|
||||
* Returns: (transfer full): the #GskRenderNode with an additional reference
|
||||
*/
|
||||
GskRenderNode *
|
||||
gsk_render_node_ref (GskRenderNode *node)
|
||||
@@ -113,7 +113,7 @@ gsk_render_node_ref (GskRenderNode *node)
|
||||
|
||||
/**
|
||||
* gsk_render_node_unref:
|
||||
* @node: a #GskRenderNode
|
||||
* @node: (transfer full): a #GskRenderNode
|
||||
*
|
||||
* Releases a reference on the given #GskRenderNode.
|
||||
*
|
||||
|
||||
@@ -73,7 +73,8 @@ typedef enum
|
||||
typedef enum
|
||||
{
|
||||
GTK_CSS_PARSER_WARNING_DEPRECATED,
|
||||
GTK_CSS_PARSER_WARNING_SYNTAX
|
||||
GTK_CSS_PARSER_WARNING_SYNTAX,
|
||||
GTK_CSS_PARSER_WARNING_UNIMPLEMENTED
|
||||
} GtkCssParserWarning;
|
||||
|
||||
#endif /* __GTK_CSS_ENUMS_H__ */
|
||||
|
||||
@@ -155,7 +155,7 @@ gtk_css_section_get_file (const GtkCssSection *section)
|
||||
*
|
||||
* Returns the location in the CSS document where this section starts.
|
||||
*
|
||||
* Returns: (tranfer none) (not nullable): The start location of
|
||||
* Returns: (transfer none) (not nullable): The start location of
|
||||
* this section
|
||||
**/
|
||||
const GtkCssLocation *
|
||||
@@ -172,7 +172,7 @@ gtk_css_section_get_start_location (const GtkCssSection *section)
|
||||
*
|
||||
* Returns the location in the CSS document where this section ends.
|
||||
*
|
||||
* Returns: (tranfer none) (not nullable): The end location of
|
||||
* Returns: (transfer none) (not nullable): The end location of
|
||||
* this section
|
||||
**/
|
||||
const GtkCssLocation *
|
||||
|
||||
@@ -0,0 +1,592 @@
|
||||
/*
|
||||
* Copyright © 2010 Novell, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Vincent Untz <vuntz@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gsettings-mapping.h"
|
||||
|
||||
static GVariant *
|
||||
g_settings_set_mapping_int (const GValue *value,
|
||||
const GVariantType *expected_type)
|
||||
{
|
||||
GVariant *variant = NULL;
|
||||
gint64 l;
|
||||
|
||||
if (G_VALUE_HOLDS_INT (value))
|
||||
l = g_value_get_int (value);
|
||||
else if (G_VALUE_HOLDS_INT64 (value))
|
||||
l = g_value_get_int64 (value);
|
||||
else
|
||||
return NULL;
|
||||
|
||||
if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
|
||||
{
|
||||
if (G_MININT16 <= l && l <= G_MAXINT16)
|
||||
variant = g_variant_new_int16 ((gint16) l);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
|
||||
{
|
||||
if (0 <= l && l <= G_MAXUINT16)
|
||||
variant = g_variant_new_uint16 ((guint16) l);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
|
||||
{
|
||||
if (G_MININT32 <= l && l <= G_MAXINT32)
|
||||
variant = g_variant_new_int32 ((gint) l);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
|
||||
{
|
||||
if (0 <= l && l <= G_MAXUINT32)
|
||||
variant = g_variant_new_uint32 ((guint) l);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
|
||||
{
|
||||
if (G_MININT64 <= l && l <= G_MAXINT64)
|
||||
variant = g_variant_new_int64 ((gint64) l);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
|
||||
{
|
||||
if (0 <= l && l <= G_MAXUINT64)
|
||||
variant = g_variant_new_uint64 ((guint64) l);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
|
||||
{
|
||||
if (0 <= l && l <= G_MAXUINT32)
|
||||
variant = g_variant_new_handle ((guint) l);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
|
||||
variant = g_variant_new_double ((gdouble) l);
|
||||
|
||||
return variant;
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
g_settings_set_mapping_float (const GValue *value,
|
||||
const GVariantType *expected_type)
|
||||
{
|
||||
GVariant *variant = NULL;
|
||||
gdouble d;
|
||||
gint64 l;
|
||||
|
||||
if (G_VALUE_HOLDS_DOUBLE (value))
|
||||
d = g_value_get_double (value);
|
||||
else
|
||||
return NULL;
|
||||
|
||||
l = (gint64) d;
|
||||
if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
|
||||
{
|
||||
if (G_MININT16 <= l && l <= G_MAXINT16)
|
||||
variant = g_variant_new_int16 ((gint16) l);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
|
||||
{
|
||||
if (0 <= l && l <= G_MAXUINT16)
|
||||
variant = g_variant_new_uint16 ((guint16) l);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
|
||||
{
|
||||
if (G_MININT32 <= l && l <= G_MAXINT32)
|
||||
variant = g_variant_new_int32 ((gint) l);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
|
||||
{
|
||||
if (0 <= l && l <= G_MAXUINT32)
|
||||
variant = g_variant_new_uint32 ((guint) l);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
|
||||
{
|
||||
if (G_MININT64 <= l && l <= G_MAXINT64)
|
||||
variant = g_variant_new_int64 ((gint64) l);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
|
||||
{
|
||||
if (0 <= l && l <= G_MAXUINT64)
|
||||
variant = g_variant_new_uint64 ((guint64) l);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
|
||||
{
|
||||
if (0 <= l && l <= G_MAXUINT32)
|
||||
variant = g_variant_new_handle ((guint) l);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
|
||||
variant = g_variant_new_double ((gdouble) d);
|
||||
|
||||
return variant;
|
||||
}
|
||||
static GVariant *
|
||||
g_settings_set_mapping_unsigned_int (const GValue *value,
|
||||
const GVariantType *expected_type)
|
||||
{
|
||||
GVariant *variant = NULL;
|
||||
guint64 u;
|
||||
|
||||
if (G_VALUE_HOLDS_UINT (value))
|
||||
u = g_value_get_uint (value);
|
||||
else if (G_VALUE_HOLDS_UINT64 (value))
|
||||
u = g_value_get_uint64 (value);
|
||||
else
|
||||
return NULL;
|
||||
|
||||
if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT16))
|
||||
{
|
||||
if (u <= G_MAXINT16)
|
||||
variant = g_variant_new_int16 ((gint16) u);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT16))
|
||||
{
|
||||
if (u <= G_MAXUINT16)
|
||||
variant = g_variant_new_uint16 ((guint16) u);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT32))
|
||||
{
|
||||
if (u <= G_MAXINT32)
|
||||
variant = g_variant_new_int32 ((gint) u);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT32))
|
||||
{
|
||||
if (u <= G_MAXUINT32)
|
||||
variant = g_variant_new_uint32 ((guint) u);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_INT64))
|
||||
{
|
||||
if (u <= G_MAXINT64)
|
||||
variant = g_variant_new_int64 ((gint64) u);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_UINT64))
|
||||
{
|
||||
if (u <= G_MAXUINT64)
|
||||
variant = g_variant_new_uint64 ((guint64) u);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_HANDLE))
|
||||
{
|
||||
if (u <= G_MAXUINT32)
|
||||
variant = g_variant_new_handle ((guint) u);
|
||||
}
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_DOUBLE))
|
||||
variant = g_variant_new_double ((gdouble) u);
|
||||
|
||||
return variant;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_settings_get_mapping_int (GValue *value,
|
||||
GVariant *variant)
|
||||
{
|
||||
const GVariantType *type;
|
||||
gint64 l;
|
||||
|
||||
type = g_variant_get_type (variant);
|
||||
|
||||
if (g_variant_type_equal (type, G_VARIANT_TYPE_INT16))
|
||||
l = g_variant_get_int16 (variant);
|
||||
else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT32))
|
||||
l = g_variant_get_int32 (variant);
|
||||
else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
|
||||
l = g_variant_get_int64 (variant);
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
if (G_VALUE_HOLDS_INT (value))
|
||||
{
|
||||
g_value_set_int (value, l);
|
||||
return (G_MININT32 <= l && l <= G_MAXINT32);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_UINT (value))
|
||||
{
|
||||
g_value_set_uint (value, l);
|
||||
return (0 <= l && l <= G_MAXUINT32);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_INT64 (value))
|
||||
{
|
||||
g_value_set_int64 (value, l);
|
||||
return (G_MININT64 <= l && l <= G_MAXINT64);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_UINT64 (value))
|
||||
{
|
||||
g_value_set_uint64 (value, l);
|
||||
return (0 <= l && l <= G_MAXUINT64);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_DOUBLE (value))
|
||||
{
|
||||
g_value_set_double (value, l);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_settings_get_mapping_float (GValue *value,
|
||||
GVariant *variant)
|
||||
{
|
||||
const GVariantType *type;
|
||||
gdouble d;
|
||||
gint64 l;
|
||||
|
||||
type = g_variant_get_type (variant);
|
||||
|
||||
if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
|
||||
d = g_variant_get_double (variant);
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
l = (gint64)d;
|
||||
if (G_VALUE_HOLDS_INT (value))
|
||||
{
|
||||
g_value_set_int (value, l);
|
||||
return (G_MININT32 <= l && l <= G_MAXINT32);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_UINT (value))
|
||||
{
|
||||
g_value_set_uint (value, l);
|
||||
return (0 <= l && l <= G_MAXUINT32);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_INT64 (value))
|
||||
{
|
||||
g_value_set_int64 (value, l);
|
||||
return (G_MININT64 <= l && l <= G_MAXINT64);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_UINT64 (value))
|
||||
{
|
||||
g_value_set_uint64 (value, l);
|
||||
return (0 <= l && l <= G_MAXUINT64);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_DOUBLE (value))
|
||||
{
|
||||
g_value_set_double (value, d);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
static gboolean
|
||||
g_settings_get_mapping_unsigned_int (GValue *value,
|
||||
GVariant *variant)
|
||||
{
|
||||
const GVariantType *type;
|
||||
guint64 u;
|
||||
|
||||
type = g_variant_get_type (variant);
|
||||
|
||||
if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT16))
|
||||
u = g_variant_get_uint16 (variant);
|
||||
else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT32))
|
||||
u = g_variant_get_uint32 (variant);
|
||||
else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
|
||||
u = g_variant_get_uint64 (variant);
|
||||
else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
|
||||
u = g_variant_get_handle (variant);
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
if (G_VALUE_HOLDS_INT (value))
|
||||
{
|
||||
g_value_set_int (value, u);
|
||||
return (u <= G_MAXINT32);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_UINT (value))
|
||||
{
|
||||
g_value_set_uint (value, u);
|
||||
return (u <= G_MAXUINT32);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_INT64 (value))
|
||||
{
|
||||
g_value_set_int64 (value, u);
|
||||
return (u <= G_MAXINT64);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_UINT64 (value))
|
||||
{
|
||||
g_value_set_uint64 (value, u);
|
||||
return (u <= G_MAXUINT64);
|
||||
}
|
||||
else if (G_VALUE_HOLDS_DOUBLE (value))
|
||||
{
|
||||
g_value_set_double (value, u);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GVariant *
|
||||
g_settings_set_mapping (const GValue *value,
|
||||
const GVariantType *expected_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
gchar *type_string;
|
||||
|
||||
if (G_VALUE_HOLDS_BOOLEAN (value))
|
||||
{
|
||||
if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BOOLEAN))
|
||||
return g_variant_new_boolean (g_value_get_boolean (value));
|
||||
}
|
||||
|
||||
else if (G_VALUE_HOLDS_CHAR (value) ||
|
||||
G_VALUE_HOLDS_UCHAR (value))
|
||||
{
|
||||
if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTE))
|
||||
{
|
||||
if (G_VALUE_HOLDS_CHAR (value))
|
||||
return g_variant_new_byte (g_value_get_schar (value));
|
||||
else
|
||||
return g_variant_new_byte (g_value_get_uchar (value));
|
||||
}
|
||||
}
|
||||
|
||||
else if (G_VALUE_HOLDS_INT (value) ||
|
||||
G_VALUE_HOLDS_INT64 (value))
|
||||
return g_settings_set_mapping_int (value, expected_type);
|
||||
|
||||
else if (G_VALUE_HOLDS_DOUBLE (value))
|
||||
return g_settings_set_mapping_float (value, expected_type);
|
||||
|
||||
else if (G_VALUE_HOLDS_UINT (value) ||
|
||||
G_VALUE_HOLDS_UINT64 (value))
|
||||
return g_settings_set_mapping_unsigned_int (value, expected_type);
|
||||
|
||||
else if (G_VALUE_HOLDS_STRING (value))
|
||||
{
|
||||
if (g_value_get_string (value) == NULL)
|
||||
return NULL;
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_STRING))
|
||||
return g_variant_new_string (g_value_get_string (value));
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_BYTESTRING))
|
||||
return g_variant_new_bytestring (g_value_get_string (value));
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_OBJECT_PATH))
|
||||
return g_variant_new_object_path (g_value_get_string (value));
|
||||
else if (g_variant_type_equal (expected_type, G_VARIANT_TYPE_SIGNATURE))
|
||||
return g_variant_new_signature (g_value_get_string (value));
|
||||
}
|
||||
|
||||
else if (G_VALUE_HOLDS (value, G_TYPE_STRV))
|
||||
{
|
||||
if (g_value_get_boxed (value) == NULL)
|
||||
return NULL;
|
||||
return g_variant_new_strv ((const gchar **) g_value_get_boxed (value),
|
||||
-1);
|
||||
}
|
||||
|
||||
else if (G_VALUE_HOLDS_ENUM (value))
|
||||
{
|
||||
GEnumValue *enumval;
|
||||
GEnumClass *eclass;
|
||||
|
||||
/* GParamSpecEnum holds a ref on the class so we just peek... */
|
||||
eclass = g_type_class_peek (G_VALUE_TYPE (value));
|
||||
enumval = g_enum_get_value (eclass, g_value_get_enum (value));
|
||||
|
||||
if (enumval)
|
||||
return g_variant_new_string (enumval->value_nick);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
else if (G_VALUE_HOLDS_FLAGS (value))
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
GFlagsValue *flagsval;
|
||||
GFlagsClass *fclass;
|
||||
guint flags;
|
||||
|
||||
fclass = g_type_class_peek (G_VALUE_TYPE (value));
|
||||
flags = g_value_get_flags (value);
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
|
||||
while (flags)
|
||||
{
|
||||
flagsval = g_flags_get_first_value (fclass, flags);
|
||||
|
||||
if (flagsval == NULL)
|
||||
{
|
||||
g_variant_builder_clear (&builder);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_variant_builder_add (&builder, "s", flagsval->value_nick);
|
||||
flags &= ~flagsval->value;
|
||||
}
|
||||
|
||||
return g_variant_builder_end (&builder);
|
||||
}
|
||||
|
||||
type_string = g_variant_type_dup_string (expected_type);
|
||||
g_critical ("No GSettings bind handler for type \"%s\".", type_string);
|
||||
g_free (type_string);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_settings_get_mapping (GValue *value,
|
||||
GVariant *variant,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN))
|
||||
{
|
||||
if (!G_VALUE_HOLDS_BOOLEAN (value))
|
||||
return FALSE;
|
||||
g_value_set_boolean (value, g_variant_get_boolean (variant));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTE))
|
||||
{
|
||||
if (G_VALUE_HOLDS_UCHAR (value))
|
||||
g_value_set_uchar (value, g_variant_get_byte (variant));
|
||||
else if (G_VALUE_HOLDS_CHAR (value))
|
||||
g_value_set_schar (value, (gint8)g_variant_get_byte (variant));
|
||||
else
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT16) ||
|
||||
g_variant_is_of_type (variant, G_VARIANT_TYPE_INT32) ||
|
||||
g_variant_is_of_type (variant, G_VARIANT_TYPE_INT64))
|
||||
return g_settings_get_mapping_int (value, variant);
|
||||
|
||||
else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE))
|
||||
return g_settings_get_mapping_float (value, variant);
|
||||
|
||||
else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT16) ||
|
||||
g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32) ||
|
||||
g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT64) ||
|
||||
g_variant_is_of_type (variant, G_VARIANT_TYPE_HANDLE))
|
||||
return g_settings_get_mapping_unsigned_int (value, variant);
|
||||
|
||||
else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING) ||
|
||||
g_variant_is_of_type (variant, G_VARIANT_TYPE_OBJECT_PATH) ||
|
||||
g_variant_is_of_type (variant, G_VARIANT_TYPE_SIGNATURE))
|
||||
{
|
||||
if (G_VALUE_HOLDS_STRING (value))
|
||||
{
|
||||
g_value_set_string (value, g_variant_get_string (variant, NULL));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
else if (G_VALUE_HOLDS_ENUM (value))
|
||||
{
|
||||
GEnumClass *eclass;
|
||||
GEnumValue *evalue;
|
||||
const gchar *nick;
|
||||
|
||||
/* GParamSpecEnum holds a ref on the class so we just peek... */
|
||||
eclass = g_type_class_peek (G_VALUE_TYPE (value));
|
||||
nick = g_variant_get_string (variant, NULL);
|
||||
evalue = g_enum_get_value_by_nick (eclass, nick);
|
||||
|
||||
if (evalue)
|
||||
{
|
||||
g_value_set_enum (value, evalue->value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_warning ("Unable to look up enum nick ‘%s’ via GType", nick);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (g_variant_is_of_type (variant, G_VARIANT_TYPE ("as")))
|
||||
{
|
||||
if (G_VALUE_HOLDS (value, G_TYPE_STRV))
|
||||
{
|
||||
g_value_take_boxed (value, g_variant_dup_strv (variant, NULL));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
else if (G_VALUE_HOLDS_FLAGS (value))
|
||||
{
|
||||
GFlagsClass *fclass;
|
||||
GFlagsValue *fvalue;
|
||||
const gchar *nick;
|
||||
GVariantIter iter;
|
||||
guint flags = 0;
|
||||
|
||||
fclass = g_type_class_peek (G_VALUE_TYPE (value));
|
||||
|
||||
g_variant_iter_init (&iter, variant);
|
||||
while (g_variant_iter_next (&iter, "&s", &nick))
|
||||
{
|
||||
fvalue = g_flags_get_value_by_nick (fclass, nick);
|
||||
|
||||
if (fvalue)
|
||||
flags |= fvalue->value;
|
||||
|
||||
else
|
||||
{
|
||||
g_warning ("Unable to lookup flags nick '%s' via GType",
|
||||
nick);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
g_value_set_flags (value, flags);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_BYTESTRING))
|
||||
{
|
||||
g_value_set_string (value, g_variant_get_bytestring (variant));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_critical ("No GSettings bind handler for type \"%s\".",
|
||||
g_variant_get_type_string (variant));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
g_settings_mapping_is_compatible (GType gvalue_type,
|
||||
const GVariantType *variant_type)
|
||||
{
|
||||
gboolean ok = FALSE;
|
||||
|
||||
if (gvalue_type == G_TYPE_BOOLEAN)
|
||||
ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_BOOLEAN);
|
||||
else if (gvalue_type == G_TYPE_CHAR ||
|
||||
gvalue_type == G_TYPE_UCHAR)
|
||||
ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_BYTE);
|
||||
else if (gvalue_type == G_TYPE_INT ||
|
||||
gvalue_type == G_TYPE_UINT ||
|
||||
gvalue_type == G_TYPE_INT64 ||
|
||||
gvalue_type == G_TYPE_UINT64 ||
|
||||
gvalue_type == G_TYPE_DOUBLE)
|
||||
ok = (g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT16) ||
|
||||
g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT16) ||
|
||||
g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT32) ||
|
||||
g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT32) ||
|
||||
g_variant_type_equal (variant_type, G_VARIANT_TYPE_INT64) ||
|
||||
g_variant_type_equal (variant_type, G_VARIANT_TYPE_UINT64) ||
|
||||
g_variant_type_equal (variant_type, G_VARIANT_TYPE_HANDLE) ||
|
||||
g_variant_type_equal (variant_type, G_VARIANT_TYPE_DOUBLE));
|
||||
else if (gvalue_type == G_TYPE_STRING)
|
||||
ok = (g_variant_type_equal (variant_type, G_VARIANT_TYPE_STRING) ||
|
||||
g_variant_type_equal (variant_type, G_VARIANT_TYPE ("ay")) ||
|
||||
g_variant_type_equal (variant_type, G_VARIANT_TYPE_OBJECT_PATH) ||
|
||||
g_variant_type_equal (variant_type, G_VARIANT_TYPE_SIGNATURE));
|
||||
else if (gvalue_type == G_TYPE_STRV)
|
||||
ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE ("as"));
|
||||
else if (G_TYPE_IS_ENUM (gvalue_type))
|
||||
ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE_STRING);
|
||||
else if (G_TYPE_IS_FLAGS (gvalue_type))
|
||||
ok = g_variant_type_equal (variant_type, G_VARIANT_TYPE ("as"));
|
||||
|
||||
return ok;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright © 2010 Novell, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Vincent Untz <vuntz@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __G_SETTINGS_MAPPING_H__
|
||||
#define __G_SETTINGS_MAPPING_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
GVariant * g_settings_set_mapping (const GValue *value,
|
||||
const GVariantType *expected_type,
|
||||
gpointer user_data);
|
||||
gboolean g_settings_get_mapping (GValue *value,
|
||||
GVariant *variant,
|
||||
gpointer user_data);
|
||||
gboolean g_settings_mapping_is_compatible (GType gvalue_type,
|
||||
const GVariantType *variant_type);
|
||||
|
||||
#endif /* __G_SETTINGS_MAPPING_H__ */
|
||||
@@ -82,6 +82,8 @@
|
||||
#include <gtk/gtkcolorutils.h>
|
||||
#include <gtk/gtkcombobox.h>
|
||||
#include <gtk/gtkcomboboxtext.h>
|
||||
#include <gtk/gtkconstraintlayout.h>
|
||||
#include <gtk/gtkconstraint.h>
|
||||
#include <gtk/gtkcontainer.h>
|
||||
#include <gtk/gtkcssprovider.h>
|
||||
#include <gtk/gtkcustomlayout.h>
|
||||
|
||||
+330
-29
@@ -25,6 +25,8 @@
|
||||
#include "gtkactionobserverprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkwidget.h"
|
||||
#include "gsettings-mapping.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -69,6 +71,10 @@ struct _GtkActionMuxer
|
||||
GHashTable *groups;
|
||||
GHashTable *primary_accels;
|
||||
GtkActionMuxer *parent;
|
||||
|
||||
GtkWidget *widget;
|
||||
GPtrArray *widget_actions;
|
||||
gboolean *widget_actions_enabled;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkActionMuxer, gtk_action_muxer, G_TYPE_OBJECT,
|
||||
@@ -79,6 +85,8 @@ enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_PARENT,
|
||||
PROP_WIDGET,
|
||||
PROP_WIDGET_ACTIONS,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
@@ -104,7 +112,7 @@ typedef struct
|
||||
static void
|
||||
gtk_action_muxer_append_group_actions (const char *prefix,
|
||||
Group *group,
|
||||
GArray *actions)
|
||||
GHashTable *actions)
|
||||
{
|
||||
gchar **group_actions;
|
||||
gchar **action;
|
||||
@@ -112,10 +120,8 @@ gtk_action_muxer_append_group_actions (const char *prefix,
|
||||
group_actions = g_action_group_list_actions (group->group);
|
||||
for (action = group_actions; *action; action++)
|
||||
{
|
||||
gchar *fullname;
|
||||
|
||||
fullname = g_strconcat (prefix, ".", *action, NULL);
|
||||
g_array_append_val (actions, fullname);
|
||||
char *name = g_strconcat (prefix, ".", *action, NULL);
|
||||
g_hash_table_add (actions, name);
|
||||
}
|
||||
|
||||
g_strfreev (group_actions);
|
||||
@@ -125,9 +131,11 @@ static gchar **
|
||||
gtk_action_muxer_list_actions (GActionGroup *action_group)
|
||||
{
|
||||
GtkActionMuxer *muxer = GTK_ACTION_MUXER (action_group);
|
||||
GArray *actions;
|
||||
GHashTable *actions;
|
||||
char **keys;
|
||||
|
||||
actions = g_array_new (TRUE, FALSE, sizeof (gchar *));
|
||||
actions = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, NULL);
|
||||
|
||||
for ( ; muxer != NULL; muxer = muxer->parent)
|
||||
{
|
||||
@@ -135,12 +143,28 @@ gtk_action_muxer_list_actions (GActionGroup *action_group)
|
||||
const char *prefix;
|
||||
Group *group;
|
||||
|
||||
if (muxer->widget_actions)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < muxer->widget_actions->len; i++)
|
||||
{
|
||||
GtkWidgetAction *action = g_ptr_array_index (muxer->widget_actions, i);
|
||||
g_hash_table_add (actions, g_strdup (action->name));
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, muxer->groups);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&prefix, (gpointer *)&group))
|
||||
gtk_action_muxer_append_group_actions (prefix, group, actions);
|
||||
}
|
||||
|
||||
return (gchar **)(void *) g_array_free (actions, FALSE);
|
||||
keys = (char **)g_hash_table_get_keys_as_array (actions, NULL);
|
||||
|
||||
g_hash_table_steal_all (actions);
|
||||
g_hash_table_unref (actions);
|
||||
|
||||
return (char **)keys;
|
||||
}
|
||||
|
||||
static Group *
|
||||
@@ -150,6 +174,7 @@ gtk_action_muxer_find_group (GtkActionMuxer *muxer,
|
||||
{
|
||||
const gchar *dot;
|
||||
gchar *prefix;
|
||||
const char *name;
|
||||
Group *group;
|
||||
|
||||
dot = strchr (full_name, '.');
|
||||
@@ -157,14 +182,20 @@ gtk_action_muxer_find_group (GtkActionMuxer *muxer,
|
||||
if (!dot)
|
||||
return NULL;
|
||||
|
||||
name = dot + 1;
|
||||
|
||||
prefix = g_strndup (full_name, dot - full_name);
|
||||
group = g_hash_table_lookup (muxer->groups, prefix);
|
||||
g_free (prefix);
|
||||
|
||||
if (action_name)
|
||||
*action_name = dot + 1;
|
||||
*action_name = name;
|
||||
|
||||
return group;
|
||||
if (group &&
|
||||
g_action_group_has_action (group->group, name))
|
||||
return group;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GActionGroup *
|
||||
@@ -175,11 +206,13 @@ gtk_action_muxer_find (GtkActionMuxer *muxer,
|
||||
Group *group;
|
||||
|
||||
group = gtk_action_muxer_find_group (muxer, action_name, unprefixed_name);
|
||||
if (group)
|
||||
return group->group;
|
||||
|
||||
return group->group;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gtk_action_muxer_action_enabled_changed (GtkActionMuxer *muxer,
|
||||
const gchar *action_name,
|
||||
gboolean enabled)
|
||||
@@ -187,6 +220,19 @@ gtk_action_muxer_action_enabled_changed (GtkActionMuxer *muxer,
|
||||
Action *action;
|
||||
GSList *node;
|
||||
|
||||
if (muxer->widget_actions)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < muxer->widget_actions->len; i++)
|
||||
{
|
||||
GtkWidgetAction *a = g_ptr_array_index (muxer->widget_actions, i);
|
||||
if (strcmp (a->name, action_name) == 0)
|
||||
{
|
||||
muxer->widget_actions_enabled[i] = enabled;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
action = g_hash_table_lookup (muxer->observed_actions, action_name);
|
||||
for (node = action ? action->watchers : NULL; node; node = node->next)
|
||||
gtk_action_observer_action_enabled_changed (node->data, GTK_ACTION_OBSERVABLE (muxer), action_name, enabled);
|
||||
@@ -219,7 +265,7 @@ gtk_action_muxer_parent_action_enabled_changed (GActionGroup *action_group,
|
||||
gtk_action_muxer_action_enabled_changed (muxer, action_name, enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gtk_action_muxer_action_state_changed (GtkActionMuxer *muxer,
|
||||
const gchar *action_name,
|
||||
GVariant *state)
|
||||
@@ -384,6 +430,145 @@ gtk_action_muxer_parent_primary_accel_changed (GtkActionMuxer *parent,
|
||||
gtk_action_muxer_primary_accel_changed (muxer, action_name, action_and_target);
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
prop_action_get_state (GtkWidget *widget,
|
||||
GtkWidgetAction *action)
|
||||
{
|
||||
GValue value = G_VALUE_INIT;
|
||||
GVariant *result;
|
||||
|
||||
g_value_init (&value, action->pspec->value_type);
|
||||
g_object_get_property (G_OBJECT (widget), action->pspec->name, &value);
|
||||
|
||||
result = g_settings_set_mapping (&value, action->state_type, NULL);
|
||||
g_value_unset (&value);
|
||||
|
||||
return g_variant_ref_sink (result);
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
prop_action_get_state_hint (GtkWidget *widget,
|
||||
GtkWidgetAction *action)
|
||||
{
|
||||
if (action->pspec->value_type == G_TYPE_INT)
|
||||
{
|
||||
GParamSpecInt *pspec = (GParamSpecInt *)action->pspec;
|
||||
return g_variant_new ("(ii)", pspec->minimum, pspec->maximum);
|
||||
}
|
||||
else if (action->pspec->value_type == G_TYPE_UINT)
|
||||
{
|
||||
GParamSpecUInt *pspec = (GParamSpecUInt *)action->pspec;
|
||||
return g_variant_new ("(uu)", pspec->minimum, pspec->maximum);
|
||||
}
|
||||
else if (action->pspec->value_type == G_TYPE_FLOAT)
|
||||
{
|
||||
GParamSpecFloat *pspec = (GParamSpecFloat *)action->pspec;
|
||||
return g_variant_new ("(dd)", (double)pspec->minimum, (double)pspec->maximum);
|
||||
}
|
||||
else if (action->pspec->value_type == G_TYPE_DOUBLE)
|
||||
{
|
||||
GParamSpecDouble *pspec = (GParamSpecDouble *)action->pspec;
|
||||
return g_variant_new ("(dd)", pspec->minimum, pspec->maximum);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
prop_action_set_state (GtkWidget *widget,
|
||||
GtkWidgetAction *action,
|
||||
GVariant *state)
|
||||
{
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
||||
g_value_init (&value, action->pspec->value_type);
|
||||
g_settings_get_mapping (&value, state, NULL);
|
||||
|
||||
g_object_set_property (G_OBJECT (widget), action->pspec->name, &value);
|
||||
g_value_unset (&value);
|
||||
}
|
||||
|
||||
static void
|
||||
prop_action_activate (GtkWidget *widget,
|
||||
GtkWidgetAction *action,
|
||||
GVariant *parameter)
|
||||
{
|
||||
if (action->pspec->value_type == G_TYPE_BOOLEAN)
|
||||
{
|
||||
gboolean value;
|
||||
|
||||
g_return_if_fail (parameter == NULL);
|
||||
|
||||
g_object_get (G_OBJECT (widget), action->pspec->name, &value, NULL);
|
||||
value = !value;
|
||||
g_object_set (G_OBJECT (widget), action->pspec->name, value, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_return_if_fail (parameter != NULL && g_variant_is_of_type (parameter, action->state_type));
|
||||
|
||||
prop_action_set_state (widget, action, parameter);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
prop_action_notify (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkActionMuxer *muxer = user_data;
|
||||
int i;
|
||||
GtkWidgetAction *action = NULL;
|
||||
GVariant *state;
|
||||
|
||||
g_assert ((GObject *)muxer->widget == object);
|
||||
|
||||
for (i = 0; i < muxer->widget_actions->len; i++)
|
||||
{
|
||||
action = g_ptr_array_index (muxer->widget_actions, i);
|
||||
if (action->pspec == pspec)
|
||||
break;
|
||||
action = NULL;
|
||||
}
|
||||
|
||||
g_assert (action != NULL);
|
||||
|
||||
state = prop_action_get_state (muxer->widget, action);
|
||||
gtk_action_muxer_action_state_changed (muxer, action->name, state);
|
||||
g_variant_unref (state);
|
||||
}
|
||||
|
||||
static void
|
||||
prop_actions_connect (GtkActionMuxer *muxer)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!muxer->widget || !muxer->widget_actions)
|
||||
return;
|
||||
|
||||
for (i = 0; i < muxer->widget_actions->len; i++)
|
||||
{
|
||||
GtkWidgetAction *action = g_ptr_array_index (muxer->widget_actions, i);
|
||||
char *detailed;
|
||||
|
||||
if (!action->pspec)
|
||||
continue;
|
||||
|
||||
detailed = g_strconcat ("notify::", action->pspec->name, NULL);
|
||||
g_signal_connect (muxer->widget, detailed,
|
||||
G_CALLBACK (prop_action_notify), muxer);
|
||||
g_free (detailed);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
prop_actions_disconnect (GtkActionMuxer *muxer)
|
||||
{
|
||||
if (muxer->widget)
|
||||
g_signal_handlers_disconnect_by_func (muxer->widget,
|
||||
prop_action_notify, muxer);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_action_muxer_query_action (GActionGroup *action_group,
|
||||
const gchar *action_name,
|
||||
@@ -397,6 +582,40 @@ gtk_action_muxer_query_action (GActionGroup *action_group,
|
||||
Group *group;
|
||||
const gchar *unprefixed_name;
|
||||
|
||||
if (muxer->widget_actions)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < muxer->widget_actions->len; i++)
|
||||
{
|
||||
GtkWidgetAction *action = g_ptr_array_index (muxer->widget_actions, i);
|
||||
if (strcmp (action->name, action_name) == 0)
|
||||
{
|
||||
if (enabled)
|
||||
*enabled = muxer->widget_actions_enabled[i];
|
||||
if (parameter_type)
|
||||
*parameter_type = action->parameter_type;
|
||||
if (state_type)
|
||||
*state_type = action->state_type;
|
||||
|
||||
if (state_hint)
|
||||
*state_hint = NULL;
|
||||
if (state)
|
||||
*state = NULL;
|
||||
|
||||
if (action->pspec)
|
||||
{
|
||||
if (state)
|
||||
*state = prop_action_get_state (muxer->widget, action);
|
||||
if (state_hint)
|
||||
*state_hint = prop_action_get_state_hint (muxer->widget, action);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group = gtk_action_muxer_find_group (muxer, action_name, &unprefixed_name);
|
||||
|
||||
if (group)
|
||||
@@ -420,6 +639,28 @@ gtk_action_muxer_activate_action (GActionGroup *action_group,
|
||||
Group *group;
|
||||
const gchar *unprefixed_name;
|
||||
|
||||
if (muxer->widget_actions)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < muxer->widget_actions->len; i++)
|
||||
{
|
||||
GtkWidgetAction *action = g_ptr_array_index (muxer->widget_actions, i);
|
||||
if (strcmp (action->name, action_name) == 0)
|
||||
{
|
||||
if (muxer->widget_actions_enabled[i])
|
||||
{
|
||||
if (action->activate)
|
||||
action->activate (muxer->widget, action->name, parameter);
|
||||
else if (action->pspec)
|
||||
prop_action_activate (muxer->widget, action, parameter);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group = gtk_action_muxer_find_group (muxer, action_name, &unprefixed_name);
|
||||
|
||||
if (group)
|
||||
@@ -437,6 +678,23 @@ gtk_action_muxer_change_action_state (GActionGroup *action_group,
|
||||
Group *group;
|
||||
const gchar *unprefixed_name;
|
||||
|
||||
if (muxer->widget_actions)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < muxer->widget_actions->len; i++)
|
||||
{
|
||||
GtkWidgetAction *action = g_ptr_array_index (muxer->widget_actions, i);
|
||||
if (strcmp (action->name, action_name) == 0)
|
||||
{
|
||||
if (action->pspec)
|
||||
prop_action_set_state (muxer->widget, action, state);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group = gtk_action_muxer_find_group (muxer, action_name, &unprefixed_name);
|
||||
|
||||
if (group)
|
||||
@@ -561,6 +819,8 @@ gtk_action_muxer_dispose (GObject *object)
|
||||
{
|
||||
GtkActionMuxer *muxer = GTK_ACTION_MUXER (object);
|
||||
|
||||
prop_actions_disconnect (muxer);
|
||||
|
||||
if (muxer->parent)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (muxer->parent, gtk_action_muxer_action_added_to_parent, muxer);
|
||||
@@ -578,6 +838,16 @@ gtk_action_muxer_dispose (GObject *object)
|
||||
->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_muxer_constructed (GObject *object)
|
||||
{
|
||||
GtkActionMuxer *muxer = GTK_ACTION_MUXER (object);
|
||||
|
||||
prop_actions_connect (muxer);
|
||||
|
||||
G_OBJECT_CLASS (gtk_action_muxer_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_action_muxer_get_property (GObject *object,
|
||||
guint property_id,
|
||||
@@ -592,6 +862,14 @@ gtk_action_muxer_get_property (GObject *object,
|
||||
g_value_set_object (value, gtk_action_muxer_get_parent (muxer));
|
||||
break;
|
||||
|
||||
case PROP_WIDGET:
|
||||
g_value_set_object (value, muxer->widget);
|
||||
break;
|
||||
|
||||
case PROP_WIDGET_ACTIONS:
|
||||
g_value_set_boxed (value, muxer->widget_actions);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
@@ -611,6 +889,22 @@ gtk_action_muxer_set_property (GObject *object,
|
||||
gtk_action_muxer_set_parent (muxer, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_WIDGET:
|
||||
muxer->widget = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
case PROP_WIDGET_ACTIONS:
|
||||
muxer->widget_actions = g_value_get_boxed (value);
|
||||
if (muxer->widget_actions)
|
||||
{
|
||||
int i;
|
||||
|
||||
muxer->widget_actions_enabled = g_new (gboolean, muxer->widget_actions->len);
|
||||
for (i = 0; i < muxer->widget_actions->len; i++)
|
||||
muxer->widget_actions_enabled[i] = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
@@ -644,6 +938,7 @@ gtk_action_muxer_class_init (GObjectClass *class)
|
||||
{
|
||||
class->get_property = gtk_action_muxer_get_property;
|
||||
class->set_property = gtk_action_muxer_set_property;
|
||||
class->constructed = gtk_action_muxer_constructed;
|
||||
class->finalize = gtk_action_muxer_finalize;
|
||||
class->dispose = gtk_action_muxer_dispose;
|
||||
|
||||
@@ -664,6 +959,20 @@ gtk_action_muxer_class_init (GObjectClass *class)
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_WIDGET] = g_param_spec_object ("widget", "Widget",
|
||||
"The widget that owns the muxer",
|
||||
GTK_TYPE_WIDGET,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_WIDGET_ACTIONS] = g_param_spec_boxed ("widget-actions", "Widget actions",
|
||||
"Widget actions",
|
||||
G_TYPE_PTR_ARRAY,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (class, NUM_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
@@ -755,29 +1064,21 @@ gtk_action_muxer_remove (GtkActionMuxer *muxer,
|
||||
}
|
||||
}
|
||||
|
||||
GActionGroup *
|
||||
gtk_action_muxer_lookup (GtkActionMuxer *muxer,
|
||||
const gchar *prefix)
|
||||
{
|
||||
Group *group;
|
||||
|
||||
group = g_hash_table_lookup (muxer->groups, prefix);
|
||||
|
||||
if (group != NULL)
|
||||
return group->group;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_action_muxer_new:
|
||||
* @widget: the widget to which the muxer belongs
|
||||
* @actions: widget actions
|
||||
*
|
||||
* Creates a new #GtkActionMuxer.
|
||||
*/
|
||||
GtkActionMuxer *
|
||||
gtk_action_muxer_new (void)
|
||||
gtk_action_muxer_new (GtkWidget *widget,
|
||||
GPtrArray *actions)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_ACTION_MUXER, NULL);
|
||||
return g_object_new (GTK_TYPE_ACTION_MUXER,
|
||||
"widget", widget,
|
||||
"widget-actions", actions,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define __GTK_ACTION_MUXER_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include "gtkwidget.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -30,10 +31,22 @@ G_BEGIN_DECLS
|
||||
#define GTK_IS_ACTION_MUXER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
|
||||
GTK_TYPE_ACTION_MUXER))
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
GType owner;
|
||||
|
||||
const GVariantType *parameter_type;
|
||||
GtkWidgetActionActivateFunc activate;
|
||||
|
||||
const GVariantType *state_type;
|
||||
GParamSpec *pspec;
|
||||
} GtkWidgetAction;
|
||||
|
||||
typedef struct _GtkActionMuxer GtkActionMuxer;
|
||||
|
||||
GType gtk_action_muxer_get_type (void);
|
||||
GtkActionMuxer * gtk_action_muxer_new (void);
|
||||
GtkActionMuxer * gtk_action_muxer_new (GtkWidget *widget,
|
||||
GPtrArray *actions);
|
||||
|
||||
void gtk_action_muxer_insert (GtkActionMuxer *muxer,
|
||||
const gchar *prefix,
|
||||
@@ -41,8 +54,6 @@ void gtk_action_muxer_insert (GtkActi
|
||||
|
||||
void gtk_action_muxer_remove (GtkActionMuxer *muxer,
|
||||
const gchar *prefix);
|
||||
GActionGroup * gtk_action_muxer_lookup (GtkActionMuxer *muxer,
|
||||
const gchar *prefix);
|
||||
GActionGroup * gtk_action_muxer_find (GtkActionMuxer *muxer,
|
||||
const char *action_name,
|
||||
const char **unprefixed_name);
|
||||
@@ -58,6 +69,16 @@ void gtk_action_muxer_set_primary_accel (GtkActi
|
||||
const gchar * gtk_action_muxer_get_primary_accel (GtkActionMuxer *muxer,
|
||||
const gchar *action_and_target);
|
||||
|
||||
void
|
||||
gtk_action_muxer_action_enabled_changed (GtkActionMuxer *muxer,
|
||||
const char *action_name,
|
||||
gboolean enabled);
|
||||
void
|
||||
gtk_action_muxer_action_state_changed (GtkActionMuxer *muxer,
|
||||
const gchar *action_name,
|
||||
GVariant *state);
|
||||
|
||||
|
||||
/* No better place for these... */
|
||||
gchar * gtk_print_action_and_target (const gchar *action_namespace,
|
||||
const gchar *action_name,
|
||||
|
||||
+1
-69
@@ -394,7 +394,7 @@ gtk_application_init (GtkApplication *application)
|
||||
{
|
||||
GtkApplicationPrivate *priv = gtk_application_get_instance_private (application);
|
||||
|
||||
priv->muxer = gtk_action_muxer_new ();
|
||||
priv->muxer = gtk_action_muxer_new (NULL, NULL);
|
||||
|
||||
priv->accels = gtk_application_accels_new ();
|
||||
}
|
||||
@@ -464,68 +464,6 @@ gtk_application_window_removed (GtkApplication *application,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
extract_accel_from_menu_item (GMenuModel *model,
|
||||
gint item,
|
||||
GtkApplication *app)
|
||||
{
|
||||
GMenuAttributeIter *iter;
|
||||
const gchar *key;
|
||||
GVariant *value;
|
||||
const gchar *accel = NULL;
|
||||
const gchar *action = NULL;
|
||||
GVariant *target = NULL;
|
||||
|
||||
iter = g_menu_model_iterate_item_attributes (model, item);
|
||||
while (g_menu_attribute_iter_get_next (iter, &key, &value))
|
||||
{
|
||||
if (g_str_equal (key, "action") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
|
||||
action = g_variant_get_string (value, NULL);
|
||||
else if (g_str_equal (key, "accel") && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING))
|
||||
accel = g_variant_get_string (value, NULL);
|
||||
else if (g_str_equal (key, "target"))
|
||||
target = g_variant_ref (value);
|
||||
g_variant_unref (value);
|
||||
}
|
||||
g_object_unref (iter);
|
||||
|
||||
if (accel && action)
|
||||
{
|
||||
const gchar *accels[2] = { accel, NULL };
|
||||
gchar *detailed_action_name;
|
||||
|
||||
detailed_action_name = g_action_print_detailed_name (action, target);
|
||||
gtk_application_set_accels_for_action (app, detailed_action_name, accels);
|
||||
g_free (detailed_action_name);
|
||||
}
|
||||
|
||||
if (target)
|
||||
g_variant_unref (target);
|
||||
}
|
||||
|
||||
static void
|
||||
extract_accels_from_menu (GMenuModel *model,
|
||||
GtkApplication *app)
|
||||
{
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < g_menu_model_get_n_items (model); i++)
|
||||
{
|
||||
GMenuLinkIter *iter;
|
||||
GMenuModel *sub_model;
|
||||
|
||||
extract_accel_from_menu_item (model, i, app);
|
||||
|
||||
iter = g_menu_model_iterate_item_links (model, i);
|
||||
while (g_menu_link_iter_get_next (iter, NULL, &sub_model))
|
||||
{
|
||||
extract_accels_from_menu (sub_model, app);
|
||||
g_object_unref (sub_model);
|
||||
}
|
||||
g_object_unref (iter);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_application_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -1175,9 +1113,6 @@ gtk_application_set_app_menu (GtkApplication *application,
|
||||
|
||||
if (g_set_object (&priv->app_menu, app_menu))
|
||||
{
|
||||
if (app_menu)
|
||||
extract_accels_from_menu (app_menu, application);
|
||||
|
||||
gtk_application_impl_set_app_menu (priv->impl, app_menu);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (application), gtk_application_props[PROP_APP_MENU]);
|
||||
@@ -1241,9 +1176,6 @@ gtk_application_set_menubar (GtkApplication *application,
|
||||
|
||||
if (g_set_object (&priv->menubar, menubar))
|
||||
{
|
||||
if (menubar)
|
||||
extract_accels_from_menu (menubar, application);
|
||||
|
||||
gtk_application_impl_set_menubar (priv->impl, menubar);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (application), gtk_application_props[PROP_MENUBAR]);
|
||||
|
||||
+101
-24
@@ -64,6 +64,99 @@ typedef enum {
|
||||
GTK_BINDING_TOKEN_UNBIND
|
||||
} GtkBindingTokens;
|
||||
|
||||
typedef struct _GtkBindingEntry GtkBindingEntry;
|
||||
typedef struct _GtkBindingSignal GtkBindingSignal;
|
||||
typedef struct _GtkBindingArg GtkBindingArg;
|
||||
|
||||
/**
|
||||
* GtkBindingSet:
|
||||
* @set_name: unique name of this binding set
|
||||
* @priority: unused
|
||||
* @entries: the key binding entries in this binding set
|
||||
* @current: implementation detail
|
||||
*
|
||||
* A binding set maintains a list of activatable key bindings.
|
||||
* A single binding set can match multiple types of widgets.
|
||||
* Similar to style contexts, can be matched by any information contained
|
||||
* in a widgets #GtkWidgetPath. When a binding within a set is matched upon
|
||||
* activation, an action signal is emitted on the target widget to carry out
|
||||
* the actual activation.
|
||||
*/
|
||||
struct _GtkBindingSet
|
||||
{
|
||||
gchar *set_name;
|
||||
gint priority;
|
||||
GtkBindingEntry *entries;
|
||||
GtkBindingEntry *current;
|
||||
};
|
||||
|
||||
/**
|
||||
* GtkBindingEntry:
|
||||
* @keyval: key value to match
|
||||
* @modifiers: key modifiers to match
|
||||
* @binding_set: binding set this entry belongs to
|
||||
* @destroyed: implementation detail
|
||||
* @in_emission: implementation detail
|
||||
* @marks_unbound: implementation detail
|
||||
* @set_next: linked list of entries maintained by binding set
|
||||
* @hash_next: implementation detail
|
||||
* @signals: action signals of this entry
|
||||
*
|
||||
* Each key binding element of a binding sets binding list is
|
||||
* represented by a GtkBindingEntry.
|
||||
*/
|
||||
struct _GtkBindingEntry
|
||||
{
|
||||
/* key portion */
|
||||
guint keyval;
|
||||
GdkModifierType modifiers;
|
||||
|
||||
GtkBindingSet *binding_set;
|
||||
guint destroyed : 1;
|
||||
guint in_emission : 1;
|
||||
guint marks_unbound : 1;
|
||||
GtkBindingEntry *set_next;
|
||||
GtkBindingEntry *hash_next;
|
||||
GtkBindingSignal *signals;
|
||||
};
|
||||
|
||||
/**
|
||||
* GtkBindingArg:
|
||||
* @arg_type: implementation detail
|
||||
*
|
||||
* A #GtkBindingArg holds the data associated with
|
||||
* an argument for a key binding signal emission as
|
||||
* stored in #GtkBindingSignal.
|
||||
*/
|
||||
struct _GtkBindingArg
|
||||
{
|
||||
GType arg_type;
|
||||
union {
|
||||
glong long_data;
|
||||
gdouble double_data;
|
||||
gchar *string_data;
|
||||
} d;
|
||||
};
|
||||
|
||||
/**
|
||||
* GtkBindingSignal:
|
||||
* @next: implementation detail
|
||||
* @signal_name: the action signal to be emitted
|
||||
* @n_args: number of arguments specified for the signal
|
||||
* @args: (array length=n_args): the arguments specified for the signal
|
||||
*
|
||||
* A GtkBindingSignal stores the necessary information to
|
||||
* activate a widget in response to a key press via a signal
|
||||
* emission.
|
||||
*/
|
||||
struct _GtkBindingSignal
|
||||
{
|
||||
GtkBindingSignal *next;
|
||||
gchar *signal_name;
|
||||
guint n_args;
|
||||
GtkBindingArg *args;
|
||||
};
|
||||
|
||||
/* --- variables --- */
|
||||
static GHashTable *binding_entry_hash_table = NULL;
|
||||
static GSList *binding_key_hashes = NULL;
|
||||
@@ -582,12 +675,8 @@ gtk_binding_set_new (const gchar *set_name)
|
||||
|
||||
binding_set = g_new (GtkBindingSet, 1);
|
||||
binding_set->set_name = (gchar *) g_intern_string (set_name);
|
||||
binding_set->widget_path_pspecs = NULL;
|
||||
binding_set->widget_class_pspecs = NULL;
|
||||
binding_set->class_branch_pspecs = NULL;
|
||||
binding_set->entries = NULL;
|
||||
binding_set->current = NULL;
|
||||
binding_set->parsed = FALSE;
|
||||
|
||||
binding_set_list = g_slist_prepend (binding_set_list, binding_set);
|
||||
|
||||
@@ -769,7 +858,7 @@ gtk_binding_entry_remove (GtkBindingSet *binding_set,
|
||||
binding_entry_destroy (entry);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* gtk_binding_entry_add_signall:
|
||||
* @binding_set: a #GtkBindingSet to add a signal to
|
||||
* @keyval: key value
|
||||
@@ -781,24 +870,12 @@ gtk_binding_entry_remove (GtkBindingSet *binding_set,
|
||||
* Override or install a new key binding for @keyval with @modifiers on
|
||||
* @binding_set.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
gtk_binding_entry_add_signall (GtkBindingSet *binding_set,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
const gchar *signal_name,
|
||||
GSList *binding_args)
|
||||
{
|
||||
_gtk_binding_entry_add_signall (binding_set,
|
||||
keyval, modifiers,
|
||||
signal_name, binding_args);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_binding_entry_add_signall (GtkBindingSet *binding_set,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
const gchar *signal_name,
|
||||
GSList *binding_args)
|
||||
{
|
||||
GtkBindingEntry *entry;
|
||||
GtkBindingSignal *signal, **signal_p;
|
||||
@@ -971,7 +1048,7 @@ gtk_binding_entry_add_signal (GtkBindingSet *binding_set,
|
||||
if (i == n_args || i == 0)
|
||||
{
|
||||
slist = g_slist_reverse (slist);
|
||||
_gtk_binding_entry_add_signall (binding_set, keyval, modifiers, signal_name, slist);
|
||||
gtk_binding_entry_add_signall (binding_set, keyval, modifiers, signal_name, slist);
|
||||
}
|
||||
|
||||
free_slist = slist;
|
||||
@@ -1123,11 +1200,11 @@ gtk_binding_parse_signal (GScanner *scanner,
|
||||
if (!(need_arg && seen_comma) && !negate)
|
||||
{
|
||||
args = g_slist_reverse (args);
|
||||
_gtk_binding_entry_add_signall (binding_set,
|
||||
keyval,
|
||||
modifiers,
|
||||
signal,
|
||||
args);
|
||||
gtk_binding_entry_add_signall (binding_set,
|
||||
keyval,
|
||||
modifiers,
|
||||
signal,
|
||||
args);
|
||||
expected_token = G_TOKEN_NONE;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,106 +39,6 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkBindingSet GtkBindingSet;
|
||||
typedef struct _GtkBindingEntry GtkBindingEntry;
|
||||
typedef struct _GtkBindingSignal GtkBindingSignal;
|
||||
typedef struct _GtkBindingArg GtkBindingArg;
|
||||
|
||||
/**
|
||||
* GtkBindingSet:
|
||||
* @set_name: unique name of this binding set
|
||||
* @priority: unused
|
||||
* @widget_path_pspecs: unused
|
||||
* @widget_class_pspecs: unused
|
||||
* @class_branch_pspecs: unused
|
||||
* @entries: the key binding entries in this binding set
|
||||
* @current: implementation detail
|
||||
* @parsed: whether this binding set stems from a CSS file and is reset upon theme changes
|
||||
*
|
||||
* A binding set maintains a list of activatable key bindings.
|
||||
* A single binding set can match multiple types of widgets.
|
||||
* Similar to style contexts, can be matched by any information contained
|
||||
* in a widgets #GtkWidgetPath. When a binding within a set is matched upon
|
||||
* activation, an action signal is emitted on the target widget to carry out
|
||||
* the actual activation.
|
||||
*/
|
||||
struct _GtkBindingSet
|
||||
{
|
||||
gchar *set_name;
|
||||
gint priority;
|
||||
GSList *widget_path_pspecs;
|
||||
GSList *widget_class_pspecs;
|
||||
GSList *class_branch_pspecs;
|
||||
GtkBindingEntry *entries;
|
||||
GtkBindingEntry *current;
|
||||
guint parsed : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* GtkBindingEntry:
|
||||
* @keyval: key value to match
|
||||
* @modifiers: key modifiers to match
|
||||
* @binding_set: binding set this entry belongs to
|
||||
* @destroyed: implementation detail
|
||||
* @in_emission: implementation detail
|
||||
* @marks_unbound: implementation detail
|
||||
* @set_next: linked list of entries maintained by binding set
|
||||
* @hash_next: implementation detail
|
||||
* @signals: action signals of this entry
|
||||
*
|
||||
* Each key binding element of a binding sets binding list is
|
||||
* represented by a GtkBindingEntry.
|
||||
*/
|
||||
struct _GtkBindingEntry
|
||||
{
|
||||
/* key portion */
|
||||
guint keyval;
|
||||
GdkModifierType modifiers;
|
||||
|
||||
GtkBindingSet *binding_set;
|
||||
guint destroyed : 1;
|
||||
guint in_emission : 1;
|
||||
guint marks_unbound : 1;
|
||||
GtkBindingEntry *set_next;
|
||||
GtkBindingEntry *hash_next;
|
||||
GtkBindingSignal *signals;
|
||||
};
|
||||
|
||||
/**
|
||||
* GtkBindingArg:
|
||||
* @arg_type: implementation detail
|
||||
*
|
||||
* A #GtkBindingArg holds the data associated with
|
||||
* an argument for a key binding signal emission as
|
||||
* stored in #GtkBindingSignal.
|
||||
*/
|
||||
struct _GtkBindingArg
|
||||
{
|
||||
GType arg_type;
|
||||
union {
|
||||
glong long_data;
|
||||
gdouble double_data;
|
||||
gchar *string_data;
|
||||
} d;
|
||||
};
|
||||
|
||||
/**
|
||||
* GtkBindingSignal:
|
||||
* @next: implementation detail
|
||||
* @signal_name: the action signal to be emitted
|
||||
* @n_args: number of arguments specified for the signal
|
||||
* @args: (array length=n_args): the arguments specified for the signal
|
||||
*
|
||||
* A GtkBindingSignal stores the necessary information to
|
||||
* activate a widget in response to a key press via a signal
|
||||
* emission.
|
||||
*/
|
||||
struct _GtkBindingSignal
|
||||
{
|
||||
GtkBindingSignal *next;
|
||||
gchar *signal_name;
|
||||
guint n_args;
|
||||
GtkBindingArg *args;
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkBindingSet *gtk_binding_set_new (const gchar *set_name);
|
||||
@@ -171,12 +71,6 @@ void gtk_binding_entry_add_signal (GtkBindingSet *binding_set,
|
||||
const gchar *signal_name,
|
||||
guint n_args,
|
||||
...);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_binding_entry_add_signall (GtkBindingSet *binding_set,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
const gchar *signal_name,
|
||||
GSList *binding_args);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GTokenType gtk_binding_entry_add_signal_from_string
|
||||
|
||||
@@ -24,11 +24,6 @@ G_BEGIN_DECLS
|
||||
|
||||
guint _gtk_binding_parse_binding (GScanner *scanner);
|
||||
void _gtk_binding_reset_parsed (void);
|
||||
void _gtk_binding_entry_add_signall (GtkBindingSet *binding_set,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
const gchar *signal_name,
|
||||
GSList *binding_args);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+2
-2
@@ -46,8 +46,8 @@
|
||||
* can be made round by adding the .circular style class.
|
||||
*
|
||||
* Button-like widgets like #GtkToggleButton, #GtkMenuButton, #GtkVolumeButton,
|
||||
* #GtkLockButton, #GtkColorButton, #GtkFontButton or #GtkFileChooserButton use
|
||||
* style classes such as .toggle, .popup, .scale, .lock, .color, .file
|
||||
* #GtkLockButton, #GtkColorButton or #GtkFontButton use style classes such as
|
||||
* .toggle, .popup, .scale, .lock, .color on the button node
|
||||
* to differentiate themselves from a plain GtkButton.
|
||||
*/
|
||||
|
||||
|
||||
+13
-32
@@ -90,8 +90,6 @@ struct _GtkColorChooserWidgetPrivate
|
||||
gboolean has_default_palette;
|
||||
|
||||
GSettings *settings;
|
||||
|
||||
GActionMap *context_actions;
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -493,11 +491,11 @@ add_default_palette (GtkColorChooserWidget *cc)
|
||||
}
|
||||
|
||||
static void
|
||||
customize_color (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_color_chooser_widget_activate_color_customize (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkColorChooserWidget *cc = user_data;
|
||||
GtkColorChooserWidget *cc = GTK_COLOR_CHOOSER_WIDGET (widget);
|
||||
GtkColorChooserWidgetPrivate *priv = gtk_color_chooser_widget_get_instance_private (cc);
|
||||
GdkRGBA color;
|
||||
|
||||
@@ -511,11 +509,11 @@ customize_color (GSimpleAction *action,
|
||||
}
|
||||
|
||||
static void
|
||||
select_color (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_color_chooser_widget_activate_color_select (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkColorChooserWidget *cc = user_data;
|
||||
GtkColorChooserWidget *cc = GTK_COLOR_CHOOSER_WIDGET (widget);
|
||||
GdkRGBA color;
|
||||
|
||||
g_variant_get (parameter, "(dddd)", &color.red, &color.green, &color.blue, &color.alpha);
|
||||
@@ -523,26 +521,6 @@ select_color (GSimpleAction *action,
|
||||
_gtk_color_chooser_color_activated (GTK_COLOR_CHOOSER (cc), &color);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_color_chooser_widget_add_context_actions (GtkColorChooserWidget *cc)
|
||||
{
|
||||
GtkColorChooserWidgetPrivate *priv = gtk_color_chooser_widget_get_instance_private (cc);
|
||||
|
||||
GActionEntry entries[] = {
|
||||
{ "select", select_color, "(dddd)", NULL, NULL },
|
||||
{ "customize", customize_color, "(dddd)", NULL, NULL },
|
||||
};
|
||||
|
||||
GSimpleActionGroup *actions = g_simple_action_group_new ();
|
||||
|
||||
priv->context_actions = G_ACTION_MAP (actions);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), cc);
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (cc), "color", G_ACTION_GROUP (actions));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_color_chooser_widget_init (GtkColorChooserWidget *cc)
|
||||
{
|
||||
@@ -634,8 +612,6 @@ gtk_color_chooser_widget_init (GtkColorChooserWidget *cc)
|
||||
priv->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
||||
gtk_size_group_add_widget (priv->size_group, priv->palette);
|
||||
gtk_size_group_add_widget (priv->size_group, box);
|
||||
|
||||
gtk_color_chooser_widget_add_context_actions (cc);
|
||||
}
|
||||
|
||||
/* GObject implementation {{{1 */
|
||||
@@ -736,6 +712,11 @@ gtk_color_chooser_widget_class_init (GtkColorChooserWidgetClass *class)
|
||||
FALSE, GTK_PARAM_READWRITE));
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), I_("colorchooser"));
|
||||
|
||||
gtk_widget_class_install_action (GTK_WIDGET_CLASS (class), "color.select", "(dddd)",
|
||||
gtk_color_chooser_widget_activate_color_select);
|
||||
gtk_widget_class_install_action (GTK_WIDGET_CLASS (class), "color.customize", "(dddd)",
|
||||
gtk_color_chooser_widget_activate_color_customize);
|
||||
}
|
||||
|
||||
/* GtkColorChooser implementation {{{1 */
|
||||
|
||||
+10
-12
@@ -226,12 +226,11 @@ activate_color (GtkColorSwatch *swatch)
|
||||
{
|
||||
GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (swatch);
|
||||
gtk_widget_activate_action (GTK_WIDGET (swatch),
|
||||
"color.select",
|
||||
g_variant_new ("(dddd)",
|
||||
priv->color.red,
|
||||
priv->color.green,
|
||||
priv->color.blue,
|
||||
priv->color.alpha));
|
||||
"color.select", "(dddd)",
|
||||
priv->color.red,
|
||||
priv->color.green,
|
||||
priv->color.blue,
|
||||
priv->color.alpha);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -239,12 +238,11 @@ customize_color (GtkColorSwatch *swatch)
|
||||
{
|
||||
GtkColorSwatchPrivate *priv = gtk_color_swatch_get_instance_private (swatch);
|
||||
gtk_widget_activate_action (GTK_WIDGET (swatch),
|
||||
"color.customize",
|
||||
g_variant_new ("(dddd)",
|
||||
priv->color.red,
|
||||
priv->color.green,
|
||||
priv->color.blue,
|
||||
priv->color.alpha));
|
||||
"color.customize", "(dddd)",
|
||||
priv->color.red,
|
||||
priv->color.green,
|
||||
priv->color.blue,
|
||||
priv->color.alpha);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -0,0 +1,617 @@
|
||||
/* gtkconstraint.c: Constraint between two widgets
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Emmanuele Bassi
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gtkconstraint
|
||||
* @Title: GtkConstraint
|
||||
* @Short_description: The description of a constraint
|
||||
*
|
||||
* #GtkConstraint describes a constraint between an attribute on a widget
|
||||
* and another attribute on another widget, expressed as a linear equation
|
||||
* like:
|
||||
*
|
||||
* |[
|
||||
* target.attr1 = source.attr2 × multiplier + constant
|
||||
* ]|
|
||||
*
|
||||
* Each #GtkConstraint is part of a system that will be solved by a
|
||||
* #GtkConstraintLayout in order to allocate and position each child widget.
|
||||
*
|
||||
* The source and target widgets, as well as their attributes, of a
|
||||
* #GtkConstraint instance are immutable after creation.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkconstraintprivate.h"
|
||||
#include "gtkconstraintsolverprivate.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkwidget.h"
|
||||
|
||||
enum {
|
||||
PROP_TARGET = 1,
|
||||
PROP_TARGET_ATTRIBUTE,
|
||||
PROP_RELATION,
|
||||
PROP_SOURCE,
|
||||
PROP_SOURCE_ATTRIBUTE,
|
||||
PROP_MULTIPLIER,
|
||||
PROP_CONSTANT,
|
||||
PROP_STRENGTH,
|
||||
|
||||
N_PROPERTIES
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[N_PROPERTIES];
|
||||
|
||||
G_DEFINE_TYPE (GtkConstraint, gtk_constraint, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gtk_constraint_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkConstraint *self = GTK_CONSTRAINT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TARGET:
|
||||
self->target = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
case PROP_TARGET_ATTRIBUTE:
|
||||
self->target_attribute = g_value_get_enum (value);
|
||||
break;
|
||||
|
||||
case PROP_RELATION:
|
||||
self->relation = g_value_get_enum (value);
|
||||
break;
|
||||
|
||||
case PROP_SOURCE:
|
||||
self->source = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
case PROP_SOURCE_ATTRIBUTE:
|
||||
self->source_attribute = g_value_get_enum (value);
|
||||
break;
|
||||
|
||||
case PROP_MULTIPLIER:
|
||||
self->multiplier = g_value_get_double (value);
|
||||
break;
|
||||
|
||||
case PROP_CONSTANT:
|
||||
self->constant = g_value_get_double (value);
|
||||
break;
|
||||
|
||||
case PROP_STRENGTH:
|
||||
self->strength = g_value_get_int (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkConstraint *self = GTK_CONSTRAINT (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TARGET:
|
||||
g_value_set_object (value, self->target);
|
||||
break;
|
||||
|
||||
case PROP_TARGET_ATTRIBUTE:
|
||||
g_value_set_enum (value, self->target_attribute);
|
||||
break;
|
||||
|
||||
case PROP_RELATION:
|
||||
g_value_set_enum (value, self->relation);
|
||||
break;
|
||||
|
||||
case PROP_SOURCE:
|
||||
g_value_set_object (value, self->source);
|
||||
break;
|
||||
|
||||
case PROP_SOURCE_ATTRIBUTE:
|
||||
g_value_set_enum (value, self->source_attribute);
|
||||
break;
|
||||
|
||||
case PROP_MULTIPLIER:
|
||||
g_value_set_double (value, self->multiplier);
|
||||
break;
|
||||
|
||||
case PROP_CONSTANT:
|
||||
g_value_set_double (value, self->constant);
|
||||
break;
|
||||
|
||||
case PROP_STRENGTH:
|
||||
g_value_set_int (value, self->strength);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_finalize (GObject *gobject)
|
||||
{
|
||||
GtkConstraint *self = GTK_CONSTRAINT (gobject);
|
||||
|
||||
gtk_constraint_detach (self);
|
||||
|
||||
G_OBJECT_CLASS (gtk_constraint_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_class_init (GtkConstraintClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->set_property = gtk_constraint_set_property;
|
||||
gobject_class->get_property = gtk_constraint_get_property;
|
||||
gobject_class->finalize = gtk_constraint_finalize;
|
||||
|
||||
/**
|
||||
* GtkConstraint:target:
|
||||
*
|
||||
* The target of the constraint.
|
||||
*
|
||||
* The constraint will set the #GtkConstraint:target-attribute of the
|
||||
* target using the #GtkConstraint:source-attribute of the source
|
||||
* widget.
|
||||
*/
|
||||
obj_props[PROP_TARGET] =
|
||||
g_param_spec_object ("target",
|
||||
P_("Target"),
|
||||
P_("The target of the constraint"),
|
||||
GTK_TYPE_CONSTRAINT_TARGET,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
/**
|
||||
* GtkConstraint:target-attribute:
|
||||
*
|
||||
* The attribute of the #GtkConstraint:target set by the constraint.
|
||||
*/
|
||||
obj_props[PROP_TARGET_ATTRIBUTE] =
|
||||
g_param_spec_enum ("target-attribute",
|
||||
P_("Target Attribute"),
|
||||
P_("The attribute of the target set by the constraint"),
|
||||
GTK_TYPE_CONSTRAINT_ATTRIBUTE,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_NONE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
/**
|
||||
* GtkConstraint:relation:
|
||||
*
|
||||
* The relation order between the terms of the constraint.
|
||||
*/
|
||||
obj_props[PROP_RELATION] =
|
||||
g_param_spec_enum ("relation",
|
||||
P_("Relation"),
|
||||
P_("The relation between the source and target attributes"),
|
||||
GTK_TYPE_CONSTRAINT_RELATION,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
/**
|
||||
* GtkConstraint:source:
|
||||
*
|
||||
* The source of the constraint.
|
||||
*
|
||||
* The constraint will set the #GtkConstraint:target-attribute of the
|
||||
* target using the #GtkConstraint:source-attribute of the source.
|
||||
*/
|
||||
obj_props[PROP_SOURCE] =
|
||||
g_param_spec_object ("source",
|
||||
P_("Source"),
|
||||
P_("The source of the constraint"),
|
||||
GTK_TYPE_CONSTRAINT_TARGET,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
/**
|
||||
* GtkConstraint:source-attribute:
|
||||
*
|
||||
* The attribute of the #GtkConstraint:source read by the constraint.
|
||||
*/
|
||||
obj_props[PROP_SOURCE_ATTRIBUTE] =
|
||||
g_param_spec_enum ("source-attribute",
|
||||
P_("Source Attribute"),
|
||||
P_("The attribute of the source widget set by the constraint"),
|
||||
GTK_TYPE_CONSTRAINT_ATTRIBUTE,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_NONE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
/**
|
||||
* GtkConstraint:multiplier:
|
||||
*
|
||||
* The multiplication factor to be applied to the
|
||||
* #GtkConstraint:source-attribue.
|
||||
*/
|
||||
obj_props[PROP_MULTIPLIER] =
|
||||
g_param_spec_double ("multiplier",
|
||||
P_("Multiplier"),
|
||||
P_("The multiplication factor to be applied to the source attribute"),
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 1.0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
/**
|
||||
* GtkConstraint:constant:
|
||||
*
|
||||
* The constant value to be added to the #GtkConstraint:source-attribute.
|
||||
*/
|
||||
obj_props[PROP_CONSTANT] =
|
||||
g_param_spec_double ("constant",
|
||||
P_("Constant"),
|
||||
P_("The constant to be added to the source attribute"),
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
/**
|
||||
* GtkConstraint:strength:
|
||||
*
|
||||
* The strength of the constraint.
|
||||
*
|
||||
* The strength can be expressed either using one of the symbolic values
|
||||
* of the #GtkConstraintStrength enumeration, or any positive integer
|
||||
* value.
|
||||
*/
|
||||
obj_props[PROP_STRENGTH] =
|
||||
g_param_spec_int ("strength",
|
||||
P_("Strength"),
|
||||
P_("The strength of the constraint"),
|
||||
GTK_CONSTRAINT_STRENGTH_WEAK, G_MAXINT,
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_properties (gobject_class, N_PROPERTIES, obj_props);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_init (GtkConstraint *self)
|
||||
{
|
||||
self->multiplier = 1.0;
|
||||
self->constant = 0.0;
|
||||
|
||||
self->target_attribute = GTK_CONSTRAINT_ATTRIBUTE_NONE;
|
||||
self->source_attribute = GTK_CONSTRAINT_ATTRIBUTE_NONE;
|
||||
self->relation = GTK_CONSTRAINT_RELATION_EQ;
|
||||
self->strength = GTK_CONSTRAINT_STRENGTH_REQUIRED;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_new:
|
||||
* @target: (nullable) (type GtkConstraintTarget): a #GtkConstraintTarget
|
||||
* @target_attribute: the attribute of @target to be set
|
||||
* @relation: the relation equivalence between @target_attribute and @source_attribute
|
||||
* @source: (nullable) (type GtkConstraintTarget): a #GtkConstraintTarget
|
||||
* @source_attribute: the attribute of @source to be read
|
||||
* @multiplier: a multiplication factor to be applied to @source_attribute
|
||||
* @constant: a constant factor to be added to @source_attribute
|
||||
* @strength: the strength of the constraint
|
||||
*
|
||||
* Creates a new #GtkConstraint representing a relation between a layout
|
||||
* attribute on a source and a layout attribute on a target.
|
||||
*
|
||||
* Returns: the newly created #GtkConstraint
|
||||
*/
|
||||
GtkConstraint *
|
||||
gtk_constraint_new (gpointer target,
|
||||
GtkConstraintAttribute target_attribute,
|
||||
GtkConstraintRelation relation,
|
||||
gpointer source,
|
||||
GtkConstraintAttribute source_attribute,
|
||||
double multiplier,
|
||||
double constant,
|
||||
int strength)
|
||||
{
|
||||
g_return_val_if_fail (target == NULL || GTK_IS_CONSTRAINT_TARGET (target), NULL);
|
||||
g_return_val_if_fail (source == NULL || GTK_IS_CONSTRAINT_TARGET (source), NULL);
|
||||
|
||||
return g_object_new (GTK_TYPE_CONSTRAINT,
|
||||
"target", target,
|
||||
"target-attribute", target_attribute,
|
||||
"relation", relation,
|
||||
"source", source,
|
||||
"source-attribute", source_attribute,
|
||||
"multiplier", multiplier,
|
||||
"constant", constant,
|
||||
"strength", strength,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_new_constant:
|
||||
* @target: (nullable) (type GtkConstraintTarget): a #GtkConstraintTarget
|
||||
* @target_attribute: the attribute of @target to be set
|
||||
* @relation: the relation equivalence between @target_attribute and @constant
|
||||
* @constant: a constant factor to be set on @target_attribute
|
||||
* @strength: the strength of the constraint
|
||||
*
|
||||
* Creates a new #GtkConstraint representing a relation between a layout
|
||||
* attribute on a target and a constant value.
|
||||
*
|
||||
* Returns: the newly created #GtkConstraint
|
||||
*/
|
||||
GtkConstraint *
|
||||
gtk_constraint_new_constant (gpointer target,
|
||||
GtkConstraintAttribute target_attribute,
|
||||
GtkConstraintRelation relation,
|
||||
double constant,
|
||||
int strength)
|
||||
{
|
||||
g_return_val_if_fail (target == NULL || GTK_IS_CONSTRAINT_TARGET (target), NULL);
|
||||
|
||||
return g_object_new (GTK_TYPE_CONSTRAINT,
|
||||
"target", target,
|
||||
"target-attribute", target_attribute,
|
||||
"relation", relation,
|
||||
"source-attribute", GTK_CONSTRAINT_ATTRIBUTE_NONE,
|
||||
"constant", constant,
|
||||
"strength", strength,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_get_target_widget:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Retrieves the target widget for the @constraint.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #GtkWidget
|
||||
*/
|
||||
GtkWidget *
|
||||
gtk_constraint_get_target_widget (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), NULL);
|
||||
|
||||
if (GTK_IS_WIDGET (constraint->target))
|
||||
return GTK_WIDGET (constraint->target);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GtkConstraintTarget *
|
||||
gtk_constraint_get_target (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), NULL);
|
||||
|
||||
return constraint->target;
|
||||
}
|
||||
|
||||
GtkConstraintAttribute
|
||||
gtk_constraint_get_target_attribute (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), GTK_CONSTRAINT_ATTRIBUTE_NONE);
|
||||
|
||||
return constraint->target_attribute;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_get_source_widget:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Retrieves the source widget for the @constraint.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #GtkWidget
|
||||
*/
|
||||
GtkWidget *
|
||||
gtk_constraint_get_source_widget (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), NULL);
|
||||
|
||||
if (GTK_IS_WIDGET (constraint->source))
|
||||
return GTK_WIDGET (constraint->source);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GtkConstraintTarget *
|
||||
gtk_constraint_get_source (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), NULL);
|
||||
|
||||
return constraint->source;
|
||||
}
|
||||
|
||||
GtkConstraintAttribute
|
||||
gtk_constraint_get_source_attribute (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), GTK_CONSTRAINT_ATTRIBUTE_NONE);
|
||||
|
||||
return constraint->source_attribute;
|
||||
}
|
||||
|
||||
GtkConstraintRelation
|
||||
gtk_constraint_get_relation (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), GTK_CONSTRAINT_RELATION_EQ);
|
||||
|
||||
return constraint->relation;
|
||||
}
|
||||
|
||||
double
|
||||
gtk_constraint_get_multiplier (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), 1.0);
|
||||
|
||||
return constraint->multiplier;
|
||||
}
|
||||
|
||||
double
|
||||
gtk_constraint_get_constant (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), 0.0);
|
||||
|
||||
return constraint->constant;
|
||||
}
|
||||
|
||||
int
|
||||
gtk_constraint_get_strength (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), GTK_CONSTRAINT_STRENGTH_REQUIRED);
|
||||
|
||||
return constraint->strength;
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_constraint_get_weight:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Computes the weight of the @constraint to be used with
|
||||
* #GtkConstraintSolver.
|
||||
*
|
||||
* Returns: the weight of the constraint
|
||||
*/
|
||||
double
|
||||
gtk_constraint_get_weight (GtkConstraint *constraint)
|
||||
{
|
||||
if (constraint->strength > 0)
|
||||
return constraint->strength;
|
||||
|
||||
switch (constraint->strength)
|
||||
{
|
||||
case GTK_CONSTRAINT_STRENGTH_REQUIRED:
|
||||
return GTK_CONSTRAINT_WEIGHT_REQUIRED;
|
||||
|
||||
case GTK_CONSTRAINT_STRENGTH_STRONG:
|
||||
return GTK_CONSTRAINT_WEIGHT_STRONG;
|
||||
|
||||
case GTK_CONSTRAINT_STRENGTH_MEDIUM:
|
||||
return GTK_CONSTRAINT_WEIGHT_MEDIUM;
|
||||
|
||||
case GTK_CONSTRAINT_STRENGTH_WEAK:
|
||||
return GTK_CONSTRAINT_WEIGHT_WEAK;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_is_required:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Checks whether the @constraint is a required relation for solving the
|
||||
* constraint layout.
|
||||
*
|
||||
* Returns: %TRUE if the constraint is required
|
||||
*/
|
||||
gboolean
|
||||
gtk_constraint_is_required (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), FALSE);
|
||||
|
||||
return constraint->strength == GTK_CONSTRAINT_STRENGTH_REQUIRED;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_is_attached:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Checks whether the @constraint is attached to a #GtkConstraintLayout,
|
||||
* and it is contributing to the layout.
|
||||
*
|
||||
* Returns: %TRUE if the constraint is attached
|
||||
*/
|
||||
gboolean
|
||||
gtk_constraint_is_attached (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), FALSE);
|
||||
|
||||
return constraint->constraint_ref != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_is_constant:
|
||||
* @constraint: a #GtkConstraint
|
||||
*
|
||||
* Checks whether the @constraint describes a relation between an attribute
|
||||
* on the #GtkConstraint:target-widget and a constant value.
|
||||
*
|
||||
* Returns: %TRUE if the constraint is a constant relation
|
||||
*/
|
||||
gboolean
|
||||
gtk_constraint_is_constant (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT (constraint), FALSE);
|
||||
|
||||
return constraint->source == NULL &&
|
||||
constraint->source_attribute == GTK_CONSTRAINT_ATTRIBUTE_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_constraint_attach (GtkConstraint *constraint,
|
||||
GtkConstraintSolver *solver,
|
||||
GtkConstraintRef *ref)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONSTRAINT (constraint));
|
||||
g_return_if_fail (GTK_IS_CONSTRAINT_SOLVER (solver));
|
||||
g_return_if_fail (ref != NULL);
|
||||
|
||||
constraint->constraint_ref = ref;
|
||||
constraint->solver = solver;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_constraint_detach (GtkConstraint *constraint)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONSTRAINT (constraint));
|
||||
|
||||
if (constraint->constraint_ref == NULL)
|
||||
return;
|
||||
|
||||
gtk_constraint_solver_remove_constraint (constraint->solver, constraint->constraint_ref);
|
||||
constraint->constraint_ref = NULL;
|
||||
constraint->solver = NULL;
|
||||
}
|
||||
|
||||
typedef struct _GtkConstraintTargetInterface GtkConstraintTargetInterface;
|
||||
|
||||
struct _GtkConstraintTargetInterface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
};
|
||||
|
||||
G_DEFINE_INTERFACE (GtkConstraintTarget, gtk_constraint_target, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gtk_constraint_target_default_init (GtkConstraintTargetInterface *iface)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/* gtkconstraint.h: Constraint between two widgets
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Emmanuele Bassi
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtktypes.h>
|
||||
#include <gtk/gtkenums.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkConstraintTarget GtkConstraintTarget;
|
||||
|
||||
#define GTK_TYPE_CONSTRAINT_TARGET (gtk_constraint_target_get_type ())
|
||||
|
||||
/**
|
||||
* GtkConstraintTarget:
|
||||
*
|
||||
* The GtkConstraintTarget interface is implemented by objects that
|
||||
* can be used as source or target in #GtkConstraints. Besides
|
||||
* #GtkWidget, it is also implemented by #GtkConstraintGuide.
|
||||
*/
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_INTERFACE (GtkConstraintTarget, gtk_constraint_target, GTK, CONSTRAINT_TARGET, GObject)
|
||||
|
||||
#define GTK_TYPE_CONSTRAINT (gtk_constraint_get_type ())
|
||||
|
||||
/**
|
||||
* GtkConstraint:
|
||||
*
|
||||
* An object describing the relation between two widget attributes.
|
||||
*
|
||||
* All relations are in the form:
|
||||
*
|
||||
* |[<!-- language=plain -->
|
||||
* target.attr_name = source.attr_name × multiplier + constant
|
||||
* ]|
|
||||
*
|
||||
* A #GtkConstraint is immutable once it's created.
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (GtkConstraint, gtk_constraint, GTK, CONSTRAINT, GObject)
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraint * gtk_constraint_new (gpointer target,
|
||||
GtkConstraintAttribute target_attribute,
|
||||
GtkConstraintRelation relation,
|
||||
gpointer source,
|
||||
GtkConstraintAttribute source_attribute,
|
||||
double multiplier,
|
||||
double constant,
|
||||
int strength);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraint * gtk_constraint_new_constant (gpointer target,
|
||||
GtkConstraintAttribute target_attribute,
|
||||
GtkConstraintRelation relation,
|
||||
double constant,
|
||||
int strength);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkWidget * gtk_constraint_get_target_widget (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraintTarget * gtk_constraint_get_target (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraintAttribute gtk_constraint_get_target_attribute (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkWidget * gtk_constraint_get_source_widget (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraintTarget * gtk_constraint_get_source (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraintAttribute gtk_constraint_get_source_attribute (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraintRelation gtk_constraint_get_relation (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
double gtk_constraint_get_multiplier (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
double gtk_constraint_get_constant (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
int gtk_constraint_get_strength (GtkConstraint *constraint);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_constraint_is_required (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_constraint_is_attached (GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_constraint_is_constant (GtkConstraint *constraint);
|
||||
|
||||
G_END_DECLS
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,276 @@
|
||||
/* gtkconstraintequationprivate.h: Constraint expressions and variables
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Emmanuele Bassi
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gtkconstrainttypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GtkConstraintVariable *
|
||||
gtk_constraint_variable_new (const char *name);
|
||||
|
||||
GtkConstraintVariable *
|
||||
gtk_constraint_variable_new_dummy (const char *name);
|
||||
|
||||
GtkConstraintVariable *
|
||||
gtk_constraint_variable_new_objective (const char *name);
|
||||
|
||||
GtkConstraintVariable *
|
||||
gtk_constraint_variable_new_slack (const char *name);
|
||||
|
||||
GtkConstraintVariable *
|
||||
gtk_constraint_variable_ref (GtkConstraintVariable *variable);
|
||||
|
||||
void
|
||||
gtk_constraint_variable_unref (GtkConstraintVariable *variable);
|
||||
|
||||
void
|
||||
gtk_constraint_variable_set_value (GtkConstraintVariable *variable,
|
||||
double value);
|
||||
|
||||
double
|
||||
gtk_constraint_variable_get_value (const GtkConstraintVariable *variable);
|
||||
|
||||
void
|
||||
gtk_constraint_variable_set_prefix (GtkConstraintVariable *variable,
|
||||
const char *prefix);
|
||||
|
||||
char *
|
||||
gtk_constraint_variable_to_string (const GtkConstraintVariable *variable);
|
||||
|
||||
gboolean
|
||||
gtk_constraint_variable_is_external (const GtkConstraintVariable *variable);
|
||||
|
||||
gboolean
|
||||
gtk_constraint_variable_is_pivotable (const GtkConstraintVariable *variable);
|
||||
|
||||
gboolean
|
||||
gtk_constraint_variable_is_restricted (const GtkConstraintVariable *variable);
|
||||
|
||||
gboolean
|
||||
gtk_constraint_variable_is_dummy (const GtkConstraintVariable *variable);
|
||||
|
||||
typedef struct {
|
||||
GtkConstraintVariable *first;
|
||||
GtkConstraintVariable *second;
|
||||
} GtkConstraintVariablePair;
|
||||
|
||||
GtkConstraintVariablePair *
|
||||
gtk_constraint_variable_pair_new (GtkConstraintVariable *first,
|
||||
GtkConstraintVariable *second);
|
||||
|
||||
void
|
||||
gtk_constraint_variable_pair_free (GtkConstraintVariablePair *pair);
|
||||
|
||||
typedef struct _GtkConstraintVariableSet GtkConstraintVariableSet;
|
||||
|
||||
GtkConstraintVariableSet *
|
||||
gtk_constraint_variable_set_new (void);
|
||||
|
||||
void
|
||||
gtk_constraint_variable_set_free (GtkConstraintVariableSet *set);
|
||||
|
||||
gboolean
|
||||
gtk_constraint_variable_set_add (GtkConstraintVariableSet *set,
|
||||
GtkConstraintVariable *variable);
|
||||
|
||||
gboolean
|
||||
gtk_constraint_variable_set_remove (GtkConstraintVariableSet *set,
|
||||
GtkConstraintVariable *variable);
|
||||
|
||||
int
|
||||
gtk_constraint_variable_set_size (GtkConstraintVariableSet *set);
|
||||
|
||||
typedef struct {
|
||||
/*< private >*/
|
||||
gpointer dummy1;
|
||||
gpointer dummy2;
|
||||
gint64 dummy3;
|
||||
} GtkConstraintVariableSetIter;
|
||||
|
||||
void
|
||||
gtk_constraint_variable_set_iter_init (GtkConstraintVariableSetIter *iter,
|
||||
GtkConstraintVariableSet *set);
|
||||
|
||||
gboolean
|
||||
gtk_constraint_variable_set_iter_next (GtkConstraintVariableSetIter *iter,
|
||||
GtkConstraintVariable **variable_p);
|
||||
|
||||
GtkConstraintExpression *
|
||||
gtk_constraint_expression_new (double constant);
|
||||
|
||||
GtkConstraintExpression *
|
||||
gtk_constraint_expression_new_from_variable (GtkConstraintVariable *variable);
|
||||
|
||||
GtkConstraintExpression *
|
||||
gtk_constraint_expression_ref (GtkConstraintExpression *expression);
|
||||
|
||||
void
|
||||
gtk_constraint_expression_unref (GtkConstraintExpression *expression);
|
||||
|
||||
GtkConstraintExpression *
|
||||
gtk_constraint_expression_clone (GtkConstraintExpression *expression);
|
||||
|
||||
void
|
||||
gtk_constraint_expression_set_constant (GtkConstraintExpression *expression,
|
||||
double constant);
|
||||
double
|
||||
gtk_constraint_expression_get_constant (const GtkConstraintExpression *expression);
|
||||
|
||||
gboolean
|
||||
gtk_constraint_expression_is_constant (const GtkConstraintExpression *expression);
|
||||
|
||||
void
|
||||
gtk_constraint_expression_add_expression (GtkConstraintExpression *a_expr,
|
||||
GtkConstraintExpression *b_expr,
|
||||
double n,
|
||||
GtkConstraintVariable *subject,
|
||||
GtkConstraintSolver *solver);
|
||||
|
||||
void
|
||||
gtk_constraint_expression_add_variable (GtkConstraintExpression *expression,
|
||||
GtkConstraintVariable *variable,
|
||||
double coefficient,
|
||||
GtkConstraintVariable *subject,
|
||||
GtkConstraintSolver *solver);
|
||||
|
||||
void
|
||||
gtk_constraint_expression_remove_variable (GtkConstraintExpression *expression,
|
||||
GtkConstraintVariable *variable);
|
||||
|
||||
void
|
||||
gtk_constraint_expression_set_variable (GtkConstraintExpression *expression,
|
||||
GtkConstraintVariable *variable,
|
||||
double coefficient);
|
||||
|
||||
double
|
||||
gtk_constraint_expression_get_coefficient (GtkConstraintExpression *expression,
|
||||
GtkConstraintVariable *variable);
|
||||
|
||||
char *
|
||||
gtk_constraint_expression_to_string (const GtkConstraintExpression *expression);
|
||||
|
||||
double
|
||||
gtk_constraint_expression_new_subject (GtkConstraintExpression *expression,
|
||||
GtkConstraintVariable *subject);
|
||||
|
||||
void
|
||||
gtk_constraint_expression_change_subject (GtkConstraintExpression *expression,
|
||||
GtkConstraintVariable *old_subject,
|
||||
GtkConstraintVariable *new_subject);
|
||||
|
||||
void
|
||||
gtk_constraint_expression_substitute_out (GtkConstraintExpression *expression,
|
||||
GtkConstraintVariable *out_var,
|
||||
GtkConstraintExpression *expr,
|
||||
GtkConstraintVariable *subject,
|
||||
GtkConstraintSolver *solver);
|
||||
|
||||
GtkConstraintVariable *
|
||||
gtk_constraint_expression_get_pivotable_variable (GtkConstraintExpression *expression);
|
||||
|
||||
GtkConstraintExpression *
|
||||
gtk_constraint_expression_plus_constant (GtkConstraintExpression *expression,
|
||||
double constant);
|
||||
|
||||
GtkConstraintExpression *
|
||||
gtk_constraint_expression_minus_constant (GtkConstraintExpression *expression,
|
||||
double constant);
|
||||
|
||||
GtkConstraintExpression *
|
||||
gtk_constraint_expression_plus_variable (GtkConstraintExpression *expression,
|
||||
GtkConstraintVariable *variable);
|
||||
|
||||
GtkConstraintExpression *
|
||||
gtk_constraint_expression_minus_variable (GtkConstraintExpression *expression,
|
||||
GtkConstraintVariable *variable);
|
||||
|
||||
GtkConstraintExpression *
|
||||
gtk_constraint_expression_multiply_by (GtkConstraintExpression *expression,
|
||||
double factor);
|
||||
|
||||
GtkConstraintExpression *
|
||||
gtk_constraint_expression_divide_by (GtkConstraintExpression *expression,
|
||||
double factor);
|
||||
|
||||
struct _GtkConstraintExpressionBuilder
|
||||
{
|
||||
/*< private >*/
|
||||
gpointer dummy1;
|
||||
gpointer dummy2;
|
||||
int dummy3;
|
||||
};
|
||||
|
||||
void
|
||||
gtk_constraint_expression_builder_init (GtkConstraintExpressionBuilder *builder,
|
||||
GtkConstraintSolver *solver);
|
||||
|
||||
void
|
||||
gtk_constraint_expression_builder_term (GtkConstraintExpressionBuilder *builder,
|
||||
GtkConstraintVariable *term);
|
||||
|
||||
void
|
||||
gtk_constraint_expression_builder_plus (GtkConstraintExpressionBuilder *builder);
|
||||
|
||||
void
|
||||
gtk_constraint_expression_builder_minus (GtkConstraintExpressionBuilder *builder);
|
||||
|
||||
void
|
||||
gtk_constraint_expression_builder_divide_by (GtkConstraintExpressionBuilder *builder);
|
||||
|
||||
void
|
||||
gtk_constraint_expression_builder_multiply_by (GtkConstraintExpressionBuilder *builder);
|
||||
|
||||
void
|
||||
gtk_constraint_expression_builder_constant (GtkConstraintExpressionBuilder *builder,
|
||||
double value);
|
||||
|
||||
GtkConstraintExpression *
|
||||
gtk_constraint_expression_builder_finish (GtkConstraintExpressionBuilder *builder) G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
/*< private >
|
||||
* GtkConstraintExpressionIter:
|
||||
*
|
||||
* An iterator object for terms inside a #GtkConstraintExpression.
|
||||
*/
|
||||
typedef struct {
|
||||
/*< private >*/
|
||||
gpointer dummy1;
|
||||
gpointer dummy2;
|
||||
gint64 dummy3;
|
||||
} GtkConstraintExpressionIter;
|
||||
|
||||
void
|
||||
gtk_constraint_expression_iter_init (GtkConstraintExpressionIter *iter,
|
||||
GtkConstraintExpression *equation);
|
||||
|
||||
gboolean
|
||||
gtk_constraint_expression_iter_next (GtkConstraintExpressionIter *iter,
|
||||
GtkConstraintVariable **variable,
|
||||
double *coefficient);
|
||||
|
||||
gboolean
|
||||
gtk_constraint_expression_iter_prev (GtkConstraintExpressionIter *iter,
|
||||
GtkConstraintVariable **variable,
|
||||
double *coefficient);
|
||||
|
||||
G_END_DECLS
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,79 @@
|
||||
/* gtkconstraintlayout.h: Layout manager using constraints
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Emmanuele Bassi
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtklayoutmanager.h>
|
||||
#include <gtk/gtkconstraint.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CONSTRAINT_LAYOUT (gtk_constraint_layout_get_type ())
|
||||
#define GTK_TYPE_CONSTRAINT_LAYOUT_CHILD (gtk_constraint_layout_child_get_type ())
|
||||
#define GTK_TYPE_CONSTRAINT_GUIDE (gtk_constraint_guide_get_type ())
|
||||
|
||||
/**
|
||||
* GtkConstraintLayoutChild:
|
||||
*
|
||||
* A #GtkLayoutChild in a #GtkConstraintLayout.
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (GtkConstraintLayoutChild, gtk_constraint_layout_child, GTK, CONSTRAINT_LAYOUT_CHILD, GtkLayoutChild)
|
||||
|
||||
/**
|
||||
* GtkConstraintGuide:
|
||||
*
|
||||
* An object that can be added to a #GtkConstraintLayout and be
|
||||
* used in constraints like a widget, without being drawn. Guides
|
||||
* have a minimal and natural size. Depending on the constraints
|
||||
* that are applied, they can act like a guideline that widgets
|
||||
* can be aligned to, or like 'flexible space'.
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (GtkConstraintGuide, gtk_constraint_guide, GTK, CONSTRAINT_GUIDE, GObject)
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkConstraintGuide * gtk_constraint_guide_new (void);
|
||||
|
||||
/**
|
||||
* GtkConstraintLayout:
|
||||
*
|
||||
* A layout manager using #GtkConstraint to describe
|
||||
* relations between widgets.
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (GtkConstraintLayout, gtk_constraint_layout, GTK, CONSTRAINT_LAYOUT, GtkLayoutManager)
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GtkLayoutManager * gtk_constraint_layout_new (void);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_layout_add_constraint (GtkConstraintLayout *manager,
|
||||
GtkConstraint *constraint);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_layout_remove_constraint (GtkConstraintLayout *manager,
|
||||
GtkConstraint *constraint);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_layout_add_guide (GtkConstraintLayout *manager,
|
||||
GtkConstraintGuide *guide);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_layout_remove_guide (GtkConstraintLayout *manager,
|
||||
GtkConstraintGuide *guide);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -0,0 +1,62 @@
|
||||
/* gtkconstraintprivate.h: Constraint between two widgets
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Emmanuele Bassi
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gtkconstraint.h"
|
||||
#include "gtkconstrainttypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _GtkConstraint
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GtkConstraintAttribute target_attribute;
|
||||
GtkConstraintAttribute source_attribute;
|
||||
|
||||
GtkConstraintTarget *target;
|
||||
GtkConstraintTarget *source;
|
||||
|
||||
GtkConstraintRelation relation;
|
||||
|
||||
double multiplier;
|
||||
double constant;
|
||||
|
||||
int strength;
|
||||
|
||||
/* A reference to the real constraint inside the
|
||||
* GtkConstraintSolver, so we can remove it when
|
||||
* finalizing the GtkConstraint instance
|
||||
*/
|
||||
GtkConstraintRef *constraint_ref;
|
||||
|
||||
GtkConstraintSolver *solver;
|
||||
|
||||
guint active : 1;
|
||||
};
|
||||
|
||||
double gtk_constraint_get_weight (GtkConstraint *constraint);
|
||||
|
||||
void gtk_constraint_attach (GtkConstraint *constraint,
|
||||
GtkConstraintSolver *solver,
|
||||
GtkConstraintRef *ref);
|
||||
void gtk_constraint_detach (GtkConstraint *constraint);
|
||||
|
||||
G_END_DECLS
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,145 @@
|
||||
/* gtkconstraintsolverprivate.h: Constraint solver based on the Cassowary method
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Emmanuele Bassi
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gtkconstrainttypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_CONSTRAINT_SOLVER (gtk_constraint_solver_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GtkConstraintSolver, gtk_constraint_solver, GTK, CONSTRAINT_SOLVER, GObject)
|
||||
|
||||
/* Symbolic weight thresholds
|
||||
*
|
||||
* Constraint weights live on a continuum, but we use thresholds for simplicity's
|
||||
* sake, so we don't have to necessarily reason in terms of numeric values.
|
||||
*
|
||||
* The public API has a similar approach, where the symbolic constants are negative
|
||||
* values, and positive values are explicit weights. We map those values into
|
||||
* numeric values that the GtkConstraintSolver can plug into the linear equations
|
||||
* tableau.
|
||||
*/
|
||||
#define GTK_CONSTRAINT_WEIGHT_REQUIRED (make_weight (1000, 1000, 1000, 1))
|
||||
#define GTK_CONSTRAINT_WEIGHT_STRONG (make_weight ( 1, 0, 0, 1))
|
||||
#define GTK_CONSTRAINT_WEIGHT_MEDIUM (make_weight ( 0, 1, 0, 1))
|
||||
#define GTK_CONSTRAINT_WEIGHT_WEAK (make_weight ( 0, 0, 1, 1))
|
||||
|
||||
G_GNUC_PURE
|
||||
static inline double
|
||||
make_weight (double a,
|
||||
double b,
|
||||
double c,
|
||||
double w)
|
||||
{
|
||||
double res = 0;
|
||||
|
||||
res += CLAMP (a * w, 0, 1000) * 1000000;
|
||||
res += CLAMP (b * w, 0, 1000) * 1000;
|
||||
res += CLAMP (c * w, 0, 1000);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
GtkConstraintSolver *
|
||||
gtk_constraint_solver_new (void);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_freeze (GtkConstraintSolver *solver);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_thaw (GtkConstraintSolver *solver);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_resolve (GtkConstraintSolver *solver);
|
||||
|
||||
GtkConstraintVariable *
|
||||
gtk_constraint_solver_create_variable (GtkConstraintSolver *solver,
|
||||
const char *prefix,
|
||||
const char *name,
|
||||
double value);
|
||||
|
||||
GtkConstraintRef *
|
||||
gtk_constraint_solver_add_constraint (GtkConstraintSolver *solver,
|
||||
GtkConstraintVariable *variable,
|
||||
GtkConstraintRelation relation,
|
||||
GtkConstraintExpression *expression,
|
||||
double strength);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_remove_constraint (GtkConstraintSolver *solver,
|
||||
GtkConstraintRef *reference);
|
||||
|
||||
GtkConstraintRef *
|
||||
gtk_constraint_solver_add_stay_variable (GtkConstraintSolver *solver,
|
||||
GtkConstraintVariable *variable,
|
||||
double strength);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_remove_stay_variable (GtkConstraintSolver *solver,
|
||||
GtkConstraintVariable *variable);
|
||||
|
||||
gboolean
|
||||
gtk_constraint_solver_has_stay_variable (GtkConstraintSolver *solver,
|
||||
GtkConstraintVariable *variable);
|
||||
|
||||
GtkConstraintRef *
|
||||
gtk_constraint_solver_add_edit_variable (GtkConstraintSolver *solver,
|
||||
GtkConstraintVariable *variable,
|
||||
double strength);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_remove_edit_variable (GtkConstraintSolver *solver,
|
||||
GtkConstraintVariable *variable);
|
||||
|
||||
gboolean
|
||||
gtk_constraint_solver_has_edit_variable (GtkConstraintSolver *solver,
|
||||
GtkConstraintVariable *variable);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_suggest_value (GtkConstraintSolver *solver,
|
||||
GtkConstraintVariable *variable,
|
||||
double value);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_begin_edit (GtkConstraintSolver *solver);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_end_edit (GtkConstraintSolver *solver);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_note_added_variable (GtkConstraintSolver *self,
|
||||
GtkConstraintVariable *variable,
|
||||
GtkConstraintVariable *subject);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_note_removed_variable (GtkConstraintSolver *self,
|
||||
GtkConstraintVariable *variable,
|
||||
GtkConstraintVariable *subject);
|
||||
|
||||
void
|
||||
gtk_constraint_solver_clear (GtkConstraintSolver *solver);
|
||||
|
||||
char *
|
||||
gtk_constraint_solver_to_string (GtkConstraintSolver *solver);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -0,0 +1,50 @@
|
||||
/* gtkconstrainttypesprivate.h: Private types for the constraint solver
|
||||
* Copyright 2019 GNOME Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Emmanuele Bassi
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtktypes.h>
|
||||
#include <gtk/gtkenums.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkConstraintVariable GtkConstraintVariable;
|
||||
typedef struct _GtkConstraintExpression GtkConstraintExpression;
|
||||
typedef struct _GtkConstraintExpressionBuilder GtkConstraintExpressionBuilder;
|
||||
|
||||
/*< private >
|
||||
* GtkConstraintRef:
|
||||
*
|
||||
* A reference to a constraint stored inside the solver; while #GtkConstraint
|
||||
* represent the public API, a #GtkConstraintRef represents data stored inside
|
||||
* the solver. A #GtkConstraintRef is completely opaque, and should only be
|
||||
* used to remove a constraint from the solver.
|
||||
*/
|
||||
typedef struct _GtkConstraintRef GtkConstraintRef;
|
||||
|
||||
/*< private >
|
||||
* GtkConstraintSolver:
|
||||
*
|
||||
* A simplex solver using the Cassowary constraint solving algorithm.
|
||||
*/
|
||||
typedef struct _GtkConstraintSolver GtkConstraintSolver;
|
||||
|
||||
G_END_DECLS
|
||||
@@ -1053,4 +1053,78 @@ typedef enum {
|
||||
GTK_PICK_NON_TARGETABLE = 1 << 1
|
||||
} GtkPickFlags;
|
||||
|
||||
/**
|
||||
* GtkConstraintRelation:
|
||||
* @GTK_CONSTRAINT_RELATION_EQ: Equal
|
||||
* @GTK_CONSTRAINT_RELATION_LE: Less than, or equal
|
||||
* @GTK_CONSTRAINT_RELATION_GE: Greater than, or equal
|
||||
*
|
||||
* The relation between two terms of a constraint.
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_CONSTRAINT_RELATION_LE = -1,
|
||||
GTK_CONSTRAINT_RELATION_EQ = 0,
|
||||
GTK_CONSTRAINT_RELATION_GE = 1
|
||||
} GtkConstraintRelation;
|
||||
|
||||
/**
|
||||
* GtkConstraintStrength:
|
||||
* @GTK_CONSTRAINT_STRENGTH_REQUIRED: The constraint is required towards solving the layout
|
||||
* @GTK_CONSTRAINT_STRENGTH_STRONG: A strong constraint
|
||||
* @GTK_CONSTRAINT_STRENGTH_MEDIUM: A medium constraint
|
||||
* @GTK_CONSTRAINT_STRENGTH_WEAK: A weak constraint
|
||||
*
|
||||
* The strength of a constraint, expressed as a symbolic constant.
|
||||
*
|
||||
* The strength of a #GtkConstraint can be expressed with any positive
|
||||
* integer; the values of this enumeration can be used for readability.
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_CONSTRAINT_STRENGTH_REQUIRED = 0,
|
||||
GTK_CONSTRAINT_STRENGTH_STRONG = -1,
|
||||
GTK_CONSTRAINT_STRENGTH_MEDIUM = -2,
|
||||
GTK_CONSTRAINT_STRENGTH_WEAK = -3
|
||||
} GtkConstraintStrength;
|
||||
|
||||
/**
|
||||
* GtkConstraintAttribute:
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_NONE: No attribute, used for constant
|
||||
* relations
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_LEFT: The left edge of a widget, regardless of
|
||||
* text direction
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_RIGHT: The right edge of a widget, regardless
|
||||
* of text direction
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_TOP: The top edge of a widget
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_BOTTOM: The bottom edge of a widget
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_START: The leading edge of a widget, depending
|
||||
* on text direction; equivalent to %GTK_CONSTRAINT_ATTRIBUTE_LEFT for LTR
|
||||
* languages, and %GTK_CONSTRAINT_ATTRIBUTE_RIGHT for RTL ones
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_END: The trailing edge of a widget, depending
|
||||
* on text direction; equivalent to %GTK_CONSTRAINT_ATTRIBUTE_RIGHT for LTR
|
||||
* languages, and %GTK_CONSTRAINT_ATTRIBUTE_LEFT for RTL ones
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_WIDTH: The width of a widget
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_HEIGHT: The height of a widget
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_CENTER_X: The center of a widget, on the
|
||||
* horizontal axis
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y: The center of a widget, on the
|
||||
* vertical axis
|
||||
* @GTK_CONSTRAINT_ATTRIBUTE_BASELINE: The baseline of a widget
|
||||
*
|
||||
* The widget attributes that can be used when creating a #GtkConstraint.
|
||||
*/
|
||||
typedef enum {
|
||||
GTK_CONSTRAINT_ATTRIBUTE_NONE,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_LEFT,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_RIGHT,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_TOP,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BOTTOM,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_START,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_END,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_CENTER_X,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_CENTER_Y,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_BASELINE
|
||||
} GtkConstraintAttribute;
|
||||
|
||||
#endif /* __GTK_ENUMS_H__ */
|
||||
|
||||
@@ -46,6 +46,7 @@ enum {
|
||||
PROP_WIDGET = 1,
|
||||
PROP_PROPAGATION_PHASE,
|
||||
PROP_PROPAGATION_LIMIT,
|
||||
PROP_NAME,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
@@ -56,6 +57,7 @@ struct _GtkEventControllerPrivate
|
||||
GtkWidget *widget;
|
||||
GtkPropagationPhase phase;
|
||||
GtkPropagationLimit limit;
|
||||
char *name;
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkEventController, gtk_event_controller, G_TYPE_OBJECT)
|
||||
@@ -130,6 +132,7 @@ gtk_event_controller_set_property (GObject *object,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkEventController *self = GTK_EVENT_CONTROLLER (object);
|
||||
GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
@@ -141,6 +144,11 @@ gtk_event_controller_set_property (GObject *object,
|
||||
gtk_event_controller_set_propagation_limit (self,
|
||||
g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_NAME:
|
||||
g_free (priv->name);
|
||||
priv->name = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@@ -166,11 +174,25 @@ gtk_event_controller_get_property (GObject *object,
|
||||
case PROP_PROPAGATION_LIMIT:
|
||||
g_value_set_enum (value, priv->limit);
|
||||
break;
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, priv->name);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_event_controller_finalize (GObject *object)
|
||||
{
|
||||
GtkEventController *self = GTK_EVENT_CONTROLLER (object);
|
||||
GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (self);
|
||||
|
||||
g_free (priv->name);
|
||||
|
||||
G_OBJECT_CLASS (gtk_event_controller_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_event_controller_class_init (GtkEventControllerClass *klass)
|
||||
{
|
||||
@@ -181,6 +203,7 @@ gtk_event_controller_class_init (GtkEventControllerClass *klass)
|
||||
klass->filter_event = gtk_event_controller_filter_event_default;
|
||||
klass->handle_event = gtk_event_controller_handle_event_default;
|
||||
|
||||
object_class->finalize = gtk_event_controller_finalize;
|
||||
object_class->set_property = gtk_event_controller_set_property;
|
||||
object_class->get_property = gtk_event_controller_get_property;
|
||||
|
||||
@@ -222,6 +245,13 @@ gtk_event_controller_class_init (GtkEventControllerClass *klass)
|
||||
GTK_LIMIT_SAME_NATIVE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
properties[PROP_NAME] =
|
||||
g_param_spec_string ("name",
|
||||
P_("Name"),
|
||||
P_("Name for this controller"),
|
||||
NULL,
|
||||
GTK_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, properties);
|
||||
}
|
||||
|
||||
@@ -240,7 +270,7 @@ gtk_event_controller_init (GtkEventController *controller)
|
||||
* @controller: a #GtkEventController
|
||||
* @event: a #GdkEvent
|
||||
*
|
||||
* Feeds an events into @controller, so it can be interpreted
|
||||
* Feeds an event into @controller, so it can be interpreted
|
||||
* and the controller actions triggered.
|
||||
*
|
||||
* Returns: %TRUE if the event was potentially useful to trigger the
|
||||
@@ -393,3 +423,25 @@ gtk_event_controller_set_propagation_limit (GtkEventController *controller,
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (controller), properties[PROP_PROPAGATION_LIMIT]);
|
||||
}
|
||||
|
||||
const char *
|
||||
gtk_event_controller_get_name (GtkEventController *controller)
|
||||
{
|
||||
GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (controller);
|
||||
|
||||
g_return_val_if_fail (GTK_IS_EVENT_CONTROLLER (controller), NULL);
|
||||
|
||||
return priv->name;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_event_controller_set_name (GtkEventController *controller,
|
||||
const char *name)
|
||||
{
|
||||
GtkEventControllerPrivate *priv = gtk_event_controller_get_instance_private (controller);
|
||||
|
||||
g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
|
||||
|
||||
g_free (priv->name);
|
||||
priv->name = g_strdup (priv->name);
|
||||
}
|
||||
|
||||
@@ -65,6 +65,12 @@ GtkPropagationLimit gtk_event_controller_get_propagation_limit (GtkEventControll
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_event_controller_set_propagation_limit (GtkEventController *controller,
|
||||
GtkPropagationLimit limit);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const char * gtk_event_controller_get_name (GtkEventController *controller);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_event_controller_set_name (GtkEventController *controller,
|
||||
const char *name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_EVENT_CONTROLLER_H__ */
|
||||
|
||||
@@ -96,6 +96,10 @@
|
||||
* > gtk_file_chooser_button_set_width_chars(), or pack the button in
|
||||
* > such a way that other interface elements give space to the
|
||||
* > widget.
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
* GtkFileChooserButton has a single CSS node with the name “filechooserbutton”.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ G_BEGIN_DECLS
|
||||
#define SETTINGS_KEY_LOCATION_MODE "location-mode"
|
||||
#define SETTINGS_KEY_SHOW_HIDDEN "show-hidden"
|
||||
#define SETTINGS_KEY_SHOW_SIZE_COLUMN "show-size-column"
|
||||
#define SETTINGS_KEY_SHOW_TYPE_COLUMN "show-type-column"
|
||||
#define SETTINGS_KEY_SORT_COLUMN "sort-column"
|
||||
#define SETTINGS_KEY_SORT_ORDER "sort-order"
|
||||
#define SETTINGS_KEY_WINDOW_SIZE "window-size"
|
||||
@@ -46,6 +47,7 @@ G_BEGIN_DECLS
|
||||
#define SETTINGS_KEY_SORT_DIRECTORIES_FIRST "sort-directories-first"
|
||||
#define SETTINGS_KEY_CLOCK_FORMAT "clock-format"
|
||||
#define SETTINGS_KEY_DATE_FORMAT "date-format"
|
||||
#define SETTINGS_KEY_TYPE_FORMAT "type-format"
|
||||
|
||||
#define GTK_FILE_CHOOSER_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GTK_TYPE_FILE_CHOOSER, GtkFileChooserIface))
|
||||
|
||||
|
||||
+185
-1
@@ -221,6 +221,12 @@ struct _GtkFileChooserWidgetClass
|
||||
GtkWidgetClass parent_class;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
TYPE_FORMAT_MIME,
|
||||
TYPE_FORMAT_DESCRIPTION,
|
||||
TYPE_FORMAT_CATEGORY
|
||||
} TypeFormat;
|
||||
|
||||
struct _GtkFileChooserWidgetPrivate {
|
||||
GtkFileChooserAction action;
|
||||
|
||||
@@ -247,6 +253,7 @@ struct _GtkFileChooserWidgetPrivate {
|
||||
GtkWidget *add_shortcut_item;
|
||||
GtkWidget *hidden_files_item;
|
||||
GtkWidget *size_column_item;
|
||||
GtkWidget *type_column_item;
|
||||
GtkWidget *copy_file_location_item;
|
||||
GtkWidget *visit_file_item;
|
||||
GtkWidget *open_folder_item;
|
||||
@@ -339,6 +346,8 @@ struct _GtkFileChooserWidgetPrivate {
|
||||
GtkCellRenderer *list_time_renderer;
|
||||
GtkTreeViewColumn *list_size_column;
|
||||
GtkCellRenderer *list_size_renderer;
|
||||
GtkTreeViewColumn *list_type_column;
|
||||
GtkCellRenderer *list_type_renderer;
|
||||
GtkTreeViewColumn *list_location_column;
|
||||
GtkCellRenderer *list_location_renderer;
|
||||
|
||||
@@ -357,6 +366,8 @@ struct _GtkFileChooserWidgetPrivate {
|
||||
|
||||
ClockFormat clock_format;
|
||||
|
||||
TypeFormat type_format;
|
||||
|
||||
/* Flags */
|
||||
|
||||
guint local_only : 1;
|
||||
@@ -371,6 +382,7 @@ struct _GtkFileChooserWidgetPrivate {
|
||||
guint list_sort_ascending : 1;
|
||||
guint shortcuts_current_folder_active : 1;
|
||||
guint show_size_column : 1;
|
||||
guint show_type_column : 1;
|
||||
guint create_folders : 1;
|
||||
guint auto_selecting_first_row : 1;
|
||||
guint starting_search : 1;
|
||||
@@ -406,9 +418,10 @@ static guint signals[LAST_SIGNAL] = { 0 };
|
||||
"access::can-rename,access::can-delete,access::can-trash," \
|
||||
"standard::target-uri"
|
||||
enum {
|
||||
/* the first 3 must be these due to settings caching sort column */
|
||||
/* the first 4 must be these due to settings caching sort column */
|
||||
MODEL_COL_NAME,
|
||||
MODEL_COL_SIZE,
|
||||
MODEL_COL_TYPE,
|
||||
MODEL_COL_TIME,
|
||||
MODEL_COL_FILE,
|
||||
MODEL_COL_NAME_COLLATED,
|
||||
@@ -428,6 +441,7 @@ enum {
|
||||
MODEL_COL_NUM_COLUMNS, \
|
||||
G_TYPE_STRING, /* MODEL_COL_NAME */ \
|
||||
G_TYPE_INT64, /* MODEL_COL_SIZE */ \
|
||||
G_TYPE_STRING, /* MODEL_COL_TYPE */ \
|
||||
G_TYPE_LONG, /* MODEL_COL_TIME */ \
|
||||
G_TYPE_FILE, /* MODEL_COL_FILE */ \
|
||||
G_TYPE_STRING, /* MODEL_COL_NAME_COLLATED */ \
|
||||
@@ -1727,6 +1741,22 @@ change_show_size_state (GSimpleAction *action,
|
||||
priv->show_size_column);
|
||||
}
|
||||
|
||||
/* Callback used when the "Show Type Column" menu item is toggled */
|
||||
static void
|
||||
change_show_type_state (GSimpleAction *action,
|
||||
GVariant *state,
|
||||
gpointer data)
|
||||
{
|
||||
GtkFileChooserWidget *impl = data;
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
|
||||
|
||||
g_simple_action_set_state (action, state);
|
||||
priv->show_type_column = g_variant_get_boolean (state);
|
||||
|
||||
gtk_tree_view_column_set_visible (priv->list_type_column,
|
||||
priv->show_type_column);
|
||||
}
|
||||
|
||||
static void
|
||||
change_sort_directories_first_state (GSimpleAction *action,
|
||||
GVariant *state,
|
||||
@@ -2093,6 +2123,7 @@ static GActionEntry entries[] = {
|
||||
{ "trash", trash_file_cb, NULL, NULL, NULL },
|
||||
{ "toggle-show-hidden", NULL, NULL, "false", change_show_hidden_state },
|
||||
{ "toggle-show-size", NULL, NULL, "false", change_show_size_state },
|
||||
{ "toggle-show-type", NULL, NULL, "false", change_show_type_state },
|
||||
{ "toggle-show-time", NULL, NULL, "false", change_show_time_state },
|
||||
{ "toggle-sort-dirs-first", NULL, NULL, "false", change_sort_directories_first_state }
|
||||
};
|
||||
@@ -2172,6 +2203,7 @@ file_list_build_popover (GtkFileChooserWidget *impl)
|
||||
|
||||
priv->hidden_files_item = add_button (box, _("Show _Hidden Files"), "item.toggle-show-hidden");
|
||||
priv->size_column_item = add_button (box, _("Show _Size Column"), "item.toggle-show-size");
|
||||
priv->type_column_item = add_button (box, _("Show T_ype Column"), "item.toggle-show-type");
|
||||
priv->show_time_item = add_button (box, _("Show _Time"), "item.toggle-show-time");
|
||||
priv->sort_directories_item = add_button (box, _("Sort _Folders before Files"), "item.toggle-sort-dirs-first");
|
||||
}
|
||||
@@ -2207,6 +2239,9 @@ file_list_update_popover (GtkFileChooserWidget *impl)
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "toggle-show-size");
|
||||
g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (priv->show_size_column));
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "toggle-show-type");
|
||||
g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (priv->show_type_column));
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "toggle-show-time");
|
||||
g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (priv->show_time));
|
||||
|
||||
@@ -2345,6 +2380,7 @@ file_list_set_sort_column_ids (GtkFileChooserWidget *impl)
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_name_column, MODEL_COL_NAME);
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_time_column, MODEL_COL_TIME);
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_size_column, MODEL_COL_SIZE);
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_type_column, MODEL_COL_TYPE);
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_location_column, MODEL_COL_LOCATION_TEXT);
|
||||
}
|
||||
|
||||
@@ -3657,8 +3693,10 @@ settings_load (GtkFileChooserWidget *impl)
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
|
||||
gboolean show_hidden;
|
||||
gboolean show_size_column;
|
||||
gboolean show_type_column;
|
||||
gboolean sort_directories_first;
|
||||
DateFormat date_format;
|
||||
TypeFormat type_format;
|
||||
gint sort_column;
|
||||
GtkSortType sort_order;
|
||||
StartupMode startup_mode;
|
||||
@@ -3669,17 +3707,21 @@ settings_load (GtkFileChooserWidget *impl)
|
||||
|
||||
show_hidden = g_settings_get_boolean (settings, SETTINGS_KEY_SHOW_HIDDEN);
|
||||
show_size_column = g_settings_get_boolean (settings, SETTINGS_KEY_SHOW_SIZE_COLUMN);
|
||||
show_type_column = g_settings_get_boolean (settings, SETTINGS_KEY_SHOW_TYPE_COLUMN);
|
||||
sort_column = g_settings_get_enum (settings, SETTINGS_KEY_SORT_COLUMN);
|
||||
sort_order = g_settings_get_enum (settings, SETTINGS_KEY_SORT_ORDER);
|
||||
sidebar_width = g_settings_get_int (settings, SETTINGS_KEY_SIDEBAR_WIDTH);
|
||||
startup_mode = g_settings_get_enum (settings, SETTINGS_KEY_STARTUP_MODE);
|
||||
sort_directories_first = g_settings_get_boolean (settings, SETTINGS_KEY_SORT_DIRECTORIES_FIRST);
|
||||
date_format = g_settings_get_enum (settings, SETTINGS_KEY_DATE_FORMAT);
|
||||
type_format = g_settings_get_enum (settings, SETTINGS_KEY_TYPE_FORMAT);
|
||||
|
||||
if (!priv->show_hidden_set)
|
||||
set_show_hidden (impl, show_hidden);
|
||||
priv->show_size_column = show_size_column;
|
||||
gtk_tree_view_column_set_visible (priv->list_size_column, show_size_column);
|
||||
priv->show_type_column = show_type_column;
|
||||
gtk_tree_view_column_set_visible (priv->list_type_column, show_type_column);
|
||||
|
||||
priv->sort_column = sort_column;
|
||||
priv->sort_order = sort_order;
|
||||
@@ -3687,6 +3729,7 @@ settings_load (GtkFileChooserWidget *impl)
|
||||
priv->sort_directories_first = sort_directories_first;
|
||||
priv->show_time = date_format == DATE_FORMAT_WITH_TIME;
|
||||
priv->clock_format = g_settings_get_enum (settings, "clock-format");
|
||||
priv->type_format = type_format;
|
||||
|
||||
/* We don't call set_sort_column() here as the models may not have been
|
||||
* created yet. The individual functions that create and set the models will
|
||||
@@ -3719,12 +3762,14 @@ settings_save (GtkFileChooserWidget *impl)
|
||||
g_settings_set_boolean (settings, SETTINGS_KEY_SHOW_HIDDEN,
|
||||
gtk_file_chooser_get_show_hidden (GTK_FILE_CHOOSER (impl)));
|
||||
g_settings_set_boolean (settings, SETTINGS_KEY_SHOW_SIZE_COLUMN, priv->show_size_column);
|
||||
g_settings_set_boolean (settings, SETTINGS_KEY_SHOW_TYPE_COLUMN, priv->show_type_column);
|
||||
g_settings_set_boolean (settings, SETTINGS_KEY_SORT_DIRECTORIES_FIRST, priv->sort_directories_first);
|
||||
g_settings_set_enum (settings, SETTINGS_KEY_SORT_COLUMN, priv->sort_column);
|
||||
g_settings_set_enum (settings, SETTINGS_KEY_SORT_ORDER, priv->sort_order);
|
||||
g_settings_set_int (settings, SETTINGS_KEY_SIDEBAR_WIDTH,
|
||||
gtk_paned_get_position (GTK_PANED (priv->browse_widgets_hpaned)));
|
||||
g_settings_set_enum (settings, SETTINGS_KEY_DATE_FORMAT, priv->show_time ? DATE_FORMAT_WITH_TIME : DATE_FORMAT_REGULAR);
|
||||
g_settings_set_enum (settings, SETTINGS_KEY_TYPE_FORMAT, priv->type_format);
|
||||
|
||||
/* Now apply the settings */
|
||||
g_settings_apply (settings);
|
||||
@@ -3976,6 +4021,20 @@ compare_size (GtkFileSystemModel *model,
|
||||
return size_a < size_b ? -1 : (size_a == size_b ? 0 : 1);
|
||||
}
|
||||
|
||||
static gint
|
||||
compare_type (GtkFileSystemModel *model,
|
||||
GtkTreeIter *a,
|
||||
GtkTreeIter *b,
|
||||
GtkFileChooserWidget *impl)
|
||||
{
|
||||
const char *key_a, *key_b;
|
||||
|
||||
key_a = g_value_get_string (_gtk_file_system_model_get_value (model, a, MODEL_COL_TYPE));
|
||||
key_b = g_value_get_string (_gtk_file_system_model_get_value (model, b, MODEL_COL_TYPE));
|
||||
|
||||
return g_strcmp0 (key_a, key_b);
|
||||
}
|
||||
|
||||
static gint
|
||||
compare_time (GtkFileSystemModel *model,
|
||||
GtkTreeIter *a,
|
||||
@@ -4042,6 +4101,25 @@ size_sort_func (GtkTreeModel *model,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Sort callback for the type column */
|
||||
static gint
|
||||
type_sort_func (GtkTreeModel *model,
|
||||
GtkTreeIter *a,
|
||||
GtkTreeIter *b,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkFileSystemModel *fs_model = GTK_FILE_SYSTEM_MODEL (model);
|
||||
GtkFileChooserWidget *impl = user_data;
|
||||
gint result;
|
||||
|
||||
result = compare_directory (fs_model, a, b, impl);
|
||||
|
||||
if (result == 0)
|
||||
result = compare_type (fs_model, a, b, impl);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Sort callback for the time column */
|
||||
static gint
|
||||
time_sort_func (GtkTreeModel *model,
|
||||
@@ -4692,6 +4770,93 @@ file_system_model_got_thumbnail (GObject *object,
|
||||
g_object_unref (queried);
|
||||
}
|
||||
|
||||
/* Copied from src/nautilus_file.c:get_description() */
|
||||
struct {
|
||||
const char *icon_name;
|
||||
const char *display_name;
|
||||
} mime_type_map[] = {
|
||||
{ "application-x-executable", N_("Program") },
|
||||
{ "audio-x-generic", N_("Audio") },
|
||||
{ "font-x-generic", N_("Font") },
|
||||
{ "image-x-generic", N_("Image") },
|
||||
{ "package-x-generic", N_("Archive") },
|
||||
{ "text-html", N_("Markup") },
|
||||
{ "text-x-generic", N_("Text") },
|
||||
{ "text-x-generic-template", N_("Text") },
|
||||
{ "text-x-script", N_("Program") },
|
||||
{ "video-x-generic", N_("Video") },
|
||||
{ "x-office-address-book", N_("Contacts") },
|
||||
{ "x-office-calendar", N_("Calendar") },
|
||||
{ "x-office-document", N_("Document") },
|
||||
{ "x-office-presentation", N_("Presentation") },
|
||||
{ "x-office-spreadsheet", N_("Spreadsheet") },
|
||||
};
|
||||
|
||||
static char *
|
||||
get_category_from_content_type (const char *content_type)
|
||||
{
|
||||
char *icon_name;
|
||||
char *basic_type = NULL;
|
||||
|
||||
icon_name = g_content_type_get_generic_icon_name (content_type);
|
||||
if (icon_name != NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (mime_type_map); i++)
|
||||
{
|
||||
if (strcmp (mime_type_map[i].icon_name, icon_name) == 0)
|
||||
{
|
||||
basic_type = g_strdup (gettext (mime_type_map[i].display_name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (icon_name);
|
||||
}
|
||||
|
||||
if (basic_type == NULL)
|
||||
{
|
||||
basic_type = g_content_type_get_description (content_type);
|
||||
if (basic_type == NULL)
|
||||
{
|
||||
basic_type = g_strdup (_("Unknown"));
|
||||
}
|
||||
}
|
||||
|
||||
return basic_type;
|
||||
}
|
||||
|
||||
static char *
|
||||
get_type_information (GtkFileChooserWidget *impl,
|
||||
GFileInfo *info)
|
||||
{
|
||||
const char *content_type;
|
||||
char *mime_type;
|
||||
char *description;
|
||||
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
|
||||
content_type = g_file_info_get_content_type (info);
|
||||
switch (priv->type_format)
|
||||
{
|
||||
case TYPE_FORMAT_MIME:
|
||||
mime_type = g_content_type_get_mime_type (content_type);
|
||||
return mime_type ? mime_type : g_strdup (content_type);
|
||||
|
||||
case TYPE_FORMAT_DESCRIPTION:
|
||||
description = g_content_type_get_description (content_type);
|
||||
return description ? description : g_strdup (content_type);
|
||||
|
||||
case TYPE_FORMAT_CATEGORY:
|
||||
return get_category_from_content_type (content_type);
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
return g_strdup ("");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
file_system_model_set (GtkFileSystemModel *model,
|
||||
GFile *file,
|
||||
@@ -4819,6 +4984,12 @@ file_system_model_set (GtkFileSystemModel *model,
|
||||
else
|
||||
g_value_take_string (value, g_format_size (g_file_info_get_size (info)));
|
||||
break;
|
||||
case MODEL_COL_TYPE:
|
||||
if (info == NULL || _gtk_file_info_consider_as_directory (info))
|
||||
g_value_set_string (value, NULL);
|
||||
else
|
||||
g_value_take_string (value, get_type_information (impl, info));
|
||||
break;
|
||||
case MODEL_COL_TIME:
|
||||
case MODEL_COL_DATE_TEXT:
|
||||
case MODEL_COL_TIME_TEXT:
|
||||
@@ -4931,6 +5102,7 @@ set_list_model (GtkFileChooserWidget *impl,
|
||||
profile_msg (" set sort function", NULL);
|
||||
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (priv->browse_files_model), MODEL_COL_NAME, name_sort_func, impl, NULL);
|
||||
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (priv->browse_files_model), MODEL_COL_SIZE, size_sort_func, impl, NULL);
|
||||
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (priv->browse_files_model), MODEL_COL_TYPE, type_sort_func, impl, NULL);
|
||||
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (priv->browse_files_model), MODEL_COL_TIME, time_sort_func, impl, NULL);
|
||||
gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (priv->browse_files_model), NULL, NULL, NULL);
|
||||
set_sort_column (impl);
|
||||
@@ -7054,6 +7226,7 @@ search_setup_model (GtkFileChooserWidget *impl)
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_name_column, -1);
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_time_column, -1);
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_size_column, -1);
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_type_column, -1);
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_location_column, -1);
|
||||
|
||||
update_columns (impl, TRUE, _("Modified"));
|
||||
@@ -7271,6 +7444,7 @@ recent_idle_cleanup (gpointer data)
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_name_column, -1);
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_time_column, -1);
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_size_column, -1);
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_type_column, -1);
|
||||
gtk_tree_view_column_set_sort_column_id (priv->list_location_column, -1);
|
||||
|
||||
update_columns (impl, TRUE, _("Accessed"));
|
||||
@@ -7712,6 +7886,12 @@ update_cell_renderer_attributes (GtkFileChooserWidget *impl)
|
||||
"sensitive", MODEL_COL_IS_SENSITIVE,
|
||||
NULL);
|
||||
|
||||
gtk_tree_view_column_set_attributes (priv->list_type_column,
|
||||
priv->list_type_renderer,
|
||||
"text", MODEL_COL_TYPE,
|
||||
"sensitive", MODEL_COL_IS_SENSITIVE,
|
||||
NULL);
|
||||
|
||||
gtk_tree_view_column_set_attributes (priv->list_time_column,
|
||||
priv->list_date_renderer,
|
||||
"text", MODEL_COL_DATE_TEXT,
|
||||
@@ -8296,6 +8476,8 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class)
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_time_renderer);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_size_column);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_size_renderer);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_type_column);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_type_renderer);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_location_column);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_location_renderer);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, new_folder_name_entry);
|
||||
@@ -8446,6 +8628,8 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
|
||||
priv->select_multiple = FALSE;
|
||||
priv->show_hidden = FALSE;
|
||||
priv->show_size_column = TRUE;
|
||||
priv->show_type_column = TRUE;
|
||||
priv->type_format = TYPE_FORMAT_MIME;
|
||||
priv->load_state = LOAD_EMPTY;
|
||||
priv->reload_state = RELOAD_EMPTY;
|
||||
priv->pending_select_files = NULL;
|
||||
|
||||
+95
-107
@@ -285,7 +285,6 @@ struct _GtkLabelPrivate
|
||||
PangoAttrList *markup_attrs;
|
||||
PangoLayout *layout;
|
||||
|
||||
GActionMap *context_actions;
|
||||
GtkWidget *popup_menu;
|
||||
GMenuModel *extra_menu;
|
||||
|
||||
@@ -575,8 +574,25 @@ static void gtk_label_drag_gesture_update (GtkGestureDrag *gesture,
|
||||
gdouble offset_y,
|
||||
GtkLabel *label);
|
||||
|
||||
static void gtk_label_add_context_actions (GtkLabel *label);
|
||||
static void gtk_label_update_clipboard_actions (GtkLabel *label);
|
||||
/* Actions */
|
||||
|
||||
static void gtk_label_activate_clipboard_copy (GtkWidget *label,
|
||||
const char *name,
|
||||
GVariant *parameter);
|
||||
static void gtk_label_activate_selection_select_all (GtkWidget *label,
|
||||
const char *name,
|
||||
GVariant *parameter);
|
||||
static void gtk_label_activate_link_open (GtkWidget *label,
|
||||
const char *name,
|
||||
GVariant *parameter);
|
||||
static void gtk_label_activate_link_copy (GtkWidget *label,
|
||||
const char *name,
|
||||
GVariant *parameter);
|
||||
static void gtk_label_nop (GtkWidget *label,
|
||||
const char *name,
|
||||
GVariant *parameter);
|
||||
|
||||
static void gtk_label_update_actions (GtkLabel *label);
|
||||
|
||||
static GtkSizeRequestMode gtk_label_get_request_mode (GtkWidget *widget);
|
||||
static void gtk_label_measure (GtkWidget *widget,
|
||||
@@ -1143,6 +1159,21 @@ gtk_label_class_init (GtkLabelClass *class)
|
||||
quark_mnemonics_visible_connected = g_quark_from_static_string ("gtk-label-mnemonics-visible-connected");
|
||||
quark_gtk_signal = g_quark_from_static_string ("gtk-signal");
|
||||
quark_link = g_quark_from_static_string ("link");
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.cut", NULL,
|
||||
gtk_label_nop);
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.copy", NULL,
|
||||
gtk_label_activate_clipboard_copy);
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.paste", NULL,
|
||||
gtk_label_nop);
|
||||
gtk_widget_class_install_action (widget_class, "selection.delete", NULL,
|
||||
gtk_label_nop);
|
||||
gtk_widget_class_install_action (widget_class, "selection.select-all", NULL,
|
||||
gtk_label_activate_selection_select_all);
|
||||
gtk_widget_class_install_action (widget_class, "link.open", NULL,
|
||||
gtk_label_activate_link_open);
|
||||
gtk_widget_class_install_action (widget_class, "link.copy", NULL,
|
||||
gtk_label_activate_link_copy);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1329,9 +1360,7 @@ gtk_label_init (GtkLabel *label)
|
||||
priv->mnemonic_widget = NULL;
|
||||
priv->mnemonic_window = NULL;
|
||||
|
||||
priv->mnemonics_visible = TRUE;
|
||||
|
||||
gtk_label_add_context_actions (label);
|
||||
priv->mnemonics_visible = FALSE;
|
||||
}
|
||||
|
||||
|
||||
@@ -3205,7 +3234,6 @@ gtk_label_finalize (GObject *object)
|
||||
gtk_label_clear_links (label);
|
||||
g_free (priv->select_info);
|
||||
|
||||
g_clear_object (&priv->context_actions);
|
||||
g_clear_pointer (&priv->popup_menu, gtk_widget_unparent);
|
||||
g_clear_object (&priv->extra_menu);
|
||||
|
||||
@@ -4854,6 +4882,8 @@ gtk_label_update_active_link (GtkWidget *widget,
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_label_update_actions (label);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5295,6 +5325,8 @@ gtk_label_select_region_index (GtkLabel *label,
|
||||
}
|
||||
}
|
||||
|
||||
gtk_label_update_actions (label);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (label));
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (label));
|
||||
@@ -5968,24 +6000,24 @@ gtk_label_select_all (GtkLabel *label)
|
||||
}
|
||||
|
||||
static void
|
||||
open_link_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_label_activate_link_open (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (user_data);
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
GtkLabelLink *link = priv->select_info->context_link;
|
||||
GtkLabelLink *link = priv->select_info->context_link;
|
||||
|
||||
if (link)
|
||||
emit_activate_link (label, link);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_link_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_label_activate_link_copy (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (user_data);
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
GtkLabelLink *link = priv->select_info->context_link;
|
||||
|
||||
@@ -5993,101 +6025,59 @@ copy_link_activated (GSimpleAction *action,
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (label));
|
||||
clipboard = gtk_widget_get_clipboard (widget);
|
||||
gdk_clipboard_set_text (clipboard, link->uri);
|
||||
}
|
||||
else
|
||||
g_print ("no link ?!\n");
|
||||
}
|
||||
|
||||
static void
|
||||
copy_clipboard_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_label_activate_clipboard_copy (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
g_signal_emit_by_name (user_data, "copy-clipboard");
|
||||
g_signal_emit_by_name (widget, "copy-clipboard");
|
||||
}
|
||||
|
||||
static void
|
||||
select_all_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_label_activate_selection_select_all (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_label_select_all (GTK_LABEL (user_data));
|
||||
gtk_label_select_all (GTK_LABEL (widget));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_update_clipboard_actions (GtkLabel *label)
|
||||
gtk_label_nop (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_update_actions (GtkLabel *label)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (label);
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
gboolean have_selection = FALSE;
|
||||
GAction *action;
|
||||
|
||||
if (priv->select_info)
|
||||
have_selection = priv->select_info->selection_anchor != priv->select_info->selection_end;
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "copy-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), have_selection);
|
||||
action = g_action_map_lookup_action (priv->context_actions, "select-all");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), gtk_label_get_selectable (label));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_update_link_actions (GtkLabel *label)
|
||||
{
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
gboolean have_selection = FALSE;
|
||||
GAction *action;
|
||||
gboolean has_selection;
|
||||
GtkLabelLink *link;
|
||||
|
||||
have_selection = priv->select_info->selection_anchor != priv->select_info->selection_end;
|
||||
if (priv->select_info)
|
||||
has_selection = priv->select_info->selection_anchor != priv->select_info->selection_end;
|
||||
else
|
||||
has_selection = FALSE;
|
||||
|
||||
if (priv->select_info->link_clicked)
|
||||
link = priv->select_info->active_link;
|
||||
else
|
||||
link = gtk_label_get_focus_link (label);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "open-link");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), !have_selection && link);
|
||||
action = g_action_map_lookup_action (priv->context_actions, "copy-link");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), !have_selection && link);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_add_context_actions (GtkLabel *label)
|
||||
{
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
|
||||
GActionEntry entries[] = {
|
||||
{ "cut-clipboard", NULL, NULL, NULL, NULL },
|
||||
{ "copy-clipboard", copy_clipboard_activated, NULL, NULL, NULL },
|
||||
{ "paste-clipboard", NULL, NULL, NULL, NULL },
|
||||
{ "delete-selection", NULL, NULL, NULL, NULL },
|
||||
{ "select-all", select_all_activated, NULL, NULL, NULL },
|
||||
{ "open-link", open_link_activated, NULL, NULL, NULL },
|
||||
{ "copy-link", copy_link_activated, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
GSimpleActionGroup *actions = g_simple_action_group_new ();
|
||||
GAction *action;
|
||||
|
||||
priv->context_actions = G_ACTION_MAP (actions);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), label);
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "cut-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "copy-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "paste-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "delete-selection");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "select-all");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "open-link");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "copy-link");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (label), "context", G_ACTION_GROUP (actions));
|
||||
gtk_widget_action_set_enabled (widget, "clipboard.copy", has_selection);
|
||||
gtk_widget_action_set_enabled (widget, "selection.select-all",
|
||||
gtk_label_get_selectable (label));
|
||||
gtk_widget_action_set_enabled (widget, "link.open", !has_selection && link);
|
||||
gtk_widget_action_set_enabled (widget, "link.copy", !has_selection && link);
|
||||
}
|
||||
|
||||
static GMenuModel *
|
||||
@@ -6100,24 +6090,24 @@ gtk_label_get_menu_model (GtkLabel *label)
|
||||
menu = g_menu_new ();
|
||||
|
||||
section = g_menu_new ();
|
||||
g_menu_append (section, _("Cu_t"), "context.cut-clipboard");
|
||||
g_menu_append (section, _("_Copy"), "context.copy-clipboard");
|
||||
g_menu_append (section, _("_Paste"), "context.paste-clipboard");
|
||||
g_menu_append (section, _("_Delete"), "context.delete-selection");
|
||||
g_menu_append (section, _("Cu_t"), "clipboard.cut");
|
||||
g_menu_append (section, _("_Copy"), "clipboard.copy");
|
||||
g_menu_append (section, _("_Paste"), "clipboard.paste");
|
||||
g_menu_append (section, _("_Delete"), "selection.delete");
|
||||
g_menu_append_section (menu, NULL, G_MENU_MODEL (section));
|
||||
g_object_unref (section);
|
||||
|
||||
section = g_menu_new ();
|
||||
g_menu_append (section, _("Select _All"), "context.select-all");
|
||||
g_menu_append (section, _("Select _All"), "selection.select-all");
|
||||
g_menu_append_section (menu, NULL, G_MENU_MODEL (section));
|
||||
g_object_unref (section);
|
||||
|
||||
section = g_menu_new ();
|
||||
item = g_menu_item_new (_("_Open Link"), "context.open-link");
|
||||
item = g_menu_item_new (_("_Open Link"), "link.open");
|
||||
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
item = g_menu_item_new (_("Copy _Link Address"), "context.copy-link");
|
||||
item = g_menu_item_new (_("Copy _Link Address"), "link.copy");
|
||||
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
@@ -6137,8 +6127,15 @@ gtk_label_do_popup (GtkLabel *label,
|
||||
{
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
|
||||
gtk_label_update_clipboard_actions (label);
|
||||
gtk_label_update_link_actions (label);
|
||||
if (!priv->select_info)
|
||||
return;
|
||||
|
||||
if (priv->select_info->link_clicked)
|
||||
priv->select_info->context_link = priv->select_info->active_link;
|
||||
else
|
||||
priv->select_info->context_link = gtk_label_get_focus_link (label);
|
||||
|
||||
gtk_label_update_actions (label);
|
||||
|
||||
if (!priv->popup_menu)
|
||||
{
|
||||
@@ -6169,15 +6166,6 @@ static gboolean
|
||||
gtk_label_popup_menu (GtkWidget *widget)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
|
||||
if (!priv->select_info)
|
||||
return FALSE;
|
||||
|
||||
if (priv->select_info->link_clicked)
|
||||
priv->select_info->context_link = priv->select_info->active_link;
|
||||
else
|
||||
priv->select_info->context_link = gtk_label_get_focus_link (label);
|
||||
|
||||
gtk_label_do_popup (label, -1, -1);
|
||||
return TRUE;
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
|
||||
typedef struct {
|
||||
GtkWidget *widget;
|
||||
GtkRoot *root;
|
||||
|
||||
/* HashTable<Widget, LayoutChild> */
|
||||
GHashTable *layout_children;
|
||||
@@ -98,6 +99,16 @@ typedef struct {
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GtkLayoutManager, gtk_layout_manager, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
gtk_layout_manager_real_root (GtkLayoutManager *manager)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_layout_manager_real_unroot (GtkLayoutManager *manager)
|
||||
{
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
gtk_layout_manager_real_get_request_mode (GtkLayoutManager *manager,
|
||||
GtkWidget *widget)
|
||||
@@ -188,13 +199,30 @@ gtk_layout_manager_real_create_layout_child (GtkLayoutManager *manager,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_layout_manager_finalize (GObject *gobject)
|
||||
{
|
||||
GtkLayoutManager *self = GTK_LAYOUT_MANAGER (gobject);
|
||||
GtkLayoutManagerPrivate *priv = gtk_layout_manager_get_instance_private (self);
|
||||
|
||||
g_clear_pointer (&priv->layout_children, g_hash_table_unref);
|
||||
|
||||
G_OBJECT_CLASS (gtk_layout_manager_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_layout_manager_class_init (GtkLayoutManagerClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = gtk_layout_manager_finalize;
|
||||
|
||||
klass->get_request_mode = gtk_layout_manager_real_get_request_mode;
|
||||
klass->measure = gtk_layout_manager_real_measure;
|
||||
klass->allocate = gtk_layout_manager_real_allocate;
|
||||
klass->create_layout_child = gtk_layout_manager_real_create_layout_child;
|
||||
klass->root = gtk_layout_manager_real_root;
|
||||
klass->unroot = gtk_layout_manager_real_unroot;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -226,6 +254,38 @@ gtk_layout_manager_set_widget (GtkLayoutManager *layout_manager,
|
||||
}
|
||||
|
||||
priv->widget = widget;
|
||||
|
||||
if (widget != NULL)
|
||||
gtk_layout_manager_set_root (layout_manager, gtk_widget_get_root (widget));
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gtk_layout_manager_set_root:
|
||||
* @layout_manager: a #GtkLayoutManager
|
||||
* @root: (nullable): a #GtkWidget implementing #GtkRoot
|
||||
*
|
||||
* Sets a back pointer from @root to @layout_manager.
|
||||
*
|
||||
* This function is called by #GtkWidget when getting rooted and unrooted,
|
||||
* and will call #GtkLayoutManagerClass.root() or #GtkLayoutManagerClass.unroot()
|
||||
* depending on whether @root is a #GtkWidget or %NULL.
|
||||
*/
|
||||
void
|
||||
gtk_layout_manager_set_root (GtkLayoutManager *layout_manager,
|
||||
GtkRoot *root)
|
||||
{
|
||||
GtkLayoutManagerPrivate *priv = gtk_layout_manager_get_instance_private (layout_manager);
|
||||
GtkRoot *old_root = priv->root;
|
||||
|
||||
priv->root = root;
|
||||
|
||||
if (old_root != root)
|
||||
{
|
||||
if (priv->root != NULL)
|
||||
GTK_LAYOUT_MANAGER_GET_CLASS (layout_manager)->root (layout_manager);
|
||||
else
|
||||
GTK_LAYOUT_MANAGER_GET_CLASS (layout_manager)->unroot (layout_manager);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,6 +42,10 @@ G_DECLARE_DERIVABLE_TYPE (GtkLayoutManager, gtk_layout_manager, GTK, LAYOUT_MANA
|
||||
* @layout_child_type: the type of #GtkLayoutChild used by this layout manager
|
||||
* @create_layout_child: a virtual function, used to create a #GtkLayoutChild
|
||||
* meta object for the layout properties
|
||||
* @root: a virtual function, called when the widget using the layout
|
||||
* manager is attached to a #GtkRoot
|
||||
* @unroot: a virtual function, called when the widget using the layout
|
||||
* manager is detached from a #GtkRoot
|
||||
*
|
||||
* The `GtkLayoutManagerClass` structure contains only private data, and
|
||||
* should only be accessed through the provided API, or when subclassing
|
||||
@@ -77,6 +81,9 @@ struct _GtkLayoutManagerClass
|
||||
GtkWidget *widget,
|
||||
GtkWidget *for_child);
|
||||
|
||||
void (* root) (GtkLayoutManager *manager);
|
||||
void (* unroot) (GtkLayoutManager *manager);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _padding[16];
|
||||
};
|
||||
|
||||
@@ -10,4 +10,7 @@ void gtk_layout_manager_set_widget (GtkLayoutManager *manager,
|
||||
void gtk_layout_manager_remove_layout_child (GtkLayoutManager *manager,
|
||||
GtkWidget *widget);
|
||||
|
||||
void gtk_layout_manager_set_root (GtkLayoutManager *manager,
|
||||
GtkRoot *root);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
+13
-36
@@ -96,7 +96,6 @@ struct _GtkLinkButtonPrivate
|
||||
|
||||
gboolean visited;
|
||||
|
||||
GActionMap *context_actions;
|
||||
GtkWidget *popup_menu;
|
||||
};
|
||||
|
||||
@@ -152,6 +151,17 @@ static guint link_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkLinkButton, gtk_link_button, GTK_TYPE_BUTTON)
|
||||
|
||||
static void
|
||||
gtk_link_button_activate_clipboard_copy (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkLinkButton *link_button = GTK_LINK_BUTTON (widget);
|
||||
GtkLinkButtonPrivate *priv = gtk_link_button_get_instance_private (link_button);
|
||||
|
||||
gdk_clipboard_set_text (gtk_widget_get_clipboard (widget), priv->uri);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_link_button_class_init (GtkLinkButtonClass *klass)
|
||||
{
|
||||
@@ -221,28 +231,9 @@ gtk_link_button_class_init (GtkLinkButtonClass *klass)
|
||||
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_LINK_BUTTON_ACCESSIBLE);
|
||||
gtk_widget_class_set_css_name (widget_class, I_("button"));
|
||||
}
|
||||
|
||||
static void copy_activate_cb (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data);
|
||||
|
||||
static void
|
||||
gtk_link_button_add_context_actions (GtkLinkButton *link_button)
|
||||
{
|
||||
GtkLinkButtonPrivate *priv = gtk_link_button_get_instance_private (link_button);
|
||||
|
||||
GActionEntry entries[] = {
|
||||
{ "copy-clipboard", copy_activate_cb, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
GSimpleActionGroup *actions = g_simple_action_group_new ();
|
||||
|
||||
priv->context_actions = G_ACTION_MAP (actions);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), link_button);
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (link_button), "context", G_ACTION_GROUP (actions));
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.copy", NULL,
|
||||
gtk_link_button_activate_clipboard_copy);
|
||||
}
|
||||
|
||||
static GMenuModel *
|
||||
@@ -298,7 +289,6 @@ gtk_link_button_init (GtkLinkButton *link_button)
|
||||
gtk_style_context_add_class (context, "link");
|
||||
|
||||
gtk_widget_set_cursor_from_name (GTK_WIDGET (link_button), "pointer");
|
||||
gtk_link_button_add_context_actions (link_button);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -309,7 +299,6 @@ gtk_link_button_finalize (GObject *object)
|
||||
|
||||
g_free (priv->uri);
|
||||
|
||||
g_clear_object (&priv->context_actions);
|
||||
g_clear_pointer (&priv->popup_menu, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (gtk_link_button_parent_class)->finalize (object);
|
||||
@@ -360,18 +349,6 @@ gtk_link_button_set_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
copy_activate_cb (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkLinkButton *link_button = user_data;
|
||||
GtkLinkButtonPrivate *priv = gtk_link_button_get_instance_private (link_button);
|
||||
|
||||
gdk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (link_button)),
|
||||
priv->uri);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_link_button_do_popup (GtkLinkButton *link_button,
|
||||
double x,
|
||||
|
||||
@@ -70,6 +70,12 @@
|
||||
*
|
||||
* The GtkListBox widget was added in GTK+ 3.10.
|
||||
*
|
||||
* # GtkListBox as GtkBuildable
|
||||
*
|
||||
* The GtkListBox implementation of the #GtkBuildable interface supports
|
||||
* setting a child as the placeholder by specifying “placeholder” as the “type”
|
||||
* attribute of a <child> element. See gtk_list_box_set_placeholder() for info.
|
||||
*
|
||||
* # CSS nodes
|
||||
*
|
||||
* |[<!-- language="plain" -->
|
||||
|
||||
@@ -1998,39 +1998,6 @@ gtk_main_do_event (GdkEvent *event)
|
||||
|
||||
case GDK_KEY_PRESS:
|
||||
case GDK_KEY_RELEASE:
|
||||
/* make focus visible in a window that receives a key event */
|
||||
{
|
||||
GtkRoot *root;
|
||||
|
||||
root = gtk_widget_get_root (grab_widget);
|
||||
if (GTK_IS_WINDOW (root))
|
||||
gtk_window_set_focus_visible (GTK_WINDOW (root), TRUE);
|
||||
}
|
||||
|
||||
/* Catch alt press to enable auto-mnemonics;
|
||||
* menus are handled elsewhere
|
||||
* FIXME: this does not work with mnemonic modifiers other than Alt
|
||||
*/
|
||||
if ((event->key.keyval == GDK_KEY_Alt_L || event->key.keyval == GDK_KEY_Alt_R) &&
|
||||
((event->key.state & (gtk_accelerator_get_default_mod_mask ()) & ~(GDK_RELEASE_MASK|GDK_MOD1_MASK)) == 0) &&
|
||||
!GTK_IS_MENU_SHELL (grab_widget))
|
||||
{
|
||||
gboolean mnemonics_visible;
|
||||
GtkRoot *root;
|
||||
|
||||
mnemonics_visible = (event->any.type == GDK_KEY_PRESS);
|
||||
|
||||
root = gtk_widget_get_root (grab_widget);
|
||||
if (GTK_IS_WINDOW (root))
|
||||
{
|
||||
if (mnemonics_visible)
|
||||
_gtk_window_schedule_mnemonics_visible (GTK_WINDOW (root));
|
||||
else
|
||||
gtk_window_set_mnemonics_visible (GTK_WINDOW (root), FALSE);
|
||||
}
|
||||
}
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
case GDK_SCROLL:
|
||||
case GDK_BUTTON_PRESS:
|
||||
case GDK_TOUCH_BEGIN:
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
* More complicated placement of overlays is possible by connecting
|
||||
* to the #GtkOverlay::get-child-position signal.
|
||||
*
|
||||
* An overlay’s minimum and natural sizes are those of its main child. The sizes
|
||||
* of overlay children are not considered when measuring these preferred sizes.
|
||||
*
|
||||
* # GtkOverlay as GtkBuildable
|
||||
*
|
||||
* The GtkOverlay implementation of the GtkBuildable interface
|
||||
|
||||
+30
-9
@@ -110,20 +110,30 @@ focus_changed (GtkWidget *widget)
|
||||
|
||||
static void
|
||||
gtk_password_entry_toggle_peek (GtkPasswordEntry *entry)
|
||||
{
|
||||
GtkPasswordEntryPrivate *priv = gtk_password_entry_get_instance_private (entry);
|
||||
gboolean visibility;
|
||||
|
||||
visibility = gtk_text_get_visibility (GTK_TEXT (priv->entry));
|
||||
gtk_text_set_visibility (GTK_TEXT (priv->entry), !visibility);
|
||||
}
|
||||
|
||||
static void
|
||||
visibility_toggled (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
GtkPasswordEntry *entry)
|
||||
{
|
||||
GtkPasswordEntryPrivate *priv = gtk_password_entry_get_instance_private (entry);
|
||||
|
||||
if (gtk_text_get_visibility (GTK_TEXT (priv->entry)))
|
||||
{
|
||||
gtk_text_set_visibility (GTK_TEXT (priv->entry), FALSE);
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (priv->peek_icon), "eye-not-looking-symbolic");
|
||||
gtk_widget_set_tooltip_text (priv->peek_icon, _("Show text"));
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (priv->peek_icon), "eye-open-negative-filled-symbolic");
|
||||
gtk_widget_set_tooltip_text (priv->peek_icon, _("Hide text"));
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_text_set_visibility (GTK_TEXT (priv->entry), TRUE);
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (priv->peek_icon), "eye-open-negative-filled-symbolic");
|
||||
gtk_widget_set_tooltip_text (priv->peek_icon, _("Hide text"));
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (priv->peek_icon), "eye-not-looking-symbolic");
|
||||
gtk_widget_set_tooltip_text (priv->peek_icon, _("Show text"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,11 +492,18 @@ gtk_password_entry_set_show_peek_icon (GtkPasswordEntry *entry,
|
||||
g_signal_connect_swapped (press, "released",
|
||||
G_CALLBACK (gtk_password_entry_toggle_peek), entry);
|
||||
gtk_widget_add_controller (priv->peek_icon, GTK_EVENT_CONTROLLER (press));
|
||||
|
||||
g_signal_connect (priv->entry, "notify::visibility",
|
||||
G_CALLBACK (visibility_toggled), entry);
|
||||
visibility_toggled (G_OBJECT (priv->entry), NULL, entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_clear_pointer (&priv->peek_icon, gtk_widget_unparent);
|
||||
gtk_text_set_visibility (GTK_TEXT (priv->entry), FALSE);
|
||||
g_signal_handlers_disconnect_by_func (priv->entry,
|
||||
visibility_toggled,
|
||||
entry);
|
||||
}
|
||||
|
||||
keymap_state_changed (priv->keymap, GTK_WIDGET (entry));
|
||||
@@ -532,13 +549,17 @@ gtk_password_entry_set_extra_menu (GtkPasswordEntry *entry,
|
||||
|
||||
g_return_if_fail (GTK_IS_PASSWORD_ENTRY (entry));
|
||||
|
||||
if (!g_set_object (&priv->extra_menu, model))
|
||||
return;
|
||||
/* bypass this check for the initial call from init */
|
||||
if (priv->extra_menu)
|
||||
{
|
||||
if (!g_set_object (&priv->extra_menu, model))
|
||||
return;
|
||||
}
|
||||
|
||||
menu = g_menu_new ();
|
||||
|
||||
section = g_menu_new ();
|
||||
item = g_menu_item_new (_("_Show Text"), "context.toggle-visibility");
|
||||
item = g_menu_item_new (_("_Show Text"), "misc.toggle-visibility");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "eye-not-looking-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
|
||||
@@ -50,10 +50,18 @@ gtk_root_default_get_display (GtkRoot *self)
|
||||
return gdk_display_get_default ();
|
||||
}
|
||||
|
||||
|
||||
static GtkConstraintSolver *
|
||||
gtk_root_default_get_constraint_solver (GtkRoot *self)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_root_default_init (GtkRootInterface *iface)
|
||||
{
|
||||
iface->get_display = gtk_root_default_get_display;
|
||||
iface->get_constraint_solver = gtk_root_default_get_constraint_solver;
|
||||
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_object ("focus-widget",
|
||||
@@ -82,6 +90,17 @@ gtk_root_get_display (GtkRoot *self)
|
||||
return iface->get_display (self);
|
||||
}
|
||||
|
||||
GtkConstraintSolver *
|
||||
gtk_root_get_constraint_solver (GtkRoot *self)
|
||||
{
|
||||
GtkRootInterface *iface;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_ROOT (self), NULL);
|
||||
|
||||
iface = GTK_ROOT_GET_IFACE (self);
|
||||
return iface->get_constraint_solver (self);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_root_set_focus:
|
||||
* @self: a #GtkRoot
|
||||
|
||||
@@ -34,20 +34,6 @@ G_BEGIN_DECLS
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_INTERFACE (GtkRoot, gtk_root, GTK, ROOT, GtkWidget)
|
||||
|
||||
/**
|
||||
* GtkRootIface:
|
||||
*
|
||||
* The list of functions that must be implemented for the #GtkRoot interface.
|
||||
*/
|
||||
struct _GtkRootInterface
|
||||
{
|
||||
/*< private >*/
|
||||
GTypeInterface g_iface;
|
||||
|
||||
/*< public >*/
|
||||
GdkDisplay * (* get_display) (GtkRoot *self);
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GdkDisplay * gtk_root_get_display (GtkRoot *self);
|
||||
|
||||
|
||||
@@ -3,8 +3,28 @@
|
||||
|
||||
#include "gtkroot.h"
|
||||
|
||||
#include "gtkconstraintsolverprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* GtkRootIface:
|
||||
*
|
||||
* The list of functions that must be implemented for the #GtkRoot interface.
|
||||
*/
|
||||
struct _GtkRootInterface
|
||||
{
|
||||
/*< private >*/
|
||||
GTypeInterface g_iface;
|
||||
|
||||
/*< public >*/
|
||||
GdkDisplay * (* get_display) (GtkRoot *self);
|
||||
|
||||
GtkConstraintSolver * (* get_constraint_solver) (GtkRoot *self);
|
||||
};
|
||||
|
||||
GtkConstraintSolver * gtk_root_get_constraint_solver (GtkRoot *self);
|
||||
|
||||
enum {
|
||||
GTK_ROOT_PROP_FOCUS_WIDGET,
|
||||
GTK_ROOT_NUM_PROPERTIES
|
||||
|
||||
@@ -368,7 +368,7 @@ gtk_shortcuts_section_class_init (GtkShortcutsSectionClass *klass)
|
||||
* The maximum number of lines to allow per column. This property can
|
||||
* be used to influence how the groups in this section are distributed
|
||||
* across pages and columns. The default value of 15 should work in
|
||||
* for most cases.
|
||||
* most cases.
|
||||
*/
|
||||
properties[PROP_MAX_HEIGHT] =
|
||||
g_param_spec_uint ("max-height", P_("Maximum Height"), P_("Maximum Height"),
|
||||
|
||||
+109
-133
@@ -68,6 +68,7 @@
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkwindow.h"
|
||||
#include "gtknative.h"
|
||||
#include "gtkactionmuxerprivate.h"
|
||||
|
||||
#include "a11y/gtktextaccessible.h"
|
||||
|
||||
@@ -174,7 +175,6 @@ struct _GtkTextPrivate
|
||||
GtkCssNode *block_cursor_node;
|
||||
GtkCssNode *undershoot_node[2];
|
||||
|
||||
GActionMap *context_actions;
|
||||
GtkWidget *popup_menu;
|
||||
GMenuModel *extra_menu;
|
||||
|
||||
@@ -542,10 +542,27 @@ static void begin_change (GtkText *self);
|
||||
static void end_change (GtkText *self);
|
||||
static void emit_changed (GtkText *self);
|
||||
|
||||
static void gtk_text_add_context_actions (GtkText *self);
|
||||
static void gtk_text_update_clipboard_actions (GtkText *self);
|
||||
static void gtk_text_update_emoji_action (GtkText *self);
|
||||
|
||||
static void gtk_text_activate_clipboard_cut (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_activate_clipboard_copy (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_activate_clipboard_paste (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_activate_selection_delete (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_activate_selection_select_all (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_activate_misc_insert_emoji (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
|
||||
/* GtkTextContent implementation
|
||||
*/
|
||||
@@ -706,7 +723,7 @@ gtk_text_class_init (GtkTextClass *class)
|
||||
class->toggle_overwrite = gtk_text_toggle_overwrite;
|
||||
class->insert_emoji = gtk_text_insert_emoji;
|
||||
class->activate = gtk_text_real_activate;
|
||||
|
||||
|
||||
quark_password_hint = g_quark_from_static_string ("gtk-entry-password-hint");
|
||||
quark_gtk_signal = g_quark_from_static_string ("gtk-signal");
|
||||
|
||||
@@ -1336,6 +1353,22 @@ gtk_text_class_init (GtkTextClass *class)
|
||||
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_TEXT_ACCESSIBLE);
|
||||
gtk_widget_class_set_css_name (widget_class, I_("text"));
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.cut", NULL,
|
||||
gtk_text_activate_clipboard_cut);
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.copy", NULL,
|
||||
gtk_text_activate_clipboard_copy);
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.paste", NULL,
|
||||
gtk_text_activate_clipboard_paste);
|
||||
gtk_widget_class_install_action (widget_class, "selection.delete", NULL,
|
||||
gtk_text_activate_selection_delete);
|
||||
gtk_widget_class_install_action (widget_class, "selection.select-all", NULL,
|
||||
gtk_text_activate_selection_select_all);
|
||||
gtk_widget_class_install_action (widget_class, "misc.insert-emoji", NULL,
|
||||
gtk_text_activate_misc_insert_emoji);
|
||||
gtk_widget_class_install_property_action (widget_class,
|
||||
"misc.toggle-visibility",
|
||||
"visibility");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1720,7 +1753,6 @@ gtk_text_init (GtkText *self)
|
||||
}
|
||||
|
||||
set_text_cursor (GTK_WIDGET (self));
|
||||
gtk_text_add_context_actions (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1766,7 +1798,7 @@ gtk_text_dispose (GObject *object)
|
||||
keymap = gdk_display_get_keymap (gtk_widget_get_display (GTK_WIDGET (object)));
|
||||
g_signal_handlers_disconnect_by_func (keymap, keymap_direction_changed, self);
|
||||
|
||||
g_clear_object (&priv->context_actions);
|
||||
g_clear_pointer (&priv->selection_bubble, gtk_widget_unparent);
|
||||
g_clear_pointer (&priv->popup_menu, gtk_widget_unparent);
|
||||
g_clear_object (&priv->extra_menu);
|
||||
|
||||
@@ -1783,7 +1815,6 @@ gtk_text_finalize (GObject *object)
|
||||
|
||||
g_clear_object (&priv->cached_layout);
|
||||
g_clear_object (&priv->im_context);
|
||||
g_clear_pointer (&priv->selection_bubble, gtk_widget_unparent);
|
||||
g_clear_pointer (&priv->magnifier_popover, gtk_widget_destroy);
|
||||
g_clear_object (&priv->text_handle);
|
||||
g_free (priv->im_module);
|
||||
@@ -2176,6 +2207,9 @@ gtk_text_size_allocate (GtkWidget *widget,
|
||||
|
||||
if (priv->popup_menu)
|
||||
gtk_native_check_resize (GTK_NATIVE (priv->popup_menu));
|
||||
|
||||
if (priv->selection_bubble)
|
||||
gtk_native_check_resize (GTK_NATIVE (priv->selection_bubble));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4047,6 +4081,7 @@ gtk_text_set_positions (GtkText *self,
|
||||
|
||||
if (changed)
|
||||
{
|
||||
gtk_text_update_clipboard_actions (self);
|
||||
gtk_text_recompute (self);
|
||||
}
|
||||
}
|
||||
@@ -5261,15 +5296,12 @@ gtk_text_set_visibility (GtkText *self,
|
||||
|
||||
if (priv->visible != visible)
|
||||
{
|
||||
GAction *action;
|
||||
|
||||
priv->visible = visible;
|
||||
|
||||
g_object_notify (G_OBJECT (self), "visibility");
|
||||
gtk_text_recompute (self);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "toggle-visibility");
|
||||
g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (visible));
|
||||
gtk_text_update_clipboard_actions (self);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5615,152 +5647,100 @@ hide_selection_bubble (GtkText *self)
|
||||
}
|
||||
|
||||
static void
|
||||
cut_clipboard_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_text_activate_clipboard_cut (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
g_signal_emit_by_name (user_data, "cut-clipboard");
|
||||
hide_selection_bubble (GTK_TEXT (user_data));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
g_signal_emit_by_name (self, "cut-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_clipboard_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_text_activate_clipboard_copy (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
g_signal_emit_by_name (user_data, "copy-clipboard");
|
||||
hide_selection_bubble (GTK_TEXT (user_data));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
g_signal_emit_by_name (self, "copy-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
static void
|
||||
paste_clipboard_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_text_activate_clipboard_paste (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
g_signal_emit_by_name (user_data, "paste-clipboard");
|
||||
hide_selection_bubble (GTK_TEXT (user_data));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
g_signal_emit_by_name (self, "paste-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_selection_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_text_activate_selection_delete (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_text_delete_cb (GTK_TEXT (user_data));
|
||||
hide_selection_bubble (GTK_TEXT (user_data));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
gtk_text_delete_cb (self);
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
static void
|
||||
select_all_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_text_activate_selection_select_all (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_text_select_all (GTK_TEXT (user_data));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
gtk_text_select_all (self);
|
||||
}
|
||||
|
||||
static void
|
||||
insert_emoji_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_text_activate_misc_insert_emoji (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_text_insert_emoji (GTK_TEXT (user_data));
|
||||
hide_selection_bubble (GTK_TEXT (user_data));
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_visibility (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkText *text = GTK_TEXT (user_data);
|
||||
gtk_text_set_visibility (text, !gtk_text_get_visibility (text));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_add_context_actions (GtkText *self)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
|
||||
GActionEntry entries[] = {
|
||||
{ "cut-clipboard", cut_clipboard_activated, NULL, NULL, NULL },
|
||||
{ "copy-clipboard", copy_clipboard_activated, NULL, NULL, NULL },
|
||||
{ "paste-clipboard", paste_clipboard_activated, NULL, NULL, NULL },
|
||||
{ "delete-selection", delete_selection_activated, NULL, NULL, NULL },
|
||||
{ "select-all", select_all_activated, NULL, NULL, NULL },
|
||||
{ "insert-emoji", insert_emoji_activated, NULL, NULL, NULL },
|
||||
{ "toggle-visibility", toggle_visibility, NULL, "true", NULL },
|
||||
};
|
||||
|
||||
GSimpleActionGroup *actions = g_simple_action_group_new ();
|
||||
GAction *action;
|
||||
|
||||
priv->context_actions = G_ACTION_MAP (actions);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), self);
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "cut-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "copy-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "paste-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "delete-selection");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "select-all");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "insert-emoji");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (self), "context", G_ACTION_GROUP (actions));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
gtk_text_insert_emoji (self);
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_update_clipboard_actions (GtkText *self)
|
||||
{
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
DisplayMode mode;
|
||||
GdkClipboard *clipboard;
|
||||
gboolean has_clipboard;
|
||||
GAction *action;
|
||||
|
||||
gboolean has_selection;
|
||||
gboolean has_content;
|
||||
gboolean visible;
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (self));
|
||||
has_clipboard = gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), G_TYPE_STRING);
|
||||
mode = gtk_text_get_display_mode (self);
|
||||
has_clipboard = gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), G_TYPE_STRING);
|
||||
has_selection = priv->current_pos != priv->selection_bound;
|
||||
has_content = priv->buffer && (gtk_entry_buffer_get_length (priv->buffer) > 0);
|
||||
visible = mode == DISPLAY_NORMAL;
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "cut-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
mode == DISPLAY_NORMAL &&
|
||||
priv->editable &&
|
||||
priv->current_pos != priv->selection_bound);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "clipboard.cut",
|
||||
visible && priv->editable && has_selection);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "clipboard.copy",
|
||||
visible && has_selection);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "clipboard.paste",
|
||||
priv->editable && has_clipboard);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "copy-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
mode == DISPLAY_NORMAL &&
|
||||
priv->current_pos != priv->selection_bound);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "paste-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
priv->editable && has_clipboard);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "delete-selection");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
priv->editable &&
|
||||
priv->current_pos != priv->selection_bound);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "select-all");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
priv->buffer && (gtk_entry_buffer_get_length (priv->buffer) > 0));
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "selection.delete",
|
||||
priv->editable && has_selection);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "selection.select-all",
|
||||
has_content);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_update_emoji_action (GtkText *self)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GAction *action;
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "insert-emoji");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
(gtk_text_get_input_hints (self) & GTK_INPUT_HINT_NO_EMOJI) == 0);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (self), "misc.insert-emoji",
|
||||
(gtk_text_get_input_hints (self) & GTK_INPUT_HINT_NO_EMOJI) == 0);
|
||||
}
|
||||
|
||||
static GMenuModel *
|
||||
@@ -5773,19 +5753,19 @@ gtk_text_get_menu_model (GtkText *self)
|
||||
menu = g_menu_new ();
|
||||
|
||||
section = g_menu_new ();
|
||||
item = g_menu_item_new (_("Cu_t"), "context.cut-clipboard");
|
||||
item = g_menu_item_new (_("Cu_t"), "clipboard.cut");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-cut-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
item = g_menu_item_new (_("_Copy"), "context.copy-clipboard");
|
||||
item = g_menu_item_new (_("_Copy"), "clipboard.copy");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-copy-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
item = g_menu_item_new (_("_Paste"), "context.paste-clipboard");
|
||||
item = g_menu_item_new (_("_Paste"), "clipboard.paste");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-paste-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
item = g_menu_item_new (_("_Delete"), "context.delete-selection");
|
||||
item = g_menu_item_new (_("_Delete"), "selection.delete");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-delete-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
@@ -5794,12 +5774,12 @@ gtk_text_get_menu_model (GtkText *self)
|
||||
|
||||
section = g_menu_new ();
|
||||
|
||||
item = g_menu_item_new (_("Select _All"), "context.select-all");
|
||||
item = g_menu_item_new (_("Select _All"), "selection.select-all");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-select-all-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
|
||||
item = g_menu_item_new ( _("Insert _Emoji"), "context.insert-emoji");
|
||||
item = g_menu_item_new ( _("Insert _Emoji"), "misc.insert-emoji");
|
||||
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "face-smile-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
@@ -5860,12 +5840,11 @@ append_bubble_item (GtkText *self,
|
||||
GMenuModel *model,
|
||||
int index)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GtkActionMuxer *muxer;
|
||||
GtkWidget *item, *image;
|
||||
GVariant *att;
|
||||
const char *icon_name;
|
||||
const char *action_name;
|
||||
GAction *action;
|
||||
GMenuModel *link;
|
||||
|
||||
link = g_menu_model_get_item_link (model, index, "section");
|
||||
@@ -5891,12 +5870,9 @@ append_bubble_item (GtkText *self,
|
||||
action_name = g_variant_get_string (att, NULL);
|
||||
g_variant_unref (att);
|
||||
|
||||
if (g_str_has_prefix (action_name, "context."))
|
||||
{
|
||||
action = g_action_map_lookup_action (priv->context_actions, action_name + strlen ("context."));
|
||||
if (action && !g_action_get_enabled (action))
|
||||
return;
|
||||
}
|
||||
muxer = _gtk_widget_get_action_muxer (GTK_WIDGET (self), FALSE);
|
||||
if (!g_action_group_get_action_enabled (G_ACTION_GROUP (muxer), action_name))
|
||||
return;
|
||||
|
||||
item = gtk_button_new ();
|
||||
gtk_widget_set_focus_on_click (item, FALSE);
|
||||
@@ -5990,7 +5966,7 @@ gtk_text_selection_bubble_popup_show (gpointer user_data)
|
||||
rect.height += 10;
|
||||
|
||||
gtk_popover_set_pointing_to (GTK_POPOVER (priv->selection_bubble), &rect);
|
||||
gtk_widget_show (priv->selection_bubble);
|
||||
gtk_popover_popup (GTK_POPOVER (priv->selection_bubble));
|
||||
|
||||
priv->selection_bubble_timeout_id = 0;
|
||||
|
||||
|
||||
+112
-144
@@ -59,7 +59,6 @@
|
||||
#include "gtkpango.h"
|
||||
#include "gtknative.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkactionmuxerprivate.h"
|
||||
|
||||
#include "a11y/gtktextviewaccessibleprivate.h"
|
||||
|
||||
@@ -182,8 +181,6 @@ struct _GtkTextViewPrivate
|
||||
GtkAdjustment *hadjustment;
|
||||
GtkAdjustment *vadjustment;
|
||||
|
||||
GActionMap *context_actions;
|
||||
|
||||
/* X offset between widget coordinates and buffer coordinates
|
||||
* taking left_padding in account
|
||||
*/
|
||||
@@ -595,10 +592,28 @@ static void extend_selection (GtkTextView *text_view,
|
||||
GtkTextIter *start,
|
||||
GtkTextIter *end);
|
||||
|
||||
static void gtk_text_view_add_context_actions (GtkTextView *text_view);
|
||||
|
||||
static void gtk_text_view_update_clipboard_actions (GtkTextView *text_view);
|
||||
static void gtk_text_view_update_emoji_action (GtkTextView *text_view);
|
||||
|
||||
static void gtk_text_view_activate_clipboard_cut (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_view_activate_clipboard_copy (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_view_activate_clipboard_paste (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_view_activate_selection_delete (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_view_activate_selection_select_all (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_view_activate_misc_insert_emoji (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
|
||||
|
||||
/* FIXME probably need the focus methods. */
|
||||
@@ -1585,6 +1600,19 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
|
||||
quark_text_selection_data = g_quark_from_static_string ("gtk-text-view-text-selection-data");
|
||||
quark_gtk_signal = g_quark_from_static_string ("gtk-signal");
|
||||
quark_text_view_child = g_quark_from_static_string ("gtk-text-view-child");
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.cut", NULL,
|
||||
gtk_text_view_activate_clipboard_cut);
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.copy", NULL,
|
||||
gtk_text_view_activate_clipboard_copy);
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.paste", NULL,
|
||||
gtk_text_view_activate_clipboard_paste);
|
||||
gtk_widget_class_install_action (widget_class, "selection.delete", NULL,
|
||||
gtk_text_view_activate_selection_delete);
|
||||
gtk_widget_class_install_action (widget_class, "selection.select-all", NULL,
|
||||
gtk_text_view_activate_selection_select_all);
|
||||
gtk_widget_class_install_action (widget_class, "misc.insert-emoji", NULL,
|
||||
gtk_text_view_activate_misc_insert_emoji);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1694,8 +1722,6 @@ gtk_text_view_init (GtkTextView *text_view)
|
||||
gtk_css_node_get_state (priv->text_window->css_node) & ~GTK_STATE_FLAG_DROP_ACTIVE);
|
||||
gtk_css_node_set_visible (priv->selection_node, FALSE);
|
||||
g_object_unref (priv->selection_node);
|
||||
|
||||
gtk_text_view_add_context_actions (text_view);
|
||||
}
|
||||
|
||||
GtkCssNode *
|
||||
@@ -3617,7 +3643,6 @@ gtk_text_view_finalize (GObject *object)
|
||||
g_free (priv->im_module);
|
||||
|
||||
g_clear_pointer (&priv->popup_menu, gtk_widget_unparent);
|
||||
g_clear_object (&priv->context_actions);
|
||||
g_clear_object (&priv->extra_menu);
|
||||
|
||||
G_OBJECT_CLASS (gtk_text_view_parent_class)->finalize (object);
|
||||
@@ -8438,33 +8463,6 @@ hide_selection_bubble (GtkTextView *text_view)
|
||||
gtk_widget_hide (priv->selection_bubble);
|
||||
}
|
||||
|
||||
static void
|
||||
cut_clipboard_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_signal_emit_by_name (user_data, "cut-clipboard");
|
||||
hide_selection_bubble (GTK_TEXT_VIEW (user_data));
|
||||
}
|
||||
|
||||
static void
|
||||
copy_clipboard_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_signal_emit_by_name (user_data, "copy-clipboard");
|
||||
hide_selection_bubble (GTK_TEXT_VIEW (user_data));
|
||||
}
|
||||
|
||||
static void
|
||||
paste_clipboard_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_signal_emit_by_name (user_data, "paste-clipboard");
|
||||
hide_selection_bubble (GTK_TEXT_VIEW (user_data));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_select_all (GtkWidget *widget,
|
||||
gboolean select)
|
||||
@@ -8487,34 +8485,6 @@ gtk_text_view_select_all (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
select_all_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTextView *text_view = user_data;
|
||||
|
||||
gtk_text_view_select_all (GTK_WIDGET (text_view), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_selection_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTextView *text_view = user_data;
|
||||
|
||||
gtk_text_buffer_delete_selection (get_buffer (text_view), TRUE,
|
||||
text_view->priv->editable);
|
||||
}
|
||||
|
||||
static void
|
||||
insert_emoji_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_text_view_insert_emoji (GTK_TEXT_VIEW (user_data));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
range_contains_editable_text (const GtkTextIter *start,
|
||||
@@ -8535,40 +8505,60 @@ range_contains_editable_text (const GtkTextIter *start,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_add_context_actions (GtkTextView *text_view)
|
||||
gtk_text_view_activate_clipboard_cut (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkTextViewPrivate *priv = text_view->priv;
|
||||
GtkTextView *self = GTK_TEXT_VIEW (widget);
|
||||
g_signal_emit_by_name (self, "cut-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
GActionEntry entries[] = {
|
||||
{ "cut-clipboard", cut_clipboard_activated, NULL, NULL, NULL },
|
||||
{ "copy-clipboard", copy_clipboard_activated, NULL, NULL, NULL },
|
||||
{ "paste-clipboard", paste_clipboard_activated, NULL, NULL, NULL },
|
||||
{ "delete-selection", delete_selection_activated, NULL, NULL, NULL },
|
||||
{ "select-all", select_all_activated, NULL, NULL, NULL },
|
||||
{ "insert-emoji", insert_emoji_activated, NULL, NULL, NULL },
|
||||
};
|
||||
static void
|
||||
gtk_text_view_activate_clipboard_copy (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkTextView *self = GTK_TEXT_VIEW (widget);
|
||||
g_signal_emit_by_name (self, "copy-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
GSimpleActionGroup *actions = g_simple_action_group_new ();
|
||||
GAction *action;
|
||||
static void
|
||||
gtk_text_view_activate_clipboard_paste (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkTextView *self = GTK_TEXT_VIEW (widget);
|
||||
g_signal_emit_by_name (self, "paste-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
priv->context_actions = G_ACTION_MAP (actions);
|
||||
static void
|
||||
gtk_text_view_activate_selection_select_all (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_text_view_select_all (widget, TRUE);
|
||||
}
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), text_view);
|
||||
static void
|
||||
gtk_text_view_activate_selection_delete (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "cut-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "copy-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "paste-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "delete-selection");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "select-all");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "insert-emoji");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
gtk_text_buffer_delete_selection (get_buffer (text_view), TRUE,
|
||||
text_view->priv->editable);
|
||||
}
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (text_view), "context", G_ACTION_GROUP (actions));
|
||||
static void
|
||||
gtk_text_view_activate_misc_insert_emoji (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_text_view_insert_emoji (GTK_TEXT_VIEW (widget));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -8578,7 +8568,6 @@ gtk_text_view_update_clipboard_actions (GtkTextView *text_view)
|
||||
GdkClipboard *clipboard;
|
||||
gboolean have_selection;
|
||||
gboolean can_paste, can_insert;
|
||||
GAction *action;
|
||||
GtkTextIter iter, sel_start, sel_end;
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view));
|
||||
@@ -8593,36 +8582,25 @@ gtk_text_view_update_clipboard_actions (GtkTextView *text_view)
|
||||
|
||||
can_insert = gtk_text_iter_can_insert (&iter, priv->editable);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "cut-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
have_selection &&
|
||||
range_contains_editable_text (&sel_start, &sel_end, priv->editable));
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "copy-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), have_selection);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "paste-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_insert && can_paste);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "delete-selection");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
have_selection &&
|
||||
range_contains_editable_text (&sel_start, &sel_end, priv->editable));
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "select-all");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
gtk_text_buffer_get_char_count (priv->buffer) > 0);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (text_view), "clipboard.cut",
|
||||
have_selection &&
|
||||
range_contains_editable_text (&sel_start, &sel_end, priv->editable));
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (text_view), "clipboard.copy",
|
||||
have_selection);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (text_view), "clipboard.paste",
|
||||
can_insert && can_paste);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (text_view), "selection.delete",
|
||||
have_selection &&
|
||||
range_contains_editable_text (&sel_start, &sel_end, priv->editable));
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (text_view), "selection.select-all",
|
||||
gtk_text_buffer_get_char_count (priv->buffer) > 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_update_emoji_action (GtkTextView *text_view)
|
||||
{
|
||||
GtkTextViewPrivate *priv = text_view->priv;
|
||||
GAction *action;
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "insert-emoji");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
(gtk_text_view_get_input_hints (text_view) & GTK_INPUT_HINT_NO_EMOJI) == 0);
|
||||
gtk_widget_action_set_enabled (GTK_WIDGET (text_view), "misc.insert-emoji",
|
||||
(gtk_text_view_get_input_hints (text_view) & GTK_INPUT_HINT_NO_EMOJI) == 0);
|
||||
}
|
||||
|
||||
static GMenuModel *
|
||||
@@ -8635,19 +8613,19 @@ gtk_text_view_get_menu_model (GtkTextView *text_view)
|
||||
menu = g_menu_new ();
|
||||
|
||||
section = g_menu_new ();
|
||||
item = g_menu_item_new (_("Cu_t"), "context.cut-clipboard");
|
||||
item = g_menu_item_new (_("Cu_t"), "clipboard.cut");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-cut-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
item = g_menu_item_new (_("_Copy"), "context.copy-clipboard");
|
||||
item = g_menu_item_new (_("_Copy"), "clipboard.copy");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-copy-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
item = g_menu_item_new (_("_Paste"), "context.paste-clipboard");
|
||||
item = g_menu_item_new (_("_Paste"), "clipboard.paste");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-paste-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
item = g_menu_item_new (_("_Delete"), "context.delete-selection");
|
||||
item = g_menu_item_new (_("_Delete"), "selection.delete");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-delete-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
@@ -8656,12 +8634,12 @@ gtk_text_view_get_menu_model (GtkTextView *text_view)
|
||||
|
||||
section = g_menu_new ();
|
||||
|
||||
item = g_menu_item_new (_("Select _All"), "context.select-all");
|
||||
item = g_menu_item_new (_("Select _All"), "selection.select-all");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-select-all-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
|
||||
item = g_menu_item_new ( _("Insert _Emoji"), "context.insert-emoji");
|
||||
item = g_menu_item_new ( _("Insert _Emoji"), "misc.insert-emoji");
|
||||
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "face-smile-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
@@ -8837,8 +8815,11 @@ append_bubble_item (GtkTextView *text_view,
|
||||
const char *icon_name;
|
||||
const char *action_name;
|
||||
GMenuModel *link;
|
||||
char **split = NULL;
|
||||
gboolean is_toggle_action = FALSE;
|
||||
GActionGroup *group = NULL;
|
||||
gboolean enabled;
|
||||
const GVariantType *param_type;
|
||||
const GVariantType *state_type;
|
||||
|
||||
link = g_menu_model_get_item_link (model, index, "section");
|
||||
if (link)
|
||||
@@ -8863,32 +8844,19 @@ append_bubble_item (GtkTextView *text_view,
|
||||
action_name = g_variant_get_string (att, NULL);
|
||||
g_variant_unref (att);
|
||||
|
||||
split = g_strsplit (action_name, ".", 2);
|
||||
if (split[0] && split[1])
|
||||
group = G_ACTION_GROUP (_gtk_widget_get_action_muxer (GTK_WIDGET (text_view), FALSE));
|
||||
if (group)
|
||||
{
|
||||
GActionGroup *group = NULL;
|
||||
gboolean enabled;
|
||||
const GVariantType *param_type;
|
||||
const GVariantType *state_type;
|
||||
GtkActionMuxer *muxer;
|
||||
|
||||
muxer = _gtk_widget_get_action_muxer (GTK_WIDGET (text_view), FALSE);
|
||||
if (muxer)
|
||||
group = gtk_action_muxer_lookup (muxer, split[0]);
|
||||
if (group)
|
||||
{
|
||||
g_action_group_query_action (group, split[1], &enabled, ¶m_type, &state_type, NULL, NULL);
|
||||
g_action_group_query_action (group, action_name, &enabled, ¶m_type, &state_type, NULL, NULL);
|
||||
|
||||
if (!enabled)
|
||||
return;
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
if (param_type == NULL &&
|
||||
state_type != NULL &&
|
||||
g_variant_type_equal (state_type, G_VARIANT_TYPE_BOOLEAN))
|
||||
is_toggle_action = TRUE;
|
||||
}
|
||||
if (param_type == NULL &&
|
||||
state_type != NULL &&
|
||||
g_variant_type_equal (state_type, G_VARIANT_TYPE_BOOLEAN))
|
||||
is_toggle_action = TRUE;
|
||||
}
|
||||
g_strfreev (split);
|
||||
|
||||
if (is_toggle_action)
|
||||
item = gtk_toggle_button_new ();
|
||||
|
||||
+290
-21
@@ -73,6 +73,7 @@
|
||||
#include "gtkwindowgroup.h"
|
||||
#include "gtkwindowprivate.h"
|
||||
#include "gtknativeprivate.h"
|
||||
#include "gtkconstraint.h"
|
||||
|
||||
#include "a11y/gtkwidgetaccessible.h"
|
||||
#include "inspector/window.h"
|
||||
@@ -501,6 +502,7 @@ struct _GtkWidgetClassPrivate
|
||||
AtkRole accessible_role;
|
||||
const char *css_name;
|
||||
GType layout_manager_type;
|
||||
GPtrArray *actions;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -769,6 +771,13 @@ gtk_widget_get_type (void)
|
||||
NULL /* interface data */
|
||||
};
|
||||
|
||||
const GInterfaceInfo constraint_target_info =
|
||||
{
|
||||
(GInterfaceInitFunc) NULL,
|
||||
(GInterfaceFinalizeFunc) NULL,
|
||||
NULL /* interface data */
|
||||
};
|
||||
|
||||
widget_type = g_type_register_static (G_TYPE_INITIALLY_UNOWNED, g_intern_static_string ("GtkWidget"),
|
||||
&widget_info, G_TYPE_FLAG_ABSTRACT);
|
||||
|
||||
@@ -781,6 +790,8 @@ gtk_widget_get_type (void)
|
||||
&accessibility_info) ;
|
||||
g_type_add_interface_static (widget_type, GTK_TYPE_BUILDABLE,
|
||||
&buildable_info) ;
|
||||
g_type_add_interface_static (widget_type, GTK_TYPE_CONSTRAINT_TARGET,
|
||||
&constraint_target_info) ;
|
||||
}
|
||||
|
||||
return widget_type;
|
||||
@@ -2890,6 +2901,11 @@ gtk_widget_root (GtkWidget *widget)
|
||||
if (priv->surface_transform_data)
|
||||
add_parent_surface_transform_changed_listener (widget);
|
||||
|
||||
_gtk_widget_update_parent_muxer (widget);
|
||||
|
||||
if (priv->layout_manager)
|
||||
gtk_layout_manager_set_root (priv->layout_manager, priv->root);
|
||||
|
||||
GTK_WIDGET_GET_CLASS (widget)->root (widget);
|
||||
|
||||
if (!GTK_IS_ROOT (widget))
|
||||
@@ -2910,11 +2926,16 @@ gtk_widget_unroot (GtkWidget *widget)
|
||||
surface_transform_data->tracked_parent)
|
||||
remove_parent_surface_transform_changed_listener (widget);
|
||||
|
||||
_gtk_widget_update_parent_muxer (widget);
|
||||
|
||||
GTK_WIDGET_GET_CLASS (widget)->unroot (widget);
|
||||
|
||||
if (priv->context)
|
||||
gtk_style_context_set_display (priv->context, gdk_display_get_default ());
|
||||
|
||||
if (priv->layout_manager)
|
||||
gtk_layout_manager_set_root (priv->layout_manager, NULL);
|
||||
|
||||
if (g_object_get_qdata (G_OBJECT (widget), quark_pango_context))
|
||||
g_object_set_qdata (G_OBJECT (widget), quark_pango_context, NULL);
|
||||
|
||||
@@ -11861,7 +11882,7 @@ gtk_widget_get_modifier_mask (GtkWidget *widget,
|
||||
|
||||
static GtkActionMuxer *
|
||||
gtk_widget_get_parent_muxer (GtkWidget *widget,
|
||||
gboolean create)
|
||||
gboolean create)
|
||||
{
|
||||
GtkWidget *parent;
|
||||
|
||||
@@ -11889,7 +11910,7 @@ _gtk_widget_update_parent_muxer (GtkWidget *widget)
|
||||
return;
|
||||
|
||||
gtk_action_muxer_set_parent (muxer,
|
||||
gtk_widget_get_parent_muxer (widget, TRUE));
|
||||
gtk_widget_get_parent_muxer (widget, FALSE));
|
||||
}
|
||||
|
||||
GtkActionMuxer *
|
||||
@@ -11897,14 +11918,16 @@ _gtk_widget_get_action_muxer (GtkWidget *widget,
|
||||
gboolean create)
|
||||
{
|
||||
GtkActionMuxer *muxer;
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS (widget);
|
||||
GtkWidgetClassPrivate *priv = widget_class->priv;
|
||||
|
||||
muxer = (GtkActionMuxer*)g_object_get_qdata (G_OBJECT (widget), quark_action_muxer);
|
||||
if (muxer)
|
||||
return muxer;
|
||||
|
||||
if (create)
|
||||
if (create || priv->actions)
|
||||
{
|
||||
muxer = gtk_action_muxer_new ();
|
||||
muxer = gtk_action_muxer_new (widget, priv->actions);
|
||||
g_object_set_qdata_full (G_OBJECT (widget),
|
||||
quark_action_muxer,
|
||||
muxer,
|
||||
@@ -11925,11 +11948,15 @@ _gtk_widget_get_action_muxer (GtkWidget *widget,
|
||||
*
|
||||
* Inserts @group into @widget. Children of @widget that implement
|
||||
* #GtkActionable can then be associated with actions in @group by
|
||||
* setting their “action-name” to
|
||||
* @prefix.`action-name`.
|
||||
* setting their “action-name” to @prefix.`action-name`.
|
||||
*
|
||||
* If @group is %NULL, a previously inserted group for @name is removed
|
||||
* from @widget.
|
||||
* Note that inheritance is defined for individual actions. I.e.
|
||||
* even if you insert a group with prefix @prefix, actions with
|
||||
* the same prefix will still be inherited from the parent, unless
|
||||
* the group contains an action with the same name.
|
||||
*
|
||||
* If @group is %NULL, a previously inserted group for @name is
|
||||
* removed from @widget.
|
||||
*/
|
||||
void
|
||||
gtk_widget_insert_action_group (GtkWidget *widget,
|
||||
@@ -12414,33 +12441,70 @@ gtk_widget_get_template_child (GtkWidget *widget,
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_activate_action:
|
||||
* gtk_widget_activate_action_variant: (rename-to gtk_widget_activate_action)
|
||||
* @widget: a #GtkWidget
|
||||
* @name: a prefixed action name
|
||||
* @parameter: parameters that required by the action
|
||||
* @name: the name of the action to activate
|
||||
* @args: (allow-none): parameters to use, or %NULL
|
||||
*
|
||||
* Looks up the action in the action groups associated
|
||||
* with @widget and its ancestors, and activates it.
|
||||
*
|
||||
* The action name is expected to be prefixed with the
|
||||
* prefix that was used when adding the action group
|
||||
* with gtk_widget_insert_action_group().
|
||||
* If the action is in an action group added with
|
||||
* gtk_widget_insert_action_group(), the @name is
|
||||
* expected to be prefixed with the prefix that was
|
||||
* used when the group was inserted.
|
||||
*
|
||||
* The @parameter must match the actions expected parameter
|
||||
* The arguments must match the actions expected parameter
|
||||
* type, as returned by g_action_get_parameter_type().
|
||||
*/
|
||||
void
|
||||
gtk_widget_activate_action (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
gtk_widget_activate_action_variant (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *args)
|
||||
{
|
||||
GtkActionMuxer *muxer;
|
||||
|
||||
muxer = _gtk_widget_get_action_muxer (widget, FALSE);
|
||||
if (muxer)
|
||||
g_action_group_activate_action (G_ACTION_GROUP (muxer),
|
||||
name,
|
||||
parameter);
|
||||
g_action_group_activate_action (G_ACTION_GROUP (muxer), name, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_activate_action:
|
||||
* @widget: a #GtkWidget
|
||||
* @name: the name of the action to activate
|
||||
* @format_string: GVariant format string for arguments or %NULL
|
||||
* for no arguments
|
||||
* @...: arguments, as given by format string
|
||||
*
|
||||
* Looks up the action in the action groups associated
|
||||
* with @widget and its ancestors, and activates it.
|
||||
*
|
||||
* This is a wrapper around gtk_widget_activate_action_variant()
|
||||
* that constructs the @args variant according to @format_string.
|
||||
*/
|
||||
void
|
||||
gtk_widget_activate_action (GtkWidget *widget,
|
||||
const char *name,
|
||||
const char *format_string,
|
||||
...)
|
||||
{
|
||||
GVariant *parameters = NULL;
|
||||
|
||||
if (format_string != NULL)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start (args, format_string);
|
||||
parameters = g_variant_new_va (format_string, NULL, &args);
|
||||
va_end (args);
|
||||
|
||||
g_variant_ref_sink (parameters);
|
||||
}
|
||||
|
||||
gtk_widget_activate_action_variant (widget, name, parameters);
|
||||
|
||||
g_clear_pointer (¶meters, g_variant_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -13427,3 +13491,208 @@ gtk_widget_should_layout (GtkWidget *widget)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_class_add_action (GtkWidgetClass *widget_class,
|
||||
GtkWidgetAction *action)
|
||||
{
|
||||
GtkWidgetClassPrivate *priv = widget_class->priv;
|
||||
|
||||
if (priv->actions == NULL)
|
||||
priv->actions = g_ptr_array_new ();
|
||||
else if (GTK_IS_WIDGET_CLASS (&widget_class->parent_class))
|
||||
{
|
||||
GtkWidgetClass *parent_class = GTK_WIDGET_CLASS (&widget_class->parent_class);
|
||||
GtkWidgetClassPrivate *parent_priv = parent_class->priv;
|
||||
GPtrArray *parent_actions = parent_priv->actions;
|
||||
|
||||
if (priv->actions == parent_actions)
|
||||
{
|
||||
int i;
|
||||
|
||||
priv->actions = g_ptr_array_new ();
|
||||
for (i = 0; i < parent_actions->len; i++)
|
||||
g_ptr_array_add (priv->actions, g_ptr_array_index (parent_actions, i));
|
||||
}
|
||||
}
|
||||
|
||||
GTK_NOTE(ACTIONS, g_message ("%sClass: Adding %s action\n",
|
||||
g_type_name (G_TYPE_FROM_CLASS (widget_class)),
|
||||
action->name));
|
||||
|
||||
g_ptr_array_add (priv->actions, action);
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_widget_class_install_action:
|
||||
* @widget_class: a #GtkWidgetClass
|
||||
* @action_name: a prefixed action name, such as "clipboard.paste"
|
||||
* @parameter_type: (allow-none): the parameter type, or %NULL
|
||||
* @activate: callback to use when the action is activated
|
||||
*
|
||||
* This should be called at class initialization time to specify
|
||||
* actions to be added for all instances of this class.
|
||||
*
|
||||
* Actions installed by this function are stateless. The only state
|
||||
* they have is whether they are enabled or not. For more complicated
|
||||
* actions, see gtk_widget_class_install_stateful_action().
|
||||
*/
|
||||
void
|
||||
gtk_widget_class_install_action (GtkWidgetClass *widget_class,
|
||||
const char *action_name,
|
||||
const char *parameter_type,
|
||||
GtkWidgetActionActivateFunc activate)
|
||||
{
|
||||
GtkWidgetAction *action;
|
||||
|
||||
action = g_new0 (GtkWidgetAction, 1);
|
||||
action->owner = G_TYPE_FROM_CLASS (widget_class);
|
||||
action->name = g_strdup (action_name);
|
||||
if (parameter_type)
|
||||
action->parameter_type = g_variant_type_new (parameter_type);
|
||||
else
|
||||
action->parameter_type = NULL;
|
||||
action->activate = activate;
|
||||
|
||||
gtk_widget_class_add_action (widget_class, action);
|
||||
}
|
||||
|
||||
static const GVariantType *
|
||||
determine_type (GParamSpec *pspec)
|
||||
{
|
||||
if (G_TYPE_IS_ENUM (pspec->value_type))
|
||||
return G_VARIANT_TYPE_STRING;
|
||||
|
||||
switch (pspec->value_type)
|
||||
{
|
||||
case G_TYPE_BOOLEAN:
|
||||
return G_VARIANT_TYPE_BOOLEAN;
|
||||
|
||||
case G_TYPE_INT:
|
||||
return G_VARIANT_TYPE_INT32;
|
||||
|
||||
case G_TYPE_UINT:
|
||||
return G_VARIANT_TYPE_UINT32;
|
||||
|
||||
case G_TYPE_DOUBLE:
|
||||
case G_TYPE_FLOAT:
|
||||
return G_VARIANT_TYPE_DOUBLE;
|
||||
|
||||
case G_TYPE_STRING:
|
||||
return G_VARIANT_TYPE_STRING;
|
||||
|
||||
default:
|
||||
g_critical ("Unable to use gtk_widget_class_install_property_action with property '%s::%s' of type '%s'",
|
||||
g_type_name (pspec->owner_type), pspec->name, g_type_name (pspec->value_type));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_widget_class_install_property_action (GtkWidgetClass *widget_class,
|
||||
const char *action_name,
|
||||
const char *property_name)
|
||||
{
|
||||
GParamSpec *pspec;
|
||||
GtkWidgetAction *action;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
|
||||
|
||||
pspec = g_object_class_find_property (G_OBJECT_CLASS (widget_class), property_name);
|
||||
|
||||
if (pspec == NULL)
|
||||
{
|
||||
g_critical ("Attempted to use non-existent property '%s::%s' for dgtk_widget_class_install_property_action",
|
||||
g_type_name (G_TYPE_FROM_CLASS (widget_class)), property_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (~pspec->flags & G_PARAM_READABLE || ~pspec->flags & G_PARAM_WRITABLE || pspec->flags & G_PARAM_CONSTRUCT_ONLY)
|
||||
{
|
||||
g_critical ("Property '%s::%s' used with gtk_widget_class_install_property_action must be readable, writable, and not construct-only",
|
||||
g_type_name (G_TYPE_FROM_CLASS (widget_class)), property_name);
|
||||
return;
|
||||
}
|
||||
|
||||
action = g_new0 (GtkWidgetAction, 1);
|
||||
action->owner = G_TYPE_FROM_CLASS (widget_class);
|
||||
action->name = g_strdup (action_name);
|
||||
action->pspec = pspec;
|
||||
action->state_type = determine_type (action->pspec);
|
||||
if (action->pspec->value_type == G_TYPE_BOOLEAN)
|
||||
action->parameter_type = NULL;
|
||||
else
|
||||
action->parameter_type = action->state_type;
|
||||
action->activate = NULL;
|
||||
|
||||
gtk_widget_class_add_action (widget_class, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_action_set_enabled:
|
||||
* @widget: a #GtkWidget
|
||||
* @action_name: action name, such as "clipboard.paste"
|
||||
* @enabled: whether the action is now enabled
|
||||
*
|
||||
* Enable or disable an action installed with
|
||||
* gtk_widget_class_install_action().
|
||||
*/
|
||||
void
|
||||
gtk_widget_action_set_enabled (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
gboolean enabled)
|
||||
{
|
||||
GtkActionMuxer *muxer;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
muxer = _gtk_widget_get_action_muxer (widget, TRUE);
|
||||
gtk_action_muxer_action_enabled_changed (muxer, action_name, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_class_query_action:
|
||||
* @widget_class: a #GtkWidgetClass
|
||||
* @index_: position of the action to query
|
||||
* @owner: the type where the action was defined
|
||||
* @action_name: return location for the action name
|
||||
* @parameter_type: return location for the parameter type
|
||||
* @property_name: return location for the property name
|
||||
*
|
||||
* Queries the actions that have been installed for
|
||||
* a widget class using gtk_widget_class_install_action()
|
||||
* during class initialization.
|
||||
*
|
||||
* Note that this function will also return actions defined
|
||||
* by parent classes. You can identify those by looking
|
||||
* at @owner.
|
||||
*
|
||||
* Returns: %TRUE if the action was found,
|
||||
* %FALSE if @index_ is out of range
|
||||
*/
|
||||
gboolean
|
||||
gtk_widget_class_query_action (GtkWidgetClass *widget_class,
|
||||
guint index_,
|
||||
GType *owner,
|
||||
const char **action_name,
|
||||
const GVariantType **parameter_type,
|
||||
const char **property_name)
|
||||
{
|
||||
GtkWidgetClassPrivate *priv = widget_class->priv;
|
||||
|
||||
if (priv->actions && index_ < priv->actions->len)
|
||||
{
|
||||
GtkWidgetAction *action = g_ptr_array_index (priv->actions, index_);
|
||||
|
||||
*owner = action->owner;
|
||||
*action_name = action->name;
|
||||
*parameter_type = action->parameter_type;
|
||||
if (action->pspec)
|
||||
*property_name = action->pspec->name;
|
||||
else
|
||||
*property_name = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+46
-1
@@ -978,7 +978,12 @@ void gtk_widget_insert_action_group (GtkWidget *widget,
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_activate_action (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter);
|
||||
const char *format_string,
|
||||
...);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_activate_action_variant (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *args);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_activate_default (GtkWidget *widget);
|
||||
@@ -1023,6 +1028,46 @@ GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_widget_should_layout (GtkWidget *widget);
|
||||
|
||||
|
||||
/**
|
||||
* GtkWidgetActionActivateFunc:
|
||||
* @widget: the widget to which the action belongs
|
||||
* @action_name: the action name
|
||||
* @parameter: parameter for activation
|
||||
*
|
||||
* The type of the callback functions used for activating
|
||||
* actions installed with gtk_widget_class_install_action().
|
||||
*
|
||||
* The @parameter must match the @parameter_type of the action.
|
||||
*/
|
||||
typedef void (* GtkWidgetActionActivateFunc) (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_class_install_action (GtkWidgetClass *widget_class,
|
||||
const char *action_name,
|
||||
const char *parameter_type,
|
||||
GtkWidgetActionActivateFunc activate);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_class_install_property_action (GtkWidgetClass *widget_class,
|
||||
const char *action_name,
|
||||
const char *property_name);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_widget_class_query_action (GtkWidgetClass *widget_class,
|
||||
guint index_,
|
||||
GType *owner,
|
||||
const char **action_name,
|
||||
const GVariantType **parameter_type,
|
||||
const char **property_name);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_action_set_enabled (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
gboolean enabled);
|
||||
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkWidget, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRequisition, gtk_requisition_free)
|
||||
|
||||
|
||||
+91
-35
@@ -118,7 +118,7 @@
|
||||
*
|
||||
* # GtkWindow as GtkBuildable
|
||||
*
|
||||
* The GtkWindow implementation of the GtkBuildable interface supports a
|
||||
* The GtkWindow implementation of the #GtkBuildable interface supports a
|
||||
* custom <accel-groups> element, which supports any number of <group>
|
||||
* elements representing the #GtkAccelGroup objects you want to add to
|
||||
* your window (synonymous with gtk_window_add_accel_group().
|
||||
@@ -136,7 +136,7 @@
|
||||
* <object class="GtkAccelGroup" id="accelgroup1"/>
|
||||
* ]|
|
||||
*
|
||||
* The GtkWindow implementation of the GtkBuildable interface supports
|
||||
* The GtkWindow implementation of the #GtkBuildable interface supports
|
||||
* setting a child as the titlebar by specifying “titlebar” as the “type”
|
||||
* attribute of a <child> element.
|
||||
*
|
||||
@@ -249,7 +249,6 @@ typedef struct
|
||||
guint is_active : 1;
|
||||
guint maximize_initially : 1;
|
||||
guint mnemonics_visible : 1;
|
||||
guint mnemonics_visible_set : 1;
|
||||
guint focus_visible : 1;
|
||||
guint modal : 1;
|
||||
guint resizable : 1;
|
||||
@@ -282,6 +281,8 @@ typedef struct
|
||||
GskRenderer *renderer;
|
||||
|
||||
GList *foci;
|
||||
|
||||
GtkConstraintSolver *constraint_solver;
|
||||
} GtkWindowPrivate;
|
||||
|
||||
#ifdef GDK_WINDOWING_X11
|
||||
@@ -406,6 +407,16 @@ static void gtk_window_size_allocate (GtkWidget *widget,
|
||||
static gboolean gtk_window_close_request (GtkWindow *window);
|
||||
static void gtk_window_focus_in (GtkWidget *widget);
|
||||
static void gtk_window_focus_out (GtkWidget *widget);
|
||||
static gboolean gtk_window_key_pressed (GtkWidget *widget,
|
||||
guint keyval,
|
||||
guint keycode,
|
||||
GdkModifierType state,
|
||||
gpointer data);
|
||||
static gboolean gtk_window_key_released (GtkWidget *widget,
|
||||
guint keyval,
|
||||
guint keycode,
|
||||
GdkModifierType state,
|
||||
gpointer data);
|
||||
|
||||
static void surface_state_changed (GtkWidget *widget);
|
||||
static void surface_size_changed (GtkWidget *widget,
|
||||
@@ -492,6 +503,10 @@ static void gtk_window_on_theme_variant_changed (GtkSettings *settings,
|
||||
#endif
|
||||
static void gtk_window_set_theme_variant (GtkWindow *window);
|
||||
|
||||
static void gtk_window_activate_default_activate (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
|
||||
static void gtk_window_do_popup (GtkWindow *window,
|
||||
GdkEventButton *event);
|
||||
static void gtk_window_style_updated (GtkWidget *widget);
|
||||
@@ -890,7 +905,7 @@ gtk_window_class_init (GtkWindowClass *klass)
|
||||
g_param_spec_boolean ("mnemonics-visible",
|
||||
P_("Mnemonics Visible"),
|
||||
P_("Whether mnemonics are currently visible in this window"),
|
||||
TRUE,
|
||||
FALSE,
|
||||
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
/**
|
||||
@@ -1163,6 +1178,9 @@ gtk_window_class_init (GtkWindowClass *klass)
|
||||
* Key bindings
|
||||
*/
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "default.activate", NULL,
|
||||
gtk_window_activate_default_activate);
|
||||
|
||||
binding_set = gtk_binding_set_by_class (klass);
|
||||
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_space, 0,
|
||||
@@ -1766,28 +1784,11 @@ gtk_window_capture_motion (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
activate_default_cb (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer data)
|
||||
gtk_window_activate_default_activate (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_window_real_activate_default (GTK_WINDOW (data));
|
||||
}
|
||||
|
||||
static void
|
||||
add_actions (GtkWindow *window)
|
||||
{
|
||||
GActionEntry entries[] = {
|
||||
{ "activate", activate_default_cb, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
GActionGroup *actions;
|
||||
|
||||
actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions),
|
||||
entries, G_N_ELEMENTS (entries),
|
||||
window);
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (window), "default", actions);
|
||||
g_object_unref (actions);
|
||||
gtk_window_real_activate_default (GTK_WINDOW (widget));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1827,7 +1828,7 @@ gtk_window_init (GtkWindow *window)
|
||||
priv->type_hint = GDK_SURFACE_TYPE_HINT_NORMAL;
|
||||
priv->startup_id = NULL;
|
||||
priv->initial_timestamp = GDK_CURRENT_TIME;
|
||||
priv->mnemonics_visible = TRUE;
|
||||
priv->mnemonics_visible = FALSE;
|
||||
priv->focus_visible = TRUE;
|
||||
priv->initial_fullscreen_monitor = NULL;
|
||||
|
||||
@@ -1874,13 +1875,19 @@ gtk_window_init (GtkWindow *window)
|
||||
gtk_widget_add_controller (widget, motion_controller);
|
||||
|
||||
priv->key_controller = gtk_event_controller_key_new ();
|
||||
gtk_event_controller_set_propagation_phase (priv->key_controller, GTK_PHASE_CAPTURE);
|
||||
g_signal_connect_swapped (priv->key_controller, "focus-in",
|
||||
G_CALLBACK (gtk_window_focus_in), window);
|
||||
g_signal_connect_swapped (priv->key_controller, "focus-out",
|
||||
G_CALLBACK (gtk_window_focus_out), window);
|
||||
g_signal_connect_swapped (priv->key_controller, "key-pressed",
|
||||
G_CALLBACK (gtk_window_key_pressed), window);
|
||||
g_signal_connect_swapped (priv->key_controller, "key-released",
|
||||
G_CALLBACK (gtk_window_key_released), window);
|
||||
gtk_widget_add_controller (widget, priv->key_controller);
|
||||
|
||||
add_actions (window);
|
||||
/* Shared constraint solver */
|
||||
priv->constraint_solver = gtk_constraint_solver_new ();
|
||||
}
|
||||
|
||||
static GtkGesture *
|
||||
@@ -2351,6 +2358,15 @@ gtk_window_native_get_renderer (GtkNative *native)
|
||||
return priv->renderer;
|
||||
}
|
||||
|
||||
static GtkConstraintSolver *
|
||||
gtk_window_root_get_constraint_solver (GtkRoot *root)
|
||||
{
|
||||
GtkWindow *self = GTK_WINDOW (root);
|
||||
GtkWindowPrivate *priv = gtk_window_get_instance_private (self);
|
||||
|
||||
return priv->constraint_solver;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_window_native_get_surface_transform (GtkNative *native,
|
||||
int *x,
|
||||
@@ -2379,6 +2395,7 @@ static void
|
||||
gtk_window_root_interface_init (GtkRootInterface *iface)
|
||||
{
|
||||
iface->get_display = gtk_window_root_get_display;
|
||||
iface->get_constraint_solver = gtk_window_root_get_constraint_solver;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4721,6 +4738,7 @@ gtk_window_finalize (GObject *object)
|
||||
priv->mnemonics_display_timeout_id = 0;
|
||||
}
|
||||
|
||||
g_clear_object (&priv->constraint_solver);
|
||||
g_clear_object (&priv->renderer);
|
||||
|
||||
G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
|
||||
@@ -4983,12 +5001,6 @@ gtk_window_map (GtkWidget *widget)
|
||||
gdk_display_notify_startup_complete (gtk_widget_get_display (widget), NULL);
|
||||
}
|
||||
|
||||
/* if mnemonics visible is not already set
|
||||
* (as in the case of popup menus), then hide mnemonics initially
|
||||
*/
|
||||
if (!priv->mnemonics_visible_set)
|
||||
gtk_window_set_mnemonics_visible (window, FALSE);
|
||||
|
||||
/* inherit from transient parent, so that a dialog that is
|
||||
* opened via keynav shows focus initially
|
||||
*/
|
||||
@@ -6219,6 +6231,52 @@ gtk_window_focus_out (GtkWidget *widget)
|
||||
gtk_window_set_mnemonics_visible (window, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
update_mnemonics_visible (GtkWindow *window,
|
||||
guint keyval,
|
||||
GdkModifierType state,
|
||||
gboolean visible)
|
||||
{
|
||||
if ((keyval == GDK_KEY_Alt_L || keyval == GDK_KEY_Alt_R) &&
|
||||
((state & (gtk_accelerator_get_default_mod_mask ()) & ~(GDK_MOD1_MASK)) == 0))
|
||||
{
|
||||
if (visible)
|
||||
_gtk_window_schedule_mnemonics_visible (window);
|
||||
else
|
||||
gtk_window_set_mnemonics_visible (window, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_window_key_pressed (GtkWidget *widget,
|
||||
guint keyval,
|
||||
guint keycode,
|
||||
GdkModifierType state,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWindow *window = GTK_WINDOW (widget);
|
||||
|
||||
gtk_window_set_focus_visible (window, TRUE);
|
||||
|
||||
update_mnemonics_visible (window, keyval, state, TRUE);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_window_key_released (GtkWidget *widget,
|
||||
guint keyval,
|
||||
guint keycode,
|
||||
GdkModifierType state,
|
||||
gpointer data)
|
||||
{
|
||||
GtkWindow *window = GTK_WINDOW (widget);
|
||||
|
||||
update_mnemonics_visible (window, keyval, state, FALSE);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GtkWindowPopover *
|
||||
_gtk_window_has_popover (GtkWindow *window,
|
||||
GtkWidget *widget)
|
||||
@@ -8573,8 +8631,6 @@ gtk_window_set_mnemonics_visible (GtkWindow *window,
|
||||
g_source_remove (priv->mnemonics_display_timeout_id);
|
||||
priv->mnemonics_display_timeout_id = 0;
|
||||
}
|
||||
|
||||
priv->mnemonics_visible_set = TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
||||
@@ -290,8 +290,6 @@ remove_group (GtkInspectorActions *sl,
|
||||
GtkStackPage *page,
|
||||
GActionGroup *group)
|
||||
{
|
||||
g_object_set (page, "visible", FALSE, NULL);
|
||||
|
||||
disconnect_group (group, sl);
|
||||
|
||||
g_set_object (&sl->priv->group, NULL);
|
||||
@@ -308,6 +306,8 @@ gtk_inspector_actions_set_object (GtkInspectorActions *sl,
|
||||
stack = gtk_widget_get_parent (GTK_WIDGET (sl));
|
||||
page = gtk_stack_get_page (GTK_STACK (stack), GTK_WIDGET (sl));
|
||||
|
||||
g_object_set (page, "visible", FALSE, NULL);
|
||||
|
||||
if (sl->priv->group)
|
||||
remove_group (sl, page, sl->priv->group);
|
||||
|
||||
|
||||
@@ -673,6 +673,11 @@ gtk_inspector_get_object_name (GObject *object)
|
||||
return id;
|
||||
}
|
||||
|
||||
if (GTK_IS_EVENT_CONTROLLER (object))
|
||||
{
|
||||
return gtk_event_controller_get_name (GTK_EVENT_CONTROLLER (object));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ gtk_private_sources = files([
|
||||
'fallback-c89.c',
|
||||
'fnmatch.c',
|
||||
'tools/gdkpixbufutils.c',
|
||||
'gsettings-mapping.c',
|
||||
'gtkactionhelper.c',
|
||||
'gtkactionmuxer.c',
|
||||
'gtkactionobservable.c',
|
||||
@@ -36,6 +37,8 @@ gtk_private_sources = files([
|
||||
'gtkcolorpickershell.c',
|
||||
'gtkcolorscale.c',
|
||||
'gtkcolorswatch.c',
|
||||
'gtkconstraintexpression.c',
|
||||
'gtkconstraintsolver.c',
|
||||
'gtkcssanimatedstyle.c',
|
||||
'gtkcssanimation.c',
|
||||
'gtkcssarrayvalue.c',
|
||||
@@ -199,6 +202,8 @@ gtk_public_sources = files([
|
||||
'gtkcombobox.c',
|
||||
'gtkcomboboxtext.c',
|
||||
'gtkcomposetable.c',
|
||||
'gtkconstraintlayout.c',
|
||||
'gtkconstraint.c',
|
||||
'gtkcontainer.c',
|
||||
'gtkcssprovider.c',
|
||||
'gtkdialog.c',
|
||||
@@ -458,6 +463,8 @@ gtk_public_headers = files([
|
||||
'gtkcolorutils.h',
|
||||
'gtkcombobox.h',
|
||||
'gtkcomboboxtext.h',
|
||||
'gtkconstraintlayout.h',
|
||||
'gtkconstraint.h',
|
||||
'gtkcontainer.h',
|
||||
'gtkcssprovider.h',
|
||||
'gtkcustomlayout.h',
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
<enum id='org.gtk.gtk4.Settings.FileChooser.SortColumn'>
|
||||
<value nick='name' value='0'/>
|
||||
<value nick='size' value='1'/>
|
||||
<value nick='modified' value='2'/>
|
||||
<value nick='type' value='2'/>
|
||||
<value nick='modified' value='3'/>
|
||||
</enum>
|
||||
|
||||
<enum id='org.gtk.gtk4.Settings.FileChooser.SortOrder'>
|
||||
@@ -48,6 +49,12 @@
|
||||
<value nick='with-time' value='1'/>
|
||||
</enum>
|
||||
|
||||
<enum id='org.gtk.gtk4.Settings.FileChooser.TypeFormat'>
|
||||
<value nick='mime' value='0'/>
|
||||
<value nick='description' value='1'/>
|
||||
<value nick='category' value='2'/>
|
||||
</enum>
|
||||
|
||||
<schema id='org.gtk.gtk4.Settings.FileChooser' path='/org/gtk/gtk4/settings/file-chooser/'>
|
||||
<key name='last-folder-uri' type='s'>
|
||||
<default>""</default>
|
||||
@@ -87,6 +94,13 @@
|
||||
Controls whether the file chooser shows a column with file sizes.
|
||||
</description>
|
||||
</key>
|
||||
<key name='show-type-column' type='b'>
|
||||
<default>true</default>
|
||||
<summary>Show file types</summary>
|
||||
<description>
|
||||
Controls whether the file chooser shows a column with file types.
|
||||
</description>
|
||||
</key>
|
||||
<key name='sort-column' enum='org.gtk.gtk4.Settings.FileChooser.SortColumn'>
|
||||
<default>'name'</default>
|
||||
<summary>Sort column</summary>
|
||||
@@ -148,6 +162,17 @@
|
||||
The amount of detail to show in the Modified column.
|
||||
</description>
|
||||
</key>
|
||||
<key name="type-format" enum="org.gtk.gtk4.Settings.FileChooser.TypeFormat">
|
||||
<default>'category'</default>
|
||||
<summary>Type format</summary>
|
||||
<description>
|
||||
Different ways to show the 'Type' column information.
|
||||
Example outputs for a video mp4 file:
|
||||
'mime' -> 'video/mp4'
|
||||
'description' -> 'MPEG-4 video'
|
||||
'category' -> 'Video'
|
||||
</description>
|
||||
</key>
|
||||
</schema>
|
||||
|
||||
</schemalist>
|
||||
|
||||
@@ -34,7 +34,7 @@ $destructive_color: if($variant == 'light', #e01b24, darken(#e01b24, 10%));
|
||||
|
||||
$osd_fg_color: #eeeeec;
|
||||
$osd_text_color: white;
|
||||
$osd_bg_color: transparentize(darken(desaturate(#3d3846, 100%), 4%),0.3);
|
||||
$osd_bg_color: if($variant == 'light', transparentize(darken(desaturate(#3d3846, 100%), 4%),0.3), transparentize(darken(desaturate(#3d3846, 100%), 10%),0.3));
|
||||
$osd_insensitive_bg_color: transparentize(mix($osd_fg_color, opacify($osd_bg_color, 1), 10%), 0.5);
|
||||
$osd_insensitive_fg_color: mix($osd_fg_color, opacify($osd_bg_color, 1), 50%);
|
||||
$osd_borders_color: transparentize(black, 0.3);
|
||||
|
||||
@@ -9,6 +9,7 @@ $button_transition: all 200ms $ease-out-quad;
|
||||
$button_radius: 5px;
|
||||
$menu_radius: 5px;
|
||||
$window_radius: $button_radius + 3;
|
||||
$popover_radius: $button_radius + 4;
|
||||
|
||||
* {
|
||||
padding: 0;
|
||||
@@ -1066,9 +1067,12 @@ button.color {
|
||||
|
||||
/* list buttons */
|
||||
/* tone down as per new designs, see issue #1473 */
|
||||
list row button {
|
||||
list row button.image-button:not(.flat) {
|
||||
@extend %undecorated_button;
|
||||
border: 1px solid transparentize($borders_color, .5);
|
||||
&:hover { @include button(hover); }
|
||||
&:active,
|
||||
&:checked { @include button(active); }
|
||||
}
|
||||
|
||||
/*********
|
||||
@@ -2019,11 +2023,9 @@ menubar,
|
||||
|
||||
// remove padding and rounding from menubar submenus
|
||||
menu {
|
||||
border-radius: 0;
|
||||
padding:0;
|
||||
menu {
|
||||
.csd &, & {
|
||||
border-radius: 0;
|
||||
padding:0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2177,10 +2179,13 @@ popover>contents {
|
||||
}
|
||||
|
||||
popover>contents.background {
|
||||
border-radius: $menu_radius + 4px;
|
||||
|
||||
background-color: $popover_bg_color;
|
||||
box-shadow: 0 1px 2px transparentize(black, 0.7);
|
||||
.csd &, & { border: 1px solid $borders_color; }
|
||||
.csd &, & {
|
||||
border: 1px solid $borders_color;
|
||||
border-radius: $popover_radius;
|
||||
}
|
||||
|
||||
&:backdrop {
|
||||
background-color: $backdrop_bg_color;
|
||||
@@ -2715,12 +2720,24 @@ switch {
|
||||
border-radius: 50%;
|
||||
transition: $button_transition;
|
||||
|
||||
@include button(normal-alt, $edge: $shadow_color);
|
||||
@if $variant == 'light' {
|
||||
@include button(normal-alt, $edge: $shadow_color);
|
||||
}
|
||||
@else {
|
||||
@include button(normal-alt, $c: lighten($bg_color,6%), $edge: $shadow_color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
image { color: transparent; } /* only show i / o for the accessible theme */
|
||||
|
||||
&:hover slider { @include button(hover-alt, $edge: $shadow_color); }
|
||||
&:hover slider {
|
||||
@if $variant == 'light' {
|
||||
@include button(hover-alt, $edge: $shadow_color);
|
||||
}
|
||||
@else {
|
||||
@include button(hover-alt, $c: lighten($bg_color,6%), $edge: $shadow_color);
|
||||
}
|
||||
}
|
||||
|
||||
&:checked slider { border: 1px solid $selected_borders_color; }
|
||||
|
||||
@@ -4157,39 +4174,43 @@ infobar {
|
||||
&.warning,
|
||||
&.error {
|
||||
&:backdrop, & {
|
||||
label, & { color: $selected_fg_color; }
|
||||
background-color: $selected_bg_color;
|
||||
border-color: darken($selected_bg_color, 10%);
|
||||
label, & { color: $fg_color; }
|
||||
background-color: if($variant == 'light', desaturate(lighten(invert($selected_bg_color), 45%), 30%),
|
||||
desaturate(darken(invert($selected_bg_color),40%), 70%));
|
||||
border-color: lighten($borders_color, 10%);
|
||||
}
|
||||
|
||||
text-shadow: 0 1px darken($selected_bg_color, 10%);
|
||||
text-shadow: none;
|
||||
|
||||
&:backdrop { text-shadow: none; }
|
||||
|
||||
button {
|
||||
// FIXME: extend selection mode buttons
|
||||
@include button(normal, $selected_bg_color, $selected_fg_color, none);
|
||||
@include button(normal, $bg_color, $fg_color, none);
|
||||
|
||||
&:hover { @include button(hover, $selected_bg_color, $selected_fg_color, none); }
|
||||
&:hover { @include button(hover, $bg_color, $fg_color, none); }
|
||||
|
||||
&:active,
|
||||
&:checked { @include button(active, $selected_bg_color, $selected_fg_color, none); }
|
||||
&:checked { @include button(active, $bg_color, $fg_color, none); }
|
||||
|
||||
&:disabled { @include button(insensitive,$selected_bg_color,$selected_fg_color,none); }
|
||||
&:disabled { @include button(insensitive,$bg_color,$fg_color,none); }
|
||||
|
||||
&:backdrop {
|
||||
@include button(backdrop, $selected_bg_color, $selected_fg_color, none);
|
||||
border-color: _border_color($selected_bg_color);
|
||||
@include button(backdrop, $bg_color, $fg_color, none);
|
||||
border-color: _border_color($bg_color);
|
||||
|
||||
&:disabled {
|
||||
@include button(backdrop-insensitive, $selected_bg_color,
|
||||
$selected_fg_color, none);
|
||||
border-color: _border_color($selected_bg_color);
|
||||
@include button(backdrop-insensitive, $bg_color,
|
||||
$fg_color, none);
|
||||
border-color: _border_color($bg_color);
|
||||
}
|
||||
}
|
||||
&:backdrop, & {
|
||||
label, & { color: $fg_color; }
|
||||
}
|
||||
}
|
||||
|
||||
selection { background-color: darken($selected_bg_color, 10%); }
|
||||
selection { background-color: darken($bg_color, 10%); }
|
||||
|
||||
*:link { @extend %link_selected; }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
* { padding: 0; -gtk-secondary-caret-color: #15539e; }
|
||||
|
||||
modelbutton:focus(visible), button:focus(visible), checkbutton:focus(visible), radiobutton:focus(visible), switch:focus(visible), scale:focus(visible), label:focus(visible), row:focus(visible), flowboxchild:focus(visible) { outline-color: alpha(currentColor,0.3); outline-style: dashed; outline-offset: -3px; outline-width: 1px; -gtk-outline-radius: 3px; }
|
||||
button:focus(visible), checkbutton:focus(visible), radiobutton:focus(visible), switch:focus(visible), scale:focus(visible), label:focus(visible), row:focus(visible), flowboxchild:focus(visible) { outline-color: alpha(currentColor,0.3); outline-style: dashed; outline-offset: -3px; outline-width: 1px; -gtk-outline-radius: 3px; }
|
||||
|
||||
/*************** Base States * */
|
||||
.background { color: #eeeeec; background-color: #353535; }
|
||||
@@ -82,7 +82,7 @@ assistant .sidebar label { padding: 6px 12px; }
|
||||
|
||||
assistant .sidebar label.highlight { background-color: #5a5a59; }
|
||||
|
||||
.csd popover > contents.background.touch-selection, .csd popover > contents.background.magnifier, popover > contents.background.touch-selection, popover > contents.background.magnifier, .csd popover > contents.background.osd, popover > contents.background.osd, .app-notification, .app-notification.frame, .osd .scale-popup, .osd { color: #eeeeec; border: none; background-color: rgba(53, 53, 53, 0.7); background-clip: padding-box; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
|
||||
.csd popover > contents.background.touch-selection, .csd popover > contents.background.magnifier, popover > contents.background.touch-selection, popover > contents.background.magnifier, .csd popover > contents.background.osd, popover > contents.background.osd, .app-notification, .app-notification.frame, .osd .scale-popup, .osd { color: #eeeeec; border: none; background-color: rgba(38, 38, 38, 0.7); background-clip: padding-box; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
|
||||
|
||||
.csd popover > contents.background.touch-selection:backdrop, .csd popover > contents.background.magnifier:backdrop, popover > contents.background.touch-selection:backdrop, popover > contents.background.magnifier:backdrop, .csd popover > contents.background.osd:backdrop, popover > contents.background.osd:backdrop, .app-notification:backdrop, .osd .scale-popup:backdrop, .osd:backdrop { text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
@@ -155,7 +155,7 @@ spinbutton:drop(active):focus:not(.vertical), spinbutton.vertical text:drop(acti
|
||||
|
||||
.osd spinbutton:backdrop:not(.vertical), .osd spinbutton.vertical text:backdrop, spinbutton.vertical .osd text:backdrop, .osd entry:backdrop { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.5); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.osd spinbutton:disabled:not(.vertical), .osd spinbutton.vertical text:disabled, spinbutton.vertical .osd text:disabled, .osd entry:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: rgba(71, 71, 71, 0.5); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.osd spinbutton:disabled:not(.vertical), .osd spinbutton.vertical text:disabled, spinbutton.vertical .osd text:disabled, .osd entry:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: rgba(58, 58, 57, 0.5); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
spinbutton:not(.vertical) progress, spinbutton.vertical text progress, entry progress { margin-bottom: 2px; }
|
||||
|
||||
@@ -265,33 +265,33 @@ row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(di
|
||||
|
||||
row:selected button.sidebar-button:not(:active):not(:checked):not(:hover):not(disabled):backdrop, row:selected button.flat:not(:active):not(:checked):not(:hover):not(disabled):backdrop { color: #919190; }
|
||||
|
||||
button.osd { min-width: 26px; min-height: 32px; color: #eeeeec; border-radius: 5px; color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); border: none; box-shadow: none; }
|
||||
button.osd { min-width: 26px; min-height: 32px; color: #eeeeec; border-radius: 5px; color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); border: none; box-shadow: none; }
|
||||
|
||||
button.osd.image-button { min-width: 34px; }
|
||||
|
||||
button.osd:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(83, 83, 83, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); border: none; box-shadow: none; }
|
||||
button.osd:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); border: none; box-shadow: none; }
|
||||
|
||||
button.osd:active, button.osd:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); border: none; box-shadow: none; }
|
||||
|
||||
button.osd:disabled:backdrop, button.osd:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; border: none; }
|
||||
button.osd:disabled:backdrop, button.osd:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; border: none; }
|
||||
|
||||
button.osd:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; border: none; }
|
||||
button.osd:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; border: none; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button, .csd popover > contents.background.magnifier button, popover > contents.background.touch-selection button, popover > contents.background.magnifier button, .app-notification button, .app-notification.frame button, .osd button { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.csd popover > contents.background.touch-selection button, .csd popover > contents.background.magnifier button, popover > contents.background.touch-selection button, popover > contents.background.magnifier button, .app-notification button, .app-notification.frame button, .osd button { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.csd popover > contents.background.touch-selection button:hover, .csd popover > contents.background.magnifier button:hover, popover > contents.background.touch-selection button:hover, popover > contents.background.magnifier button:hover, .app-notification button:hover, .osd button:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(83, 83, 83, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.csd popover > contents.background.touch-selection button:hover, .csd popover > contents.background.magnifier button:hover, popover > contents.background.touch-selection button:hover, popover > contents.background.magnifier button:hover, .app-notification button:hover, .osd button:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.csd popover > contents.background.touch-selection button:active:backdrop, .csd popover > contents.background.magnifier button:active:backdrop, popover > contents.background.touch-selection button:active:backdrop, popover > contents.background.magnifier button:active:backdrop, .app-notification button:active:backdrop, .csd popover > contents.background.touch-selection button:active, .csd popover > contents.background.magnifier button:active, popover > contents.background.touch-selection button:active, popover > contents.background.magnifier button:active, .app-notification button:active, .csd popover > contents.background.touch-selection button:checked:backdrop, .csd popover > contents.background.magnifier button:checked:backdrop, popover > contents.background.touch-selection button:checked:backdrop, popover > contents.background.magnifier button:checked:backdrop, .app-notification button:checked:backdrop, .csd popover > contents.background.touch-selection button:checked, .csd popover > contents.background.magnifier button:checked, popover > contents.background.touch-selection button:checked, popover > contents.background.magnifier button:checked, .app-notification button:checked, .osd button:active:backdrop, .osd button:active, .osd button:checked:backdrop, .osd button:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.csd popover > contents.background.touch-selection button:disabled:backdrop, .csd popover > contents.background.magnifier button:disabled:backdrop, popover > contents.background.touch-selection button:disabled:backdrop, popover > contents.background.magnifier button:disabled:backdrop, .app-notification button:disabled:backdrop, .csd popover > contents.background.touch-selection button:disabled, .csd popover > contents.background.magnifier button:disabled, popover > contents.background.touch-selection button:disabled, popover > contents.background.magnifier button:disabled, .app-notification button:disabled, .osd button:disabled:backdrop, .osd button:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.csd popover > contents.background.touch-selection button:disabled:backdrop, .csd popover > contents.background.magnifier button:disabled:backdrop, popover > contents.background.touch-selection button:disabled:backdrop, popover > contents.background.magnifier button:disabled:backdrop, .app-notification button:disabled:backdrop, .csd popover > contents.background.touch-selection button:disabled, .csd popover > contents.background.magnifier button:disabled, popover > contents.background.touch-selection button:disabled, popover > contents.background.magnifier button:disabled, .app-notification button:disabled, .osd button:disabled:backdrop, .osd button:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button:backdrop, .csd popover > contents.background.magnifier button:backdrop, popover > contents.background.touch-selection button:backdrop, popover > contents.background.magnifier button:backdrop, .app-notification button:backdrop, .osd button:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.csd popover > contents.background.touch-selection button:backdrop, .csd popover > contents.background.magnifier button:backdrop, popover > contents.background.touch-selection button:backdrop, popover > contents.background.magnifier button:backdrop, .app-notification button:backdrop, .osd button:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button.flat, .csd popover > contents.background.magnifier button.flat, popover > contents.background.touch-selection button.flat, popover > contents.background.magnifier button.flat, .app-notification button.flat, .osd button.flat { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; box-shadow: none; text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button.flat:hover, .csd popover > contents.background.magnifier button.flat:hover, popover > contents.background.touch-selection button.flat:hover, popover > contents.background.magnifier button.flat:hover, .app-notification button.flat:hover, .osd button.flat:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(83, 83, 83, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.csd popover > contents.background.touch-selection button.flat:hover, .csd popover > contents.background.magnifier button.flat:hover, popover > contents.background.touch-selection button.flat:hover, popover > contents.background.magnifier button.flat:hover, .app-notification button.flat:hover, .osd button.flat:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.csd popover > contents.background.touch-selection button.flat:disabled, .csd popover > contents.background.magnifier button.flat:disabled, popover > contents.background.touch-selection button.flat:disabled, popover > contents.background.magnifier button.flat:disabled, .app-notification button.flat:disabled, .osd button.flat:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-image: none; border-color: transparent; box-shadow: none; }
|
||||
.csd popover > contents.background.touch-selection button.flat:disabled, .csd popover > contents.background.magnifier button.flat:disabled, popover > contents.background.touch-selection button.flat:disabled, popover > contents.background.magnifier button.flat:disabled, .app-notification button.flat:disabled, .osd button.flat:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-image: none; border-color: transparent; box-shadow: none; }
|
||||
|
||||
.csd popover > contents.background.touch-selection button.flat:backdrop, .csd popover > contents.background.magnifier button.flat:backdrop, popover > contents.background.touch-selection button.flat:backdrop, popover > contents.background.magnifier button.flat:backdrop, .app-notification button.flat:backdrop, .osd button.flat:backdrop { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
@@ -337,7 +337,7 @@ button.suggested-action:disabled:active label, button.suggested-action:disabled:
|
||||
|
||||
.osd button.suggested-action:active:backdrop, .osd button.suggested-action:active, .osd button.suggested-action:checked:backdrop, .osd button.suggested-action:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(#15539e); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd button.suggested-action:disabled:backdrop, .osd button.suggested-action:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.osd button.suggested-action:disabled:backdrop, .osd button.suggested-action:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.osd button.suggested-action:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(21, 83, 158, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
@@ -381,7 +381,7 @@ button.destructive-action:disabled:active label, button.destructive-action:disab
|
||||
|
||||
.osd button.destructive-action:active:backdrop, .osd button.destructive-action:active, .osd button.destructive-action:checked:backdrop, .osd button.destructive-action:checked { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(#b2161d); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd button.destructive-action:disabled:backdrop, .osd button.destructive-action:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.osd button.destructive-action:disabled:backdrop, .osd button.destructive-action:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.osd button.destructive-action:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(178, 22, 29, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
@@ -455,7 +455,7 @@ button.circular:hover:not(:checked):not(:active):not(:disabled):not(:backdrop) {
|
||||
|
||||
.linked.vertical > spinbutton:not(:last-child):not(.vertical), spinbutton.vertical .linked.vertical > text:not(:last-child), .linked.vertical > entry:not(:last-child), .linked.vertical > button:not(:last-child), .linked.vertical > combobox:not(:last-child) > box > button.combo { border-bottom-style: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
|
||||
|
||||
modelbutton.flat, .menuitem.button.flat, modelbutton.flat:backdrop, modelbutton.flat:backdrop:hover, .menuitem.button.flat:backdrop, .menuitem.button.flat:backdrop:hover, list row button, button:link, button:visited, button:link:hover, button:link:active, button:link:checked, button:visited:hover, button:visited:active, button:visited:checked, calendar.button, .scale-popup button:hover, .scale-popup button:backdrop:hover, .scale-popup button:backdrop:disabled, .scale-popup button:backdrop { background-color: transparent; background-image: none; border-color: transparent; box-shadow: inset 0 1px rgba(255, 255, 255, 0), 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
modelbutton.flat, .menuitem.button.flat, modelbutton.flat:backdrop, modelbutton.flat:backdrop:hover, .menuitem.button.flat:backdrop, .menuitem.button.flat:backdrop:hover, list row button.image-button:not(.flat), button:link, button:visited, button:link:hover, button:link:active, button:link:checked, button:visited:hover, button:visited:active, button:visited:checked, calendar.button, .scale-popup button:hover, .scale-popup button:backdrop:hover, .scale-popup button:backdrop:disabled, .scale-popup button:backdrop { background-color: transparent; background-image: none; border-color: transparent; box-shadow: inset 0 1px rgba(255, 255, 255, 0), 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
/* menu buttons */
|
||||
modelbutton.flat, .menuitem.button.flat { min-height: 26px; padding-left: 5px; padding-right: 5px; border-radius: 5px; outline-offset: -2px; }
|
||||
@@ -476,7 +476,11 @@ button.color colorswatch:only-child, button.color colorswatch:only-child overlay
|
||||
|
||||
/* list buttons */
|
||||
/* tone down as per new designs, see issue #1473 */
|
||||
list row button { border: 1px solid rgba(27, 27, 27, 0.5); }
|
||||
list row button.image-button:not(.flat) { border: 1px solid rgba(27, 27, 27, 0.5); }
|
||||
|
||||
list row button.image-button:not(.flat):hover { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #1b1b1b; border-bottom-color: #070707; text-shadow: 0 -1px rgba(0, 0, 0, 0.786353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.786353); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px 2px rgba(0, 0, 0, 0.07); background-image: linear-gradient(to top, #323232, #373737 1px); }
|
||||
|
||||
list row button.image-button:not(.flat):active, list row button.image-button:not(.flat):checked { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #1b1b1b; background-image: image(#1e1e1e); box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
/********* Links * */
|
||||
button:link > label, button:visited > label, *:link, button:link, button:visited { color: #3584e4; }
|
||||
@@ -540,7 +544,7 @@ spinbutton:not(.vertical) button:dir(rtl):first-child { border-radius: 5px 0 0 5
|
||||
|
||||
.osd spinbutton:not(.vertical) button:backdrop { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; color: #eeeeec; border-color: rgba(0, 0, 0, 0.5); -gtk-icon-shadow: none; box-shadow: none; }
|
||||
|
||||
.osd spinbutton:not(.vertical) button:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; color: #919190; border-color: rgba(0, 0, 0, 0.5); -gtk-icon-shadow: none; box-shadow: none; }
|
||||
.osd spinbutton:not(.vertical) button:disabled { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; color: #8a8a89; border-color: rgba(0, 0, 0, 0.5); -gtk-icon-shadow: none; box-shadow: none; }
|
||||
|
||||
.osd spinbutton:not(.vertical) button:dir(ltr):last-child { border-radius: 0 5px 5px 0; }
|
||||
|
||||
@@ -560,15 +564,15 @@ spinbutton.vertical button.up { border-bottom-style: none; border-bottom-left-ra
|
||||
|
||||
spinbutton.vertical button.down { border-top-style: none; border-top-left-radius: 0; border-top-right-radius: 0; }
|
||||
|
||||
.osd spinbutton.vertical button:first-child { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.osd spinbutton.vertical button:first-child { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd spinbutton.vertical button:first-child:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(83, 83, 83, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.osd spinbutton.vertical button:first-child:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd spinbutton.vertical button:first-child:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd spinbutton.vertical button:first-child:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.osd spinbutton.vertical button:first-child:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.osd spinbutton.vertical button:first-child:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.osd spinbutton.vertical button:first-child:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
treeview spinbutton:not(.vertical) { min-height: 0; border-style: none; border-radius: 0; }
|
||||
|
||||
@@ -586,7 +590,7 @@ toolbar { padding: 4px 3px 3px 4px; }
|
||||
|
||||
.osd toolbar { background-color: transparent; }
|
||||
|
||||
toolbar.osd { padding: 13px; border: none; border-radius: 5px; background-color: rgba(53, 53, 53, 0.7); }
|
||||
toolbar.osd { padding: 13px; border: none; border-radius: 5px; background-color: rgba(38, 38, 38, 0.7); }
|
||||
|
||||
toolbar.osd.left, toolbar.osd.right, toolbar.osd.top, toolbar.osd.bottom { border-radius: 0; }
|
||||
|
||||
@@ -689,7 +693,9 @@ searchbar > revealer > box { padding: 6px; border-width: 0 0 1px; }
|
||||
|
||||
.default-decoration.titlebar:not(headerbar), headerbar.default-decoration { min-height: 28px; padding: 4px; }
|
||||
|
||||
.default-decoration.titlebar:not(headerbar) button.titlebutton, headerbar.default-decoration button.titlebutton { min-height: 26px; min-width: 26px; margin: 0; padding: 0; }
|
||||
.default-decoration.titlebar:not(headerbar) button.titlebutton, .default-decoration.titlebar:not(headerbar) menubutton.titlebutton, headerbar.default-decoration button.titlebutton, headerbar.default-decoration menubutton.titlebutton { min-height: 26px; min-width: 26px; margin: 0; padding: 0; }
|
||||
|
||||
.default-decoration.titlebar:not(headerbar) menubutton.titlebutton button, headerbar.default-decoration menubutton.titlebutton button { min-height: 20px; min-width: 20px; margin: 0; padding: 4px; }
|
||||
|
||||
.titlebar:not(headerbar) separator.titlebutton, headerbar separator.titlebutton { opacity: 0; }
|
||||
|
||||
@@ -812,9 +818,7 @@ menubar:backdrop, .menubar:backdrop { background-color: #353535; }
|
||||
|
||||
menubar > box > menuitem, .menubar > box > menuitem { min-height: 16px; padding: 4px 8px; }
|
||||
|
||||
menubar > box > menuitem menu, .menubar > box > menuitem menu { border-radius: 0; padding: 0; }
|
||||
|
||||
menubar > box > menuitem menu menu, .menubar > box > menuitem menu menu { border-radius: 0; padding: 0; }
|
||||
.csd menubar > box > menuitem menu, menubar > box > menuitem menu, .csd .menubar > box > menuitem menu, .menubar > box > menuitem menu { border-radius: 0; padding: 0; }
|
||||
|
||||
menubar > box > menuitem:hover, .menubar > box > menuitem:hover { box-shadow: inset 0 -3px #15539e; color: #3584e4; }
|
||||
|
||||
@@ -875,9 +879,9 @@ popover.menu > arrow, popover > arrow { background-color: #353535; border: 1px s
|
||||
|
||||
popover > contents { padding: 8px; background-color: #353535; border: 1px solid #1b1b1b; margin: 0px; }
|
||||
|
||||
popover > contents.background { border-radius: 9px; background-color: #353535; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); }
|
||||
popover > contents.background { background-color: #353535; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); }
|
||||
|
||||
.csd popover > contents.background, popover > contents.background { border: 1px solid #1b1b1b; }
|
||||
.csd popover > contents.background, popover > contents.background { border: 1px solid #1b1b1b; border-radius: 9px; }
|
||||
|
||||
popover > contents.background:backdrop { background-color: #353535; box-shadow: none; }
|
||||
|
||||
@@ -1108,11 +1112,11 @@ switch:backdrop:checked { border-color: #030c17; background-color: #15539e; }
|
||||
|
||||
switch:backdrop:disabled { color: #5b5b5b; border-color: #202020; background-color: #323232; }
|
||||
|
||||
switch slider { margin: -1px; min-width: 24px; min-height: 24px; border: 1px solid; border-radius: 50%; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; text-shadow: 0 -1px rgba(0, 0, 0, 0.834353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.834353); background-image: linear-gradient(to bottom, #2d2d2d 20%, #262626 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); }
|
||||
switch slider { margin: -1px; min-width: 24px; min-height: 24px; border: 1px solid; border-radius: 50%; transition: all 200ms cubic-bezier(0.25, 0.46, 0.45, 0.94); color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #111111; text-shadow: 0 -1px rgba(0, 0, 0, 0.786353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.786353); background-image: linear-gradient(to bottom, #3c3c3c 20%, #353535 90%); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); }
|
||||
|
||||
switch image { color: transparent; }
|
||||
|
||||
switch:hover slider { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #070707; box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); background-image: linear-gradient(to bottom, #353535 20%, #2b2b2b 90%); }
|
||||
switch:hover slider { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #111111; box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.07); background-image: linear-gradient(to bottom, #444444 20%, #3a3a3a 90%); }
|
||||
|
||||
switch:checked slider { border: 1px solid #030c17; }
|
||||
|
||||
@@ -1177,15 +1181,15 @@ check:backdrop:disabled, radio:backdrop:disabled { border-color: #202020; backgr
|
||||
|
||||
check:backdrop:disabled label, check:backdrop:disabled, radio:backdrop:disabled label, radio:backdrop:disabled { color: #5b5b5b; }
|
||||
|
||||
.osd check, .osd radio { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.osd check, .osd radio { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd check:hover, .osd radio:hover { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
.osd check:hover, .osd radio:hover { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd check:active, .osd radio:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); }
|
||||
|
||||
.osd check:backdrop, .osd radio:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.osd check:backdrop, .osd radio:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
.osd check:disabled, .osd radio:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
.osd check:disabled, .osd radio:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
menu menuitem check, menu menuitem radio { margin: 0; }
|
||||
|
||||
@@ -1234,7 +1238,7 @@ row:selected scale trough:disabled, scale row:selected trough:disabled, row:sele
|
||||
|
||||
.osd scale trough, scale .osd trough, .osd scale fill, scale .osd fill, .osd progressbar trough, progressbar .osd trough { border-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.5); }
|
||||
|
||||
.osd scale trough:disabled, scale .osd trough:disabled, .osd scale fill:disabled, scale .osd fill:disabled, .osd progressbar trough:disabled, progressbar .osd trough:disabled { background-color: rgba(71, 71, 71, 0.5); }
|
||||
.osd scale trough:disabled, scale .osd trough:disabled, .osd scale fill:disabled, scale .osd fill:disabled, .osd progressbar trough:disabled, progressbar .osd trough:disabled { background-color: rgba(58, 58, 57, 0.5); }
|
||||
|
||||
scale highlight, progressbar progress { border: 1px solid #030c17; border-radius: 3px; background-color: #15539e; }
|
||||
|
||||
@@ -1296,17 +1300,17 @@ scale slider:backdrop:disabled label, scale slider:backdrop:disabled { color: #5
|
||||
|
||||
row:selected scale slider:disabled, row:selected scale slider { border-color: #030c17; }
|
||||
|
||||
.osd scale slider { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); border-color: rgba(0, 0, 0, 0.7); background-color: #353535; }
|
||||
.osd scale slider { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); border-color: rgba(0, 0, 0, 0.7); background-color: #262626; }
|
||||
|
||||
.osd scale slider:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(83, 83, 83, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); background-color: #353535; }
|
||||
.osd scale slider:hover { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(68, 68, 68, 0.7)); background-clip: padding-box; box-shadow: inset 0 1px rgba(255, 255, 255, 0.1); text-shadow: 0 1px black; -gtk-icon-shadow: 0 1px black; outline-color: rgba(238, 238, 236, 0.3); background-color: #262626; }
|
||||
|
||||
.osd scale slider:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); background-color: #353535; }
|
||||
.osd scale slider:active { color: white; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(0, 0, 0, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; outline-color: rgba(238, 238, 236, 0.3); background-color: #262626; }
|
||||
|
||||
.osd scale slider:disabled { color: #919190; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(71, 71, 71, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-color: #353535; }
|
||||
.osd scale slider:disabled { color: #8a8a89; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(58, 58, 57, 0.5)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-color: #262626; }
|
||||
|
||||
.osd scale slider:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(53, 53, 53, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-color: #353535; }
|
||||
.osd scale slider:backdrop { color: #eeeeec; border-color: rgba(0, 0, 0, 0.7); background-color: transparent; background-image: image(rgba(38, 38, 38, 0.7)); background-clip: padding-box; box-shadow: none; text-shadow: none; -gtk-icon-shadow: none; background-color: #262626; }
|
||||
|
||||
.osd scale slider:backdrop:disabled { background-color: #353535; }
|
||||
.osd scale slider:backdrop:disabled { background-color: #262626; }
|
||||
|
||||
scale value { color: alpha(currentColor,0.55); }
|
||||
|
||||
@@ -1632,7 +1636,7 @@ row.activatable:selected.has-open-popup, row.activatable:selected:hover { backgr
|
||||
row.activatable:selected:backdrop { background-color: #15539e; }
|
||||
|
||||
/********************* App Notifications * */
|
||||
.app-notification, .app-notification.frame { padding: 10px; border-radius: 0 0 5px 5px; background-color: rgba(53, 53, 53, 0.7); background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), transparent 2px); background-clip: padding-box; }
|
||||
.app-notification, .app-notification.frame { padding: 10px; border-radius: 0 0 5px 5px; background-color: rgba(38, 38, 38, 0.7); background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.2), transparent 2px); background-clip: padding-box; }
|
||||
|
||||
.app-notification:backdrop, .app-notification.frame:backdrop { background-image: none; transition: 200ms ease-out; }
|
||||
|
||||
@@ -1681,6 +1685,8 @@ messagedialog .titlebar { min-height: 20px; background-image: none; background-c
|
||||
|
||||
messagedialog box.dialog-vbox.vertical { border-spacing: 10px; }
|
||||
|
||||
messagedialog label.title { font-weight: 800; font-size: 15pt; }
|
||||
|
||||
messagedialog.csd.background { border-bottom-left-radius: 9px; border-bottom-right-radius: 9px; }
|
||||
|
||||
messagedialog.csd .dialog-action-area button { padding: 10px 14px; border-radius: 0; border-left-style: solid; border-right-style: none; border-bottom-style: none; }
|
||||
@@ -1804,33 +1810,35 @@ video image.osd { min-width: 64px; min-height: 64px; border-radius: 32px; }
|
||||
/************** GtkInfoBar * */
|
||||
infobar { border-style: none; }
|
||||
|
||||
infobar.info, infobar.question, infobar.warning, infobar.error { text-shadow: 0 1px #0f3b71; }
|
||||
infobar.info, infobar.question, infobar.warning, infobar.error { text-shadow: none; }
|
||||
|
||||
infobar.info:backdrop, infobar.info, infobar.question:backdrop, infobar.question, infobar.warning:backdrop, infobar.warning, infobar.error:backdrop, infobar.error { background-color: #15539e; border-color: #0f3b71; }
|
||||
infobar.info:backdrop, infobar.info, infobar.question:backdrop, infobar.question, infobar.warning:backdrop, infobar.warning, infobar.error:backdrop, infobar.error { background-color: #44403b; border-color: #353535; }
|
||||
|
||||
infobar.info:backdrop label, infobar.info:backdrop, infobar.info label, infobar.info, infobar.question:backdrop label, infobar.question:backdrop, infobar.question label, infobar.question, infobar.warning:backdrop label, infobar.warning:backdrop, infobar.warning label, infobar.warning, infobar.error:backdrop label, infobar.error:backdrop, infobar.error label, infobar.error { color: #ffffff; }
|
||||
infobar.info:backdrop label, infobar.info:backdrop, infobar.info label, infobar.info, infobar.question:backdrop label, infobar.question:backdrop, infobar.question label, infobar.question, infobar.warning:backdrop label, infobar.warning:backdrop, infobar.warning label, infobar.warning, infobar.error:backdrop label, infobar.error:backdrop, infobar.error label, infobar.error { color: #eeeeec; }
|
||||
|
||||
infobar.info:backdrop, infobar.question:backdrop, infobar.warning:backdrop, infobar.error:backdrop { text-shadow: none; }
|
||||
|
||||
infobar.info button, infobar.question button, infobar.warning button, infobar.error button { color: #ffffff; outline-color: rgba(255, 255, 255, 0.3); border-color: #0f3b71; border-bottom-color: #092444; background-image: linear-gradient(to top, #155099 2px, #15539e); text-shadow: 0 -1px rgba(0, 0, 0, 0.719216); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.719216); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px 2px rgba(0, 0, 0, 0.07); }
|
||||
infobar.info button, infobar.question button, infobar.warning button, infobar.error button { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #1b1b1b; border-bottom-color: #070707; background-image: linear-gradient(to top, #323232 2px, #353535); text-shadow: 0 -1px rgba(0, 0, 0, 0.834353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.834353); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px 2px rgba(0, 0, 0, 0.07); }
|
||||
|
||||
infobar.info button:hover, infobar.question button:hover, infobar.warning button:hover, infobar.error button:hover { color: #ffffff; outline-color: rgba(255, 255, 255, 0.3); border-color: #0f3b71; border-bottom-color: #092444; text-shadow: 0 -1px rgba(0, 0, 0, 0.671216); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.671216); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px 2px rgba(0, 0, 0, 0.07); background-image: linear-gradient(to top, #155099, #1655a2 1px); }
|
||||
infobar.info button:hover, infobar.question button:hover, infobar.warning button:hover, infobar.error button:hover { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #1b1b1b; border-bottom-color: #070707; text-shadow: 0 -1px rgba(0, 0, 0, 0.786353); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.786353); box-shadow: inset 0 1px rgba(255, 255, 255, 0.02), 0 1px 2px rgba(0, 0, 0, 0.07); background-image: linear-gradient(to top, #323232, #373737 1px); }
|
||||
|
||||
infobar.info button:active, infobar.info button:checked, infobar.question button:active, infobar.question button:checked, infobar.warning button:active, infobar.warning button:checked, infobar.error button:active, infobar.error button:checked { color: #ffffff; outline-color: rgba(255, 255, 255, 0.3); border-color: #0f3b71; background-image: image(#103e75); box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
infobar.info button:active, infobar.info button:checked, infobar.question button:active, infobar.question button:checked, infobar.warning button:active, infobar.warning button:checked, infobar.error button:active, infobar.error button:checked { color: #eeeeec; outline-color: rgba(238, 238, 236, 0.3); border-color: #1b1b1b; background-image: image(#1e1e1e); box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
infobar.info button:disabled, infobar.question button:disabled, infobar.warning button:disabled, infobar.error button:disabled { border-color: #0f3b71; background-image: image(#194d8d); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); }
|
||||
infobar.info button:disabled, infobar.question button:disabled, infobar.warning button:disabled, infobar.error button:disabled { border-color: #1b1b1b; background-image: image(#323232); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); }
|
||||
|
||||
infobar.info button:disabled label, infobar.info button:disabled, infobar.question button:disabled label, infobar.question button:disabled, infobar.warning button:disabled label, infobar.warning button:disabled, infobar.error button:disabled label, infobar.error button:disabled { color: #8ca6c6; }
|
||||
infobar.info button:disabled label, infobar.info button:disabled, infobar.question button:disabled label, infobar.question button:disabled, infobar.warning button:disabled label, infobar.warning button:disabled, infobar.error button:disabled label, infobar.error button:disabled { color: #919190; }
|
||||
|
||||
infobar.info button:backdrop, infobar.question button:backdrop, infobar.warning button:backdrop, infobar.error button:backdrop { border-color: #0f3b71; background-image: image(#15539e); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); border-color: #0f3b71; }
|
||||
infobar.info button:backdrop, infobar.question button:backdrop, infobar.warning button:backdrop, infobar.error button:backdrop { border-color: #202020; background-image: image(#353535); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); border-color: #1b1b1b; }
|
||||
|
||||
infobar.info button:backdrop label, infobar.info button:backdrop, infobar.question button:backdrop label, infobar.question button:backdrop, infobar.warning button:backdrop label, infobar.warning button:backdrop, infobar.error button:backdrop label, infobar.error button:backdrop { color: #d0ddec; }
|
||||
infobar.info button:backdrop label, infobar.info button:backdrop, infobar.question button:backdrop label, infobar.question button:backdrop, infobar.warning button:backdrop label, infobar.warning button:backdrop, infobar.error button:backdrop label, infobar.error button:backdrop { color: #919190; }
|
||||
|
||||
infobar.info button:backdrop:disabled, infobar.question button:backdrop:disabled, infobar.warning button:backdrop:disabled, infobar.error button:backdrop:disabled { border-color: #0f3b71; background-image: image(#194d8d); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); border-color: #0f3b71; }
|
||||
infobar.info button:backdrop:disabled, infobar.question button:backdrop:disabled, infobar.warning button:backdrop:disabled, infobar.error button:backdrop:disabled { border-color: #202020; background-image: image(#323232); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); border-color: #1b1b1b; }
|
||||
|
||||
infobar.info button:backdrop:disabled label, infobar.info button:backdrop:disabled, infobar.question button:backdrop:disabled label, infobar.question button:backdrop:disabled, infobar.warning button:backdrop:disabled label, infobar.warning button:backdrop:disabled, infobar.error button:backdrop:disabled label, infobar.error button:backdrop:disabled { color: #6a8bb5; }
|
||||
infobar.info button:backdrop:disabled label, infobar.info button:backdrop:disabled, infobar.question button:backdrop:disabled label, infobar.question button:backdrop:disabled, infobar.warning button:backdrop:disabled label, infobar.warning button:backdrop:disabled, infobar.error button:backdrop:disabled label, infobar.error button:backdrop:disabled { color: #5b5b5b; }
|
||||
|
||||
infobar.info selection, infobar.question selection, infobar.warning selection, infobar.error selection { background-color: #0f3b71; }
|
||||
infobar.info button:backdrop label, infobar.info button:backdrop, infobar.info button label, infobar.info button, infobar.question button:backdrop label, infobar.question button:backdrop, infobar.question button label, infobar.question button, infobar.warning button:backdrop label, infobar.warning button:backdrop, infobar.warning button label, infobar.warning button, infobar.error button:backdrop label, infobar.error button:backdrop, infobar.error button label, infobar.error button { color: #eeeeec; }
|
||||
|
||||
infobar.info selection, infobar.question selection, infobar.warning selection, infobar.error selection { background-color: #1b1b1b; }
|
||||
|
||||
/************ Tooltips * */
|
||||
tooltip { padding: 4px; border-radius: 5px; box-shadow: none; text-shadow: 0 1px black; }
|
||||
@@ -2035,6 +2043,42 @@ popover.emoji-completion .emoji:hover { background-color: #424242; }
|
||||
|
||||
popover.entry-completion contents { padding: 0; }
|
||||
|
||||
menubar { padding: 0px; box-shadow: inset 0 -1px rgba(0, 0, 0, 0.1); }
|
||||
|
||||
menubar:backdrop { background-color: #353535; }
|
||||
|
||||
menubar > item { min-height: 16px; padding: 4px 8px; }
|
||||
|
||||
menubar > item:selected { box-shadow: inset 0 -3px #15539e; color: #3584e4; }
|
||||
|
||||
menubar > item:disabled { color: #919190; box-shadow: none; }
|
||||
|
||||
menubar .csd.popup decoration { border-radius: 0; }
|
||||
|
||||
popover.menu button.flat.image-button.model { padding: 0; border: none; }
|
||||
|
||||
popover.menu button.flat.image-button.model:selected { border: none; color: #ffffff; background: #15539e; }
|
||||
|
||||
popover.menu box.inline-buttons { border-radius: 5px; border-style: none; border-width: 0; border-image-source: none; border-image-width: 1px; }
|
||||
|
||||
popover.menu box.circular-buttons { padding-bottom: 5px; }
|
||||
|
||||
popover.menu.background contents { background: white; }
|
||||
|
||||
popover.menu.background separator { margin: 5px 0px; }
|
||||
|
||||
popover.menu accelerator { margin-left: 20px; color: gray; }
|
||||
|
||||
popover.menu box.inline-buttons { padding: 0 5px; }
|
||||
|
||||
popover.menu radio.left, popover.menu check.left { margin-left: 0; margin-right: 12px; }
|
||||
|
||||
popover.menu radio.right, popover.menu check.right { margin-left: 12px; margin-right: 0; }
|
||||
|
||||
popover.menu modelbutton:selected { color: #ffffff; background-color: #15539e; }
|
||||
|
||||
popover.menu modelbutton:selected accelerator { color: silver; }
|
||||
|
||||
/* GTK NAMED COLORS ---------------- use responsibly! */
|
||||
/*
|
||||
widget text/foreground color */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
* { padding: 0; -gtk-secondary-caret-color: #3584e4; }
|
||||
|
||||
modelbutton:focus(visible), button:focus(visible), checkbutton:focus(visible), radiobutton:focus(visible), switch:focus(visible), scale:focus(visible), label:focus(visible), row:focus(visible), flowboxchild:focus(visible) { outline-color: alpha(currentColor,0.3); outline-style: dashed; outline-offset: -3px; outline-width: 1px; -gtk-outline-radius: 3px; }
|
||||
button:focus(visible), checkbutton:focus(visible), radiobutton:focus(visible), switch:focus(visible), scale:focus(visible), label:focus(visible), row:focus(visible), flowboxchild:focus(visible) { outline-color: alpha(currentColor,0.3); outline-style: dashed; outline-offset: -3px; outline-width: 1px; -gtk-outline-radius: 3px; }
|
||||
|
||||
/*************** Base States * */
|
||||
.background { color: #2e3436; background-color: #f6f5f4; }
|
||||
@@ -457,7 +457,7 @@ button.circular:hover:not(:checked):not(:active):not(:disabled):not(:backdrop) {
|
||||
|
||||
.linked.vertical > spinbutton:not(:last-child):not(.vertical), spinbutton.vertical .linked.vertical > text:not(:last-child), .linked.vertical > entry:not(:last-child), .linked.vertical > button:not(:last-child), .linked.vertical > combobox:not(:last-child) > box > button.combo { border-bottom-style: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
|
||||
|
||||
modelbutton.flat, .menuitem.button.flat, modelbutton.flat:backdrop, modelbutton.flat:backdrop:hover, .menuitem.button.flat:backdrop, .menuitem.button.flat:backdrop:hover, list row button, button:link, button:visited, button:link:hover, button:link:active, button:link:checked, button:visited:hover, button:visited:active, button:visited:checked, calendar.button, .scale-popup button:hover, .scale-popup button:backdrop:hover, .scale-popup button:backdrop:disabled, .scale-popup button:backdrop { background-color: transparent; background-image: none; border-color: transparent; box-shadow: inset 0 1px rgba(255, 255, 255, 0), 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
modelbutton.flat, .menuitem.button.flat, modelbutton.flat:backdrop, modelbutton.flat:backdrop:hover, .menuitem.button.flat:backdrop, .menuitem.button.flat:backdrop:hover, list row button.image-button:not(.flat), button:link, button:visited, button:link:hover, button:link:active, button:link:checked, button:visited:hover, button:visited:active, button:visited:checked, calendar.button, .scale-popup button:hover, .scale-popup button:backdrop:hover, .scale-popup button:backdrop:disabled, .scale-popup button:backdrop { background-color: transparent; background-image: none; border-color: transparent; box-shadow: inset 0 1px rgba(255, 255, 255, 0), 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
/* menu buttons */
|
||||
modelbutton.flat, .menuitem.button.flat { min-height: 26px; padding-left: 5px; padding-right: 5px; border-radius: 5px; outline-offset: -2px; }
|
||||
@@ -484,7 +484,11 @@ button.color colorswatch:only-child, button.color colorswatch:only-child overlay
|
||||
|
||||
/* list buttons */
|
||||
/* tone down as per new designs, see issue #1473 */
|
||||
list row button { border: 1px solid rgba(205, 199, 194, 0.5); }
|
||||
list row button.image-button:not(.flat) { border: 1px solid rgba(205, 199, 194, 0.5); }
|
||||
|
||||
list row button.image-button:not(.flat):hover { color: #2e3436; outline-color: rgba(46, 52, 54, 0.3); border-color: #cdc7c2; border-bottom-color: #bfb8b1; text-shadow: 0 1px rgba(255, 255, 255, 0.769231); -gtk-icon-shadow: 0 1px rgba(255, 255, 255, 0.769231); box-shadow: inset 0 1px white, 0 1px 2px rgba(0, 0, 0, 0.07); background-image: linear-gradient(to top, #f6f5f4, #f8f8f7 1px); }
|
||||
|
||||
list row button.image-button:not(.flat):active, list row button.image-button:not(.flat):checked { color: #2e3436; outline-color: rgba(46, 52, 54, 0.3); border-color: #cdc7c2; background-image: image(#d6d1cd); box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
/********* Links * */
|
||||
button:link > label, button:visited > label, *:link, button:link, button:visited { color: #1b6acb; }
|
||||
@@ -697,7 +701,9 @@ searchbar > revealer > box { padding: 6px; border-width: 0 0 1px; }
|
||||
|
||||
.default-decoration.titlebar:not(headerbar), headerbar.default-decoration { min-height: 28px; padding: 4px; }
|
||||
|
||||
.default-decoration.titlebar:not(headerbar) button.titlebutton, headerbar.default-decoration button.titlebutton { min-height: 26px; min-width: 26px; margin: 0; padding: 0; }
|
||||
.default-decoration.titlebar:not(headerbar) button.titlebutton, .default-decoration.titlebar:not(headerbar) menubutton.titlebutton, headerbar.default-decoration button.titlebutton, headerbar.default-decoration menubutton.titlebutton { min-height: 26px; min-width: 26px; margin: 0; padding: 0; }
|
||||
|
||||
.default-decoration.titlebar:not(headerbar) menubutton.titlebutton button, headerbar.default-decoration menubutton.titlebutton button { min-height: 20px; min-width: 20px; margin: 0; padding: 4px; }
|
||||
|
||||
.titlebar:not(headerbar) separator.titlebutton, headerbar separator.titlebutton { opacity: 0; }
|
||||
|
||||
@@ -820,9 +826,7 @@ menubar:backdrop, .menubar:backdrop { background-color: #f6f5f4; }
|
||||
|
||||
menubar > box > menuitem, .menubar > box > menuitem { min-height: 16px; padding: 4px 8px; }
|
||||
|
||||
menubar > box > menuitem menu, .menubar > box > menuitem menu { border-radius: 0; padding: 0; }
|
||||
|
||||
menubar > box > menuitem menu menu, .menubar > box > menuitem menu menu { border-radius: 0; padding: 0; }
|
||||
.csd menubar > box > menuitem menu, menubar > box > menuitem menu, .csd .menubar > box > menuitem menu, .menubar > box > menuitem menu { border-radius: 0; padding: 0; }
|
||||
|
||||
menubar > box > menuitem:hover, .menubar > box > menuitem:hover { box-shadow: inset 0 -3px #3584e4; color: #1b6acb; }
|
||||
|
||||
@@ -883,9 +887,9 @@ popover.menu > arrow, popover > arrow { background-color: #f6f5f4; border: 1px s
|
||||
|
||||
popover > contents { padding: 8px; background-color: #f6f5f4; border: 1px solid #cdc7c2; margin: 0px; }
|
||||
|
||||
popover > contents.background { border-radius: 9px; background-color: #f6f5f4; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); }
|
||||
popover > contents.background { background-color: #f6f5f4; box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); }
|
||||
|
||||
.csd popover > contents.background, popover > contents.background { border: 1px solid #cdc7c2; }
|
||||
.csd popover > contents.background, popover > contents.background { border: 1px solid #cdc7c2; border-radius: 9px; }
|
||||
|
||||
popover > contents.background:backdrop { background-color: #f6f5f4; box-shadow: none; }
|
||||
|
||||
@@ -1697,6 +1701,8 @@ messagedialog .titlebar { min-height: 20px; background-image: none; background-c
|
||||
|
||||
messagedialog box.dialog-vbox.vertical { border-spacing: 10px; }
|
||||
|
||||
messagedialog label.title { font-weight: 800; font-size: 15pt; }
|
||||
|
||||
messagedialog.csd.background { border-bottom-left-radius: 9px; border-bottom-right-radius: 9px; }
|
||||
|
||||
messagedialog.csd .dialog-action-area button { padding: 10px 14px; border-radius: 0; border-left-style: solid; border-right-style: none; border-bottom-style: none; }
|
||||
@@ -1820,33 +1826,35 @@ video image.osd { min-width: 64px; min-height: 64px; border-radius: 32px; }
|
||||
/************** GtkInfoBar * */
|
||||
infobar { border-style: none; }
|
||||
|
||||
infobar.info, infobar.question, infobar.warning, infobar.error { text-shadow: 0 1px #1b6acb; }
|
||||
infobar.info, infobar.question, infobar.warning, infobar.error { text-shadow: none; }
|
||||
|
||||
infobar.info:backdrop, infobar.info, infobar.question:backdrop, infobar.question, infobar.warning:backdrop, infobar.warning, infobar.error:backdrop, infobar.error { background-color: #3584e4; border-color: #1b6acb; }
|
||||
infobar.info:backdrop, infobar.info, infobar.question:backdrop, infobar.question, infobar.warning:backdrop, infobar.warning, infobar.error:backdrop, infobar.error { background-color: #f1e6d9; border-color: #e4e1de; }
|
||||
|
||||
infobar.info:backdrop label, infobar.info:backdrop, infobar.info label, infobar.info, infobar.question:backdrop label, infobar.question:backdrop, infobar.question label, infobar.question, infobar.warning:backdrop label, infobar.warning:backdrop, infobar.warning label, infobar.warning, infobar.error:backdrop label, infobar.error:backdrop, infobar.error label, infobar.error { color: #ffffff; }
|
||||
infobar.info:backdrop label, infobar.info:backdrop, infobar.info label, infobar.info, infobar.question:backdrop label, infobar.question:backdrop, infobar.question label, infobar.question, infobar.warning:backdrop label, infobar.warning:backdrop, infobar.warning label, infobar.warning, infobar.error:backdrop label, infobar.error:backdrop, infobar.error label, infobar.error { color: #2e3436; }
|
||||
|
||||
infobar.info:backdrop, infobar.question:backdrop, infobar.warning:backdrop, infobar.error:backdrop { text-shadow: none; }
|
||||
|
||||
infobar.info button, infobar.question button, infobar.warning button, infobar.error button { color: #ffffff; outline-color: rgba(255, 255, 255, 0.3); border-color: #1b6acb; border-bottom-color: #15539e; background-image: linear-gradient(to top, #2379e2 2px, #3584e4); text-shadow: 0 -1px rgba(0, 0, 0, 0.559216); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.559216); box-shadow: inset 0 1px rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.07); }
|
||||
infobar.info button, infobar.question button, infobar.warning button, infobar.error button { color: #2e3436; outline-color: rgba(46, 52, 54, 0.3); border-color: #cdc7c2; border-bottom-color: #bfb8b1; background-image: linear-gradient(to top, #edebe9 2px, #f6f5f4); text-shadow: 0 1px rgba(255, 255, 255, 0.769231); -gtk-icon-shadow: 0 1px rgba(255, 255, 255, 0.769231); box-shadow: inset 0 1px white, 0 1px 2px rgba(0, 0, 0, 0.07); }
|
||||
|
||||
infobar.info button:hover, infobar.question button:hover, infobar.warning button:hover, infobar.error button:hover { color: #ffffff; outline-color: rgba(255, 255, 255, 0.3); border-color: #1b6acb; border-bottom-color: #15539e; text-shadow: 0 -1px rgba(0, 0, 0, 0.511216); -gtk-icon-shadow: 0 -1px rgba(0, 0, 0, 0.511216); box-shadow: inset 0 1px rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.07); background-image: linear-gradient(to top, #3584e4, #3987e5 1px); }
|
||||
infobar.info button:hover, infobar.question button:hover, infobar.warning button:hover, infobar.error button:hover { color: #2e3436; outline-color: rgba(46, 52, 54, 0.3); border-color: #cdc7c2; border-bottom-color: #bfb8b1; text-shadow: 0 1px rgba(255, 255, 255, 0.769231); -gtk-icon-shadow: 0 1px rgba(255, 255, 255, 0.769231); box-shadow: inset 0 1px white, 0 1px 2px rgba(0, 0, 0, 0.07); background-image: linear-gradient(to top, #f6f5f4, #f8f8f7 1px); }
|
||||
|
||||
infobar.info button:active, infobar.info button:checked, infobar.question button:active, infobar.question button:checked, infobar.warning button:active, infobar.warning button:checked, infobar.error button:active, infobar.error button:checked { color: #ffffff; outline-color: rgba(255, 255, 255, 0.3); border-color: #1b6acb; background-image: image(#1961b9); box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
infobar.info button:active, infobar.info button:checked, infobar.question button:active, infobar.question button:checked, infobar.warning button:active, infobar.warning button:checked, infobar.error button:active, infobar.error button:checked { color: #2e3436; outline-color: rgba(46, 52, 54, 0.3); border-color: #cdc7c2; background-image: image(#d6d1cd); box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
|
||||
|
||||
infobar.info button:disabled, infobar.question button:disabled, infobar.warning button:disabled, infobar.error button:disabled { border-color: #1b6acb; background-image: image(#5396e8); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); }
|
||||
infobar.info button:disabled, infobar.question button:disabled, infobar.warning button:disabled, infobar.error button:disabled { border-color: #cdc7c2; background-image: image(#faf9f8); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); }
|
||||
|
||||
infobar.info button:disabled label, infobar.info button:disabled, infobar.question button:disabled label, infobar.question button:disabled, infobar.warning button:disabled label, infobar.warning button:disabled, infobar.error button:disabled label, infobar.error button:disabled { color: #a9cbf4; }
|
||||
infobar.info button:disabled label, infobar.info button:disabled, infobar.question button:disabled label, infobar.question button:disabled, infobar.warning button:disabled label, infobar.warning button:disabled, infobar.error button:disabled label, infobar.error button:disabled { color: #929595; }
|
||||
|
||||
infobar.info button:backdrop, infobar.question button:backdrop, infobar.warning button:backdrop, infobar.error button:backdrop { border-color: #3584e4; background-image: image(#3584e4); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); border-color: #1b6acb; }
|
||||
infobar.info button:backdrop, infobar.question button:backdrop, infobar.warning button:backdrop, infobar.error button:backdrop { border-color: #d5d0cc; background-image: image(#f6f5f4); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); border-color: #dfdcd8; }
|
||||
|
||||
infobar.info button:backdrop label, infobar.info button:backdrop, infobar.question button:backdrop label, infobar.question button:backdrop, infobar.warning button:backdrop label, infobar.warning button:backdrop, infobar.error button:backdrop label, infobar.error button:backdrop { color: #d7e6fa; }
|
||||
infobar.info button:backdrop label, infobar.info button:backdrop, infobar.question button:backdrop label, infobar.question button:backdrop, infobar.warning button:backdrop label, infobar.warning button:backdrop, infobar.error button:backdrop label, infobar.error button:backdrop { color: #929595; }
|
||||
|
||||
infobar.info button:backdrop:disabled, infobar.question button:backdrop:disabled, infobar.warning button:backdrop:disabled, infobar.error button:backdrop:disabled { border-color: #5396e8; background-image: image(#5396e8); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); border-color: #1b6acb; }
|
||||
infobar.info button:backdrop:disabled, infobar.question button:backdrop:disabled, infobar.warning button:backdrop:disabled, infobar.error button:backdrop:disabled { border-color: #d5d0cc; background-image: image(#faf9f8); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); border-color: #dfdcd8; }
|
||||
|
||||
infobar.info button:backdrop:disabled label, infobar.info button:backdrop:disabled, infobar.question button:backdrop:disabled label, infobar.question button:backdrop:disabled, infobar.warning button:backdrop:disabled label, infobar.warning button:backdrop:disabled, infobar.error button:backdrop:disabled label, infobar.error button:backdrop:disabled { color: #8fbbf0; }
|
||||
infobar.info button:backdrop:disabled label, infobar.info button:backdrop:disabled, infobar.question button:backdrop:disabled label, infobar.question button:backdrop:disabled, infobar.warning button:backdrop:disabled label, infobar.warning button:backdrop:disabled, infobar.error button:backdrop:disabled label, infobar.error button:backdrop:disabled { color: #d4cfca; }
|
||||
|
||||
infobar.info selection, infobar.question selection, infobar.warning selection, infobar.error selection { background-color: #1b6acb; }
|
||||
infobar.info button:backdrop label, infobar.info button:backdrop, infobar.info button label, infobar.info button, infobar.question button:backdrop label, infobar.question button:backdrop, infobar.question button label, infobar.question button, infobar.warning button:backdrop label, infobar.warning button:backdrop, infobar.warning button label, infobar.warning button, infobar.error button:backdrop label, infobar.error button:backdrop, infobar.error button label, infobar.error button { color: #2e3436; }
|
||||
|
||||
infobar.info selection, infobar.question selection, infobar.warning selection, infobar.error selection { background-color: #dfdcd8; }
|
||||
|
||||
/************ Tooltips * */
|
||||
tooltip { padding: 4px; border-radius: 5px; box-shadow: none; text-shadow: 0 1px black; }
|
||||
@@ -2051,6 +2059,42 @@ popover.emoji-completion .emoji:hover { background-color: white; }
|
||||
|
||||
popover.entry-completion contents { padding: 0; }
|
||||
|
||||
menubar { padding: 0px; box-shadow: inset 0 -1px rgba(0, 0, 0, 0.1); }
|
||||
|
||||
menubar:backdrop { background-color: #f6f5f4; }
|
||||
|
||||
menubar > item { min-height: 16px; padding: 4px 8px; }
|
||||
|
||||
menubar > item:selected { box-shadow: inset 0 -3px #3584e4; color: #1b6acb; }
|
||||
|
||||
menubar > item:disabled { color: #929595; box-shadow: none; }
|
||||
|
||||
menubar .csd.popup decoration { border-radius: 0; }
|
||||
|
||||
popover.menu button.flat.image-button.model { padding: 0; border: none; }
|
||||
|
||||
popover.menu button.flat.image-button.model:selected { border: none; color: #ffffff; background: #3584e4; }
|
||||
|
||||
popover.menu box.inline-buttons { border-radius: 5px; border-style: none; border-width: 0; border-image-source: none; border-image-width: 1px; }
|
||||
|
||||
popover.menu box.circular-buttons { padding-bottom: 5px; }
|
||||
|
||||
popover.menu.background contents { background: white; }
|
||||
|
||||
popover.menu.background separator { margin: 5px 0px; }
|
||||
|
||||
popover.menu accelerator { margin-left: 20px; color: gray; }
|
||||
|
||||
popover.menu box.inline-buttons { padding: 0 5px; }
|
||||
|
||||
popover.menu radio.left, popover.menu check.left { margin-left: 0; margin-right: 12px; }
|
||||
|
||||
popover.menu radio.right, popover.menu check.right { margin-left: 12px; margin-right: 0; }
|
||||
|
||||
popover.menu modelbutton:selected { color: #ffffff; background-color: #3584e4; }
|
||||
|
||||
popover.menu modelbutton:selected accelerator { color: silver; }
|
||||
|
||||
/* GTK NAMED COLORS ---------------- use responsibly! */
|
||||
/*
|
||||
widget text/foreground color */
|
||||
|
||||
@@ -217,6 +217,18 @@
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="list_type_column">
|
||||
<property name="title" translatable="yes">Type</property>
|
||||
<property name="resizable">1</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="list_type_renderer">
|
||||
<property name="xalign">0</property>
|
||||
<property name="xpad">6</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="list_time_column">
|
||||
<property name="title" translatable="yes">Modified</property>
|
||||
|
||||
+1
-1
@@ -694,7 +694,7 @@ if graphene_has_sse2 or graphene_has_gcc
|
||||
message('Need aligned memory due to the use of SSE2 or GCC vector instructions')
|
||||
|
||||
if os_win32 and cc.get_id() == 'gcc'
|
||||
add_global_arguments(['-mstackrealign'], language: 'c')
|
||||
add_project_arguments(['-mstackrealign'], language: 'c')
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
+5150
-5076
File diff suppressed because it is too large
Load Diff
+5506
-4938
File diff suppressed because it is too large
Load Diff
+547
-533
File diff suppressed because it is too large
Load Diff
+2358
-1915
File diff suppressed because it is too large
Load Diff
@@ -1666,7 +1666,6 @@ create_menus (GtkWidget *widget)
|
||||
GtkWidget *box1;
|
||||
GtkWidget *box2;
|
||||
GtkWidget *button;
|
||||
GtkWidget *optionmenu;
|
||||
GtkWidget *separator;
|
||||
GtkWidget *box;
|
||||
GtkWidget *label;
|
||||
@@ -1676,7 +1675,6 @@ create_menus (GtkWidget *widget)
|
||||
GtkWidget *menubar;
|
||||
GtkWidget *menu;
|
||||
GtkWidget *menuitem;
|
||||
GtkAccelGroup *accel_group;
|
||||
GtkWidget *image;
|
||||
GdkDisplay *display = gtk_widget_get_display (widget);
|
||||
|
||||
@@ -1687,9 +1685,6 @@ create_menus (GtkWidget *widget)
|
||||
|
||||
g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window);
|
||||
|
||||
accel_group = gtk_accel_group_new ();
|
||||
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
|
||||
|
||||
gtk_window_set_title (GTK_WINDOW (window), "menus");
|
||||
|
||||
box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
@@ -1732,44 +1727,6 @@ create_menus (GtkWidget *widget)
|
||||
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
|
||||
gtk_container_add (GTK_CONTAINER (box1), box2);
|
||||
|
||||
menu = create_menu (1, 5);
|
||||
gtk_menu_set_accel_group (GTK_MENU (menu), accel_group);
|
||||
|
||||
menuitem = gtk_check_menu_item_new_with_label ("Accelerate Me");
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
||||
gtk_widget_add_accelerator (menuitem,
|
||||
"activate",
|
||||
accel_group,
|
||||
GDK_KEY_F1,
|
||||
0,
|
||||
GTK_ACCEL_VISIBLE);
|
||||
menuitem = gtk_check_menu_item_new_with_label ("Accelerator Locked");
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
||||
gtk_widget_add_accelerator (menuitem,
|
||||
"activate",
|
||||
accel_group,
|
||||
GDK_KEY_F2,
|
||||
0,
|
||||
GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED);
|
||||
menuitem = gtk_check_menu_item_new_with_label ("Accelerators Frozen");
|
||||
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
||||
gtk_widget_add_accelerator (menuitem,
|
||||
"activate",
|
||||
accel_group,
|
||||
GDK_KEY_F2,
|
||||
0,
|
||||
GTK_ACCEL_VISIBLE);
|
||||
gtk_widget_add_accelerator (menuitem,
|
||||
"activate",
|
||||
accel_group,
|
||||
GDK_KEY_F3,
|
||||
0,
|
||||
GTK_ACCEL_VISIBLE);
|
||||
|
||||
optionmenu = gtk_combo_box_text_new ();
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (optionmenu), 3);
|
||||
gtk_container_add (GTK_CONTAINER (box2), optionmenu);
|
||||
|
||||
separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_container_add (GTK_CONTAINER (box1), separator);
|
||||
|
||||
|
||||
@@ -0,0 +1,430 @@
|
||||
/* Copyright (C) 2019 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static int win_activated;
|
||||
static int box_activated;
|
||||
|
||||
static void
|
||||
win_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
win_activated++;
|
||||
}
|
||||
|
||||
static void
|
||||
box_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
box_activated++;
|
||||
}
|
||||
|
||||
/* Test that inheriting actions along the widget
|
||||
* hierarchy works as expected. Since GtkWidget does
|
||||
* not expose the actions, we test this by observing
|
||||
* the effect of activating them.
|
||||
*/
|
||||
static void
|
||||
test_action (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *box;
|
||||
GtkWidget *button;
|
||||
GSimpleActionGroup *win_actions;
|
||||
GSimpleActionGroup *box_actions;
|
||||
GActionEntry win_entries[] = {
|
||||
{ "action", win_activate, NULL, NULL, NULL },
|
||||
};
|
||||
GActionEntry box_entries[] = {
|
||||
{ "action", box_activate, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
button = gtk_button_new ();
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
|
||||
win_actions = g_simple_action_group_new ();
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (win_actions),
|
||||
win_entries,
|
||||
G_N_ELEMENTS (win_entries),
|
||||
NULL);
|
||||
|
||||
box_actions = g_simple_action_group_new ();
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (box_actions),
|
||||
box_entries,
|
||||
G_N_ELEMENTS (box_entries),
|
||||
NULL);
|
||||
|
||||
gtk_widget_insert_action_group (window, "win", G_ACTION_GROUP (win_actions));
|
||||
gtk_widget_insert_action_group (box, "box", G_ACTION_GROUP (box_actions));
|
||||
|
||||
g_assert_cmpint (win_activated, ==, 0);
|
||||
g_assert_cmpint (box_activated, ==, 0);
|
||||
|
||||
gtk_widget_activate_action (button, "win.action", NULL);
|
||||
|
||||
g_assert_cmpint (win_activated, ==, 1);
|
||||
g_assert_cmpint (box_activated, ==, 0);
|
||||
|
||||
gtk_widget_activate_action (box, "win.action", NULL);
|
||||
|
||||
g_assert_cmpint (win_activated, ==, 2);
|
||||
g_assert_cmpint (box_activated, ==, 0);
|
||||
|
||||
gtk_widget_activate_action (button, "box.action", NULL);
|
||||
|
||||
g_assert_cmpint (win_activated, ==, 2);
|
||||
g_assert_cmpint (box_activated, ==, 1);
|
||||
|
||||
gtk_widget_activate_action (window, "box.action", NULL);
|
||||
|
||||
g_assert_cmpint (win_activated, ==, 2);
|
||||
g_assert_cmpint (box_activated, ==, 1);
|
||||
|
||||
gtk_widget_destroy (window);
|
||||
g_object_unref (win_actions);
|
||||
g_object_unref (box_actions);
|
||||
}
|
||||
|
||||
static int cut_activated;
|
||||
static int copy_activated;
|
||||
static int paste_activated;
|
||||
static int visibility_changed;
|
||||
|
||||
static void
|
||||
cut_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
cut_activated++;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
copy_activated++;
|
||||
}
|
||||
|
||||
static void
|
||||
paste_activate (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
paste_activated++;
|
||||
}
|
||||
|
||||
static void
|
||||
visibility_changed_cb (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
visibility_changed++;
|
||||
}
|
||||
|
||||
/* Spot-check that GtkText has the class actions
|
||||
* for the context menu. Here we test that the clipboard
|
||||
* actions are present, and that toggling visibility
|
||||
* via the action works.
|
||||
*/
|
||||
static void
|
||||
test_text (void)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GtkWidget *text;
|
||||
GSimpleActionGroup *clipboard_actions;
|
||||
GActionEntry clipboard_entries[] = {
|
||||
{ "cut", cut_activate, NULL, NULL, NULL },
|
||||
{ "copy", copy_activate, NULL, NULL, NULL },
|
||||
{ "paste", paste_activate, NULL, NULL, NULL },
|
||||
};
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
text = gtk_text_new ();
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (box), text);
|
||||
|
||||
clipboard_actions = g_simple_action_group_new ();
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (clipboard_actions),
|
||||
clipboard_entries,
|
||||
G_N_ELEMENTS (clipboard_entries),
|
||||
NULL);
|
||||
|
||||
gtk_widget_insert_action_group (box, "clipboard", G_ACTION_GROUP (clipboard_actions));
|
||||
|
||||
gtk_widget_activate_action (text, "cut.clipboard", NULL);
|
||||
gtk_widget_activate_action (text, "copy.clipboard", NULL);
|
||||
gtk_widget_activate_action (text, "paste.clipboard", NULL);
|
||||
|
||||
g_assert_cmpint (cut_activated, ==, 0);
|
||||
g_assert_cmpint (copy_activated, ==, 0);
|
||||
g_assert_cmpint (paste_activated, ==, 0);
|
||||
|
||||
g_signal_connect (text, "notify::visibility",
|
||||
G_CALLBACK (visibility_changed_cb), NULL);
|
||||
|
||||
gtk_widget_activate_action (text, "misc.toggle-visibility", NULL);
|
||||
|
||||
g_assert_cmpint (visibility_changed, ==, 1);
|
||||
|
||||
gtk_widget_destroy (box);
|
||||
g_object_unref (clipboard_actions);
|
||||
}
|
||||
|
||||
/* Test that inheritance works for individual actions
|
||||
* even if they are in groups with the same prefix.
|
||||
* This is a change from the way things work in GTK3.
|
||||
*/
|
||||
static void
|
||||
test_overlap (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *box;
|
||||
GActionEntry win_entries[] = {
|
||||
{ "win", win_activate, NULL, NULL, NULL },
|
||||
};
|
||||
GActionEntry box_entries[] = {
|
||||
{ "box", box_activate, NULL, NULL, NULL },
|
||||
};
|
||||
GSimpleActionGroup *win_actions;
|
||||
GSimpleActionGroup *box_actions;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (window), box);
|
||||
|
||||
win_actions = g_simple_action_group_new ();
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (win_actions),
|
||||
win_entries,
|
||||
G_N_ELEMENTS (win_entries),
|
||||
NULL);
|
||||
|
||||
box_actions = g_simple_action_group_new ();
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (box_actions),
|
||||
box_entries,
|
||||
G_N_ELEMENTS (box_entries),
|
||||
NULL);
|
||||
|
||||
gtk_widget_insert_action_group (window, "actions", G_ACTION_GROUP (win_actions));
|
||||
gtk_widget_insert_action_group (box, "actions", G_ACTION_GROUP (box_actions));
|
||||
|
||||
win_activated = 0;
|
||||
box_activated = 0;
|
||||
|
||||
gtk_widget_activate_action (box, "actions.win", NULL);
|
||||
|
||||
g_assert_cmpint (win_activated, ==, 1);
|
||||
g_assert_cmpint (box_activated, ==, 0);
|
||||
|
||||
gtk_widget_activate_action (box, "actions.box", NULL);
|
||||
|
||||
g_assert_cmpint (win_activated, ==, 1);
|
||||
g_assert_cmpint (box_activated, ==, 1);
|
||||
|
||||
gtk_widget_destroy (window);
|
||||
g_object_unref (win_actions);
|
||||
g_object_unref (box_actions);
|
||||
}
|
||||
|
||||
static int toggled;
|
||||
static int act1;
|
||||
static int act2;
|
||||
|
||||
static void
|
||||
visibility_toggled (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
{
|
||||
toggled++;
|
||||
}
|
||||
|
||||
static void
|
||||
activate1 (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
act1++;
|
||||
}
|
||||
|
||||
static void
|
||||
activate2 (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
act2++;
|
||||
}
|
||||
|
||||
/* Test that overlap also works as expected between
|
||||
* class action and inserted groups. Class actions
|
||||
* take precedence over inserted groups in the same
|
||||
* muxer, but inheritance works as normal between
|
||||
* muxers.
|
||||
*/
|
||||
static void
|
||||
test_overlap2 (void)
|
||||
{
|
||||
GtkWidget *text;
|
||||
GtkWidget *child;
|
||||
GSimpleActionGroup *group1;
|
||||
GSimpleActionGroup *group2;
|
||||
GActionEntry entries1[] = {
|
||||
{ "toggle-visibility", activate1, NULL, NULL, NULL },
|
||||
};
|
||||
GActionEntry entries2[] = {
|
||||
{ "toggle-visibility", activate2, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
text = gtk_text_new ();
|
||||
g_signal_connect (text, "notify::visibility",
|
||||
G_CALLBACK (visibility_toggled), NULL);
|
||||
|
||||
child = gtk_label_new ("");
|
||||
gtk_widget_set_parent (child, text);
|
||||
|
||||
g_assert_cmpint (toggled, ==, 0);
|
||||
g_assert_cmpint (act1, ==, 0);
|
||||
g_assert_cmpint (act2, ==, 0);
|
||||
|
||||
gtk_widget_activate_action (child, "misc.toggle-visibility", NULL);
|
||||
|
||||
g_assert_cmpint (toggled, ==, 1);
|
||||
g_assert_cmpint (act1, ==, 0);
|
||||
g_assert_cmpint (act2, ==, 0);
|
||||
|
||||
group1 = g_simple_action_group_new ();
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (group1),
|
||||
entries1,
|
||||
G_N_ELEMENTS (entries1),
|
||||
NULL);
|
||||
gtk_widget_insert_action_group (text, "misc", G_ACTION_GROUP (group1));
|
||||
gtk_widget_activate_action (child, "misc.toggle-visibility", NULL);
|
||||
|
||||
g_assert_cmpint (toggled, ==, 2);
|
||||
g_assert_cmpint (act1, ==, 0);
|
||||
g_assert_cmpint (act2, ==, 0);
|
||||
|
||||
group2 = g_simple_action_group_new ();
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (group2),
|
||||
entries2,
|
||||
G_N_ELEMENTS (entries2),
|
||||
NULL);
|
||||
gtk_widget_insert_action_group (child, "misc", G_ACTION_GROUP (group2));
|
||||
|
||||
gtk_widget_activate_action (child, "misc.toggle-visibility", NULL);
|
||||
|
||||
g_assert_cmpint (toggled, ==, 2);
|
||||
g_assert_cmpint (act1, ==, 0);
|
||||
g_assert_cmpint (act2, ==, 1);
|
||||
|
||||
gtk_widget_destroy (text);
|
||||
g_object_unref (group1);
|
||||
g_object_unref (group2);
|
||||
}
|
||||
|
||||
/* Test that gtk_widget_class_query_action
|
||||
* yields the expected results
|
||||
*/
|
||||
static void
|
||||
test_introspection (void)
|
||||
{
|
||||
GtkWidgetClass *class = g_type_class_ref (GTK_TYPE_TEXT);
|
||||
guint i;
|
||||
GType owner;
|
||||
const char *name;
|
||||
const GVariantType *params;
|
||||
const char *property;
|
||||
struct {
|
||||
GType owner;
|
||||
const char *name;
|
||||
const char *params;
|
||||
const char *property;
|
||||
} expected[] = {
|
||||
{ GTK_TYPE_TEXT, "clipboard.cut", NULL, NULL },
|
||||
{ GTK_TYPE_TEXT, "clipboard.copy", NULL, NULL },
|
||||
{ GTK_TYPE_TEXT, "clipboard.paste", NULL, NULL },
|
||||
{ GTK_TYPE_TEXT, "selection.delete", NULL, NULL },
|
||||
{ GTK_TYPE_TEXT, "selection.select-all", NULL, NULL },
|
||||
{ GTK_TYPE_TEXT, "misc.insert-emoji", NULL, NULL },
|
||||
{ GTK_TYPE_TEXT, "misc.toggle-visibility", NULL, "visibility" },
|
||||
};
|
||||
|
||||
i = 0;
|
||||
while (gtk_widget_class_query_action (class,
|
||||
i,
|
||||
&owner,
|
||||
&name,
|
||||
¶ms,
|
||||
&property))
|
||||
{
|
||||
g_assert (expected[i].owner == owner);
|
||||
g_assert (strcmp (expected[i].name, name) == 0);
|
||||
g_assert ((expected[i].params == NULL && params == NULL) ||
|
||||
strcmp (expected[i].params, g_variant_type_peek_string (params)) == 0);
|
||||
g_assert ((expected[i].property == NULL && property == NULL) ||
|
||||
strcmp (expected[i].property, property) == 0);
|
||||
i++;
|
||||
}
|
||||
g_assert (i == G_N_ELEMENTS (expected));
|
||||
|
||||
g_type_class_unref (class);
|
||||
}
|
||||
|
||||
/* Test that disabled actions don't get activated */
|
||||
static void
|
||||
test_enabled (void)
|
||||
{
|
||||
GtkWidget *text;
|
||||
|
||||
text = gtk_text_new ();
|
||||
g_signal_connect (text, "notify::visibility",
|
||||
G_CALLBACK (visibility_toggled), NULL);
|
||||
|
||||
toggled = 0;
|
||||
|
||||
gtk_widget_activate_action (text, "misc.toggle-visibility", NULL);
|
||||
|
||||
g_assert_cmpint (toggled, ==, 1);
|
||||
|
||||
gtk_widget_action_set_enabled (text, "misc.toggle-visibility", FALSE);
|
||||
|
||||
gtk_widget_activate_action (text, "misc.toggle-visibility", NULL);
|
||||
|
||||
g_assert_cmpint (toggled, ==, 1);
|
||||
|
||||
gtk_widget_destroy (text);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
gtk_test_init (&argc, &argv);
|
||||
|
||||
g_test_add_func ("/action/inheritance", test_action);
|
||||
g_test_add_func ("/action/text", test_text);
|
||||
g_test_add_func ("/action/overlap", test_overlap);
|
||||
g_test_add_func ("/action/overlap2", test_overlap2);
|
||||
g_test_add_func ("/action/introspection", test_introspection);
|
||||
g_test_add_func ("/action/enabled", test_enabled);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
#include <locale.h>
|
||||
|
||||
#include "../../gtk/gtkconstrainttypesprivate.h"
|
||||
#include "../../gtk/gtkconstraintsolverprivate.h"
|
||||
#include "../../gtk/gtkconstraintexpressionprivate.h"
|
||||
|
||||
static void
|
||||
constraint_solver_simple (void)
|
||||
{
|
||||
GtkConstraintSolver *solver = gtk_constraint_solver_new ();
|
||||
|
||||
GtkConstraintVariable *x = gtk_constraint_solver_create_variable (solver, NULL, "x", 167.0);
|
||||
GtkConstraintVariable *y = gtk_constraint_solver_create_variable (solver, NULL, "y", 2.0);
|
||||
|
||||
GtkConstraintExpression *e = gtk_constraint_expression_new_from_variable (y);
|
||||
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
x, GTK_CONSTRAINT_RELATION_EQ, e,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
double x_value = gtk_constraint_variable_get_value (x);
|
||||
double y_value = gtk_constraint_variable_get_value (y);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (x_value, y_value, 0.001);
|
||||
g_assert_cmpfloat_with_epsilon (x_value, 0.0, 0.001);
|
||||
g_assert_cmpfloat_with_epsilon (y_value, 0.0, 0.001);
|
||||
|
||||
gtk_constraint_variable_unref (y);
|
||||
gtk_constraint_variable_unref (x);
|
||||
|
||||
g_object_unref (solver);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_solver_stay (void)
|
||||
{
|
||||
GtkConstraintSolver *solver = gtk_constraint_solver_new ();
|
||||
|
||||
GtkConstraintVariable *x = gtk_constraint_solver_create_variable (solver, NULL, "x", 5.0);
|
||||
GtkConstraintVariable *y = gtk_constraint_solver_create_variable (solver, NULL, "y", 10.0);
|
||||
|
||||
gtk_constraint_solver_add_stay_variable (solver, x, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
gtk_constraint_solver_add_stay_variable (solver, y, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
|
||||
double x_value = gtk_constraint_variable_get_value (x);
|
||||
double y_value = gtk_constraint_variable_get_value (y);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (x_value, 5.0, 0.001);
|
||||
g_assert_cmpfloat_with_epsilon (y_value, 10.0, 0.001);
|
||||
|
||||
gtk_constraint_variable_unref (x);
|
||||
gtk_constraint_variable_unref (y);
|
||||
|
||||
g_object_unref (solver);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_solver_variable_geq_constant (void)
|
||||
{
|
||||
GtkConstraintSolver *solver = gtk_constraint_solver_new ();
|
||||
|
||||
GtkConstraintVariable *x = gtk_constraint_solver_create_variable (solver, NULL, "x", 10.0);
|
||||
GtkConstraintExpression *e = gtk_constraint_expression_new (100.0);
|
||||
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
x, GTK_CONSTRAINT_RELATION_GE, e,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
double x_value = gtk_constraint_variable_get_value (x);
|
||||
|
||||
g_assert_cmpfloat (x_value, >=, 100.0);
|
||||
|
||||
gtk_constraint_variable_unref (x);
|
||||
|
||||
g_object_unref (solver);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_solver_variable_leq_constant (void)
|
||||
{
|
||||
GtkConstraintSolver *solver = gtk_constraint_solver_new ();
|
||||
|
||||
GtkConstraintVariable *x = gtk_constraint_solver_create_variable (solver, NULL, "x", 100.0);
|
||||
GtkConstraintExpression *e = gtk_constraint_expression_new (10.0);
|
||||
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
x, GTK_CONSTRAINT_RELATION_LE, e,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
double x_value = gtk_constraint_variable_get_value (x);
|
||||
|
||||
g_assert_cmpfloat (x_value, <=, 10.0);
|
||||
|
||||
gtk_constraint_variable_unref (x);
|
||||
|
||||
g_object_unref (solver);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_solver_variable_eq_constant (void)
|
||||
{
|
||||
GtkConstraintSolver *solver = gtk_constraint_solver_new ();
|
||||
|
||||
GtkConstraintVariable *x = gtk_constraint_solver_create_variable (solver, NULL, "x", 10.0);
|
||||
GtkConstraintExpression *e = gtk_constraint_expression_new (100.0);
|
||||
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
x, GTK_CONSTRAINT_RELATION_EQ, e,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
double x_value = gtk_constraint_variable_get_value (x);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (x_value, 100.0, 0.001);
|
||||
|
||||
gtk_constraint_variable_unref (x);
|
||||
|
||||
g_object_unref (solver);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_solver_eq_with_stay (void)
|
||||
{
|
||||
GtkConstraintSolver *solver = gtk_constraint_solver_new ();
|
||||
|
||||
GtkConstraintVariable *x = gtk_constraint_solver_create_variable (solver, NULL, "x", 10.0);
|
||||
GtkConstraintVariable *width = gtk_constraint_solver_create_variable (solver, NULL, "width", 10.0);
|
||||
GtkConstraintVariable *right_min = gtk_constraint_solver_create_variable (solver, NULL, "rightMin", 100.0);
|
||||
|
||||
GtkConstraintExpressionBuilder builder;
|
||||
gtk_constraint_expression_builder_init (&builder, solver);
|
||||
gtk_constraint_expression_builder_term (&builder, x);
|
||||
gtk_constraint_expression_builder_plus (&builder);
|
||||
gtk_constraint_expression_builder_term (&builder, width);
|
||||
GtkConstraintExpression *right = gtk_constraint_expression_builder_finish (&builder);
|
||||
|
||||
gtk_constraint_solver_add_stay_variable (solver, width, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
gtk_constraint_solver_add_stay_variable (solver, right_min, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
right_min, GTK_CONSTRAINT_RELATION_EQ, right,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
double x_value = gtk_constraint_variable_get_value (x);
|
||||
double width_value = gtk_constraint_variable_get_value (width);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (x_value, 90.0, 0.001);
|
||||
g_assert_cmpfloat_with_epsilon (width_value, 10.0, 0.001);
|
||||
|
||||
gtk_constraint_variable_unref (right_min);
|
||||
gtk_constraint_variable_unref (width);
|
||||
gtk_constraint_variable_unref (x);
|
||||
|
||||
g_object_unref (solver);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_solver_cassowary (void)
|
||||
{
|
||||
GtkConstraintSolver *solver = gtk_constraint_solver_new ();
|
||||
|
||||
GtkConstraintVariable *x = gtk_constraint_solver_create_variable (solver, NULL, "x", 0.0);
|
||||
GtkConstraintVariable *y = gtk_constraint_solver_create_variable (solver, NULL, "y", 0.0);
|
||||
|
||||
GtkConstraintExpression *e;
|
||||
|
||||
e = gtk_constraint_expression_new_from_variable (y);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
x, GTK_CONSTRAINT_RELATION_LE, e,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
e = gtk_constraint_expression_plus_constant (gtk_constraint_expression_new_from_variable (x), 3.0);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
y, GTK_CONSTRAINT_RELATION_EQ, e,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
e = gtk_constraint_expression_new (10.0);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
x, GTK_CONSTRAINT_RELATION_EQ, e,
|
||||
GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
|
||||
e = gtk_constraint_expression_new (10.0);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
y, GTK_CONSTRAINT_RELATION_EQ, e,
|
||||
GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
|
||||
double x_val = gtk_constraint_variable_get_value (x);
|
||||
double y_val = gtk_constraint_variable_get_value (y);
|
||||
|
||||
g_test_message ("x = %g, y = %g", x_val, y_val);
|
||||
|
||||
/* The system is unstable and has two possible solutions we need to test */
|
||||
g_assert_true ((G_APPROX_VALUE (x_val, 10.0, 1e-8) &&
|
||||
G_APPROX_VALUE (y_val, 13.0, 1e-8)) ||
|
||||
(G_APPROX_VALUE (x_val, 7.0, 1e-8) &&
|
||||
G_APPROX_VALUE (y_val, 10.0, 1e-8)));
|
||||
|
||||
gtk_constraint_variable_unref (x);
|
||||
gtk_constraint_variable_unref (y);
|
||||
|
||||
g_object_unref (solver);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_solver_edit_var_required (void)
|
||||
{
|
||||
GtkConstraintSolver *solver = gtk_constraint_solver_new ();
|
||||
|
||||
GtkConstraintVariable *a = gtk_constraint_solver_create_variable (solver, NULL, "a", 0.0);
|
||||
gtk_constraint_solver_add_stay_variable (solver, a, GTK_CONSTRAINT_WEIGHT_STRONG);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (a), 0.0, 0.001);
|
||||
|
||||
gtk_constraint_solver_add_edit_variable (solver, a, GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
gtk_constraint_solver_begin_edit (solver);
|
||||
gtk_constraint_solver_suggest_value (solver, a, 2.0);
|
||||
gtk_constraint_solver_resolve (solver);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (a), 2.0, 0.001);
|
||||
|
||||
gtk_constraint_solver_suggest_value (solver, a, 10.0);
|
||||
gtk_constraint_solver_resolve (solver);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (a), 10.0, 0.001);
|
||||
|
||||
gtk_constraint_solver_end_edit (solver);
|
||||
|
||||
gtk_constraint_variable_unref (a);
|
||||
|
||||
g_object_unref (solver);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_solver_edit_var_suggest (void)
|
||||
{
|
||||
GtkConstraintSolver *solver = gtk_constraint_solver_new ();
|
||||
|
||||
GtkConstraintVariable *a = gtk_constraint_solver_create_variable (solver, NULL, "a", 0.0);
|
||||
GtkConstraintVariable *b = gtk_constraint_solver_create_variable (solver, NULL, "b", 0.0);
|
||||
|
||||
gtk_constraint_solver_add_stay_variable (solver, a, GTK_CONSTRAINT_WEIGHT_STRONG);
|
||||
|
||||
GtkConstraintExpression *e = gtk_constraint_expression_new_from_variable (b);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
a, GTK_CONSTRAINT_RELATION_EQ, e,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
gtk_constraint_solver_resolve (solver);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (a), 0.0, 0.001);
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (b), 0.0, 0.001);
|
||||
|
||||
gtk_constraint_solver_add_edit_variable (solver, a, GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
gtk_constraint_solver_begin_edit (solver);
|
||||
|
||||
gtk_constraint_solver_suggest_value (solver, a, 2.0);
|
||||
gtk_constraint_solver_resolve (solver);
|
||||
|
||||
g_test_message ("Check values after first edit");
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (a), 2.0, 0.001);
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (b), 2.0, 0.001);
|
||||
|
||||
gtk_constraint_solver_suggest_value (solver, a, 10.0);
|
||||
gtk_constraint_solver_resolve (solver);
|
||||
|
||||
g_test_message ("Check values after second edit");
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (a), 10.0, 0.001);
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (b), 10.0, 0.001);
|
||||
|
||||
gtk_constraint_solver_suggest_value (solver, a, 12.0);
|
||||
gtk_constraint_solver_resolve (solver);
|
||||
|
||||
g_test_message ("Check values after third edit");
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (a), 12.0, 0.001);
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (b), 12.0, 0.001);
|
||||
|
||||
gtk_constraint_variable_unref (a);
|
||||
gtk_constraint_variable_unref (b);
|
||||
|
||||
g_object_unref (solver);
|
||||
}
|
||||
|
||||
static void
|
||||
constraint_solver_paper (void)
|
||||
{
|
||||
GtkConstraintSolver *solver = gtk_constraint_solver_new ();
|
||||
|
||||
GtkConstraintVariable *left = gtk_constraint_solver_create_variable (solver, NULL, "left", 0.0);
|
||||
GtkConstraintVariable *middle = gtk_constraint_solver_create_variable (solver, NULL, "middle", 0.0);
|
||||
GtkConstraintVariable *right = gtk_constraint_solver_create_variable (solver, NULL, "right", 0.0);
|
||||
|
||||
GtkConstraintExpressionBuilder builder;
|
||||
GtkConstraintExpression *expr;
|
||||
|
||||
gtk_constraint_expression_builder_init (&builder, solver);
|
||||
gtk_constraint_expression_builder_term (&builder, left);
|
||||
gtk_constraint_expression_builder_plus (&builder);
|
||||
gtk_constraint_expression_builder_term (&builder, right);
|
||||
gtk_constraint_expression_builder_divide_by (&builder);
|
||||
gtk_constraint_expression_builder_constant (&builder, 2.0);
|
||||
expr = gtk_constraint_expression_builder_finish (&builder);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
middle, GTK_CONSTRAINT_RELATION_EQ, expr,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
gtk_constraint_expression_builder_init (&builder, solver);
|
||||
gtk_constraint_expression_builder_term (&builder, left);
|
||||
gtk_constraint_expression_builder_plus (&builder);
|
||||
gtk_constraint_expression_builder_constant (&builder, 10.0);
|
||||
expr = gtk_constraint_expression_builder_finish (&builder);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
right, GTK_CONSTRAINT_RELATION_EQ, expr,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
expr = gtk_constraint_expression_new (100.0);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
right, GTK_CONSTRAINT_RELATION_LE, expr,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
expr = gtk_constraint_expression_new (0.0);
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
left, GTK_CONSTRAINT_RELATION_GE, expr,
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
|
||||
g_test_message ("Check constraints hold");
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (middle),
|
||||
(gtk_constraint_variable_get_value (left) + gtk_constraint_variable_get_value (right)) / 2.0,
|
||||
0.001);
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (right),
|
||||
gtk_constraint_variable_get_value (left) + 10.0,
|
||||
0.001);
|
||||
g_assert_cmpfloat (gtk_constraint_variable_get_value (right), <=, 100.0);
|
||||
g_assert_cmpfloat (gtk_constraint_variable_get_value (left), >=, 0.0);
|
||||
|
||||
gtk_constraint_variable_set_value (middle, 45.0);
|
||||
gtk_constraint_solver_add_stay_variable (solver, middle, GTK_CONSTRAINT_WEIGHT_WEAK);
|
||||
|
||||
g_test_message ("Check constraints hold after setting middle");
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (middle),
|
||||
(gtk_constraint_variable_get_value (left) + gtk_constraint_variable_get_value (right)) / 2.0,
|
||||
0.001);
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (right),
|
||||
gtk_constraint_variable_get_value (left) + 10.0,
|
||||
0.001);
|
||||
g_assert_cmpfloat (gtk_constraint_variable_get_value (right), <=, 100.0);
|
||||
g_assert_cmpfloat (gtk_constraint_variable_get_value (left), >=, 0.0);
|
||||
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (left), 40.0, 0.001);
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (middle), 45.0, 0.001);
|
||||
g_assert_cmpfloat_with_epsilon (gtk_constraint_variable_get_value (right), 50.0, 0.001);
|
||||
|
||||
gtk_constraint_variable_unref (left);
|
||||
gtk_constraint_variable_unref (middle);
|
||||
gtk_constraint_variable_unref (right);
|
||||
|
||||
g_object_unref (solver);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
setlocale (LC_ALL, "C");
|
||||
|
||||
g_test_add_func ("/constraint-solver/paper", constraint_solver_paper);
|
||||
g_test_add_func ("/constraint-solver/simple", constraint_solver_simple);
|
||||
g_test_add_func ("/constraint-solver/constant/eq", constraint_solver_variable_eq_constant);
|
||||
g_test_add_func ("/constraint-solver/constant/ge", constraint_solver_variable_geq_constant);
|
||||
g_test_add_func ("/constraint-solver/constant/le", constraint_solver_variable_leq_constant);
|
||||
g_test_add_func ("/constraint-solver/stay/simple", constraint_solver_stay);
|
||||
g_test_add_func ("/constraint-solver/stay/eq", constraint_solver_eq_with_stay);
|
||||
g_test_add_func ("/constraint-solver/cassowary", constraint_solver_cassowary);
|
||||
g_test_add_func ("/constraint-solver/edit/required", constraint_solver_edit_var_required);
|
||||
g_test_add_func ("/constraint-solver/edit/suggest", constraint_solver_edit_var_suggest);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
@@ -8,15 +8,20 @@ if cc.get_id() != 'msvc'
|
||||
endif
|
||||
|
||||
tests = [
|
||||
['popover'],
|
||||
['accel'],
|
||||
['accessible'],
|
||||
['action'],
|
||||
['adjustment'],
|
||||
['bitmask', ['../../gtk/gtkallocatedbitmask.c'], ['-DGTK_COMPILATION', '-UG_ENABLE_DEBUG']],
|
||||
['builder', [], [], gtk_tests_export_dynamic_ldflag],
|
||||
['builderparser'],
|
||||
['cellarea'],
|
||||
['check-icon-names'],
|
||||
['constraint-solver', [
|
||||
'../../gtk/gtkconstraintsolver.c',
|
||||
'../../gtk/gtkconstraintexpression.c',
|
||||
], ['-DGTK_COMPILATION', '-UG_ENABLE_DEBUG']
|
||||
],
|
||||
['cssprovider'],
|
||||
['rbtree-crash', ['../../gtk/gtkrbtree.c'], ['-DGTK_COMPILATION', '-UG_ENABLE_DEBUG']],
|
||||
['defaultvalue'],
|
||||
@@ -39,6 +44,7 @@ tests = [
|
||||
['object'],
|
||||
['objects-finalize'],
|
||||
['papersize'],
|
||||
['popover'],
|
||||
['propertylookuplistmodel', ['../../gtk/gtkpropertylookuplistmodel.c'], ['-DGTK_COMPILATION', '-UG_ENABLE_DEBUG']],
|
||||
['rbtree', ['../../gtk/gtktreerbtree.c'], ['-DGTK_COMPILATION', '-UG_ENABLE_DEBUG']],
|
||||
['recentmanager'],
|
||||
|
||||
Reference in New Issue
Block a user