1 | /* Builder |
2 | * #Keywords: GMenu, GtkPopoverMenuBar, GtkBuilder, GtkStatusBar, GtkShortcutController, toolbar |
3 | * |
4 | * Demonstrates a traditional interface, loaded from a XML description, |
5 | * and shows how to connect actions to the menu items and toolbar buttons. |
6 | */ |
7 | |
8 | #include <gtk/gtk.h> |
9 | |
10 | static void |
11 | quit_activate (GSimpleAction *action, |
12 | GVariant *parameter, |
13 | gpointer user_data) |
14 | { |
15 | GtkWidget *window = user_data; |
16 | |
17 | gtk_window_destroy (GTK_WINDOW (window)); |
18 | } |
19 | |
20 | static void |
21 | about_activate (GSimpleAction *action, |
22 | GVariant *parameter, |
23 | gpointer user_data) |
24 | { |
25 | GtkWidget *window = user_data; |
26 | GtkWidget *about_dlg; |
27 | |
28 | about_dlg = GTK_WIDGET (g_object_get_data (G_OBJECT (window), "about" )); |
29 | gtk_window_present (GTK_WINDOW (about_dlg)); |
30 | } |
31 | |
32 | static void |
33 | remove_timeout (gpointer data) |
34 | { |
35 | guint id = GPOINTER_TO_UINT (data); |
36 | |
37 | g_source_remove (tag: id); |
38 | } |
39 | |
40 | static gboolean |
41 | pop_status (gpointer data) |
42 | { |
43 | gtk_statusbar_pop (GTK_STATUSBAR (data), context_id: 0); |
44 | g_object_set_data (G_OBJECT (data), key: "timeout" , NULL); |
45 | return G_SOURCE_REMOVE; |
46 | } |
47 | |
48 | static void |
49 | status_message (GtkStatusbar *status, |
50 | const char *text) |
51 | { |
52 | guint id; |
53 | |
54 | gtk_statusbar_push (GTK_STATUSBAR (status), context_id: 0, text); |
55 | id = g_timeout_add (interval: 5000, function: pop_status, data: status); |
56 | |
57 | g_object_set_data_full (G_OBJECT (status), key: "timeout" , GUINT_TO_POINTER (id), destroy: remove_timeout); |
58 | } |
59 | |
60 | static void |
61 | help_activate (GSimpleAction *action, |
62 | GVariant *parameter, |
63 | gpointer user_data) |
64 | { |
65 | GtkWidget *status; |
66 | |
67 | status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status" )); |
68 | status_message (GTK_STATUSBAR (status), text: "Help not available" ); |
69 | } |
70 | |
71 | static void |
72 | not_implemented (GSimpleAction *action, |
73 | GVariant *parameter, |
74 | gpointer user_data) |
75 | { |
76 | GtkWidget *status; |
77 | char *text; |
78 | |
79 | text = g_strdup_printf (format: "Action ā%sā not implemented" , g_action_get_name (G_ACTION (action))); |
80 | status = GTK_WIDGET (g_object_get_data (G_OBJECT (user_data), "status" )); |
81 | status_message (GTK_STATUSBAR (status), text); |
82 | g_free (mem: text); |
83 | } |
84 | |
85 | static GActionEntry win_entries[] = { |
86 | { "new" , not_implemented, NULL, NULL, NULL }, |
87 | { "open" , not_implemented, NULL, NULL, NULL }, |
88 | { "save" , not_implemented, NULL, NULL, NULL }, |
89 | { "save-as" , not_implemented, NULL, NULL, NULL }, |
90 | { "copy" , not_implemented, NULL, NULL, NULL }, |
91 | { "cut" , not_implemented, NULL, NULL, NULL }, |
92 | { "paste" , not_implemented, NULL, NULL, NULL }, |
93 | { "quit" , quit_activate, NULL, NULL, NULL }, |
94 | { "about" , about_activate, NULL, NULL, NULL }, |
95 | { "help" , help_activate, NULL, NULL, NULL } |
96 | }; |
97 | |
98 | GtkWidget * |
99 | do_builder (GtkWidget *do_widget) |
100 | { |
101 | static GtkWidget *window = NULL; |
102 | GActionGroup *actions; |
103 | |
104 | if (!window) |
105 | { |
106 | GtkBuilder *builder; |
107 | GtkWidget *about; |
108 | GtkWidget *status; |
109 | GtkEventController *controller; |
110 | |
111 | builder = gtk_builder_new_from_resource (resource_path: "/builder/demo.ui" ); |
112 | |
113 | window = GTK_WIDGET (gtk_builder_get_object (builder, "window1" )); |
114 | gtk_window_set_display (GTK_WINDOW (window), |
115 | display: gtk_widget_get_display (widget: do_widget)); |
116 | g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window); |
117 | actions = (GActionGroup*)g_simple_action_group_new (); |
118 | g_action_map_add_action_entries (G_ACTION_MAP (actions), |
119 | entries: win_entries, G_N_ELEMENTS (win_entries), |
120 | user_data: window); |
121 | gtk_widget_insert_action_group (widget: window, name: "win" , group: actions); |
122 | |
123 | controller = gtk_shortcut_controller_new (); |
124 | gtk_shortcut_controller_set_scope (GTK_SHORTCUT_CONTROLLER (controller), |
125 | scope: GTK_SHORTCUT_SCOPE_GLOBAL); |
126 | gtk_widget_add_controller (widget: window, controller); |
127 | gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller), |
128 | shortcut: gtk_shortcut_new (trigger: gtk_keyval_trigger_new (GDK_KEY_n, modifiers: GDK_CONTROL_MASK), |
129 | action: gtk_named_action_new (name: "win.new" ))); |
130 | gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller), |
131 | shortcut: gtk_shortcut_new (trigger: gtk_keyval_trigger_new (GDK_KEY_o, modifiers: GDK_CONTROL_MASK), |
132 | action: gtk_named_action_new (name: "win.open" ))); |
133 | gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller), |
134 | shortcut: gtk_shortcut_new (trigger: gtk_keyval_trigger_new (GDK_KEY_s, modifiers: GDK_CONTROL_MASK), |
135 | action: gtk_named_action_new (name: "win.save" ))); |
136 | gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller), |
137 | shortcut: gtk_shortcut_new (trigger: gtk_keyval_trigger_new (GDK_KEY_s, modifiers: GDK_CONTROL_MASK|GDK_SHIFT_MASK), |
138 | action: gtk_named_action_new (name: "win.save-as" ))); |
139 | gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller), |
140 | shortcut: gtk_shortcut_new (trigger: gtk_keyval_trigger_new (GDK_KEY_q, modifiers: GDK_CONTROL_MASK), |
141 | action: gtk_named_action_new (name: "win.quit" ))); |
142 | gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller), |
143 | shortcut: gtk_shortcut_new (trigger: gtk_keyval_trigger_new (GDK_KEY_c, modifiers: GDK_CONTROL_MASK), |
144 | action: gtk_named_action_new (name: "win.copy" ))); |
145 | gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller), |
146 | shortcut: gtk_shortcut_new (trigger: gtk_keyval_trigger_new (GDK_KEY_x, modifiers: GDK_CONTROL_MASK), |
147 | action: gtk_named_action_new (name: "win.cut" ))); |
148 | gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller), |
149 | shortcut: gtk_shortcut_new (trigger: gtk_keyval_trigger_new (GDK_KEY_v, modifiers: GDK_CONTROL_MASK), |
150 | action: gtk_named_action_new (name: "win.paste" ))); |
151 | gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller), |
152 | shortcut: gtk_shortcut_new (trigger: gtk_keyval_trigger_new (GDK_KEY_F1, modifiers: 0), |
153 | action: gtk_named_action_new (name: "win.help" ))); |
154 | gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER (controller), |
155 | shortcut: gtk_shortcut_new (trigger: gtk_keyval_trigger_new (GDK_KEY_F7, modifiers: 0), |
156 | action: gtk_named_action_new (name: "win.about" ))); |
157 | |
158 | about = GTK_WIDGET (gtk_builder_get_object (builder, "aboutdialog1" )); |
159 | gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (window)); |
160 | gtk_window_set_hide_on_close (GTK_WINDOW (about), TRUE); |
161 | g_object_set_data_full (G_OBJECT (window), key: "about" , |
162 | data: about, destroy: (GDestroyNotify)gtk_window_destroy); |
163 | |
164 | status = GTK_WIDGET (gtk_builder_get_object (builder, "statusbar1" )); |
165 | g_object_set_data (G_OBJECT (window), key: "status" , data: status); |
166 | |
167 | g_object_unref (object: builder); |
168 | } |
169 | |
170 | if (!gtk_widget_get_visible (widget: window)) |
171 | gtk_widget_show (widget: window); |
172 | else |
173 | gtk_window_destroy (GTK_WINDOW (window)); |
174 | |
175 | return window; |
176 | } |
177 | |