1 | #include <gtk/gtk.h> |
2 | |
3 | static void |
4 | update_offset (GObject *object, |
5 | GParamSpec *pspec, |
6 | GtkWidget *widget) |
7 | { |
8 | if (gtk_check_button_get_active (GTK_CHECK_BUTTON (object))) |
9 | gtk_popover_set_offset (GTK_POPOVER (widget), x_offset: 12, y_offset: 12); |
10 | else |
11 | gtk_popover_set_offset (GTK_POPOVER (widget), x_offset: 0, y_offset: 0); |
12 | } |
13 | |
14 | static void |
15 | update_shadow (GObject *object, |
16 | GParamSpec *pspec, |
17 | GtkWidget *widget) |
18 | { |
19 | const char *classes[] = { |
20 | "no-shadow" , |
21 | "shadow1" , |
22 | "shadow2" , |
23 | "shadow3" , |
24 | "shadow4" , |
25 | }; |
26 | guint selected; |
27 | |
28 | selected = gtk_drop_down_get_selected (self: GTK_DROP_DOWN (ptr: object)); |
29 | g_assert (selected < G_N_ELEMENTS (classes)); |
30 | |
31 | for (int i = 0; i < G_N_ELEMENTS (classes); i++) |
32 | gtk_widget_remove_css_class (widget, css_class: classes[i]); |
33 | |
34 | gtk_widget_add_css_class (widget, css_class: classes[selected]); |
35 | } |
36 | |
37 | static const char css[] = |
38 | "popover.no-shadow > contents { box-shadow: none; }\n" |
39 | "popover.shadow1 > contents { box-shadow: 6px 6px rgba(128,0,255,0.5); }\n" |
40 | "popover.shadow2 > contents { box-shadow: -6px -6px rgba(255,0,0,0.5), 6px 6px rgba(128,0,255,0.5); }\n" |
41 | "popover.shadow3 > contents { box-shadow: -6px -6px rgba(255,0,0,0.5), 18px 18px rgba(128,0,255,0.5); }\n" |
42 | "popover.shadow4 > contents { box-shadow: -18px -18px rgba(255,0,0,0.5), 18px 18px rgba(128,0,255,0.5); }\n" ; |
43 | |
44 | int |
45 | main (int argc, char *argv[]) |
46 | { |
47 | GtkWidget *window; |
48 | GtkWidget *box; |
49 | GtkWidget *button; |
50 | GtkWidget *popover; |
51 | GtkWidget *box2; |
52 | GtkWidget *box3; |
53 | GtkWidget *checkbox; |
54 | GtkWidget *checkbox2; |
55 | GtkWidget *dropdown; |
56 | GtkWidget *dropdown2; |
57 | GtkCssProvider *provider; |
58 | |
59 | gtk_init (); |
60 | |
61 | provider = gtk_css_provider_new (); |
62 | gtk_css_provider_load_from_data (css_provider: provider, data: css, length: -1); |
63 | |
64 | gtk_style_context_add_provider_for_display (display: gdk_display_get_default (), |
65 | GTK_STYLE_PROVIDER (provider), |
66 | priority: 800); |
67 | |
68 | window = gtk_window_new (); |
69 | box = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 10); |
70 | g_object_set (object: box, |
71 | first_property_name: "margin-top" , 20, |
72 | "margin-bottom" , 20, |
73 | "margin-start" , 20, |
74 | "margin-end" , 20, |
75 | NULL); |
76 | |
77 | button = gtk_menu_button_new (); |
78 | |
79 | gtk_widget_set_halign (widget: button, align: GTK_ALIGN_CENTER); |
80 | gtk_widget_set_valign (widget: button, align: GTK_ALIGN_CENTER); |
81 | |
82 | gtk_box_append (GTK_BOX (box), child: button); |
83 | |
84 | popover = gtk_popover_new (); |
85 | box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10); |
86 | gtk_popover_set_child (GTK_POPOVER (popover), child: box2); |
87 | |
88 | gtk_box_append (GTK_BOX (box2), child: gtk_label_new (str: "First item" )); |
89 | gtk_box_append (GTK_BOX (box2), child: gtk_label_new (str: "Second item" )); |
90 | gtk_box_append (GTK_BOX (box2), child: gtk_label_new (str: "Third item" )); |
91 | |
92 | gtk_menu_button_set_popover (GTK_MENU_BUTTON (button), popover); |
93 | |
94 | box3 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10); |
95 | dropdown = gtk_drop_down_new_from_strings (strings: (const char*[]){ "Left" , "Right" , "Top" , "Bottom" , NULL }); |
96 | gtk_drop_down_set_selected (self: GTK_DROP_DOWN (ptr: dropdown), position: 3); |
97 | |
98 | checkbox = gtk_check_button_new_with_label (label: "Arrow" ); |
99 | |
100 | checkbox2 = gtk_check_button_new_with_label (label: "Offset" ); |
101 | |
102 | dropdown2 = gtk_drop_down_new_from_strings (strings: (const char*[]){ "No Shadow" , "Shadow 1" , "Shadow 2" , "Shadow 3" , "Shadow 4" , NULL }); |
103 | |
104 | gtk_box_append (GTK_BOX (box3), child: checkbox); |
105 | gtk_box_append (GTK_BOX (box3), child: checkbox2); |
106 | gtk_box_append (GTK_BOX (box3), child: dropdown); |
107 | gtk_box_append (GTK_BOX (box3), child: dropdown2); |
108 | |
109 | gtk_box_append (GTK_BOX (box), child: box3); |
110 | |
111 | g_object_bind_property (source: checkbox, source_property: "active" , |
112 | target: popover, target_property: "has-arrow" , |
113 | flags: G_BINDING_SYNC_CREATE); |
114 | g_signal_connect (checkbox2, "notify::active" , |
115 | G_CALLBACK (update_offset), popover); |
116 | g_object_bind_property (source: dropdown, source_property: "selected" , |
117 | target: popover, target_property: "position" , |
118 | flags: G_BINDING_SYNC_CREATE); |
119 | g_signal_connect (dropdown2, "notify::selected" , |
120 | G_CALLBACK (update_shadow), popover); |
121 | update_shadow (G_OBJECT (dropdown2), NULL, widget: popover); |
122 | |
123 | gtk_window_set_child (GTK_WINDOW (window), child: box); |
124 | |
125 | gtk_window_present (GTK_WINDOW (window)); |
126 | |
127 | while (g_list_model_get_n_items (list: gtk_window_get_toplevels ()) > 0) |
128 | g_main_context_iteration (NULL, TRUE); |
129 | |
130 | return 0; |
131 | } |
132 | |