1 | /* Benchmark/Themes |
2 | * |
3 | * This demo continuously switches themes, like some of you. |
4 | * |
5 | * Warning: This demo involves rapidly flashing changes and may |
6 | * be hazardous to photosensitive viewers. |
7 | */ |
8 | |
9 | #include <gtk/gtk.h> |
10 | |
11 | static guint tick_cb; |
12 | |
13 | typedef struct { |
14 | const char *name; |
15 | gboolean dark; |
16 | } Theme; |
17 | |
18 | static Theme themes[] = { |
19 | { "Adwaita" , FALSE }, |
20 | { "Adwaita" , TRUE }, |
21 | { "HighContrast" , FALSE }, |
22 | { "HighContrastInverse" , FALSE } |
23 | }; |
24 | |
25 | static int theme; |
26 | |
27 | static gboolean |
28 | change_theme (GtkWidget *widget, |
29 | GdkFrameClock *frame_clock, |
30 | gpointer data) |
31 | { |
32 | GtkWidget *label = data; |
33 | Theme next = themes[theme++ % G_N_ELEMENTS (themes)]; |
34 | char *name; |
35 | |
36 | g_object_set (object: gtk_settings_get_default (), |
37 | first_property_name: "gtk-theme-name" , next.name, |
38 | "gtk-application-prefer-dark-theme" , next.dark, |
39 | NULL); |
40 | |
41 | name = g_strconcat (string1: next.name, next.dark ? " (dark)" : NULL, NULL); |
42 | gtk_window_set_title (GTK_WINDOW (widget), title: name); |
43 | g_free (mem: name); |
44 | |
45 | if (frame_clock) |
46 | { |
47 | char *fps; |
48 | |
49 | fps = g_strdup_printf (format: "%.2f fps" , gdk_frame_clock_get_fps (frame_clock)); |
50 | gtk_label_set_label (GTK_LABEL (label), str: fps); |
51 | g_free (mem: fps); |
52 | } |
53 | else |
54 | gtk_label_set_label (GTK_LABEL (label), str: "" ); |
55 | |
56 | return G_SOURCE_CONTINUE; |
57 | } |
58 | |
59 | static void |
60 | toggle_cycle (GObject *button, |
61 | GParamSpec *pspec, |
62 | gpointer data) |
63 | { |
64 | GtkWidget *warning = data; |
65 | gboolean active; |
66 | GtkWidget *window; |
67 | |
68 | g_object_get (object: button, first_property_name: "active" , &active, NULL); |
69 | |
70 | window = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_WINDOW); |
71 | |
72 | if (active && !tick_cb) |
73 | { |
74 | gtk_window_present (GTK_WINDOW (warning)); |
75 | } |
76 | else if (!active && tick_cb) |
77 | { |
78 | gtk_widget_remove_tick_callback (widget: window, id: tick_cb); |
79 | tick_cb = 0; |
80 | } |
81 | } |
82 | |
83 | static void |
84 | warning_closed (GtkDialog *warning, |
85 | int response_id, |
86 | gpointer data) |
87 | { |
88 | GtkWidget *window; |
89 | GtkWidget *button; |
90 | |
91 | gtk_widget_hide (GTK_WIDGET (warning)); |
92 | |
93 | window = gtk_widget_get_ancestor (GTK_WIDGET (data), GTK_TYPE_WINDOW); |
94 | button = GTK_WIDGET (g_object_get_data (G_OBJECT (window), "button" )); |
95 | |
96 | if (response_id == GTK_RESPONSE_OK) |
97 | tick_cb = gtk_widget_add_tick_callback (widget: window, callback: change_theme, user_data: data, NULL); |
98 | else |
99 | gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE); |
100 | } |
101 | |
102 | GtkWidget * |
103 | do_themes (GtkWidget *do_widget) |
104 | { |
105 | static GtkWidget *window = NULL; |
106 | |
107 | if (!window) |
108 | { |
109 | GtkBuilder *builder; |
110 | GtkWidget *button; |
111 | GtkWidget *label; |
112 | GtkWidget *warning; |
113 | |
114 | builder = gtk_builder_new_from_resource (resource_path: "/themes/themes.ui" ); |
115 | window = GTK_WIDGET (gtk_builder_get_object (builder, "window" )); |
116 | g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window); |
117 | gtk_window_set_display (GTK_WINDOW (window), |
118 | display: gtk_widget_get_display (widget: do_widget)); |
119 | |
120 | label = GTK_WIDGET (gtk_builder_get_object (builder, "fps" )); |
121 | warning = GTK_WIDGET (gtk_builder_get_object (builder, "warning" )); |
122 | g_signal_connect (warning, "response" , G_CALLBACK (warning_closed), label); |
123 | |
124 | button = GTK_WIDGET (gtk_builder_get_object (builder, "toggle" )); |
125 | g_object_set_data (G_OBJECT (window), key: "button" , data: button); |
126 | g_signal_connect (button, "notify::active" , G_CALLBACK (toggle_cycle), warning); |
127 | gtk_widget_realize (widget: window); |
128 | |
129 | g_object_unref (object: builder); |
130 | } |
131 | |
132 | if (!gtk_widget_get_visible (widget: window)) |
133 | gtk_widget_show (widget: window); |
134 | else |
135 | gtk_window_destroy (GTK_WINDOW (window)); |
136 | |
137 | return window; |
138 | } |
139 | |