summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlliver Schinagl <o.schinagl@ultimaker.com>2015-07-30 13:31:59 (GMT)
committerOlliver Schinagl <o.schinagl@ultimaker.com>2015-07-30 13:31:59 (GMT)
commit98430e79bd1cb3884539b00e69b4e4915e9562fb (patch)
treebc8a92976a9b53f28fb60259c08164bd4fe9bafb
parent7d9482dfa3636633e50303ba22059dbdc42c6164 (diff)
downloadeulogium-98430e79bd1cb3884539b00e69b4e4915e9562fb.zip
eulogium-98430e79bd1cb3884539b00e69b4e4915e9562fb.tar.gz
eulogium-98430e79bd1cb3884539b00e69b4e4915e9562fb.tar.bz2
fix print progress procedures, untested is procedure finish
Signed-off-by: Olliver Schinagl <o.schinagl@ultimaker.com>
-rw-r--r--src/eulogium.c142
-rw-r--r--src/eulogium.h1
-rw-r--r--src/procedures.c67
-rw-r--r--src/procedures.h6
-rw-r--r--src/ui_widgets.c117
5 files changed, 145 insertions, 188 deletions
diff --git a/src/eulogium.c b/src/eulogium.c
index e4b8338..3ffab75 100644
--- a/src/eulogium.c
+++ b/src/eulogium.c
@@ -31,14 +31,6 @@
#define COPYRIGHT "Copyright © 2015 Olliver Schinagl <o.schinagl@ultimaker.com> and various contributors (see AUTHORS)."
-#define SECOND 1L
-#define MINUTE (60L * SECOND)
-#define HOUR (60L * MINUTE)
-#define DAY (24L * HOUR)
-#define WEEK (7L * DAY)
-#define MONTH (4L * WEEK)
-#define YEAR (52L * WEEK)
-
/* TODO Create def for a menu/screen to house all the buttons */
/* BTN is better then but-sex. */
@@ -2790,73 +2782,6 @@ struct _status_msg {
char *s;
};
-static Eina_Bool _timer_progress_data_update_cb(void *data)
-{
- struct eulogium_data *eulogium = data;
- struct print_data *progress = eulogium->procedures[PROC_PRINT].meta;
- static enum printer_status status = -1;
- static double value = 0;
- static double time = -1;
-
- procedure_metadata_key_get(progress->proc_key);
-
-#if 0
- if (eulogium->printer.status != status) {
- elm_object_text_set(eulogium->status, "TODO (step key)");
- if (eulogium->printer.status == COOLING)
- elm_progressbar_inverted_set(eulogium->progress, EINA_TRUE);
- status = eulogium->printer.status;
- }
- if (progress->value != value) {
- elm_progressbar_value_set(eulogium->progress, progress->value);
- value = progress->value;
- }
- if (progress->time != time) {
- char buf[255], *str;
- int_fast32_t time = 0;
-
- if (progress->time < 1) {
- str = "Print time unknown";
- time = 0;
- }
- if (progress->time > 0) {
- str = "Time left: %d second%s";
- time = progress->time;
- }
- if (progress->time > MINUTE) {
- str = "Time left: %d minute%s";
- time = progress->time / MINUTE;
- }
- if (progress->time > HOUR) {
- str = "Time left: %d hour%s";
- time = progress->time / HOUR;
- }
- if (progress->time > DAY) {
- str = "Time left: %d day%s";
- time = progress->time / DAY;
- }
- if (progress->time > WEEK) {
- str = "Time left: %d week%s";
- time = progress->time / WEEK;
- }
- if (progress->time > MONTH) {
- str = "Time left: %d month%s";
- time = progress->time / MONTH;
- }
- if (progress->time > YEAR) {
- str = "Time left: %d year%s";
- time = progress->time / YEAR;
- }
-
- snprintf(buf, sizeof(buf), str, (int)progress->time, (time > 1) ? "s" : ""); /* TODO: This won't work with in10 */
- elm_object_text_set(eulogium->time, _(buf));
- progress->time = time;
- }
-
-#endif
- return ECORE_CALLBACK_RENEW;
-}
-
/* FIXME: bug here. If the user hits 'abort print' button, an abort is sent to the backend. This timer however
* still keeps going and requests the backend status afterwards. Because of this, the status change gets
* triggered in the menu state machine and if we're not idle, we jump to a progress screen.
@@ -2958,69 +2883,6 @@ Evas_Object *eulogium_pre_print(Evas_Object *parent, struct eulogium_data *eulog
return eulogium_split_screen(eulogium->navi, _top, _bottom);
}
-Evas_Object *eulogium_print_progress(Evas_Object *parent, struct eulogium_data *eulogium, const struct print_data *progress) /* TODO pass timer var to store timer in */
-{
- Evas_Object *_top, *_bottom;
-
- /* TODO maybe this timer needs to be split into twofold update the widgets locally here,
- * emit a signal/tell the metadata cb to start gathering meta data */
- /* this needs to be done, so that we can pass the proper parameters. For now, just hackishly split them.
- */
- eulogium->progress_data_refresh = ecore_timer_add(0.5, _timer_progress_data_update_cb, eulogium);
- if (!eulogium->progress_data_refresh) { /* TODO make define for the timeout */
- EINA_LOG_CRIT("Unable to create progress update timer");
- return NULL;
- }
-
- return ui_widget_progress(parent, eulogium->procedures[PROC_PRINT].meta, &eulogium->procedures[PROC_PRINT].event);
-#if 0
- _top = elm_box_add(parent);
- evas_object_size_hint_weight_set(_top, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_size_hint_align_set(_top, EVAS_HINT_FILL, EVAS_HINT_FILL);
- elm_box_homogeneous_set(_top, EINA_FALSE);
- evas_object_show(_top);
-
- eulogium->time = elm_label_add(_top);
- elm_object_text_set(eulogium->time, _("Calculating time ..."));
- elm_label_slide_mode_set(eulogium->time, ELM_LABEL_SLIDE_MODE_NONE);
- evas_object_size_hint_align_set(eulogium->time, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_show(eulogium->time);
- elm_box_pack_end(_top, eulogium->time);
-
- eulogium->status = elm_label_add(_top);
- elm_object_text_set(eulogium->status, _("Unknown print status"));
- elm_label_slide_mode_set(eulogium->status, ELM_LABEL_SLIDE_MODE_NONE);
- evas_object_size_hint_align_set(eulogium->status, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_show(eulogium->status);
- elm_box_pack_end(_top, eulogium->status);
-
- eulogium->name = elm_label_add(_top);
- elm_object_text_set(eulogium->name, progress->jobname);
- elm_label_slide_mode_set(eulogium->name, ELM_LABEL_SLIDE_MODE_AUTO);
- //elm_label_slide_speed_set(object, 2);
- elm_label_slide_go(eulogium->name);
- elm_object_style_set(eulogium->name, "slide_bounce");
- evas_object_size_hint_align_set(eulogium->name, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_show(eulogium->name);
- elm_box_pack_end(_top, eulogium->name);
-
- eulogium->progress = elm_progressbar_add(_top); /* TODO: depending on i18n sig, change inverted */
- elm_progressbar_horizontal_set(eulogium->progress, EINA_TRUE);
- elm_progressbar_pulse_set(eulogium->progress, EINA_FALSE); /* TODO: pulse = time-unknown/pause */
- elm_progressbar_pulse(eulogium->progress, EINA_FALSE);
- elm_progressbar_value_set(eulogium->progress, progress->value);
- elm_progressbar_unit_format_set(eulogium->progress, "%1.1f %%");
- evas_object_size_hint_align_set(eulogium->progress, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_show(eulogium->progress);
- elm_box_pack_end(_top, eulogium->progress);
-
- _bottom = eulogium_dual_button_add(parent, &but_print_tune, &but_print_abort_confirm);
- evas_object_show(_bottom);
-
- return eulogium_split_screen(parent, _top, _bottom);
-#endif
-}
-
void eulogium_generic_error(struct eulogium_data *eulogium, uint_fast16_t error_code, const char *error_msg)
{
Evas_Object *content, *object;
@@ -3610,7 +3472,7 @@ static void eulogium_printer_status_set(struct eulogium_data *eulogium, struct _
eulogium->print.block_active = EINA_TRUE;
content = eulogium_print_ignore(eulogium);
} else {
- content = eulogium_print_progress(eulogium);
+ content = widget_progress_add(eulogium);
}
}
}
@@ -4266,7 +4128,7 @@ static void eulogium_setup(struct eulogium_data *eulogium)
procedure_meta_set(&eulogium->procedures[PROC_CURRENT_XY], PROC_META_SLIDER, &dials[PROC_CURRENT_XY]);
procedure_meta_set(&eulogium->procedures[PROC_CURRENT_Z], PROC_META_SLIDER, &dials[PROC_CURRENT_Z]);
procedure_meta_set(&eulogium->procedures[PROC_CURRENT_E], PROC_META_SLIDER, &dials[PROC_CURRENT_E]);
- procedure_meta_getall(); /* XXX do we really want to get all metadata at start? Not only of active and special procedures? */
+ procedure_metadata_getall(); /* XXX do we really want to get all metadata at start? Not only of active and special procedures? */
}
void _priviledges_drop(void)
diff --git a/src/eulogium.h b/src/eulogium.h
index 2420276..4dae23b 100644
--- a/src/eulogium.h
+++ b/src/eulogium.h
@@ -89,7 +89,6 @@ Evas_Object *eulogium_tripple_button_menu(Evas_Object *parent, const struct butt
Evas_Object *eulogium_dual_button_add(Evas_Object *parent, const struct button_def *left, const struct button_def *right);
Evas_Object *eulogium_print_menu(struct eulogium_data *eulogium, char *filepath);
Evas_Object *eulogium_print_ignore(struct eulogium_data *eulogium);
-Evas_Object *eulogium_print_progress(Evas_Object *parent, struct eulogium_data *eulogium, const struct print_data *progress);
Evas_Object *eulogium_pre_print(Evas_Object *parent, struct eulogium_data *eulogium);
Evas_Object *eulogium_settings_dial(Evas_Object *parent, struct eulogium_data *eulogium, struct settings_dial_data *dial_data);
Evas_Object *eulogium_multi_text_menu(struct eulogium_data *eulogium, Evas_Object *parent, struct button_def *button, struct multi_text *data, const uint_fast8_t pagenum, Eina_Bool pageindex);
diff --git a/src/procedures.c b/src/procedures.c
index 21ef87e..38d320b 100644
--- a/src/procedures.c
+++ b/src/procedures.c
@@ -1,6 +1,6 @@
/*
* TODO: rename this to dbus_procedures.c
- * eulogium_procedures, available procedures
+ * procedures, available procedures
*
* Copyright (c) 2015 Ultimaker B.V.
* Author: Olliver Schinagl <o.schinagl@ultimaker.com>
@@ -277,12 +277,18 @@ void procedure_process_step(struct procedure_data *procedure, struct eulogium_da
/* XXX TODO build 'remember previous screen so we don't redraw the same' */
EINA_LOG_CRIT("processing key %s step %s", procedure->key, procedure->step_active->key);
if (procedure->step_active->step == STEP_FIRMWARE_UPDATE_WRITING) {
- procedure_metadata_poll(procedure, EINA_TRUE);
+ procedure_metadata_poll_start(procedure); /* Poll for progress information, no signal on these */
content = ui_widget_progress(eulogium->navi, procedure->meta, &procedure->event);
page_state = PAGE_FIRMWARE;
}
+// if (procedure->step_active->step == HEATUP_HOTEND) {
+// procedure_metadata_poll_start(procedure); /* Poll for progress information, no signal on these */
+// content = ui_widget_progress(eulogium->navi, procedure->meta, &procedure->event);
+// page_state = PAGE_PRINTING;
+// }
if (procedure->step_active->step == STEP_PRINTING) {
- content = eulogium_print_progress(eulogium->navi, eulogium, (struct print_data *)procedure->meta);
+ procedure_metadata_poll_start(procedure); /* Poll for progress information, no signal on these */
+ content = ui_widget_progress(eulogium->navi, procedure->meta, &procedure->event);
page_state = PAGE_PRINTING;
}
if (procedure->step_active->step == PROC_WAIT_FOR_CLEANUP) {
@@ -305,12 +311,18 @@ void procedure_process_finish(struct procedure_data *procedure, struct eulogium_
return;
EINA_LOG_CRIT("finishing key %s", procedure->key);
- if (procedure->proc_key == PROC_FIRMWARE_UPDATE) {
+ switch (procedure->proc_key) {
+ case PROC_FIRMWARE_UPDATE:
+ procedure_metadata_poll_stop(procedure);
ui_stack_page_invalidate(eulogium->navi, PAGE_FIRMWARE);
ui_stack_pop(eulogium->navi);
+ break;
+ case PROC_PRINT:
+ procedure_metadata_poll_stop(procedure);
+ break;
+ default:
+ break;
}
- if (procedure->proc_key == PROC_PRINT) {
- };
}
static struct procedure_msg print_msgs[] = {
@@ -533,7 +545,7 @@ static struct procedure_data procedures[] = {
.step_active = NULL,
.meta = NULL, /* struct print_data */
.event = {
- .in = 0.0,
+ .in = 0.5,
.timer = NULL,
.type = 0,
},
@@ -1089,20 +1101,35 @@ Eldbus_Pending *procedure_target_set(const enum procedure_key proc_key)
return eldbus_proxy_send(__proxy, msg, _on_start_dial_ret, dial_data->label, -1);
}
-void procedure_metadata_poll(struct procedure_data *procedure, Eina_Bool polling)
+static Eina_Bool _cb_timer_procedure_metadata_poll(void *data)
{
- if (polling)
- if (procedure->event.timer)
- return; /* Timer already running */
- // procedure->event.timer = ecore_timer_add(procedure->event.in, procedure->event.func, procedure);
- if (!procedure->event.timer) {
- EINA_LOG_CRIT("Unable to create metadata polling timer");
- } else {
- if (procedure->event.timer)
- ecore_timer_del(procedure->event.timer);
- else
- EINA_LOG_CRIT("Unable to delete non-existing timer");
+ struct procedure_data *procedure = data;
+
+ if (!procedure)
+ return ECORE_CALLBACK_CANCEL;
+
+ procedure_metadata_get(procedure);
+
+ return ECORE_CALLBACK_RENEW;
+}
+
+void procedure_metadata_poll_start(struct procedure_data *procedure)
+{
+ if (procedure->event.timer) {
+ EINA_LOG_WARN("Starting poll timer when already running for procedure %s.", procedure->key);
+ return; /* Timer already running */
}
+ procedure->event.timer = ecore_timer_add(procedure->event.in, _cb_timer_procedure_metadata_poll, procedure);
+ if (!procedure->event.timer)
+ EINA_LOG_CRIT("Unable to create metadata polling timer for procedure %s.", procedure->key);
+}
+
+void procedure_metadata_poll_stop(struct procedure_data *procedure)
+{
+ if (procedure->event.timer)
+ ecore_timer_del(procedure->event.timer);
+ else
+ EINA_LOG_CRIT("Unable to delete metadata polling timer for procedure %s.", procedure->key);
}
Eldbus_Pending *procedure_metadata_get(const struct procedure_data *procedure)
@@ -1115,7 +1142,7 @@ Eldbus_Pending *procedure_metadata_key_get(enum procedure_key proc_key)
return eldbus_proxy_call(__proxy, "getProcedureMetaData", on_method_get_procedure_metadata_ret, &procedures[proc_key], -1, "s", procedures[proc_key].key);
}
-void procedure_meta_getall(void)
+void procedure_metadata_getall(void)
{
enum procedure_key i;
diff --git a/src/procedures.h b/src/procedures.h
index 40b032f..cb6fd8a 100644
--- a/src/procedures.h
+++ b/src/procedures.h
@@ -158,7 +158,6 @@ struct procedure_data {
struct eulogium_data; /* XXX remove later when struct eulogium gets refactored. */
struct procedure_data *procedures_init(Eldbus_Proxy *proxy);
-void procedure_meta_getall(void);
struct procedure_data *procedure_get(const char *key);
const struct procedure_step *procedure_step_get(const struct procedure_data *proc, const char *key);
void procedure_process_step(struct procedure_data *procedure, struct eulogium_data *eulogium);
@@ -167,7 +166,6 @@ Eldbus_Pending *procedure_message(const struct procedure_data *proc, const struc
struct print_data; /* XXX only here until print_start gets simplified */
Eldbus_Pending *procedure_print_start(const struct print_data *print);
Eldbus_Pending *procedure_print_printer_cleaned(void);
-Eldbus_Pending *procedure_print_progress_get(struct procedure_data *procedure);
void *procedure_meta_data_get(struct procedure_data *procedure);
enum meta_type procedure_meta_type_get(struct procedure_data *procedure);
@@ -176,7 +174,9 @@ void procedure_meta_set(struct procedure_data *procedure, enum meta_type type, v
Eldbus_Pending *procedure_start_simple(const enum procedure_key proc_key);
Eldbus_Pending *procedure_metadata_get(const struct procedure_data *procedure);
Eldbus_Pending *procedure_metadata_key_get(enum procedure_key proc_key);
-void procedure_metadata_poll(struct procedure_data *procedure, Eina_Bool polling);
+void procedure_metadata_getall(void);
+void procedure_metadata_poll_start(struct procedure_data *procedure);
+void procedure_metadata_poll_stop(struct procedure_data *procedure);
Eldbus_Pending *procedure_target_set(const enum procedure_key proc_key);
void procedures_shutdown(void);
diff --git a/src/ui_widgets.c b/src/ui_widgets.c
index fdd5f24..ec69984 100644
--- a/src/ui_widgets.c
+++ b/src/ui_widgets.c
@@ -380,38 +380,111 @@ static void _widget_progress_del(void *data, Evas *e EINA_UNUSED, Evas_Object *e
ecore_event_handler_del(handler);
}
-static Eina_Bool _widget_progress_update(void *data, int type EINA_UNUSED, void *ev)
+#define SECOND 1L
+#define MINUTE (60L * SECOND)
+#define HOUR (60L * MINUTE)
+#define DAY (24L * HOUR)
+#define WEEK (7L * DAY)
+#define MONTH (4L * WEEK)
+#define YEAR (52L * WEEK)
+
+static Eina_Bool _widget_progress_status_update(void *data, int type EINA_UNUSED, void *ev)
{
- Evas_Object *progressbar = data;
+ Evas_Object *progress_status = data;
+ const struct print_data *progress = ev;
+ int_fast32_t time = 0;
+ char buf[35], *str; /* 35 is a random approximation */
+
+ if (progress->time < SECOND) {
+ str = N_("Time unknown");
+ }
+ if (progress->time > SECOND) {
+ str = N_("Time left: %d sec%s");
+ time = progress->time;
+ }
+ if (progress->time > MINUTE) {
+ str = N_("Time left: %d min%s");
+ time = progress->time / MINUTE;
+ }
+ if (progress->time > HOUR) {
+ str = N_("Time left: %d hour%s");
+ time = progress->time / HOUR;
+ }
+ if (progress->time > DAY) {
+ str = N_("Time left: %d day%s");
+ time = progress->time / DAY;
+ }
+ if (progress->time > WEEK) {
+ str = N_("Time left: %d week%s");
+ time = progress->time / WEEK;
+ }
+ if (progress->time > MONTH) {
+ str = N_("Time left: %d month%s");
+ time = progress->time / MONTH;
+ }
+ if (progress->time > YEAR) {
+ str = N_("Time left: %d year%s");
+ time = progress->time / YEAR;
+ }
+
+ snprintf(buf, sizeof(buf), str, (int)time, (time > 1) ? "s" : ""); /* TODO: check for real i10n time funcs */
+ elm_object_text_set(progress_status, _(buf));
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+Evas_Object *widgets_progress_status_add(Evas_Object *parent, const struct print_data *progress, const struct event_info *event)
+{
+ Evas_Object *progress_status;
+ Ecore_Event_Handler *handler;
+
+ progress_status = elm_label_add(parent);
+ elm_object_text_set(progress_status, _("Unknown status"));
+ elm_label_slide_mode_set(progress_status, ELM_LABEL_SLIDE_MODE_NONE);
+ evas_object_size_hint_align_set(progress_status, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ evas_object_show(progress_status);
+
+ _widget_progress_status_update((void *)progress_status, event->type, (void *)progress);
+ handler = ecore_event_handler_add(event->type, _widget_progress_status_update, progress_status);
+ evas_object_event_callback_add(progress_status, EVAS_CALLBACK_DEL, _widget_progress_del, handler);
+ evas_object_show(progress_status);
+
+ return progress_status;
+}
+
+static Eina_Bool _widget_progress_bar_update(void *data, int type EINA_UNUSED, void *ev)
+{
+ Evas_Object *progress_bar = data;
const struct print_data *progress = ev;
if (progress->value < 0) {
- elm_progressbar_pulse_set(progressbar, EINA_TRUE);
- elm_progressbar_pulse(progressbar, EINA_TRUE);
+ elm_progressbar_pulse_set(progress_bar, EINA_TRUE);
+ elm_progressbar_pulse(progress_bar, EINA_TRUE);
} else {
- elm_progressbar_pulse_set(progressbar, EINA_FALSE);
- elm_progressbar_pulse(progressbar, EINA_FALSE);
- elm_progressbar_value_set(progressbar, progress->value);
+ elm_progressbar_pulse_set(progress_bar, EINA_FALSE);
+ elm_progressbar_pulse(progress_bar, EINA_FALSE);
+ elm_progressbar_value_set(progress_bar, progress->value);
}
return ECORE_CALLBACK_PASS_ON;
}
-Evas_Object *widgets_progressbar_add(Evas_Object *parent, const struct print_data *progress, const struct event_info *event)
+Evas_Object *widgets_progress_bar_add(Evas_Object *parent, const struct print_data *progress, const struct event_info *event)
{
- Evas_Object *obj;
+ Evas_Object *progress_bar;
Ecore_Event_Handler *handler;
- obj = elm_progressbar_add(parent);
- elm_progressbar_horizontal_set(obj, EINA_TRUE);
- elm_progressbar_unit_format_set(obj, progress->format);
- evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
- _widget_progress_update((void *)obj, event->type, (void *)progress);
- handler = ecore_event_handler_add(event->type, _widget_progress_update, obj);
- evas_object_event_callback_add(obj, EVAS_CALLBACK_DEL, _widget_progress_del, handler);
- evas_object_show(obj);
+ progress_bar = elm_progressbar_add(parent);
+ elm_progressbar_horizontal_set(progress_bar, EINA_TRUE);
+ elm_progressbar_unit_format_set(progress_bar, progress->format);
+ evas_object_size_hint_align_set(progress_bar, EVAS_HINT_FILL, EVAS_HINT_FILL);
- return obj;
+ _widget_progress_bar_update((void *)progress_bar, event->type, (void *)progress);
+ handler = ecore_event_handler_add(event->type, _widget_progress_bar_update, progress_bar);
+ evas_object_event_callback_add(progress_bar, EVAS_CALLBACK_DEL, _widget_progress_del, handler);
+ evas_object_show(progress_bar);
+
+ return progress_bar;
}
Evas_Object *ui_widget_progress(Evas_Object *parent, const struct print_data *progress, const struct event_info *event)
@@ -432,11 +505,7 @@ Evas_Object *ui_widget_progress(Evas_Object *parent, const struct print_data *pr
evas_object_show(obj);
elm_box_pack_end(_top, obj);
- obj = elm_label_add(_top);
- elm_object_text_set(obj, _("Unknown status"));
- elm_label_slide_mode_set(obj, ELM_LABEL_SLIDE_MODE_NONE);
- evas_object_size_hint_align_set(obj, EVAS_HINT_FILL, EVAS_HINT_FILL);
- evas_object_show(obj);
+ obj = widgets_progress_status_add(_top, progress, event);
elm_box_pack_end(_top, obj);
obj = elm_label_add(_top);
@@ -449,7 +518,7 @@ Evas_Object *ui_widget_progress(Evas_Object *parent, const struct print_data *pr
evas_object_show(obj);
elm_box_pack_end(_top, obj);
- obj = widgets_progressbar_add(_top, progress, event);
+ obj = widgets_progress_bar_add(_top, progress, event);
elm_box_pack_end(_top, obj);
_bottom = eulogium_dual_button_add(parent, &but_print_tune, &but_print_abort_confirm);