Compare commits
154 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f2f5db449 | |||
| 783ce4c870 | |||
| 761e2ae5e0 | |||
| 013c18040a | |||
| 3e0d6bdd9a | |||
| 129030a0dc | |||
| 695b4a6cae | |||
| 7bfb369fa3 | |||
| 85fbd2c3b7 | |||
| 7e11df9154 | |||
| aed7d32cde | |||
| 49897bdce8 | |||
| ad087634fd | |||
| 7a190da5f4 | |||
| b236cab3ba | |||
| 1e46874eb0 | |||
| 043fed8612 | |||
| b0824a5784 | |||
| 469da877d7 | |||
| 6ecaa45fb8 | |||
| 7beca2a33a | |||
| d5f77b10b9 | |||
| 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 | |||
| 97ba872ef3 | |||
| a5c327bb02 | |||
| bda5a8214b | |||
| 3ad8797068 | |||
| 2457ed03c2 | |||
| 4623642925 | |||
| 75713a9e47 | |||
| cc667926d6 | |||
| bc56860fa1 | |||
| 820929958d | |||
| 72d306c132 | |||
| 9bb2d1eb5c | |||
| d2e0d3222f | |||
| 44970b5182 | |||
| 00c828e752 | |||
| 3b565d7f6e | |||
| db7f0189dd | |||
| d2a794b411 | |||
| 8cfdd6c591 | |||
| 732630e0e2 |
@@ -0,0 +1,281 @@
|
||||
/* 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 = gtk_constraint_guide_new ();
|
||||
gtk_constraint_guide_set_name (guide, "space");
|
||||
gtk_constraint_guide_set_min_size (guide, 10, 10);
|
||||
gtk_constraint_guide_set_nat_size (guide, 100, 10);
|
||||
gtk_constraint_guide_set_max_size (guide, 200, 20);
|
||||
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,11 +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_get_action_group
|
||||
gtk_widget_activate_action
|
||||
gtk_widget_activate_default
|
||||
gtk_widget_measure
|
||||
gtk_widget_snapshot_child
|
||||
gtk_widget_get_next_sibling
|
||||
@@ -4630,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
|
||||
@@ -5196,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>
|
||||
|
||||
+351
-42
@@ -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
|
||||
};
|
||||
|
||||
@@ -102,23 +110,18 @@ typedef struct
|
||||
} Group;
|
||||
|
||||
static void
|
||||
gtk_action_muxer_append_group_actions (gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data)
|
||||
gtk_action_muxer_append_group_actions (const char *prefix,
|
||||
Group *group,
|
||||
GHashTable *actions)
|
||||
{
|
||||
const gchar *prefix = key;
|
||||
Group *group = value;
|
||||
GArray *actions = user_data;
|
||||
gchar **group_actions;
|
||||
gchar **action;
|
||||
|
||||
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);
|
||||
@@ -128,18 +131,40 @@ 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)
|
||||
{
|
||||
g_hash_table_foreach (muxer->groups,
|
||||
gtk_action_muxer_append_group_actions,
|
||||
actions);
|
||||
GHashTableIter iter;
|
||||
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 *
|
||||
@@ -149,6 +174,7 @@ gtk_action_muxer_find_group (GtkActionMuxer *muxer,
|
||||
{
|
||||
const gchar *dot;
|
||||
gchar *prefix;
|
||||
const char *name;
|
||||
Group *group;
|
||||
|
||||
dot = strchr (full_name, '.');
|
||||
@@ -156,17 +182,37 @@ 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;
|
||||
}
|
||||
|
||||
static void
|
||||
GActionGroup *
|
||||
gtk_action_muxer_find (GtkActionMuxer *muxer,
|
||||
const char *action_name,
|
||||
const char **unprefixed_name)
|
||||
{
|
||||
Group *group;
|
||||
|
||||
group = gtk_action_muxer_find_group (muxer, action_name, unprefixed_name);
|
||||
if (group)
|
||||
return group->group;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_action_muxer_action_enabled_changed (GtkActionMuxer *muxer,
|
||||
const gchar *action_name,
|
||||
gboolean enabled)
|
||||
@@ -174,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);
|
||||
@@ -206,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)
|
||||
@@ -371,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,
|
||||
@@ -384,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)
|
||||
@@ -407,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)
|
||||
@@ -424,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)
|
||||
@@ -548,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);
|
||||
@@ -565,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,
|
||||
@@ -579,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);
|
||||
}
|
||||
@@ -598,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);
|
||||
}
|
||||
@@ -631,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;
|
||||
|
||||
@@ -651,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);
|
||||
}
|
||||
|
||||
@@ -742,35 +1064,21 @@ gtk_action_muxer_remove (GtkActionMuxer *muxer,
|
||||
}
|
||||
}
|
||||
|
||||
const gchar **
|
||||
gtk_action_muxer_list_prefixes (GtkActionMuxer *muxer)
|
||||
{
|
||||
return (const gchar **) g_hash_table_get_keys_as_array (muxer->groups, NULL);
|
||||
}
|
||||
|
||||
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 >
|
||||
@@ -959,3 +1267,4 @@ gtk_normalise_detailed_action_name (const gchar *detailed_action_name)
|
||||
|
||||
return action_and_target;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,9 +54,9 @@ void gtk_action_muxer_insert (GtkActi
|
||||
|
||||
void gtk_action_muxer_remove (GtkActionMuxer *muxer,
|
||||
const gchar *prefix);
|
||||
const gchar ** gtk_action_muxer_list_prefixes (GtkActionMuxer *muxer);
|
||||
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);
|
||||
GtkActionMuxer * gtk_action_muxer_get_parent (GtkActionMuxer *muxer);
|
||||
|
||||
void gtk_action_muxer_set_parent (GtkActionMuxer *muxer,
|
||||
@@ -56,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
|
||||
@@ -0,0 +1,540 @@
|
||||
/* gtkconstraintguide.c: Flexible space for constraints
|
||||
* Copyright 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.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: Matthias Clasen
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkconstraintguide.h"
|
||||
|
||||
#include "gtkconstraintguideprivate.h"
|
||||
#include "gtkconstraintlayoutprivate.h"
|
||||
#include "gtkconstraintexpressionprivate.h"
|
||||
#include "gtkconstraintsolverprivate.h"
|
||||
|
||||
#include "gtkdebug.h"
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
MIN_WIDTH,
|
||||
MIN_HEIGHT,
|
||||
NAT_WIDTH,
|
||||
NAT_HEIGHT,
|
||||
MAX_WIDTH,
|
||||
MAX_HEIGHT,
|
||||
LAST_VALUE
|
||||
} GuideValue;
|
||||
|
||||
struct _GtkConstraintGuide
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
char *name;
|
||||
|
||||
int values[LAST_VALUE];
|
||||
|
||||
GtkConstraintLayout *layout;
|
||||
|
||||
/* HashTable<static string, Variable>; a hash table of variables,
|
||||
* one for each attribute; we use these to query and suggest the
|
||||
* values for the solver. The string is static and does not need
|
||||
* to be freed.
|
||||
*/
|
||||
GHashTable *bound_attributes;
|
||||
|
||||
GtkConstraintRef *constraints[LAST_VALUE];
|
||||
};
|
||||
|
||||
|
||||
struct _GtkConstraintGuideClass {
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_MIN_WIDTH = 1,
|
||||
PROP_MIN_HEIGHT,
|
||||
PROP_NAT_WIDTH,
|
||||
PROP_NAT_HEIGHT,
|
||||
PROP_MAX_WIDTH,
|
||||
PROP_MAX_HEIGHT,
|
||||
PROP_NAME,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static GParamSpec *guide_props[LAST_PROP];
|
||||
|
||||
static void
|
||||
gtk_constraint_guide_constraint_target_iface_init (GtkConstraintTargetInterface *iface)
|
||||
{
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkConstraintGuide, gtk_constraint_guide, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_CONSTRAINT_TARGET,
|
||||
gtk_constraint_guide_constraint_target_iface_init))
|
||||
|
||||
static void
|
||||
gtk_constraint_guide_init (GtkConstraintGuide *guide)
|
||||
{
|
||||
guide->bound_attributes =
|
||||
g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL,
|
||||
(GDestroyNotify) gtk_constraint_variable_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_guide_update_constraint (GtkConstraintGuide *guide,
|
||||
GuideValue index)
|
||||
{
|
||||
GtkConstraintSolver *solver;
|
||||
GtkConstraintVariable *var;
|
||||
int attr[LAST_VALUE] = {
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_WIDTH,
|
||||
GTK_CONSTRAINT_ATTRIBUTE_HEIGHT,
|
||||
};
|
||||
int relation[LAST_VALUE] = {
|
||||
GTK_CONSTRAINT_RELATION_GE,
|
||||
GTK_CONSTRAINT_RELATION_GE,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_RELATION_EQ,
|
||||
GTK_CONSTRAINT_RELATION_LE,
|
||||
GTK_CONSTRAINT_RELATION_LE,
|
||||
};
|
||||
|
||||
if (!guide->layout)
|
||||
return;
|
||||
|
||||
solver = gtk_constraint_layout_get_solver (guide->layout);
|
||||
if (!solver)
|
||||
return;
|
||||
|
||||
if (guide->constraints[index] != NULL)
|
||||
gtk_constraint_solver_remove_constraint (solver, guide->constraints[index]);
|
||||
|
||||
var = gtk_constraint_layout_get_attribute (guide->layout, attr[index], "guide", NULL, guide->bound_attributes);
|
||||
if (relation[index] == GTK_CONSTRAINT_RELATION_EQ)
|
||||
{
|
||||
gtk_constraint_variable_set_value (var, guide->values[index]);
|
||||
guide->constraints[index] =
|
||||
gtk_constraint_solver_add_stay_variable (solver,
|
||||
var,
|
||||
GTK_CONSTRAINT_WEIGHT_MEDIUM);
|
||||
}
|
||||
else
|
||||
{
|
||||
guide->constraints[index] =
|
||||
gtk_constraint_solver_add_constraint (solver,
|
||||
var,
|
||||
relation[index],
|
||||
gtk_constraint_expression_new (guide->values[index]),
|
||||
GTK_CONSTRAINT_WEIGHT_REQUIRED);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gtk_constraint_guide_update (GtkConstraintGuide *guide)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < LAST_VALUE; i++)
|
||||
gtk_constraint_guide_update_constraint (guide, i);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_constraint_guide_detach (GtkConstraintGuide *guide)
|
||||
{
|
||||
GtkConstraintSolver *solver;
|
||||
int i;
|
||||
|
||||
if (!guide->layout)
|
||||
return;
|
||||
|
||||
solver = gtk_constraint_layout_get_solver (guide->layout);
|
||||
if (!solver)
|
||||
return;
|
||||
|
||||
for (i = 0; i < LAST_VALUE; i++)
|
||||
{
|
||||
gtk_constraint_solver_remove_constraint (solver, guide->constraints[i]);
|
||||
guide->constraints[i] = NULL;
|
||||
}
|
||||
|
||||
g_hash_table_remove_all (guide->bound_attributes);
|
||||
}
|
||||
|
||||
GtkConstraintVariable *
|
||||
gtk_constraint_guide_get_attribute (GtkConstraintGuide *guide,
|
||||
GtkConstraintAttribute attr)
|
||||
{
|
||||
GtkLayoutManager *manager = GTK_LAYOUT_MANAGER (guide->layout);
|
||||
GtkWidget *widget = gtk_layout_manager_get_widget (manager);
|
||||
|
||||
return gtk_constraint_layout_get_attribute (guide->layout, attr, "guide", widget, guide->bound_attributes);
|
||||
}
|
||||
|
||||
GtkConstraintLayout *
|
||||
gtk_constraint_guide_get_layout (GtkConstraintGuide *guide)
|
||||
{
|
||||
return guide->layout;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_constraint_guide_set_layout (GtkConstraintGuide *guide,
|
||||
GtkConstraintLayout *layout)
|
||||
{
|
||||
guide->layout = layout;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_guide_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkConstraintGuide *self = GTK_CONSTRAINT_GUIDE (gobject);
|
||||
int val;
|
||||
GuideValue index;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_MIN_WIDTH:
|
||||
case PROP_MIN_HEIGHT:
|
||||
case PROP_NAT_WIDTH:
|
||||
case PROP_NAT_HEIGHT:
|
||||
case PROP_MAX_WIDTH:
|
||||
case PROP_MAX_HEIGHT:
|
||||
val = g_value_get_int (value);
|
||||
index = prop_id - 1;
|
||||
if (self->values[index] != val)
|
||||
{
|
||||
self->values[index] = val;
|
||||
g_object_notify_by_pspec (gobject, pspec);
|
||||
gtk_constraint_guide_update_constraint (self, index);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
gtk_constraint_guide_set_name (self, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_guide_get_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkConstraintGuide *self = GTK_CONSTRAINT_GUIDE (gobject);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_MIN_WIDTH:
|
||||
case PROP_MIN_HEIGHT:
|
||||
case PROP_NAT_WIDTH:
|
||||
case PROP_NAT_HEIGHT:
|
||||
case PROP_MAX_WIDTH:
|
||||
case PROP_MAX_HEIGHT:
|
||||
g_value_set_int (value, self->values[prop_id - 1]);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, self->name);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_guide_finalize (GObject *object)
|
||||
{
|
||||
GtkConstraintGuide *self = GTK_CONSTRAINT_GUIDE (object);
|
||||
|
||||
g_free (self->name);
|
||||
|
||||
g_clear_pointer (&self->bound_attributes, g_hash_table_unref);
|
||||
|
||||
G_OBJECT_CLASS (gtk_constraint_guide_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_constraint_guide_class_init (GtkConstraintGuideClass *class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||
|
||||
object_class->finalize = gtk_constraint_guide_finalize;
|
||||
object_class->set_property = gtk_constraint_guide_set_property;
|
||||
object_class->get_property = gtk_constraint_guide_get_property;
|
||||
|
||||
guide_props[PROP_MIN_WIDTH] =
|
||||
g_param_spec_int ("min-width",
|
||||
"Minimum width",
|
||||
"Minimum width",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE|
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
guide_props[PROP_MIN_HEIGHT] =
|
||||
g_param_spec_int ("min-height",
|
||||
"Minimum height",
|
||||
"Minimum height",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE|
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
guide_props[PROP_NAT_WIDTH] =
|
||||
g_param_spec_int ("nat-width",
|
||||
"Natural width",
|
||||
"Natural width",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE|
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
guide_props[PROP_NAT_HEIGHT] =
|
||||
g_param_spec_int ("nat-height",
|
||||
"Natural height",
|
||||
"Natural height",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE|
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
guide_props[PROP_MAX_WIDTH] =
|
||||
g_param_spec_int ("max-width",
|
||||
"Maximum width",
|
||||
"Maximum width",
|
||||
0, G_MAXINT, G_MAXINT,
|
||||
G_PARAM_READWRITE|
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
guide_props[PROP_MAX_HEIGHT] =
|
||||
g_param_spec_int ("max-height",
|
||||
"Maximum height",
|
||||
"Maximum height",
|
||||
0, G_MAXINT, G_MAXINT,
|
||||
G_PARAM_READWRITE|
|
||||
G_PARAM_EXPLICIT_NOTIFY);
|
||||
|
||||
guide_props[PROP_NAME] =
|
||||
g_param_spec_string ("name",
|
||||
"Name",
|
||||
"A name to use in debug message",
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_properties (object_class, LAST_PROP, guide_props);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_guide_new:
|
||||
*
|
||||
* Creates a new #GtkConstraintGuide object.
|
||||
*
|
||||
* Return: a new #GtkConstraintGuide object.
|
||||
*/
|
||||
GtkConstraintGuide *
|
||||
gtk_constraint_guide_new (void)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_CONSTRAINT_GUIDE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_guide_set_min_size:
|
||||
* @guide: a #GtkConstraintGuide object
|
||||
* @width: the new minimum width, or -1 to not change it
|
||||
* @height: the new minimum height, or -1 to not change it
|
||||
*
|
||||
* Sets the minimum size of @guide.
|
||||
*
|
||||
* If @guide is attached to a #GtkConstraintLayout,
|
||||
* the constraints will be updated to reflect the new size.
|
||||
*/
|
||||
void
|
||||
gtk_constraint_guide_set_min_size (GtkConstraintGuide *guide,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONSTRAINT_GUIDE (guide));
|
||||
g_return_if_fail (width >= -1);
|
||||
g_return_if_fail (height >= -1);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (guide));
|
||||
|
||||
if (width != -1)
|
||||
g_object_set (guide, "min-width", width, NULL);
|
||||
|
||||
if (height != -1)
|
||||
g_object_set (guide, "min-height", height, NULL);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (guide));
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_guide_get_min_size:
|
||||
* @guide: a #GtkContraintGuide object
|
||||
* @width: (allow-none): return location for the minimum width,
|
||||
* or %NULL
|
||||
* @height: (allow-none): return location for the minimum height,
|
||||
* or %NULL
|
||||
*
|
||||
* Gets the minimum size of @guide.
|
||||
*/
|
||||
void
|
||||
gtk_constraint_guide_get_min_size (GtkConstraintGuide *guide,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONSTRAINT_GUIDE (guide));
|
||||
|
||||
if (width)
|
||||
*width = guide->values[MIN_WIDTH];
|
||||
if (height)
|
||||
*height = guide->values[MIN_HEIGHT];
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_guide_set_nat_size:
|
||||
* @guide: a #GtkConstraintGuide object
|
||||
* @width: the new natural width, or -1 to not change it
|
||||
* @height: the new natural height, or -1 to not change it
|
||||
*
|
||||
* Sets the natural size of @guide.
|
||||
*
|
||||
* If @guide is attached to a #GtkConstraintLayout,
|
||||
* the constraints will be updated to reflect the new size.
|
||||
*/
|
||||
void
|
||||
gtk_constraint_guide_set_nat_size (GtkConstraintGuide *guide,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONSTRAINT_GUIDE (guide));
|
||||
g_return_if_fail (width >= -1);
|
||||
g_return_if_fail (height >= -1);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (guide));
|
||||
|
||||
if (width != -1)
|
||||
g_object_set (guide, "nat-width", width, NULL);
|
||||
|
||||
if (height != -1)
|
||||
g_object_set (guide, "nat-height", height, NULL);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (guide));
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_guide_get_nat_size:
|
||||
* @guide: a #GtkContraintGuide object
|
||||
* @width: (allow-none): return location for the natural width,
|
||||
* or %NULL
|
||||
* @height: (allow-none): return location for the natural height,
|
||||
* or %NULL
|
||||
*
|
||||
* Gets the natural size of @guide.
|
||||
*/
|
||||
void
|
||||
gtk_constraint_guide_get_nat_size (GtkConstraintGuide *guide,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONSTRAINT_GUIDE (guide));
|
||||
|
||||
if (width)
|
||||
*width = guide->values[NAT_WIDTH];
|
||||
if (height)
|
||||
*height = guide->values[NAT_HEIGHT];
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_guide_set_max_size:
|
||||
* @guide: a #GtkConstraintGuide object
|
||||
* @width: the new maximum width, or -1 to not change it
|
||||
* @height: the new maximum height, or -1 to not change it
|
||||
*
|
||||
* Sets the maximum size of @guide.
|
||||
*
|
||||
* If @guide is attached to a #GtkConstraintLayout,
|
||||
* the constraints will be updated to reflect the new size.
|
||||
*/
|
||||
void
|
||||
gtk_constraint_guide_set_max_size (GtkConstraintGuide *guide,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONSTRAINT_GUIDE (guide));
|
||||
g_return_if_fail (width >= -1);
|
||||
g_return_if_fail (height >= -1);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (guide));
|
||||
|
||||
if (width != -1)
|
||||
g_object_set (guide, "max-width", width, NULL);
|
||||
|
||||
if (height != -1)
|
||||
g_object_set (guide, "max-height", height, NULL);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (guide));
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_constraint_guide_get_max_size:
|
||||
* @guide: a #GtkContraintGuide object
|
||||
* @width: (allow-none): return location for the maximum width,
|
||||
* or %NULL
|
||||
* @height: (allow-none): return location for the maximum height,
|
||||
* or %NULL
|
||||
*
|
||||
* Gets the maximum size of @guide.
|
||||
*/
|
||||
void
|
||||
gtk_constraint_guide_get_max_size (GtkConstraintGuide *guide,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONSTRAINT_GUIDE (guide));
|
||||
|
||||
if (width)
|
||||
*width = guide->values[MAX_WIDTH];
|
||||
if (height)
|
||||
*height = guide->values[MAX_HEIGHT];
|
||||
}
|
||||
|
||||
const char *
|
||||
gtk_constraint_guide_get_name (GtkConstraintGuide *guide)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_CONSTRAINT_GUIDE (guide), NULL);
|
||||
|
||||
return guide->name;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_constraint_guide_set_name (GtkConstraintGuide *guide,
|
||||
const char *name)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_CONSTRAINT_GUIDE (guide));
|
||||
|
||||
g_free (guide->name);
|
||||
guide->name = g_strdup (name);
|
||||
g_object_notify_by_pspec (G_OBJECT (guide), guide_props[PROP_NAME]);
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/* gtkconstraintguide.h: Flexible space for constraints
|
||||
* Copyright 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.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: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtktypes.h>
|
||||
#include <gtk/gtkenums.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define GTK_TYPE_CONSTRAINT_GUIDE (gtk_constraint_guide_get_type ())
|
||||
|
||||
/**
|
||||
* GtkConstraintGuide:
|
||||
*
|
||||
* An object that can be added to a #GtkConstraintLayout and be
|
||||
* used in constraints like a widget, without being drawn.
|
||||
*
|
||||
* Guides have a minimum, maximum 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);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_guide_set_min_size (GtkConstraintGuide *guide,
|
||||
int width,
|
||||
int height);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_guide_get_min_size (GtkConstraintGuide *guide,
|
||||
int *width,
|
||||
int *height);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_guide_set_nat_size (GtkConstraintGuide *guide,
|
||||
int width,
|
||||
int height);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_guide_get_nat_size (GtkConstraintGuide *guide,
|
||||
int *width,
|
||||
int *height);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_guide_set_max_size (GtkConstraintGuide *guide,
|
||||
int width,
|
||||
int height);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_guide_get_max_size (GtkConstraintGuide *guide,
|
||||
int *width,
|
||||
int *height);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_constraint_guide_set_name (GtkConstraintGuide *guide,
|
||||
const char *name);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const char * gtk_constraint_guide_get_name (GtkConstraintGuide *guide);
|
||||
|
||||
G_END_DECLS
|
||||
@@ -0,0 +1,38 @@
|
||||
/* gtkconstraintguideprivate.h: Constraint between two widgets
|
||||
* Copyright 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.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: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gtkconstraintguide.h"
|
||||
#include "gtkconstraintlayout.h"
|
||||
#include "gtkconstrainttypesprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void gtk_constraint_guide_update (GtkConstraintGuide *guide);
|
||||
void gtk_constraint_guide_detach (GtkConstraintGuide *guide);
|
||||
|
||||
GtkConstraintVariable *gtk_constraint_guide_get_attribute (GtkConstraintGuide *guide,
|
||||
GtkConstraintAttribute attr);
|
||||
|
||||
GtkConstraintLayout *gtk_constraint_guide_get_layout (GtkConstraintGuide *guide);
|
||||
void gtk_constraint_guide_set_layout (GtkConstraintGuide *guide,
|
||||
GtkConstraintLayout *layout);
|
||||
|
||||
G_END_DECLS
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,64 @@
|
||||
/* 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>
|
||||
#include <gtk/gtkconstraintguide.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 ())
|
||||
|
||||
/**
|
||||
* GtkConstraintLayoutChild:
|
||||
*
|
||||
* A #GtkLayoutChild in a #GtkConstraintLayout.
|
||||
*/
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (GtkConstraintLayoutChild, gtk_constraint_layout_child, GTK, CONSTRAINT_LAYOUT_CHILD, GtkLayoutChild)
|
||||
|
||||
/**
|
||||
* 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,37 @@
|
||||
/*
|
||||
* Copyright 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.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: Matthias Clasen
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gtkconstraintlayout.h"
|
||||
#include "gtkconstraintsolverprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GtkConstraintSolver *
|
||||
gtk_constraint_layout_get_solver (GtkConstraintLayout *layout);
|
||||
|
||||
GtkConstraintVariable *
|
||||
gtk_constraint_layout_get_attribute (GtkConstraintLayout *layout,
|
||||
GtkConstraintAttribute attr,
|
||||
const char *prefix,
|
||||
GtkWidget *widget,
|
||||
GHashTable *bound_attributes);
|
||||
|
||||
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,165 @@
|
||||
/* 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
|
||||
|
||||
#ifdef GTK_TEST_EXTERNAL
|
||||
|
||||
#define GTK_TYPE_CONSTRAINT_SOLVER (g_type_from_name ("GtkConstraintSolver"))
|
||||
#define GTK_CONSTRAINT_SOLVER(solver) (G_TYPE_CHECK_INSTANCE_CAST ((solver), GTK_TYPE_CONSTRAINT_SOLVER, GtkConstraintSolver))
|
||||
#define GTK_CONSTRAINT_SOLVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CONSTRAINT_SOLVER, GtkConstraintSolverClass))
|
||||
#define GTK_IS_CONSTRAINT_SOLVER(solver) (G_TYPE_CHECK_INSTANCE_TYPE ((solver), GTK_TYPE_CONSTRAINT_SOLVER))
|
||||
#define GTK_IS_CONSTRAINT_SOLVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CONSTRAINT_SOLVER))
|
||||
#define GTK_CONSTRAINT_SOLVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CONSTRAINT_SOLVER, GtkConstraintSolverClass))
|
||||
|
||||
typedef struct _GtkConstraintSolver GtkConstraintSolver;
|
||||
typedef struct _GtkConstraintSolverClass GtkConstraintSolverClass;
|
||||
|
||||
struct _GtkConstraintSolverClass {
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define GTK_TYPE_CONSTRAINT_SOLVER (gtk_constraint_solver_get_type())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GtkConstraintSolver, gtk_constraint_solver, GTK, CONSTRAINT_SOLVER, GObject)
|
||||
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
@@ -3477,8 +3477,6 @@ set_show_emoji_icon (GtkEntry *entry,
|
||||
gboolean value)
|
||||
{
|
||||
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
|
||||
GActionGroup *actions;
|
||||
GAction *action;
|
||||
|
||||
if (priv->show_emoji_icon == value)
|
||||
return;
|
||||
@@ -3520,14 +3518,6 @@ set_show_emoji_icon (GtkEntry *entry,
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (entry), entry_props[PROP_SHOW_EMOJI_ICON]);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (entry));
|
||||
|
||||
#if 0
|
||||
actions = gtk_widget_get_action_group (priv->text, "context");
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "insert-emoji");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
priv->show_emoji_icon ||
|
||||
(gtk_entry_get_input_hints (entry) & GTK_INPUT_HINT_NO_EMOJI) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
GtkEventController *
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
+204
-22
@@ -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;
|
||||
|
||||
@@ -228,6 +234,8 @@ struct _GtkFileChooserWidgetPrivate {
|
||||
|
||||
GtkWidget *box;
|
||||
|
||||
GActionGroup *item_actions;
|
||||
|
||||
/* Save mode widgets */
|
||||
GtkWidget *save_widgets;
|
||||
GtkWidget *save_widgets_table;
|
||||
@@ -245,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;
|
||||
@@ -337,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;
|
||||
|
||||
@@ -355,6 +366,8 @@ struct _GtkFileChooserWidgetPrivate {
|
||||
|
||||
ClockFormat clock_format;
|
||||
|
||||
TypeFormat type_format;
|
||||
|
||||
/* Flags */
|
||||
|
||||
guint local_only : 1;
|
||||
@@ -369,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;
|
||||
@@ -404,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,
|
||||
@@ -426,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 */ \
|
||||
@@ -678,6 +694,8 @@ gtk_file_chooser_widget_finalize (GObject *object)
|
||||
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (object);
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
|
||||
|
||||
g_clear_object (&priv->item_actions);
|
||||
|
||||
g_clear_pointer (&priv->choices, g_hash_table_unref);
|
||||
|
||||
if (priv->location_changed_id > 0)
|
||||
@@ -1723,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,
|
||||
@@ -2004,28 +2038,25 @@ check_file_list_popover_sensitivity (GtkFileChooserWidget *impl)
|
||||
gboolean all_files;
|
||||
gboolean all_folders;
|
||||
gboolean active;
|
||||
GActionGroup *actions;
|
||||
GAction *action, *action2;
|
||||
|
||||
actions = gtk_widget_get_action_group (priv->browse_files_tree_view, "item");
|
||||
|
||||
selection_check (impl, &num_selected, &all_files, &all_folders);
|
||||
|
||||
active = (num_selected != 0);
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "copy-location");
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "copy-location");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), active);
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "add-shortcut");
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "add-shortcut");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), active && all_folders);
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "visit");
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "visit");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), active);
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "open");
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "open");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), (num_selected == 1) && all_folders);
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "rename");
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "rename");
|
||||
if (num_selected == 1)
|
||||
{
|
||||
GSList *infos;
|
||||
@@ -2042,8 +2073,8 @@ check_file_list_popover_sensitivity (GtkFileChooserWidget *impl)
|
||||
else
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "delete");
|
||||
action2 = g_action_map_lookup_action (G_ACTION_MAP (actions), "trash");
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "delete");
|
||||
action2 = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "trash");
|
||||
|
||||
if (num_selected == 1)
|
||||
{
|
||||
@@ -2092,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 }
|
||||
};
|
||||
@@ -2100,14 +2132,13 @@ static void
|
||||
add_actions (GtkFileChooserWidget *impl)
|
||||
{
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
|
||||
GActionGroup *actions;
|
||||
|
||||
actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions),
|
||||
priv->item_actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (priv->item_actions),
|
||||
entries, G_N_ELEMENTS (entries),
|
||||
impl);
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (priv->browse_files_tree_view), "item", actions);
|
||||
g_object_unref (actions);
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (priv->browse_files_tree_view), "item",
|
||||
priv->item_actions);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
@@ -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");
|
||||
}
|
||||
@@ -2181,7 +2213,6 @@ static void
|
||||
file_list_update_popover (GtkFileChooserWidget *impl)
|
||||
{
|
||||
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
|
||||
GActionGroup *actions;
|
||||
GAction *action;
|
||||
|
||||
file_list_build_popover (impl);
|
||||
@@ -2202,17 +2233,19 @@ file_list_update_popover (GtkFileChooserWidget *impl)
|
||||
|
||||
gtk_widget_set_visible (priv->visit_file_item, (priv->operation_mode != OPERATION_MODE_BROWSE));
|
||||
|
||||
actions = gtk_widget_get_action_group (priv->browse_files_tree_view, "item");
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "toggle-show-hidden");
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "toggle-show-hidden");
|
||||
g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (priv->show_hidden));
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "toggle-show-size");
|
||||
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 (actions), "toggle-show-time");
|
||||
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));
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "toggle-sort-dirs-first");
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "toggle-sort-dirs-first");
|
||||
g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (priv->sort_directories_first));
|
||||
}
|
||||
|
||||
@@ -2347,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);
|
||||
}
|
||||
|
||||
@@ -3659,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;
|
||||
@@ -3671,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;
|
||||
@@ -3689,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
|
||||
@@ -3721,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);
|
||||
@@ -3978,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,
|
||||
@@ -4044,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,
|
||||
@@ -4694,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,
|
||||
@@ -4821,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:
|
||||
@@ -4933,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);
|
||||
@@ -7056,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"));
|
||||
@@ -7273,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"));
|
||||
@@ -7714,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,
|
||||
@@ -8298,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);
|
||||
@@ -8448,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:
|
||||
|
||||
@@ -551,7 +551,7 @@ _gtk_menu_tracker_item_new (GtkActionObservable *observable,
|
||||
if (found)
|
||||
{
|
||||
GTK_NOTE(ACTIONS, g_message ("menutracker: action %s existed from the start", action_name));
|
||||
gtk_menu_tracker_item_action_added (GTK_ACTION_OBSERVER (self), observable, NULL, parameter_type, enabled, state);
|
||||
gtk_menu_tracker_item_action_added (GTK_ACTION_OBSERVER (self), observable, action_name, parameter_type, enabled, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
+11
-12
@@ -128,6 +128,8 @@ struct _GtkPlacesSidebar {
|
||||
|
||||
GtkBookmarksManager *bookmarks_manager;
|
||||
|
||||
GActionGroup *row_actions;
|
||||
|
||||
#ifdef HAVE_CLOUDPROVIDERS
|
||||
CloudProvidersCollector *cloud_manager;
|
||||
GList *unready_accounts;
|
||||
@@ -2247,8 +2249,7 @@ check_popover_sensitivity (GtkSidebarRow *row,
|
||||
GDrive *drive;
|
||||
GVolume *volume;
|
||||
GMount *mount;
|
||||
GtkWidget *sidebar;
|
||||
GActionGroup *actions;
|
||||
GtkPlacesSidebar *sidebar;
|
||||
GAction *action;
|
||||
|
||||
g_object_get (row,
|
||||
@@ -2261,13 +2262,12 @@ check_popover_sensitivity (GtkSidebarRow *row,
|
||||
|
||||
gtk_widget_set_visible (data->add_shortcut_item, (type == PLACES_MOUNTED_VOLUME));
|
||||
|
||||
actions = gtk_widget_get_action_group (sidebar, "row");
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "remove");
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (sidebar->row_actions), "remove");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), (type == PLACES_BOOKMARK));
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "rename");
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (sidebar->row_actions), "rename");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), (type == PLACES_BOOKMARK ||
|
||||
type == PLACES_XDG_DIR));
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "open");
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (sidebar->row_actions), "open");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), !gtk_list_box_row_is_selected (GTK_LIST_BOX_ROW (row)));
|
||||
|
||||
check_visibility (mount, volume, drive,
|
||||
@@ -3479,14 +3479,11 @@ static GActionEntry entries[] = {
|
||||
static void
|
||||
add_actions (GtkPlacesSidebar *sidebar)
|
||||
{
|
||||
GActionGroup *actions;
|
||||
|
||||
actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions),
|
||||
sidebar->row_actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (sidebar->row_actions),
|
||||
entries, G_N_ELEMENTS (entries),
|
||||
sidebar);
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (sidebar), "row", actions);
|
||||
g_object_unref (actions);
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (sidebar), "row", sidebar->row_actions);
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
@@ -4375,6 +4372,8 @@ gtk_places_sidebar_finalize (GObject *object)
|
||||
{
|
||||
GtkPlacesSidebar *sidebar = GTK_PLACES_SIDEBAR (object);
|
||||
|
||||
g_clear_object (&sidebar->row_actions);
|
||||
|
||||
#ifdef HAVE_CLOUDPROVIDERS
|
||||
g_clear_object (&sidebar->cloud_manager);
|
||||
#endif
|
||||
|
||||
@@ -140,8 +140,6 @@
|
||||
|
||||
#define POS_IS_VERTICAL(p) ((p) == GTK_POS_TOP || (p) == GTK_POS_BOTTOM)
|
||||
|
||||
static GListStore *popover_list = NULL;
|
||||
|
||||
typedef struct {
|
||||
GdkSurface *surface;
|
||||
GskRenderer *renderer;
|
||||
@@ -743,21 +741,8 @@ gtk_popover_dispose (GObject *object)
|
||||
{
|
||||
GtkPopover *popover = GTK_POPOVER (object);
|
||||
GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
|
||||
guint i;
|
||||
GtkWidget *child;
|
||||
|
||||
for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (popover_list)); i++)
|
||||
{
|
||||
gpointer item = g_list_model_get_item (G_LIST_MODEL (popover_list), i);
|
||||
if (item == object)
|
||||
{
|
||||
g_list_store_remove (popover_list, i);
|
||||
break;
|
||||
}
|
||||
else
|
||||
g_object_unref (item);
|
||||
}
|
||||
|
||||
child = gtk_bin_get_child (GTK_BIN (popover));
|
||||
|
||||
if (child)
|
||||
@@ -778,13 +763,6 @@ gtk_popover_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (gtk_popover_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_popover_constructed (GObject *object)
|
||||
{
|
||||
g_list_store_append (popover_list, object);
|
||||
g_object_unref (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_popover_get_gap_coords (GtkPopover *popover,
|
||||
gint *initial_x_out,
|
||||
@@ -1333,10 +1311,6 @@ gtk_popover_class_init (GtkPopoverClass *klass)
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
|
||||
|
||||
if (popover_list == NULL)
|
||||
popover_list = g_list_store_new (GTK_TYPE_WIDGET);
|
||||
|
||||
object_class->constructed = gtk_popover_constructed;
|
||||
object_class->dispose = gtk_popover_dispose;
|
||||
object_class->finalize = gtk_popover_finalize;
|
||||
object_class->set_property = gtk_popover_set_property;
|
||||
@@ -1446,22 +1420,6 @@ size_changed (GtkWidget *widget,
|
||||
gtk_popover_move_resize (popover);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_popover_get_popovers:
|
||||
*
|
||||
* Returns the list of all existing #GtkPopover widgets.
|
||||
*
|
||||
* Returns: (transfer none): The list of existing popovers.
|
||||
*/
|
||||
GListModel *
|
||||
gtk_popover_get_popovers (void)
|
||||
{
|
||||
if (popover_list == NULL)
|
||||
popover_list = g_list_store_new (GTK_TYPE_WIDGET);
|
||||
|
||||
return G_LIST_MODEL (popover_list);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_popover_set_default_widget (GtkPopover *popover,
|
||||
GtkWidget *widget)
|
||||
|
||||
@@ -101,8 +101,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
void gtk_popover_set_default_widget (GtkPopover *popover,
|
||||
GtkWidget *widget);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GListModel * gtk_popover_get_popovers (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -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"),
|
||||
|
||||
+112
-182
@@ -68,6 +68,7 @@
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkwindow.h"
|
||||
#include "gtknative.h"
|
||||
#include "gtkactionmuxerprivate.h"
|
||||
|
||||
#include "a11y/gtktextaccessible.h"
|
||||
|
||||
@@ -383,10 +384,6 @@ static void gtk_text_set_max_width_chars (GtkText *self,
|
||||
static void gtk_text_set_alignment (GtkText *self,
|
||||
float xalign);
|
||||
|
||||
/* GActionGroup implementations */
|
||||
|
||||
static void gtk_text_action_group_init (GActionGroupInterface *iface);
|
||||
|
||||
/* Default signal handlers
|
||||
*/
|
||||
static GMenuModel *gtk_text_get_menu_model (GtkText *self);
|
||||
@@ -545,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
|
||||
*/
|
||||
@@ -637,8 +651,7 @@ gtk_text_content_init (GtkTextContent *content)
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkText, gtk_text, GTK_TYPE_WIDGET,
|
||||
G_ADD_PRIVATE (GtkText)
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE, gtk_text_editable_init)
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_ACTION_GROUP, gtk_text_action_group_init))
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE, gtk_text_editable_init))
|
||||
|
||||
static void
|
||||
add_move_binding (GtkBindingSet *binding_set,
|
||||
@@ -710,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");
|
||||
|
||||
@@ -1340,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
|
||||
@@ -1724,7 +1753,6 @@ gtk_text_init (GtkText *self)
|
||||
}
|
||||
|
||||
set_text_cursor (GTK_WIDGET (self));
|
||||
gtk_text_add_context_actions (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1770,6 +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_pointer (&priv->selection_bubble, gtk_widget_unparent);
|
||||
g_clear_pointer (&priv->popup_menu, gtk_widget_unparent);
|
||||
g_clear_object (&priv->extra_menu);
|
||||
|
||||
@@ -1786,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);
|
||||
@@ -2179,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
|
||||
@@ -4050,6 +4081,7 @@ gtk_text_set_positions (GtkText *self,
|
||||
|
||||
if (changed)
|
||||
{
|
||||
gtk_text_update_clipboard_actions (self);
|
||||
gtk_text_recompute (self);
|
||||
}
|
||||
}
|
||||
@@ -5269,9 +5301,7 @@ gtk_text_set_visibility (GtkText *self,
|
||||
g_object_notify (G_OBJECT (self), "visibility");
|
||||
gtk_text_recompute (self);
|
||||
|
||||
g_action_group_action_state_changed (G_ACTION_GROUP (self),
|
||||
"toggle-visibility",
|
||||
g_variant_new_boolean (visible));
|
||||
gtk_text_update_clipboard_actions (self);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5616,157 +5646,68 @@ hide_selection_bubble (GtkText *self)
|
||||
gtk_widget_hide (priv->selection_bubble);
|
||||
}
|
||||
|
||||
static char **
|
||||
gtk_text_action_group_list_actions (GActionGroup *group)
|
||||
static void
|
||||
gtk_text_activate_clipboard_cut (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
const char *actions[] = {
|
||||
"cut-clipboard",
|
||||
"copy-clipboard",
|
||||
"paste-clipboard",
|
||||
"delete-selection",
|
||||
"select-all",
|
||||
"insert-emoji",
|
||||
"toggle-visibility",
|
||||
NULL
|
||||
};
|
||||
|
||||
return g_strdupv ((char **)actions);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_text_action_group_query_action (GActionGroup *group,
|
||||
const char *name,
|
||||
gboolean *enabled,
|
||||
const GVariantType **parameter_type,
|
||||
const GVariantType **state_type,
|
||||
GVariant **state_hint,
|
||||
GVariant **state)
|
||||
{
|
||||
GtkText *self = GTK_TEXT (group);
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GdkClipboard *clipboard;
|
||||
DisplayMode mode;
|
||||
gboolean has_clipboard;
|
||||
gboolean has_selection;
|
||||
gboolean has_content;
|
||||
gboolean visible;
|
||||
gboolean found;
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (self));
|
||||
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;
|
||||
if (parameter_type)
|
||||
*parameter_type = NULL;
|
||||
if (state_type)
|
||||
*state_type = NULL;
|
||||
if (state_hint)
|
||||
*state_hint = NULL;
|
||||
if (state)
|
||||
*state = NULL;
|
||||
|
||||
found = TRUE;
|
||||
if (strcmp (name, "cut-clipboard") == 0)
|
||||
{
|
||||
*enabled = visible && priv->editable && has_selection;
|
||||
}
|
||||
else if (strcmp (name, "copy-clipboard") == 0)
|
||||
{
|
||||
*enabled = visible && has_selection;
|
||||
}
|
||||
else if (strcmp (name, "paste-clipboard") == 0)
|
||||
{
|
||||
*enabled = priv->editable && has_clipboard;
|
||||
}
|
||||
else if (strcmp (name, "delete-selection") == 0)
|
||||
{
|
||||
*enabled = priv->editable && has_selection;
|
||||
}
|
||||
else if (strcmp (name, "select-all") == 0)
|
||||
{
|
||||
*enabled = has_content;
|
||||
}
|
||||
else if (strcmp (name, "insert-emoji") == 0)
|
||||
{
|
||||
*enabled = (gtk_text_get_input_hints (self) & GTK_INPUT_HINT_NO_EMOJI) == 0;
|
||||
}
|
||||
else if (strcmp (name, "toggle-visibility") == 0)
|
||||
{
|
||||
*enabled = TRUE;
|
||||
if (state_type)
|
||||
*state_type = G_VARIANT_TYPE_BOOLEAN;
|
||||
if (state)
|
||||
*state = g_variant_new_boolean (visible);
|
||||
}
|
||||
else
|
||||
{
|
||||
found = FALSE;
|
||||
}
|
||||
|
||||
return found;
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
g_signal_emit_by_name (self, "cut-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_action_group_activate_action (GActionGroup *group,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
gtk_text_activate_clipboard_copy (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkText *self = GTK_TEXT (group);
|
||||
|
||||
if (strcmp (name, "cut-clipboard") == 0)
|
||||
{
|
||||
g_signal_emit_by_name (self, "cut-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
else if (strcmp (name, "copy-clipboard") == 0)
|
||||
{
|
||||
g_signal_emit_by_name (self, "copy-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
else if (strcmp (name, "paste-clipboard") == 0)
|
||||
{
|
||||
g_signal_emit_by_name (self, "paste-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
else if (strcmp (name, "delete-selection") == 0)
|
||||
{
|
||||
gtk_text_delete_cb (self);
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
else if (strcmp (name, "select-all") == 0)
|
||||
{
|
||||
gtk_text_select_all (self);
|
||||
}
|
||||
else if (strcmp (name, "insert-emoji") == 0)
|
||||
{
|
||||
gtk_text_insert_emoji (self);
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
else if (strcmp (name, "toggle-visibility") == 0)
|
||||
{
|
||||
gtk_text_set_visibility (self, !gtk_text_get_visibility (self));
|
||||
}
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
g_signal_emit_by_name (self, "copy-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_action_group_init (GActionGroupInterface *iface)
|
||||
gtk_text_activate_clipboard_paste (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
iface->list_actions = gtk_text_action_group_list_actions;
|
||||
iface->query_action = gtk_text_action_group_query_action;
|
||||
iface->activate_action = gtk_text_action_group_activate_action;
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
g_signal_emit_by_name (self, "paste-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_add_context_actions (GtkText *self)
|
||||
gtk_text_activate_selection_delete (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (self), "context", G_ACTION_GROUP (self));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
gtk_text_delete_cb (self);
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_activate_selection_select_all (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
gtk_text_select_all (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_activate_misc_insert_emoji (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
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;
|
||||
@@ -5774,7 +5715,7 @@ gtk_text_update_clipboard_actions (GtkText *self)
|
||||
gboolean has_selection;
|
||||
gboolean has_content;
|
||||
gboolean visible;
|
||||
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (self));
|
||||
mode = gtk_text_get_display_mode (self);
|
||||
has_clipboard = gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), G_TYPE_STRING);
|
||||
@@ -5782,33 +5723,24 @@ gtk_text_update_clipboard_actions (GtkText *self)
|
||||
has_content = priv->buffer && (gtk_entry_buffer_get_length (priv->buffer) > 0);
|
||||
visible = mode == DISPLAY_NORMAL;
|
||||
|
||||
g_action_group_action_enabled_changed (G_ACTION_GROUP (self),
|
||||
"cut-clipboard",
|
||||
visible && priv->editable && has_selection);
|
||||
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);
|
||||
|
||||
g_action_group_action_enabled_changed (G_ACTION_GROUP (self),
|
||||
"copy-clipboard",
|
||||
visible && has_selection);
|
||||
|
||||
g_action_group_action_enabled_changed (G_ACTION_GROUP (self),
|
||||
"paste-clipboard",
|
||||
priv->editable && has_clipboard);
|
||||
|
||||
g_action_group_action_enabled_changed (G_ACTION_GROUP (self),
|
||||
"delete-selection",
|
||||
priv->editable && has_selection);
|
||||
|
||||
g_action_group_action_enabled_changed (G_ACTION_GROUP (self),
|
||||
"select-all",
|
||||
has_content);
|
||||
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)
|
||||
{
|
||||
g_action_group_action_enabled_changed (G_ACTION_GROUP (self),
|
||||
"insert-emoji",
|
||||
(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 *
|
||||
@@ -5821,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);
|
||||
@@ -5842,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);
|
||||
@@ -5908,6 +5840,7 @@ append_bubble_item (GtkText *self,
|
||||
GMenuModel *model,
|
||||
int index)
|
||||
{
|
||||
GtkActionMuxer *muxer;
|
||||
GtkWidget *item, *image;
|
||||
GVariant *att;
|
||||
const char *icon_name;
|
||||
@@ -5937,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."))
|
||||
{
|
||||
const char *name = action_name + strlen ("context.");
|
||||
if (!g_action_group_get_action_enabled (G_ACTION_GROUP (self), name))
|
||||
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);
|
||||
@@ -6036,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 ();
|
||||
|
||||
+281
-64
@@ -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,85 +12441,70 @@ gtk_widget_get_template_child (GtkWidget *widget,
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_list_action_prefixes:
|
||||
* @widget: A #GtkWidget
|
||||
* gtk_widget_activate_action_variant: (rename-to gtk_widget_activate_action)
|
||||
* @widget: a #GtkWidget
|
||||
* @name: the name of the action to activate
|
||||
* @args: (allow-none): parameters to use, or %NULL
|
||||
*
|
||||
* Retrieves a %NULL-terminated array of strings containing the prefixes of
|
||||
* #GActionGroup's available to @widget.
|
||||
* Looks up the action in the action groups associated
|
||||
* with @widget and its ancestors, and activates it.
|
||||
*
|
||||
* Returns: (transfer container): a %NULL-terminated array of strings.
|
||||
* 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 arguments must match the actions expected parameter
|
||||
* type, as returned by g_action_get_parameter_type().
|
||||
*/
|
||||
const gchar **
|
||||
gtk_widget_list_action_prefixes (GtkWidget *widget)
|
||||
void
|
||||
gtk_widget_activate_action_variant (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *args)
|
||||
{
|
||||
GtkActionMuxer *muxer;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
||||
|
||||
muxer = _gtk_widget_get_action_muxer (widget, FALSE);
|
||||
if (muxer)
|
||||
return gtk_action_muxer_list_prefixes (muxer);
|
||||
|
||||
return g_new0 (const gchar *, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_get_action_group:
|
||||
* @widget: A #GtkWidget
|
||||
* @prefix: The “prefix” of the action group.
|
||||
*
|
||||
* Retrieves the #GActionGroup that was registered using @prefix. The resulting
|
||||
* #GActionGroup may have been registered to @widget or any #GtkWidget in its
|
||||
* ancestry.
|
||||
*
|
||||
* If no action group was found matching @prefix, then %NULL is returned.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): A #GActionGroup or %NULL.
|
||||
*/
|
||||
GActionGroup *
|
||||
gtk_widget_get_action_group (GtkWidget *widget,
|
||||
const gchar *prefix)
|
||||
{
|
||||
GtkActionMuxer *muxer;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
||||
g_return_val_if_fail (prefix, NULL);
|
||||
|
||||
muxer = _gtk_widget_get_action_muxer (widget, FALSE);
|
||||
if (muxer)
|
||||
return gtk_action_muxer_lookup (muxer, prefix);
|
||||
|
||||
return NULL;
|
||||
g_action_group_activate_action (G_ACTION_GROUP (muxer), name, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @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.
|
||||
*
|
||||
* 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().
|
||||
*
|
||||
* The @parameter must match the actions expected parameter
|
||||
* type, as returned by g_action_get_parameter_type().
|
||||
* 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,
|
||||
GVariant *parameter)
|
||||
const char *format_string,
|
||||
...)
|
||||
{
|
||||
GtkActionMuxer *muxer;
|
||||
GVariant *parameters = NULL;
|
||||
|
||||
muxer = _gtk_widget_get_action_muxer (widget, FALSE);
|
||||
if (muxer)
|
||||
g_action_group_activate_action (G_ACTION_GROUP (muxer),
|
||||
name,
|
||||
parameter);
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -13479,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;
|
||||
}
|
||||
|
||||
+49
-11
@@ -833,11 +833,6 @@ GDK_AVAILABLE_IN_ALL
|
||||
GdkModifierType gtk_widget_get_modifier_mask (GtkWidget *widget,
|
||||
GdkModifierIntent intent);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_insert_action_group (GtkWidget *widget,
|
||||
const gchar *name,
|
||||
GActionGroup *group);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
guint gtk_widget_add_tick_callback (GtkWidget *widget,
|
||||
GtkTickCallback callback,
|
||||
@@ -976,16 +971,19 @@ void gtk_widget_class_bind_template_child_full (GtkWidgetClass *
|
||||
gssize struct_offset);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
GActionGroup *gtk_widget_get_action_group (GtkWidget *widget,
|
||||
const gchar *prefix);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
const gchar ** gtk_widget_list_action_prefixes (GtkWidget *widget);
|
||||
void gtk_widget_insert_action_group (GtkWidget *widget,
|
||||
const gchar *name,
|
||||
GActionGroup *group);
|
||||
|
||||
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);
|
||||
@@ -1030,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
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
struct _GtkInspectorActionEditorPrivate
|
||||
{
|
||||
GActionGroup *group;
|
||||
gchar *prefix;
|
||||
gchar *name;
|
||||
gboolean enabled;
|
||||
const GVariantType *parameter_type;
|
||||
@@ -44,7 +43,6 @@ enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_GROUP,
|
||||
PROP_PREFIX,
|
||||
PROP_NAME,
|
||||
PROP_SIZEGROUP
|
||||
};
|
||||
@@ -232,6 +230,20 @@ state_changed (GtkWidget *editor,
|
||||
g_action_group_change_action_state (r->priv->group, r->priv->name, value);
|
||||
}
|
||||
|
||||
static void
|
||||
update_enabled (GtkInspectorActionEditor *r,
|
||||
gboolean enabled)
|
||||
{
|
||||
r->priv->enabled = enabled;
|
||||
if (r->priv->parameter_entry)
|
||||
{
|
||||
gtk_widget_set_sensitive (r->priv->parameter_entry, enabled);
|
||||
parameter_changed (r->priv->parameter_entry, r);
|
||||
}
|
||||
if (r->priv->activate_button)
|
||||
gtk_widget_set_sensitive (r->priv->activate_button, enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
action_enabled_changed_cb (GActionGroup *group,
|
||||
const gchar *action_name,
|
||||
@@ -241,12 +253,15 @@ action_enabled_changed_cb (GActionGroup *group,
|
||||
if (!g_str_equal (action_name, r->priv->name))
|
||||
return;
|
||||
|
||||
r->priv->enabled = enabled;
|
||||
if (r->priv->parameter_entry)
|
||||
{
|
||||
gtk_widget_set_sensitive (r->priv->parameter_entry, enabled);
|
||||
parameter_changed (r->priv->parameter_entry, r);
|
||||
}
|
||||
update_enabled (r, enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
update_state (GtkInspectorActionEditor *r,
|
||||
GVariant *state)
|
||||
{
|
||||
if (r->priv->state_entry)
|
||||
variant_editor_set_value (r->priv->state_entry, state);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -258,8 +273,7 @@ action_state_changed_cb (GActionGroup *group,
|
||||
if (!g_str_equal (action_name, r->priv->name))
|
||||
return;
|
||||
|
||||
if (r->priv->state_entry)
|
||||
variant_editor_set_value (r->priv->state_entry, state);
|
||||
update_state (r, state);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -319,7 +333,6 @@ finalize (GObject *object)
|
||||
{
|
||||
GtkInspectorActionEditor *r = GTK_INSPECTOR_ACTION_EDITOR (object);
|
||||
|
||||
g_free (r->priv->prefix);
|
||||
g_free (r->priv->name);
|
||||
g_object_unref (r->priv->sg);
|
||||
if (r->priv->state_type)
|
||||
@@ -344,10 +357,6 @@ get_property (GObject *object,
|
||||
g_value_set_object (value, r->priv->group);
|
||||
break;
|
||||
|
||||
case PROP_PREFIX:
|
||||
g_value_set_string (value, r->priv->prefix);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, r->priv->name);
|
||||
break;
|
||||
@@ -376,18 +385,13 @@ set_property (GObject *object,
|
||||
r->priv->group = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
case PROP_PREFIX:
|
||||
g_free (r->priv->prefix);
|
||||
r->priv->prefix = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_NAME:
|
||||
g_free (r->priv->name);
|
||||
r->priv->name = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_SIZEGROUP:
|
||||
r->priv->sg = g_value_get_object (value);
|
||||
r->priv->sg = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -410,10 +414,6 @@ gtk_inspector_action_editor_class_init (GtkInspectorActionEditorClass *klass)
|
||||
g_param_spec_object ("group", "Action Group", "The Action Group containing the action",
|
||||
G_TYPE_ACTION_GROUP, G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_PREFIX,
|
||||
g_param_spec_string ("prefix", "Prefix", "The action name prefix",
|
||||
NULL, G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_NAME,
|
||||
g_param_spec_string ("name", "Name", "The action name",
|
||||
NULL, G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
|
||||
@@ -424,14 +424,21 @@ gtk_inspector_action_editor_class_init (GtkInspectorActionEditorClass *klass)
|
||||
|
||||
GtkWidget *
|
||||
gtk_inspector_action_editor_new (GActionGroup *group,
|
||||
const gchar *prefix,
|
||||
const gchar *name,
|
||||
GtkSizeGroup *activate)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_INSPECTOR_ACTION_EDITOR,
|
||||
"group", group,
|
||||
"prefix", prefix,
|
||||
"name", name,
|
||||
"sizegroup", activate,
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_inspector_action_editor_update (GtkInspectorActionEditor *r,
|
||||
gboolean enabled,
|
||||
GVariant *state)
|
||||
{
|
||||
update_enabled (r, enabled);
|
||||
update_state (r, state);
|
||||
}
|
||||
|
||||
@@ -49,9 +49,11 @@ G_BEGIN_DECLS
|
||||
|
||||
GType gtk_inspector_action_editor_get_type (void);
|
||||
GtkWidget *gtk_inspector_action_editor_new (GActionGroup *group,
|
||||
const gchar *prefix,
|
||||
const gchar *name,
|
||||
GtkSizeGroup *activate);
|
||||
void gtk_inspector_action_editor_update (GtkInspectorActionEditor *r,
|
||||
gboolean enabled,
|
||||
GVariant *state);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
+168
-86
@@ -26,6 +26,7 @@
|
||||
#include "gtktreeview.h"
|
||||
#include "gtkliststore.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkactionmuxerprivate.h"
|
||||
#include "gtkpopover.h"
|
||||
#include "gtklabel.h"
|
||||
#include "gtkstack.h"
|
||||
@@ -33,26 +34,21 @@
|
||||
#include "gtkstylecontext.h"
|
||||
#include "gtksizegroup.h"
|
||||
|
||||
enum
|
||||
{
|
||||
COLUMN_PREFIX,
|
||||
COLUMN_NAME,
|
||||
COLUMN_ENABLED,
|
||||
COLUMN_PARAMETER,
|
||||
COLUMN_STATE,
|
||||
COLUMN_GROUP
|
||||
};
|
||||
|
||||
struct _GtkInspectorActionsPrivate
|
||||
{
|
||||
GtkWidget *list;
|
||||
GtkSizeGroup *prefix;
|
||||
GtkSizeGroup *name;
|
||||
GtkSizeGroup *enabled;
|
||||
GtkSizeGroup *parameter;
|
||||
GtkSizeGroup *state;
|
||||
GtkSizeGroup *activate;
|
||||
GHashTable *groups;
|
||||
GActionGroup *group;
|
||||
GtkWidget *button;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_BUTTON
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorActions, gtk_inspector_actions, GTK_TYPE_BOX)
|
||||
@@ -61,17 +57,12 @@ static void
|
||||
gtk_inspector_actions_init (GtkInspectorActions *sl)
|
||||
{
|
||||
sl->priv = gtk_inspector_actions_get_instance_private (sl);
|
||||
sl->priv->groups = g_hash_table_new_full (g_direct_hash,
|
||||
g_direct_equal,
|
||||
NULL,
|
||||
g_free);
|
||||
gtk_widget_init_template (GTK_WIDGET (sl));
|
||||
}
|
||||
|
||||
static void
|
||||
add_action (GtkInspectorActions *sl,
|
||||
GActionGroup *group,
|
||||
const gchar *prefix,
|
||||
const gchar *name)
|
||||
{
|
||||
gboolean enabled;
|
||||
@@ -81,7 +72,7 @@ add_action (GtkInspectorActions *sl,
|
||||
GtkWidget *row;
|
||||
GtkWidget *label;
|
||||
GtkWidget *box;
|
||||
char *key = g_strconcat (prefix, ".", name, NULL);
|
||||
char *key = g_strdup (name);
|
||||
GtkWidget *editor;
|
||||
|
||||
enabled = g_action_group_get_action_enabled (group, name);
|
||||
@@ -99,12 +90,6 @@ add_action (GtkInspectorActions *sl,
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
gtk_container_add (GTK_CONTAINER (row), box);
|
||||
|
||||
label = gtk_label_new (prefix);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (label), "cell");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_size_group_add_widget (sl->priv->prefix, label);
|
||||
gtk_container_add (GTK_CONTAINER (box), label);
|
||||
|
||||
label = gtk_label_new (name);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (label), "cell");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
@@ -114,6 +99,7 @@ add_action (GtkInspectorActions *sl,
|
||||
label = gtk_label_new (enabled ? "+" : "-");
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (label), "cell");
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
|
||||
gtk_size_group_add_widget (sl->priv->enabled, label);
|
||||
gtk_container_add (GTK_CONTAINER (box), label);
|
||||
|
||||
@@ -132,9 +118,10 @@ add_action (GtkInspectorActions *sl,
|
||||
gtk_container_add (GTK_CONTAINER (box), label);
|
||||
g_object_set_data (G_OBJECT (row), "state", label);
|
||||
|
||||
editor = gtk_inspector_action_editor_new (group, prefix, name, sl->priv->activate);
|
||||
editor = gtk_inspector_action_editor_new (group, name, sl->priv->activate);
|
||||
gtk_style_context_add_class (gtk_widget_get_style_context (editor), "cell");
|
||||
gtk_container_add (GTK_CONTAINER (box), editor);
|
||||
g_object_set_data (G_OBJECT (row), "editor", editor);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (sl->priv->list), row);
|
||||
|
||||
@@ -143,27 +130,23 @@ add_action (GtkInspectorActions *sl,
|
||||
|
||||
static GtkWidget *
|
||||
find_row (GtkInspectorActions *sl,
|
||||
const char *prefix,
|
||||
const char *action_name)
|
||||
{
|
||||
GtkWidget *row = NULL;
|
||||
GtkWidget *widget;
|
||||
char *key = g_strconcat (prefix, ".", action_name, NULL);
|
||||
|
||||
for (widget = gtk_widget_get_first_child (sl->priv->list);
|
||||
widget;
|
||||
widget = gtk_widget_get_next_sibling (widget))
|
||||
{
|
||||
const char *rkey = g_object_get_data (G_OBJECT (widget), "key");
|
||||
if (g_str_equal (key, rkey))
|
||||
const char *key = g_object_get_data (G_OBJECT (widget), "key");
|
||||
if (g_str_equal (key, action_name))
|
||||
{
|
||||
row = widget;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (key);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
@@ -172,9 +155,7 @@ action_added_cb (GActionGroup *group,
|
||||
const gchar *action_name,
|
||||
GtkInspectorActions *sl)
|
||||
{
|
||||
const gchar *prefix;
|
||||
prefix = g_hash_table_lookup (sl->priv->groups, group);
|
||||
add_action (sl, group, prefix, action_name);
|
||||
add_action (sl, group, action_name);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -182,13 +163,21 @@ action_removed_cb (GActionGroup *group,
|
||||
const gchar *action_name,
|
||||
GtkInspectorActions *sl)
|
||||
{
|
||||
const gchar *prefix;
|
||||
GtkWidget *row;
|
||||
|
||||
prefix = g_hash_table_lookup (sl->priv->groups, group);
|
||||
row = find_row (sl, prefix, action_name);
|
||||
row = find_row (sl, action_name);
|
||||
if (row)
|
||||
gtk_container_remove (GTK_CONTAINER (sl->priv->list), row);
|
||||
gtk_widget_destroy (row);
|
||||
}
|
||||
|
||||
static void
|
||||
set_row_enabled (GtkWidget *row,
|
||||
gboolean enabled)
|
||||
{
|
||||
GtkWidget *label;
|
||||
|
||||
label = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "enabled"));
|
||||
gtk_label_set_label (GTK_LABEL (label), enabled ? "+" : "-" );
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -197,31 +186,19 @@ action_enabled_changed_cb (GActionGroup *group,
|
||||
gboolean enabled,
|
||||
GtkInspectorActions *sl)
|
||||
{
|
||||
const gchar *prefix;
|
||||
GtkWidget *row;
|
||||
GtkWidget *label;
|
||||
|
||||
prefix = g_hash_table_lookup (sl->priv->groups, group);
|
||||
|
||||
row = find_row (sl, prefix, action_name);
|
||||
label = GTK_WIDGET (g_object_get_data (G_OBJECT (row), "enabled"));
|
||||
gtk_label_set_label (GTK_LABEL (label), enabled ? "+" : "-" );
|
||||
row = find_row (sl, action_name);
|
||||
set_row_enabled (row, enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
action_state_changed_cb (GActionGroup *group,
|
||||
const gchar *action_name,
|
||||
GVariant *state,
|
||||
GtkInspectorActions *sl)
|
||||
set_row_state (GtkWidget *row,
|
||||
GVariant *state)
|
||||
{
|
||||
const gchar *prefix;
|
||||
gchar *state_string;
|
||||
GtkWidget *row;
|
||||
GtkWidget *label;
|
||||
|
||||
prefix = g_hash_table_lookup (sl->priv->groups, group);
|
||||
|
||||
row = find_row (sl, prefix, action_name);
|
||||
if (state)
|
||||
state_string = g_variant_print (state, FALSE);
|
||||
else
|
||||
@@ -231,39 +208,91 @@ action_state_changed_cb (GActionGroup *group,
|
||||
g_free (state_string);
|
||||
}
|
||||
|
||||
static void
|
||||
action_state_changed_cb (GActionGroup *group,
|
||||
const gchar *action_name,
|
||||
GVariant *state,
|
||||
GtkInspectorActions *sl)
|
||||
{
|
||||
GtkWidget *row;
|
||||
|
||||
row = find_row (sl, action_name);
|
||||
set_row_state (row, state);
|
||||
}
|
||||
|
||||
static void
|
||||
refresh_all (GtkInspectorActions *sl)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
|
||||
for (widget = gtk_widget_get_first_child (sl->priv->list);
|
||||
widget;
|
||||
widget = gtk_widget_get_next_sibling (widget))
|
||||
{
|
||||
const char *name = g_object_get_data (G_OBJECT (widget), "key");
|
||||
gboolean enabled;
|
||||
GVariant *state;
|
||||
GtkInspectorActionEditor *r;
|
||||
|
||||
enabled = g_action_group_get_action_enabled (sl->priv->group, name);
|
||||
state = g_action_group_get_action_state (sl->priv->group, name);
|
||||
|
||||
set_row_enabled (widget, enabled);
|
||||
set_row_state (widget, state);
|
||||
|
||||
r = (GtkInspectorActionEditor*)g_object_get_data (G_OBJECT (widget), "editor");
|
||||
gtk_inspector_action_editor_update (r, enabled, state);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
connect_group (GActionGroup *group,
|
||||
GtkInspectorActions *sl)
|
||||
{
|
||||
g_signal_connect (group, "action-added", G_CALLBACK (action_added_cb), sl);
|
||||
g_signal_connect (group, "action-removed", G_CALLBACK (action_removed_cb), sl);
|
||||
g_signal_connect (group, "action-enabled-changed", G_CALLBACK (action_enabled_changed_cb), sl);
|
||||
g_signal_connect (group, "action-state-changed", G_CALLBACK (action_state_changed_cb), sl);
|
||||
}
|
||||
|
||||
static void
|
||||
disconnect_group (GActionGroup *group,
|
||||
GtkInspectorActions *sl)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (group, action_added_cb, sl);
|
||||
g_signal_handlers_disconnect_by_func (group, action_removed_cb, sl);
|
||||
g_signal_handlers_disconnect_by_func (group, action_enabled_changed_cb, sl);
|
||||
g_signal_handlers_disconnect_by_func (group, action_state_changed_cb, sl);
|
||||
}
|
||||
|
||||
static void
|
||||
add_group (GtkInspectorActions *sl,
|
||||
GtkStackPage *page,
|
||||
GActionGroup *group,
|
||||
const gchar *prefix)
|
||||
GActionGroup *group)
|
||||
{
|
||||
gint i;
|
||||
gchar **names;
|
||||
|
||||
g_object_set (page, "visible", TRUE, NULL);
|
||||
|
||||
g_signal_connect (group, "action-added", G_CALLBACK (action_added_cb), sl);
|
||||
g_signal_connect (group, "action-removed", G_CALLBACK (action_removed_cb), sl);
|
||||
g_signal_connect (group, "action-enabled-changed", G_CALLBACK (action_enabled_changed_cb), sl);
|
||||
g_signal_connect (group, "action-state-changed", G_CALLBACK (action_state_changed_cb), sl);
|
||||
g_hash_table_insert (sl->priv->groups, group, g_strdup (prefix));
|
||||
connect_group (group, sl);
|
||||
|
||||
names = g_action_group_list_actions (group);
|
||||
for (i = 0; names[i]; i++)
|
||||
add_action (sl, group, prefix, names[i]);
|
||||
add_action (sl, group, names[i]);
|
||||
g_strfreev (names);
|
||||
|
||||
g_set_object (&sl->priv->group, group);
|
||||
}
|
||||
|
||||
static void
|
||||
disconnect_group (gpointer key, gpointer value, gpointer data)
|
||||
remove_group (GtkInspectorActions *sl,
|
||||
GtkStackPage *page,
|
||||
GActionGroup *group)
|
||||
{
|
||||
GActionGroup *group = key;
|
||||
GtkInspectorActions *sl = data;
|
||||
disconnect_group (group, sl);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (group, action_added_cb, sl);
|
||||
g_signal_handlers_disconnect_by_func (group, action_removed_cb, sl);
|
||||
g_signal_handlers_disconnect_by_func (group, action_enabled_changed_cb, sl);
|
||||
g_signal_handlers_disconnect_by_func (group, action_state_changed_cb, sl);
|
||||
g_set_object (&sl->priv->group, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -272,43 +301,96 @@ gtk_inspector_actions_set_object (GtkInspectorActions *sl,
|
||||
{
|
||||
GtkWidget *stack;
|
||||
GtkStackPage *page;
|
||||
GtkWidget *child;
|
||||
|
||||
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);
|
||||
g_hash_table_foreach (sl->priv->groups, disconnect_group, sl);
|
||||
g_hash_table_remove_all (sl->priv->groups);
|
||||
|
||||
if (sl->priv->group)
|
||||
remove_group (sl, page, sl->priv->group);
|
||||
|
||||
while ((child = gtk_widget_get_first_child (sl->priv->list)))
|
||||
gtk_widget_destroy (child);
|
||||
|
||||
if (GTK_IS_APPLICATION (object))
|
||||
add_group (sl, page, G_ACTION_GROUP (object), "app");
|
||||
add_group (sl, page, G_ACTION_GROUP (object));
|
||||
else if (GTK_IS_WIDGET (object))
|
||||
{
|
||||
const gchar **prefixes;
|
||||
GActionGroup *group;
|
||||
gint i;
|
||||
GtkActionMuxer *muxer;
|
||||
|
||||
prefixes = gtk_widget_list_action_prefixes (GTK_WIDGET (object));
|
||||
if (prefixes)
|
||||
{
|
||||
for (i = 0; prefixes[i]; i++)
|
||||
{
|
||||
group = gtk_widget_get_action_group (GTK_WIDGET (object), prefixes[i]);
|
||||
add_group (sl, page, group, prefixes[i]);
|
||||
}
|
||||
g_free (prefixes);
|
||||
}
|
||||
muxer = _gtk_widget_get_action_muxer (GTK_WIDGET (object), FALSE);
|
||||
if (muxer)
|
||||
add_group (sl, page, G_ACTION_GROUP (muxer));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_property (GObject *object,
|
||||
guint param_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkInspectorActions *sl = GTK_INSPECTOR_ACTIONS (object);
|
||||
|
||||
switch (param_id)
|
||||
{
|
||||
case PROP_BUTTON:
|
||||
g_value_set_object (value, sl->priv->button);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_property (GObject *object,
|
||||
guint param_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkInspectorActions *sl = GTK_INSPECTOR_ACTIONS (object);
|
||||
|
||||
switch (param_id)
|
||||
{
|
||||
case PROP_BUTTON:
|
||||
sl->priv->button = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
constructed (GObject *object)
|
||||
{
|
||||
GtkInspectorActions *sl = GTK_INSPECTOR_ACTIONS (object);
|
||||
|
||||
g_signal_connect_swapped (sl->priv->button, "clicked",
|
||||
G_CALLBACK (refresh_all), sl);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_inspector_actions_class_init (GtkInspectorActionsClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->get_property = get_property;
|
||||
object_class->set_property = set_property;
|
||||
object_class->constructed = constructed;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_BUTTON,
|
||||
g_param_spec_object ("button", NULL, NULL,
|
||||
GTK_TYPE_WIDGET, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/actions.ui");
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorActions, list);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorActions, prefix);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorActions, name);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorActions, enabled);
|
||||
gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorActions, parameter);
|
||||
|
||||
@@ -20,12 +20,6 @@
|
||||
<style>
|
||||
<class name="header"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkLabel" id="prefix_heading">
|
||||
<property name="label" translatable="yes">Prefix</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="name_heading">
|
||||
<property name="label" translatable="yes">Name</property>
|
||||
@@ -73,12 +67,6 @@
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
<object class="GtkSizeGroup" id="prefix">
|
||||
<property name="mode">horizontal</property>
|
||||
<widgets>
|
||||
<widget name="prefix_heading"/>
|
||||
</widgets>
|
||||
</object>
|
||||
<object class="GtkSizeGroup" id="name">
|
||||
<property name="mode">horizontal</property>
|
||||
<widgets>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -955,7 +960,6 @@ search (GtkInspectorObjectTree *wt,
|
||||
result = search_children (child, text, forward);
|
||||
if (result)
|
||||
{
|
||||
g_print ("selecting!\n");
|
||||
gtk_inspector_object_tree_select_object (wt, result);
|
||||
g_object_unref (result);
|
||||
g_object_unref (child);
|
||||
@@ -1145,7 +1149,6 @@ create_root_model (void)
|
||||
g_object_unref);
|
||||
gtk_filter_list_model_set_model (filter, gtk_window_get_toplevels ());
|
||||
g_list_store_append (list, filter);
|
||||
g_list_store_append (list, gtk_popover_get_popovers ());
|
||||
g_object_unref (filter);
|
||||
|
||||
flatten = gtk_flatten_list_model_new (G_TYPE_OBJECT, G_LIST_MODEL (list));
|
||||
|
||||
@@ -1255,8 +1255,6 @@ action_ancestor (GtkWidget *widget)
|
||||
{
|
||||
if (GTK_IS_MENU (widget))
|
||||
return gtk_menu_get_attach_widget (GTK_MENU (widget));
|
||||
else if (GTK_IS_POPOVER (widget))
|
||||
return gtk_popover_get_relative_to (GTK_POPOVER (widget));
|
||||
else
|
||||
return gtk_widget_get_parent (widget);
|
||||
}
|
||||
@@ -1266,41 +1264,36 @@ find_action_owner (GtkActionable *actionable)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (actionable);
|
||||
const gchar *full_name;
|
||||
const gchar *dot;
|
||||
const gchar *name;
|
||||
gchar *prefix;
|
||||
GtkWidget *win;
|
||||
GActionGroup *group;
|
||||
|
||||
full_name = gtk_actionable_get_action_name (actionable);
|
||||
if (!full_name)
|
||||
return NULL;
|
||||
|
||||
dot = strchr (full_name, '.');
|
||||
prefix = g_strndup (full_name, dot - full_name);
|
||||
name = dot + 1;
|
||||
|
||||
win = gtk_widget_get_ancestor (widget, GTK_TYPE_APPLICATION_WINDOW);
|
||||
if (g_strcmp0 (prefix, "win") == 0)
|
||||
if (g_str_has_prefix (full_name, "win.") == 0)
|
||||
{
|
||||
if (G_IS_OBJECT (win))
|
||||
return (GObject *)win;
|
||||
}
|
||||
else if (g_strcmp0 (prefix, "app") == 0)
|
||||
{
|
||||
else if (g_str_has_prefix (full_name, "app.") == 0)
|
||||
{
|
||||
if (GTK_IS_WINDOW (win))
|
||||
return (GObject *)gtk_window_get_application (GTK_WINDOW (win));
|
||||
}
|
||||
|
||||
while (widget != NULL)
|
||||
{
|
||||
group = gtk_widget_get_action_group (widget, prefix);
|
||||
if (group && g_action_group_has_action (group, name))
|
||||
GtkActionMuxer *muxer;
|
||||
|
||||
muxer = _gtk_widget_get_action_muxer (widget, FALSE);
|
||||
if (muxer && gtk_action_muxer_find (muxer, full_name, NULL))
|
||||
return (GObject *)widget;
|
||||
|
||||
widget = action_ancestor (widget);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+20
-3
@@ -226,13 +226,12 @@
|
||||
<object class="GtkCenterBox">
|
||||
<child type="start">
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">10</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="icon-name">go-previous-symbolic</property>
|
||||
<property name="tooltip-text" translatable="yes">Toggle Sidebar</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="margin-start">6</property>
|
||||
<property name="margin">6</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="valign">center</property>
|
||||
<signal name="clicked" handler="toggle_sidebar"/>
|
||||
@@ -240,6 +239,7 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="object_start_stack">
|
||||
<property name="homogeneous">0</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">empty</property>
|
||||
@@ -248,11 +248,25 @@
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">actions</property>
|
||||
<property name="child">
|
||||
<object class="GtkButton" id="refresh_actions_button">
|
||||
<property name="margin">6</property>
|
||||
<property name="icon-name">view-refresh-symbolic</property>
|
||||
<property name="tooltip-text" translatable="yes">Refresh action state</property>
|
||||
<property name="relief">none</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">magnifier</property>
|
||||
<property name="child">
|
||||
<object class="GtkScale">
|
||||
<property name="margin">6</property>
|
||||
<property name="width-request">150</property>
|
||||
<property name="draw-value">0</property>
|
||||
<property name="adjustment">magnification_adjustment</property>
|
||||
@@ -276,6 +290,7 @@
|
||||
<property name="transition-type">crossfade</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="homogeneous">0</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="name">title</property>
|
||||
@@ -382,7 +397,9 @@
|
||||
<property name="name">actions</property>
|
||||
<property name="title" translatable="yes">Actions</property>
|
||||
<property name="child">
|
||||
<object class="GtkInspectorActions" id="actions"/>
|
||||
<object class="GtkInspectorActions" id="actions">
|
||||
<property name="button">refresh_actions_button</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
|
||||
@@ -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,9 @@ gtk_public_sources = files([
|
||||
'gtkcombobox.c',
|
||||
'gtkcomboboxtext.c',
|
||||
'gtkcomposetable.c',
|
||||
'gtkconstraintguide.c',
|
||||
'gtkconstraintlayout.c',
|
||||
'gtkconstraint.c',
|
||||
'gtkcontainer.c',
|
||||
'gtkcssprovider.c',
|
||||
'gtkdialog.c',
|
||||
@@ -458,6 +464,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
+519
-515
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user