1 #include <gtk/gtk.h>
2 
3 #if 0
4 #define gtk_event_controller_motion_new gtk_drop_controller_motion_new
5 #define gtk_event_controller_motion_contains_pointer gtk_drop_controller_motion_contains_pointer
6 #define gtk_event_controller_motion_is_pointer gtk_drop_controller_motion_is_pointer
7 #undef GTK_EVENT_CONTROLLER_MOTION
8 #define GTK_EVENT_CONTROLLER_MOTION GTK_DROP_CONTROLLER_MOTION
9 #endif
10 
11 static void
quit_cb(GtkWidget * widget,gpointer unused)12 quit_cb (GtkWidget *widget,
13          gpointer   unused)
14 {
15   g_main_context_wakeup (NULL);
16 }
17 
18 static void
enter_annoy_cb(GtkEventController * controller,double x,double y)19 enter_annoy_cb (GtkEventController *controller,
20                 double              x,
21                 double              y)
22 {
23   GtkWidget *widget = gtk_event_controller_get_widget (controller);
24   GtkWindow *window = GTK_WINDOW (gtk_widget_get_root (widget));
25 
26   g_print ("%15s ENTER %s %g, %g\n",
27            gtk_window_get_title (window),
28            gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller))
29            ? gtk_event_controller_motion_is_pointer (GTK_EVENT_CONTROLLER_MOTION (controller))
30              ? "IS     "
31              : "CONTAIN"
32              : "       ",
33            x, y);
34 }
35 
36 static void
motion_annoy_cb(GtkEventController * controller,double x,double y)37 motion_annoy_cb (GtkEventController *controller,
38                  double              x,
39                  double              y)
40 {
41   GtkWidget *widget = gtk_event_controller_get_widget (controller);
42   GtkWindow *window = GTK_WINDOW (gtk_widget_get_root (widget));
43 
44   g_print ("%15s MOVE  %s %g, %g\n",
45            gtk_window_get_title (window),
46            gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller))
47            ? gtk_event_controller_motion_is_pointer (GTK_EVENT_CONTROLLER_MOTION (controller))
48              ? "IS     "
49              : "CONTAIN"
50              : "       ",
51            x, y);
52 }
53 
54 static void
leave_annoy_cb(GtkEventController * controller)55 leave_annoy_cb (GtkEventController *controller)
56 {
57   GtkWidget *widget = gtk_event_controller_get_widget (controller);
58   GtkWindow *window = GTK_WINDOW (gtk_widget_get_root (widget));
59 
60   g_print ("%15s LEAVE %s\n",
61            gtk_window_get_title (window),
62            gtk_event_controller_motion_contains_pointer (GTK_EVENT_CONTROLLER_MOTION (controller))
63            ? gtk_event_controller_motion_is_pointer (GTK_EVENT_CONTROLLER_MOTION (controller))
64              ? "IS     "
65              : "CONTAIN"
66              : "       ");
67 }
68 
69 static GtkEventController *
annoying_event_controller_motion_new(void)70 annoying_event_controller_motion_new (void)
71 {
72   GtkEventController *controller = gtk_event_controller_motion_new ();
73 
74   g_signal_connect (controller, "enter", G_CALLBACK (enter_annoy_cb), NULL);
75   g_signal_connect (controller, "motion", G_CALLBACK (motion_annoy_cb), NULL);
76   g_signal_connect (controller, "leave", G_CALLBACK (leave_annoy_cb), NULL);
77 
78   return controller;
79 }
80 
81 /*** TEST 1: remove()/add() ***/
82 
83 static void
enter1_cb(GtkEventController * controller)84 enter1_cb (GtkEventController *controller)
85 {
86   GtkWidget *box = gtk_event_controller_get_widget (controller);
87 
88   gtk_box_remove (GTK_BOX (box), gtk_widget_get_first_child (box));
89   gtk_box_append (GTK_BOX (box), gtk_label_new ("HOVER!"));
90 }
91 
92 static void
leave1_cb(GtkEventController * controller)93 leave1_cb (GtkEventController *controller)
94 {
95   GtkWidget *box = gtk_event_controller_get_widget (controller);
96 
97   gtk_box_remove (GTK_BOX (box), gtk_widget_get_first_child (box));
98   gtk_box_append (GTK_BOX (box), gtk_image_new_from_icon_name ("start-here"));
99 }
100 
101 static void
test1(void)102 test1 (void)
103 {
104   GtkWidget *win;
105   GtkWidget *box;
106   GtkEventController *controller;
107   win = gtk_window_new ();
108   gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
109   gtk_window_set_title (GTK_WINDOW (win), "add/remove");
110 
111   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE);
112   gtk_window_set_child (GTK_WINDOW (win), box);
113   controller = annoying_event_controller_motion_new ();
114   g_signal_connect (controller, "enter", G_CALLBACK (enter1_cb), NULL);
115   g_signal_connect (controller, "leave", G_CALLBACK (leave1_cb), NULL);
116   gtk_widget_add_controller (box, controller);
117 
118   gtk_box_append (GTK_BOX (box), gtk_image_new_from_icon_name ("start-here"));
119 
120   gtk_widget_show (win);
121 
122   g_signal_connect (win, "destroy", G_CALLBACK (quit_cb), NULL);
123 }
124 
125 /*** TEST 2: hide()/show() ***/
126 
127 static void
enter2_cb(GtkEventController * controller)128 enter2_cb (GtkEventController *controller)
129 {
130   GtkWidget *box = gtk_event_controller_get_widget (controller);
131 
132   gtk_widget_hide (gtk_widget_get_first_child (box));
133   gtk_widget_show (gtk_widget_get_last_child (box));
134 }
135 
136 static void
leave2_cb(GtkEventController * controller)137 leave2_cb (GtkEventController *controller)
138 {
139   GtkWidget *box = gtk_event_controller_get_widget (controller);
140 
141   gtk_widget_show (gtk_widget_get_first_child (box));
142   gtk_widget_hide (gtk_widget_get_last_child (box));
143 }
144 
145 static void
test2(void)146 test2 (void)
147 {
148   GtkWidget *win;
149   GtkWidget *box;
150   GtkEventController *controller;
151   win = gtk_window_new ();
152   gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
153   gtk_window_set_title (GTK_WINDOW (win), "show/hide");
154 
155   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, FALSE);
156   gtk_window_set_child (GTK_WINDOW (win), box);
157   controller = annoying_event_controller_motion_new ();
158   g_signal_connect (controller, "enter", G_CALLBACK (enter2_cb), NULL);
159   g_signal_connect (controller, "leave", G_CALLBACK (leave2_cb), NULL);
160   gtk_widget_add_controller (box, controller);
161 
162   gtk_box_append (GTK_BOX (box), gtk_image_new_from_icon_name ("start-here"));
163   gtk_box_append (GTK_BOX (box), gtk_label_new ("HOVER!"));
164   gtk_widget_hide (gtk_widget_get_last_child (box));
165 
166   gtk_widget_show (win);
167 
168   g_signal_connect (win, "destroy", G_CALLBACK (quit_cb), NULL);
169 }
170 
171 /*** TEST 3: set_child_visible() ***/
172 
173 static void
enter3_cb(GtkEventController * controller)174 enter3_cb (GtkEventController *controller)
175 {
176   GtkWidget *stack = gtk_event_controller_get_widget (controller);
177 
178   gtk_stack_set_visible_child_name (GTK_STACK (stack), "enter");
179 }
180 
181 static void
leave3_cb(GtkEventController * controller)182 leave3_cb (GtkEventController *controller)
183 {
184   GtkWidget *stack = gtk_event_controller_get_widget (controller);
185 
186   gtk_stack_set_visible_child_name (GTK_STACK (stack), "leave");
187 }
188 
189 static void
test3(void)190 test3 (void)
191 {
192   GtkWidget *win;
193   GtkWidget *stack;
194   GtkEventController *controller;
195   win = gtk_window_new ();
196   gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
197   gtk_window_set_title (GTK_WINDOW (win), "child-visible");
198 
199   stack = gtk_stack_new ();
200   gtk_window_set_child (GTK_WINDOW (win), stack);
201   controller = annoying_event_controller_motion_new ();
202   g_signal_connect (controller, "enter", G_CALLBACK (enter3_cb), NULL);
203   g_signal_connect (controller, "leave", G_CALLBACK (leave3_cb), NULL);
204   gtk_widget_add_controller (stack, controller);
205 
206   gtk_stack_add_named (GTK_STACK (stack), gtk_image_new_from_icon_name ("start-here"), "leave");
207   gtk_stack_add_named (GTK_STACK (stack), gtk_label_new ("HOVER!"), "enter");
208   gtk_stack_set_visible_child_name (GTK_STACK (stack), "leave");
209 
210   gtk_widget_show (win);
211 
212   g_signal_connect (win, "destroy", G_CALLBACK (quit_cb), NULL);
213 }
214 
215 /*** TEST 4: move ***/
216 
217 static void
enter4_cb(GtkEventController * controller)218 enter4_cb (GtkEventController *controller)
219 {
220   GtkWidget *fixed = gtk_event_controller_get_widget (controller);
221 
222   gtk_fixed_move (GTK_FIXED (fixed), gtk_widget_get_first_child (fixed), -1000, -1000);
223   gtk_fixed_move (GTK_FIXED (fixed), gtk_widget_get_last_child (fixed), 0, 0);
224 }
225 
226 static void
leave4_cb(GtkEventController * controller)227 leave4_cb (GtkEventController *controller)
228 {
229   GtkWidget *fixed = gtk_event_controller_get_widget (controller);
230 
231   gtk_fixed_move (GTK_FIXED (fixed), gtk_widget_get_first_child (fixed), 0, 0);
232   gtk_fixed_move (GTK_FIXED (fixed), gtk_widget_get_last_child (fixed), -1000, -1000);
233 }
234 
235 static void
test4(void)236 test4 (void)
237 {
238   GtkWidget *win;
239   GtkWidget *fixed;
240   GtkEventController *controller;
241   win = gtk_window_new ();
242   gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
243   gtk_window_set_title (GTK_WINDOW (win), "move");
244 
245   fixed = gtk_fixed_new ();
246   gtk_window_set_child (GTK_WINDOW (win), fixed);
247   controller = annoying_event_controller_motion_new ();
248   g_signal_connect (controller, "enter", G_CALLBACK (enter4_cb), NULL);
249   g_signal_connect (controller, "leave", G_CALLBACK (leave4_cb), NULL);
250   gtk_widget_add_controller (fixed, controller);
251 
252   gtk_fixed_put (GTK_FIXED (fixed), gtk_image_new_from_icon_name ("start-here"), 0, 0);
253   gtk_fixed_put (GTK_FIXED (fixed), gtk_label_new ("HOVER!"), -1000, -1000);
254 
255   gtk_widget_show (win);
256 
257   g_signal_connect (win, "destroy", G_CALLBACK (quit_cb), NULL);
258 }
259 
260 int
main(int argc,char * argv[])261 main (int argc, char *argv[])
262 {
263   GtkCssProvider *provider;
264 
265   gtk_init ();
266 
267   provider = gtk_css_provider_new ();
268   gtk_css_provider_load_from_data (provider,
269       ":hover {"
270       "   box-shadow: inset 0px 0px 0px 1px red;"
271       " }"
272       " window :not(.title):hover {"
273       "   background: yellow;"
274       " }"
275       " window :not(.title):hover * {"
276       "   background: goldenrod;"
277       " }",
278       -1);
279   gtk_style_context_add_provider_for_display (gdk_display_get_default (), GTK_STYLE_PROVIDER (provider), 800);
280   g_object_unref (provider);
281 
282   test1();
283   test2();
284   test3();
285   test4();
286 
287   while (gtk_window_list_toplevels ())
288     g_main_context_iteration (NULL, TRUE);
289 
290   return 0;
291 }
292