]> sigrok.org Git - sigrok-gtk.git/blame - toolbar.c
gtk: Consistent 'sigrok' spelling.
[sigrok-gtk.git] / toolbar.c
CommitLineData
3f63165c
UH
1/*
2 * This file is part of the sigrok project.
3 *
4 * Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <stdlib.h>
21
22#include <sigrok.h>
23
24#include <gtk/gtk.h>
25
26#include <stdlib.h>
27
28#include "sigrok-gtk.h"
29
30enum {
43132a90 31 DEV_PROP_HWCAP,
3f63165c
UH
32 DEV_PROP_TYPE,
33 DEV_PROP_SHORTNAME,
34 DEV_PROP_DESCRIPTION,
35 DEV_PROP_IS_TEXT,
36 DEV_PROP_TEXTVALUE,
37 DEV_PROP_BOOLVALUE,
38 MAX_DEV_PROP
39};
40
41static void prop_edited(GtkCellRendererText *cel, gchar *path, gchar *text,
42 GtkListStore *props)
43{
44 (void)cel;
45
ffe80b55 46 struct sr_dev *dev = g_object_get_data(G_OBJECT(props), "dev");
3f63165c
UH
47 GtkTreeIter iter;
48 int type, cap;
49 guint64 tmp_u64;
50 int ret = SR_ERR;
51
52 gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(props), &iter, path);
53 gtk_tree_model_get(GTK_TREE_MODEL(props), &iter,
43132a90 54 DEV_PROP_HWCAP, &cap,
3f63165c
UH
55 DEV_PROP_TYPE, &type, -1);
56
57 switch (type) {
58 case SR_T_UINT64:
59 if (sr_parse_sizestring(text, &tmp_u64) != SR_OK)
60 return;
61
a4f48bca 62 ret = dev->driver->dev_config_set(dev->driver_index,
31345264 63 cap, &tmp_u64);
3f63165c
UH
64 break;
65 case SR_T_CHAR:
a4f48bca 66 ret = dev->driver->dev_config_set(dev->driver_index, cap, text);
3f63165c
UH
67 break;
68 /* SR_T_BOOL will be handled by prop_toggled */
69 }
70
71 if (!ret)
72 gtk_list_store_set(props, &iter, DEV_PROP_TEXTVALUE, text, -1);
73}
74
75static void prop_toggled(GtkCellRendererToggle *cel, gchar *path,
76 GtkListStore *props)
77{
ffe80b55 78 struct sr_dev *dev = g_object_get_data(G_OBJECT(props), "dev");
3f63165c
UH
79 GtkTreeIter iter;
80 int type, cap;
81 int ret;
82 gboolean val;
83 gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(props), &iter, path);
84 gtk_tree_model_get(GTK_TREE_MODEL(props), &iter,
43132a90 85 DEV_PROP_HWCAP, &cap,
3f63165c
UH
86 DEV_PROP_TYPE, &type, -1);
87
88 val = !gtk_cell_renderer_toggle_get_active(cel);
a4f48bca 89 ret = dev->driver->dev_config_set(dev->driver_index, cap,
31345264 90 GINT_TO_POINTER(val));
3f63165c
UH
91
92 if (!ret)
93 gtk_list_store_set(props, &iter, DEV_PROP_BOOLVALUE, val, -1);
94}
95
96void dev_prop_bool_data_func(GtkCellLayout *cell_layout,
97 GtkCellRenderer *cell,
98 GtkTreeModel *tree_model,
99 GtkTreeIter *iter,
100 gpointer data)
101{
102 (void)cell_layout;
103 (void)data;
104
105 gboolean istext, val;
106 gtk_tree_model_get(tree_model, iter,
107 DEV_PROP_IS_TEXT, &istext,
108 DEV_PROP_BOOLVALUE, &val, -1);
109 g_object_set(G_OBJECT(cell), "visible", !istext, "active", val, NULL);
110}
111
112static void dev_set_options(GtkAction *action, GtkWindow *parent)
113{
114 (void)action;
115
ffe80b55
UH
116 struct sr_dev *dev = g_object_get_data(G_OBJECT(parent), "dev");
117 if (!dev)
3f63165c
UH
118 return;
119
120 GtkWidget *dialog = gtk_dialog_new_with_buttons("Device Properties",
121 parent, GTK_DIALOG_MODAL,
122 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
123 NULL);
124 GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL);
125 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
126 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
127 gtk_widget_set_size_request(sw, 300, 200);
128 GtkWidget *tv = gtk_tree_view_new();
129 gtk_container_add(GTK_CONTAINER(sw), tv);
130 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), sw,
131 TRUE, TRUE, 0);
132
133 /* Populate list store with config options */
134 GtkListStore *props = gtk_list_store_new(MAX_DEV_PROP,
135 G_TYPE_INT, G_TYPE_INT,
136 G_TYPE_STRING, G_TYPE_STRING,
137 G_TYPE_BOOLEAN, G_TYPE_STRING,
138 G_TYPE_BOOLEAN);
139 gtk_tree_view_set_model(GTK_TREE_VIEW(tv), GTK_TREE_MODEL(props));
a4f48bca 140 int *hwcaps = dev->driver->hwcap_get_all();
3f63165c
UH
141 int cap;
142 GtkTreeIter iter;
43132a90 143 for (cap = 0; hwcaps[cap]; cap++) {
3f63165c 144 struct sr_hwcap_option *hwo;
43132a90 145 if (!(hwo = sr_hw_hwcap_get(hwcaps[cap])))
3f63165c
UH
146 continue;
147 gtk_list_store_append(props, &iter);
148 gtk_list_store_set(props, &iter,
43132a90 149 DEV_PROP_HWCAP, hwcaps[cap],
3f63165c
UH
150 DEV_PROP_TYPE, hwo->type,
151 DEV_PROP_SHORTNAME, hwo->shortname,
152 DEV_PROP_DESCRIPTION, hwo->description,
153 DEV_PROP_IS_TEXT, hwo->type != SR_T_BOOL,
154 -1);
155 }
156
157 /* Popup tooltop containing description if mouse hovers */
158 gtk_tree_view_set_tooltip_column(GTK_TREE_VIEW(tv),
159 DEV_PROP_DESCRIPTION);
160
161 /* Save device with list so that property can be set by edited
162 * handler. */
ffe80b55 163 g_object_set_data(G_OBJECT(props), "dev", dev);
3f63165c
UH
164
165 /* Add columns to the tree view */
166 GtkTreeViewColumn *col;
167 col = gtk_tree_view_column_new_with_attributes("Property",
168 gtk_cell_renderer_text_new(),
169 "text", DEV_PROP_SHORTNAME, NULL);
170 gtk_tree_view_append_column(GTK_TREE_VIEW(tv), col);
171 /* We pack both a text and toggle renderer. Only one will be visible.
172 * depending on type.
173 */
174 GtkCellRenderer *cel = gtk_cell_renderer_text_new();
175 g_object_set(cel, "editable", TRUE, NULL);
176 g_signal_connect(cel, "edited", G_CALLBACK(prop_edited), props);
177 col = gtk_tree_view_column_new_with_attributes("Value",
178 cel, "text", DEV_PROP_TEXTVALUE,
179 "visible", DEV_PROP_IS_TEXT, NULL);
180 cel = gtk_cell_renderer_toggle_new();
181 g_signal_connect(cel, "toggled", G_CALLBACK(prop_toggled), props);
182 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(col), cel, TRUE);
183 gtk_cell_layout_set_cell_data_func(GTK_CELL_LAYOUT(col), cel,
184 dev_prop_bool_data_func, NULL, NULL);
185 gtk_tree_view_append_column(GTK_TREE_VIEW(tv), col);
186
187
188 gtk_widget_show_all(dialog);
189 gtk_dialog_run(GTK_DIALOG(dialog));
190
191 gtk_widget_destroy(dialog);
192}
193
194enum {
195 PROBE_NUMBER,
196 PROBE_ENABLED,
197 PROBE_NAME,
198 PROBE_TRIGGER,
199 MAX_PROBE
200};
201
202static void probe_toggled(GtkCellRenderer *cel, gchar *path,
203 GtkTreeModel *probes)
204{
ffe80b55 205 struct sr_dev *dev = g_object_get_data(G_OBJECT(probes), "dev");
3f63165c
UH
206 GtkTreeIter iter;
207 struct sr_probe *probe;
208 gint i;
209 gboolean en;
210
211 (void)cel;
212
213 gtk_tree_model_get_iter_from_string(probes, &iter, path);
214 gtk_tree_model_get(probes, &iter, PROBE_NUMBER, &i,
215 PROBE_ENABLED, &en, -1);
ffe80b55 216 probe = sr_dev_probe_find(dev, i);
3f63165c
UH
217 probe->enabled = !en;
218 gtk_list_store_set(GTK_LIST_STORE(probes), &iter,
219 PROBE_ENABLED, probe->enabled, -1);
220}
221
222static void probe_named(GtkCellRendererText *cel, gchar *path, gchar *text,
223 GtkTreeModel *probes)
224{
ffe80b55 225 struct sr_dev *dev = g_object_get_data(G_OBJECT(probes), "dev");
3f63165c
UH
226 GtkTreeIter iter;
227 gint i;
228
229 (void)cel;
230
231 gtk_tree_model_get_iter_from_string(probes, &iter, path);
232 gtk_tree_model_get(probes, &iter, PROBE_NUMBER, &i, -1);
4bedfdb7 233 sr_dev_probe_name_set(dev, i, text);
3f63165c
UH
234 gtk_list_store_set(GTK_LIST_STORE(probes), &iter, PROBE_NAME, text, -1);
235}
236
237static void probe_trigger_set(GtkCellRendererText *cel, gchar *path,
238 gchar *text, GtkTreeModel *probes)
239{
ffe80b55 240 struct sr_dev *dev = g_object_get_data(G_OBJECT(probes), "dev");
3f63165c
UH
241 GtkTreeIter iter;
242 gint i;
243
244 (void)cel;
245
246 gtk_tree_model_get_iter_from_string(probes, &iter, path);
247 gtk_tree_model_get(probes, &iter, PROBE_NUMBER, &i, -1);
ffe80b55 248 sr_dev_trigger_set(dev, i, text);
3f63165c
UH
249 gtk_list_store_set(GTK_LIST_STORE(probes), &iter,
250 PROBE_TRIGGER, text, -1);
251}
252
253static void dev_set_probes(GtkAction *action, GtkWindow *parent)
254{
255 (void)action;
256
ffe80b55
UH
257 struct sr_dev *dev = g_object_get_data(G_OBJECT(parent), "dev");
258 if (!dev)
3f63165c
UH
259 return;
260
261 GtkWidget *dialog = gtk_dialog_new_with_buttons("Configure Probes",
262 parent, GTK_DIALOG_MODAL,
263 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
264 NULL);
265 GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL);
266 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
267 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
268 gtk_widget_set_size_request(sw, 300, 200);
269 GtkWidget *tv = gtk_tree_view_new();
270 gtk_container_add(GTK_CONTAINER(sw), tv);
271 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), sw,
272 TRUE, TRUE, 0);
273
274 /* Populate list store with probe options */
275 GtkListStore *probes = gtk_list_store_new(MAX_PROBE,
276 G_TYPE_INT, G_TYPE_BOOLEAN,
277 G_TYPE_STRING, GTK_TYPE_STRING);
278 gtk_tree_view_set_model(GTK_TREE_VIEW(tv), GTK_TREE_MODEL(probes));
279 GtkTreeIter iter;
280 GSList *p;
281 int i;
ffe80b55 282 for (p = dev->probes, i = 1; p; p = g_slist_next(p), i++) {
3f63165c
UH
283 struct sr_probe *probe = p->data;
284 gtk_list_store_append(probes, &iter);
285 gtk_list_store_set(probes, &iter, PROBE_NUMBER, i,
286 PROBE_ENABLED, probe->enabled,
287 PROBE_NAME, probe->name,
288 PROBE_TRIGGER, probe->trigger,
289 -1);
290 }
291
292 /* Save device with list so that property can be set by edited
293 * handler. */
ffe80b55 294 g_object_set_data(G_OBJECT(probes), "dev", dev);
3f63165c
UH
295
296 /* Add columns to the tree view */
297 GtkTreeViewColumn *col;
298 col = gtk_tree_view_column_new_with_attributes("Probe",
299 gtk_cell_renderer_text_new(),
300 "text", PROBE_NUMBER, NULL);
301 gtk_tree_view_append_column(GTK_TREE_VIEW(tv), col);
302 GtkCellRenderer *cel = gtk_cell_renderer_toggle_new();
303 g_object_set(cel, "activatable", TRUE, NULL);
304 g_signal_connect(cel, "toggled", G_CALLBACK(probe_toggled), probes);
305 col = gtk_tree_view_column_new_with_attributes("En",
306 cel, "active", PROBE_ENABLED, NULL);
307 gtk_tree_view_append_column(GTK_TREE_VIEW(tv), col);
308 cel = gtk_cell_renderer_text_new();
309 g_object_set(cel, "editable", TRUE, NULL);
310 g_signal_connect(cel, "edited", G_CALLBACK(probe_named), probes);
311 col = gtk_tree_view_column_new_with_attributes("Signal Name", cel,
312 "text", PROBE_NAME,
313 "sensitive", PROBE_ENABLED, NULL);
314 gtk_tree_view_column_set_resizable(col, TRUE);
315 gtk_tree_view_append_column(GTK_TREE_VIEW(tv), col);
316 cel = gtk_cell_renderer_text_new();
317 g_object_set(cel, "editable", TRUE, NULL);
318 g_signal_connect(cel, "edited", G_CALLBACK(probe_trigger_set), probes);
319 col = gtk_tree_view_column_new_with_attributes("Trigger", cel,
320 "text", PROBE_TRIGGER,
321 "sensitive", PROBE_ENABLED, NULL);
322 gtk_tree_view_append_column(GTK_TREE_VIEW(tv), col);
323
324 gtk_widget_show_all(dialog);
325 gtk_dialog_run(GTK_DIALOG(dialog));
326
327 gtk_widget_destroy(dialog);
328}
329
330static void capture_run(GtkAction *action, GObject *parent)
331{
332 (void)action;
333
ffe80b55 334 struct sr_dev *dev = g_object_get_data(G_OBJECT(parent), "dev");
3f63165c
UH
335 GtkEntry *timesamples = g_object_get_data(parent, "timesamples");
336 GtkComboBox *timeunit = g_object_get_data(parent, "timeunit");
337 gint i = gtk_combo_box_get_active(timeunit);
338 guint64 time_msec = 0;
339 guint64 limit_samples = 0;
340
341 switch (i) {
342 case 0: /* Samples */
343 sr_parse_sizestring(gtk_entry_get_text(timesamples),
344 &limit_samples);
345 break;
346 case 1: /* Milliseconds */
347 time_msec = strtoull(gtk_entry_get_text(timesamples), NULL, 10);
348 break;
349 case 2: /* Seconds */
350 time_msec = strtoull(gtk_entry_get_text(timesamples), NULL, 10)
351 * 1000;
352 break;
353 }
354
355 if (time_msec) {
6054cbb8 356 if (sr_driver_hwcap_exists(dev->driver, SR_HWCAP_LIMIT_MSEC)) {
a4f48bca 357 if (dev->driver->dev_config_set(dev->driver_index,
31345264
UH
358 SR_HWCAP_LIMIT_MSEC,
359 &time_msec) != SR_OK) {
3f63165c
UH
360 g_critical("Failed to configure time limit.");
361 sr_session_destroy();
362 return;
363 }
364 } else {
365 /* time limit set, but device doesn't support this...
366 * convert to samples based on the samplerate.
367 */
368 limit_samples = 0;
ffe80b55 369 if (sr_dev_has_hwcap(dev, SR_HWCAP_SAMPLERATE)) {
3f63165c 370 guint64 tmp_u64;
a4f48bca
UH
371 tmp_u64 = *((uint64_t *)dev->driver->dev_info_get(
372 dev->driver_index,
3f63165c
UH
373 SR_DI_CUR_SAMPLERATE));
374 limit_samples = tmp_u64 * time_msec / (uint64_t) 1000;
375 }
376 if (limit_samples == 0) {
377 g_critical("Not enough time at this samplerate.");
378 return;
379 }
380
a4f48bca 381 if (dev->driver->dev_config_set(dev->driver_index,
31345264
UH
382 SR_HWCAP_LIMIT_SAMPLES,
383 &limit_samples) != SR_OK) {
3f63165c
UH
384 g_critical("Failed to configure time-based sample limit.");
385 return;
386 }
387 }
388 }
389 if (limit_samples) {
a4f48bca 390 if (dev->driver->dev_config_set(dev->driver_index,
31345264
UH
391 SR_HWCAP_LIMIT_SAMPLES,
392 &limit_samples) != SR_OK) {
3f63165c
UH
393 g_critical("Failed to configure sample limit.");
394 return;
395 }
396 }
397
a4f48bca 398 if (dev->driver->dev_config_set(dev->driver_index,
97fe0e2b 399 SR_HWCAP_PROBECONFIG, (char *)dev->probes) != SR_OK) {
3f63165c
UH
400 printf("Failed to configure probes.\n");
401 sr_session_destroy();
402 return;
403 }
404
405 if (sr_session_start() != SR_OK) {
406 g_critical("Failed to start session.");
407 return;
408 }
409
410 sr_session_run();
411}
412
413static void dev_file_open(GtkAction *action, GtkWindow *parent)
414{
415 (void)action;
416 static GtkWidget *dialog;
417 const gchar *filename;
418
419 if(!dialog)
420 dialog = gtk_file_chooser_dialog_new("Open", parent,
421 GTK_FILE_CHOOSER_ACTION_OPEN,
422 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
423 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
424 g_signal_connect(dialog, "delete-event",
425 G_CALLBACK(gtk_widget_hide_on_delete),
426 NULL);
427
428 if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
429 /* Dialog was cancelled or closed */
430 gtk_widget_hide(dialog);
431 return;
432 }
433
434 gtk_widget_hide(dialog);
435
436 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
437 load_input_file(parent, filename);
438}
439
440void toggle_log(GtkToggleAction *action, GObject *parent)
441{
442 GtkWidget *log = g_object_get_data(parent, "logview");
443 gtk_widget_set_visible(log, gtk_toggle_action_get_active(action));
444}
445
446void zoom_in(GtkAction *action, GObject *parent)
447{
448 (void)action;
449
450 GtkWidget *sigview = g_object_get_data(parent, "sigview");
451 sigview_zoom(sigview, 1.5, 0);
452}
453
454void zoom_out(GtkAction *action, GObject *parent)
455{
456 (void)action;
457
458 GtkWidget *sigview = g_object_get_data(parent, "sigview");
459 sigview_zoom(sigview, 1/1.5, 0);
460}
461
462void zoom_fit(GtkAction *action, GObject *parent)
463{
464 (void)action;
465
466 GtkWidget *sigview = g_object_get_data(parent, "sigview");
467 sigview_zoom(sigview, 0, 0);
468}
469
470static const GtkActionEntry action_items[] = {
471 /* name, stock-id, label, accel, tooltip, callback */
472 {"DevMenu", NULL, "_Device", NULL, NULL, NULL},
473 {"DevOpen", GTK_STOCK_OPEN, "_Open", "<control>O",
474 "Open Session File", G_CALLBACK(dev_file_open)},
475 {"DevSelectMenu", NULL, "Select Device", NULL, NULL, NULL},
476 {"DevRescan", GTK_STOCK_REFRESH, "_Rescan", "<control>R",
477 "Rescan for LA devices", G_CALLBACK(dev_select_rescan)},
478 {"DevProperties", GTK_STOCK_PROPERTIES, "_Properties", "<control>P",
479 "Configure LA", G_CALLBACK(dev_set_options)},
480 {"DevProbes", GTK_STOCK_COLOR_PICKER, "_Probes", "<control>O",
481 "Configure Probes", G_CALLBACK(dev_set_probes)},
482 {"DevAcquire", GTK_STOCK_EXECUTE, "_Acquire", "<control>A",
483 "Acquire Samples", G_CALLBACK(capture_run)},
484 {"Exit", GTK_STOCK_QUIT, "E_xit", "<control>Q",
485 "Exit the program", G_CALLBACK(gtk_main_quit) },
486
487 {"ViewMenu", NULL, "_View", NULL, NULL, NULL},
676bf74f 488 {"ViewZoomIn", GTK_STOCK_ZOOM_IN, "Zoom _In", "plus", NULL,
3f63165c 489 G_CALLBACK(zoom_in)},
676bf74f 490 {"ViewZoomOut", GTK_STOCK_ZOOM_OUT, "Zoom _Out", "minus",
3f63165c
UH
491 NULL, G_CALLBACK(zoom_out)},
492 {"ViewZoomFit", GTK_STOCK_ZOOM_FIT, NULL, NULL,
493 NULL, G_CALLBACK(zoom_fit)},
494
495 {"HelpMenu", NULL, "_Help", NULL, NULL, NULL},
82ae3349 496 {"HelpWiki", GTK_STOCK_ABOUT, "sigrok _Wiki", NULL, NULL,
3f63165c
UH
497 G_CALLBACK(help_wiki)},
498 {"HelpAbout", GTK_STOCK_ABOUT, "_About", NULL, NULL,
499 G_CALLBACK(help_about)},
500};
501
502static const GtkToggleActionEntry toggle_items[] = {
503 /* name, stock-id, label, accel, tooltip, callback, isactive */
504 {"ViewLog", GTK_STOCK_JUSTIFY_LEFT, "_Log", NULL, NULL,
505 G_CALLBACK(toggle_log), FALSE},
506};
507
508static const char ui_xml[] =
509"<ui>"
510" <menubar>"
511" <menu action='DevMenu'>"
512" <menuitem action='DevOpen'/>"
513" <separator/>"
514" <menu action='DevSelectMenu'>"
515" <separator/>"
516" <menuitem action='DevRescan'/>"
517" </menu>"
518" <menuitem action='DevProperties'/>"
519" <menuitem action='DevProbes'/>"
520" <separator/>"
521" <menuitem action='DevAcquire'/>"
522" <separator/>"
523" <menuitem action='Exit'/>"
524" </menu>"
525" <menu action='ViewMenu'>"
526" <menuitem action='ViewZoomIn'/>"
527" <menuitem action='ViewZoomOut'/>"
528" <menuitem action='ViewZoomFit'/>"
529" <separator/>"
530" <menuitem action='ViewLog'/>"
531" </menu>"
532" <menu action='HelpMenu'>"
533" <menuitem action='HelpWiki'/>"
534" <menuitem action='HelpAbout'/>"
535" </menu>"
536" </menubar>"
537" <toolbar>"
538" <placeholder name='DevSelect'/>"
539" <toolitem action='DevRescan'/>"
540" <toolitem action='DevProperties'/>"
541" <toolitem action='DevProbes'/>"
542" <separator/>"
543" <placeholder name='DevSampleCount' />"
544" <toolitem action='DevAcquire'/>"
545" <separator/>"
546" <toolitem action='ViewZoomIn'/>"
547" <toolitem action='ViewZoomOut'/>"
548" <toolitem action='ViewZoomFit'/>"
549" <separator/>"
550" </toolbar>"
551"</ui>";
552
553GtkWidget *toolbar_init(GtkWindow *parent)
554{
555 GtkWidget *vbox = gtk_vbox_new(FALSE, 0);
556 GtkToolbar *toolbar;
557 GtkActionGroup *ag = gtk_action_group_new("Actions");
558 gtk_action_group_add_actions(ag, action_items,
559 G_N_ELEMENTS(action_items), parent);
560 gtk_action_group_add_toggle_actions(ag, toggle_items,
561 G_N_ELEMENTS(toggle_items), parent);
562
563 GtkUIManager *ui = gtk_ui_manager_new();
564 g_object_set_data(G_OBJECT(parent), "ui_manager", ui);
565 gtk_ui_manager_insert_action_group(ui, ag, 0);
566 GtkAccelGroup *accel = gtk_ui_manager_get_accel_group(ui);
567 gtk_window_add_accel_group(parent, accel);
568
569 GError *error = NULL;
570 if (!gtk_ui_manager_add_ui_from_string (ui, ui_xml, -1, &error)) {
571 g_message ("building menus failed: %s", error->message);
572 g_error_free (error);
573 exit (-1);
574 }
575
576 GtkWidget *menubar = gtk_ui_manager_get_widget(ui, "/menubar");
577 gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(menubar), FALSE, TRUE, 0);
578 toolbar = GTK_TOOLBAR(gtk_ui_manager_get_widget(ui, "/toolbar"));
579 gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(toolbar), FALSE, TRUE, 0);
580
3f63165c 581 /* Time/Samples entry */
3cc6b11b 582 GtkToolItem *toolitem = gtk_tool_item_new();
3f63165c
UH
583 GtkWidget *timesamples = gtk_entry_new();
584 gtk_entry_set_text(GTK_ENTRY(timesamples), "100");
585 gtk_entry_set_alignment(GTK_ENTRY(timesamples), 1.0);
586 gtk_widget_set_size_request(timesamples, 100, -1);
587 gtk_container_add(GTK_CONTAINER(toolitem), timesamples);
588 gtk_toolbar_insert(toolbar, toolitem, 7);
589
590 /* Time unit combo box */
591 toolitem = gtk_tool_item_new();
3cc6b11b 592 GtkWidget *align = gtk_alignment_new(0.5, 0.5, 2, 0);
3f63165c
UH
593 GtkWidget *timeunit = gtk_combo_box_new_text();
594 gtk_combo_box_append_text(GTK_COMBO_BOX(timeunit), "samples");
595 gtk_combo_box_append_text(GTK_COMBO_BOX(timeunit), "ms");
596 gtk_combo_box_append_text(GTK_COMBO_BOX(timeunit), "s");
597 gtk_combo_box_set_active(GTK_COMBO_BOX(timeunit), 0);
598 gtk_container_add(GTK_CONTAINER(align), timeunit);
599 gtk_container_add(GTK_CONTAINER(toolitem), align);
600 gtk_toolbar_insert(toolbar, toolitem, 8);
601
602 g_object_set_data(G_OBJECT(parent), "timesamples", timesamples);
603 g_object_set_data(G_OBJECT(parent), "timeunit", timeunit);
604
3cc6b11b
HE
605 /* Device selection GtkComboBox */
606 toolitem = gtk_tool_item_new();
607 align = gtk_alignment_new(0.5, 0.5, 2, 0);
608 GtkWidget *dev = dev_select_combo_box_new(parent);
609
610 gtk_container_add(GTK_CONTAINER(align), dev);
611 gtk_container_add(GTK_CONTAINER(toolitem), align);
612 gtk_toolbar_insert(toolbar, toolitem, 0);
613
614
3f63165c
UH
615 return GTK_WIDGET(vbox);
616}
617