From 4d253049d5139b34e35154e74850d3c68e4d0b8b Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Wed, 6 Jan 2010 01:42:21 +0100 Subject: [PATCH] Fix non-clearing of timeout. Template support for timeout text. --- gfxmenu/gui_circular_progress.c | 39 +++++++------- gfxmenu/gui_progress_bar.c | 96 +++++++++++++++++++++------------ gfxmenu/view.c | 44 ++++++--------- include/grub/gui.h | 11 ++++ normal/menu.c | 2 + 5 files changed, 110 insertions(+), 82 deletions(-) diff --git a/gfxmenu/gui_circular_progress.c b/gfxmenu/gui_circular_progress.c index 7634c368d..9a859ee2e 100644 --- a/gfxmenu/gui_circular_progress.c +++ b/gfxmenu/gui_circular_progress.c @@ -28,7 +28,7 @@ struct grub_gui_circular_progress { - struct grub_gui_component comp; + struct grub_gui_progress progress; grub_gui_container_t parent; grub_video_rect_t bounds; @@ -215,19 +215,7 @@ static grub_err_t circprog_set_property (void *vself, const char *name, const char *value) { circular_progress_t self = vself; - if (grub_strcmp (name, "value") == 0) - { - self->value = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "start") == 0) - { - self->start = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "end") == 0) - { - self->end = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "num_ticks") == 0) + if (grub_strcmp (name, "num_ticks") == 0) { self->num_ticks = grub_strtol (value, 0, 10); } @@ -257,10 +245,6 @@ circprog_set_property (void *vself, const char *name, const char *value) grub_free (self->theme_dir); self->theme_dir = value ? grub_strdup (value) : 0; } - else if (grub_strcmp (name, "visible") == 0) - { - self->visible = grub_strcmp (value, "false") != 0; - } else if (grub_strcmp (name, "id") == 0) { grub_free (self->id); @@ -272,6 +256,17 @@ circprog_set_property (void *vself, const char *name, const char *value) return grub_errno; } +static void +circprog_set_state (void *vself, int visible, int start, + int current, int end) +{ + circular_progress_t self = vself; + self->visible = visible; + self->start = start; + self->value = current; + self->end = end; +} + static struct grub_gui_component_ops circprog_ops = { .destroy = circprog_destroy, @@ -285,6 +280,11 @@ static struct grub_gui_component_ops circprog_ops = .set_property = circprog_set_property }; +static struct grub_gui_progress_ops circprog_prog_ops = + { + .set_state = circprog_set_state + }; + grub_gui_component_t grub_gui_circular_progress_new (void) { @@ -292,7 +292,8 @@ grub_gui_circular_progress_new (void) self = grub_zalloc (sizeof (*self)); if (! self) return 0; - self->comp.ops = &circprog_ops; + self->progress.ops = &circprog_prog_ops; + self->progress.component.ops = &circprog_ops; self->visible = 1; self->num_ticks = 64; self->start_angle = -64; diff --git a/gfxmenu/gui_progress_bar.c b/gfxmenu/gui_progress_bar.c index d982924cb..6a7f43962 100644 --- a/gfxmenu/gui_progress_bar.c +++ b/gfxmenu/gui_progress_bar.c @@ -24,10 +24,11 @@ #include #include #include +#include struct grub_gui_progress_bar { - struct grub_gui_component component; + struct grub_gui_progress progress; grub_gui_container_t parent; grub_video_rect_t bounds; @@ -37,7 +38,7 @@ struct grub_gui_progress_bar int end; int value; int show_text; - char *text; + char *template; grub_font_t font; grub_gui_color_t text_color; grub_gui_color_t border_color; @@ -156,14 +157,20 @@ draw_pixmap_bar (grub_gui_progress_bar_t self) static void draw_text (grub_gui_progress_bar_t self) { - const char *text = self->text; - if (text && self->show_text) + if (self->template) { grub_font_t font = self->font; grub_video_color_t text_color = grub_gui_map_color (self->text_color); int width = self->bounds.width; int height = self->bounds.height; - + char *text = grub_asprintf (self->template, + self->value > 0 ? self->value : -self->value); + if (!text) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + return; + } /* Center the text. */ int text_width = grub_font_get_string_width (font, text); int x = (width - text_width) / 2; @@ -228,35 +235,60 @@ progress_bar_get_bounds (void *vself, grub_video_rect_t *bounds) } static void -progress_bar_get_minimal_size (void *vself __attribute__ ((unused)), +progress_bar_get_minimal_size (void *vself, unsigned *width, unsigned *height) { + unsigned text_width = 0, text_height = 0; + grub_gui_progress_bar_t self = vself; + + if (self->template) + { + text_width = grub_font_get_string_width (self->font, self->template); + text_width += grub_font_get_string_width (self->font, "XXXXXXXXXX"); + text_height = grub_font_get_descent (self->font) + + grub_font_get_ascent (self->font); + } *width = 200; + if (*width < text_width) + *width = text_width; *height = 28; + if (*height < text_height) + *height = text_height; +} + +static void +progress_bar_set_state (void *vself, int visible, int start, + int current, int end) +{ + grub_gui_progress_bar_t self = vself; + self->visible = visible; + self->start = start; + self->value = current; + self->end = end; } static grub_err_t progress_bar_set_property (void *vself, const char *name, const char *value) { grub_gui_progress_bar_t self = vself; - if (grub_strcmp (name, "value") == 0) + if (grub_strcmp (name, "text") == 0) { - self->value = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "start") == 0) - { - self->start = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "end") == 0) - { - self->end = grub_strtol (value, 0, 10); - } - else if (grub_strcmp (name, "text") == 0) - { - grub_free (self->text); - if (! value) - value = ""; - self->text = grub_strdup (value); + grub_free (self->template); + if (grub_strcmp (value, "@TIMEOUT_NOTIFICATION_LONG@") == 0) + value + = _("The highlighted entry will be executed automatically in %ds."); + else if (grub_strcmp (value, "@TIMEOUT_NOTIFICATION_MIDDLE@") == 0) + /* TRANSLATORS: 's' stands for seconds. + It's a standalone timeout notification. + Please use the short form in your language. */ + value = _("%ds remaining."); + else if (grub_strcmp (value, "@TIMEOUT_NOTIFICATION_SHORT@") == 0) + /* TRANSLATORS: 's' stands for seconds. + It's a standalone timeout notification. + Please use the shortest form available in you language. */ + value = _("%ds"); + + self->template = grub_strdup (value); } else if (grub_strcmp (name, "font") == 0) { @@ -298,14 +330,6 @@ progress_bar_set_property (void *vself, const char *name, const char *value) grub_free (self->theme_dir); self->theme_dir = value ? grub_strdup (value) : 0; } - else if (grub_strcmp (name, "visible") == 0) - { - self->visible = grub_strcmp (value, "false") != 0; - } - else if (grub_strcmp (name, "show_text") == 0) - { - self->show_text = grub_strcmp (value, "false") != 0; - } else if (grub_strcmp (name, "id") == 0) { grub_free (self->id); @@ -331,6 +355,11 @@ static struct grub_gui_component_ops progress_bar_ops = .set_property = progress_bar_set_property }; +static struct grub_gui_progress_ops progress_bar_pb_ops = + { + .set_state = progress_bar_set_state + }; + grub_gui_component_t grub_gui_progress_bar_new (void) { @@ -338,10 +367,9 @@ grub_gui_progress_bar_new (void) self = grub_zalloc (sizeof (*self)); if (! self) return 0; - self->component.ops = &progress_bar_ops; + self->progress.ops = &progress_bar_pb_ops; + self->progress.component.ops = &progress_bar_ops; self->visible = 1; - self->show_text = 1; - self->text = grub_strdup (""); self->font = grub_font_get ("Helvetica 10"); grub_gui_color_t black = { .red = 0, .green = 0, .blue = 0, .alpha = 255 }; grub_gui_color_t gray = { .red = 128, .green = 128, .blue = 128, .alpha = 255 }; diff --git a/gfxmenu/view.c b/gfxmenu/view.c index 5008b105b..611c01e1b 100644 --- a/gfxmenu/view.c +++ b/gfxmenu/view.c @@ -160,11 +160,10 @@ draw_title (grub_gfxmenu_view_t view) struct progress_value_data { - const char *visible; - const char *start; - const char *end; - const char *value; - const char *text; + int visible; + int start; + int end; + int value; }; static void @@ -174,19 +173,14 @@ update_timeout_visit (grub_gui_component_t component, struct progress_value_data *pv; pv = (struct progress_value_data *) userdata; - component->ops->set_property (component, "visible", pv->visible); - component->ops->set_property (component, "start", pv->start); - component->ops->set_property (component, "end", pv->end); - component->ops->set_property (component, "value", pv->value); - component->ops->set_property (component, "text", pv->text); + ((struct grub_gui_progress *) component)->ops + ->set_state ((struct grub_gui_progress *) component, + pv->visible, pv->start, pv->value, pv->end); } void grub_gfxmenu_print_timeout (int timeout, void *data) { - char valuebuf[sizeof ("-XXXXXXXXXXX")]; - char startbuf[sizeof ("-XXXXXXXXXXX")]; - char msgbuf[120]; struct grub_gfxmenu_view *view = data; struct progress_value_data pv; @@ -205,17 +199,10 @@ grub_gfxmenu_print_timeout (int timeout, void *data) if (view->first_timeout == -1) view->first_timeout = timeout; - pv.visible = "true"; - grub_sprintf (startbuf, "%d", -(view->first_timeout + 1)); - pv.start = startbuf; - pv.end = "0"; - grub_sprintf (valuebuf, "%d", -timeout); - pv.value = valuebuf; - - grub_sprintf (msgbuf, - "The highlighted entry will be booted automatically in %d s.", - timeout); - pv.text = msgbuf; + pv.visible = 1; + pv.start = -(view->first_timeout + 1); + pv.end = 0; + pv.value = -timeout; grub_gui_find_by_id ((grub_gui_component_t) view->canvas, TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv); @@ -244,11 +231,10 @@ grub_gfxmenu_clear_timeout (void *data) grub_gfxmenu_view_redraw (view, &bounds); } - pv.visible = "false"; - pv.start = "1"; - pv.end = "0"; - pv.value = "0"; - pv.text = ""; + pv.visible = 0; + pv.start = 1; + pv.end = 0; + pv.value = 0; grub_gui_find_by_id ((grub_gui_component_t) view->canvas, TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv); diff --git a/include/grub/gui.h b/include/grub/gui.h index 6f8f44805..7bd71acd3 100644 --- a/include/grub/gui.h +++ b/include/grub/gui.h @@ -74,6 +74,11 @@ struct grub_gui_list_ops grub_gfxmenu_view_t view); }; +struct grub_gui_progress_ops +{ + void (*set_state) (void *self, int visible, int start, int current, int end); +}; + typedef signed grub_fixed_signed_t; #define GRUB_FIXED_1 0x10000 @@ -120,6 +125,12 @@ struct grub_gui_component grub_fixed_signed_t hfrac; }; +struct grub_gui_progress +{ + struct grub_gui_component component; + struct grub_gui_progress_ops *ops; +}; + struct grub_gui_container { struct grub_gui_component component; diff --git a/normal/menu.c b/normal/menu.c index 17730eff3..bbd1049e4 100644 --- a/normal/menu.c +++ b/normal/menu.c @@ -362,6 +362,8 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) if (timeout > 0) menu_print_timeout (timeout); + else + clear_timeout (); while (1) {