1 /* gui_progress_bar.c - GUI progress bar component. */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2008,2009 Free Software Foundation, Inc.
6 * GRUB 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.
11 * GRUB 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.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
21 #include <grub/misc.h>
23 #include <grub/font.h>
24 #include <grub/gui_string_util.h>
25 #include <grub/gfxmenu_view.h>
26 #include <grub/gfxwidgets.h>
28 struct grub_gui_progress_bar
30 struct grub_gui_component_ops
*progress_bar
;
32 grub_gui_container_t parent
;
33 grub_video_rect_t bounds
;
44 grub_gui_color_t text_color
;
45 grub_gui_color_t border_color
;
46 grub_gui_color_t bg_color
;
47 grub_gui_color_t fg_color
;
50 int need_to_recreate_pixmaps
;
52 char *highlight_pattern
;
53 grub_gfxmenu_box_t bar_box
;
54 grub_gfxmenu_box_t highlight_box
;
57 typedef struct grub_gui_progress_bar
*grub_gui_progress_bar_t
;
60 progress_bar_destroy (void *vself
)
62 grub_gui_progress_bar_t self
= vself
;
67 progress_bar_get_id (void *vself
)
69 grub_gui_progress_bar_t self
= vself
;
74 progress_bar_is_instance (void *vself
__attribute__((unused
)), const char *type
)
76 return grub_strcmp (type
, "component") == 0;
80 check_pixmaps (grub_gui_progress_bar_t self
)
82 if (self
->need_to_recreate_pixmaps
)
84 grub_gui_recreate_box (&self
->bar_box
,
88 grub_gui_recreate_box (&self
->highlight_box
,
89 self
->highlight_pattern
,
92 self
->need_to_recreate_pixmaps
= 0;
95 return (self
->bar_box
!= 0 && self
->highlight_box
!= 0);
99 draw_filled_rect_bar (grub_gui_progress_bar_t self
)
101 /* Set the progress bar's frame. */
105 f
.width
= self
->bounds
.width
- 2;
106 f
.height
= self
->bounds
.height
- 2;
109 grub_video_fill_rect (grub_gui_map_color (self
->border_color
),
111 f
.width
+ 2, f
.height
+ 2);
113 /* Bar background. */
114 int barwidth
= (f
.width
115 * (self
->value
- self
->start
)
116 / (self
->end
- self
->start
));
117 grub_video_fill_rect (grub_gui_map_color (self
->bg_color
),
119 f
.width
- barwidth
, f
.height
);
121 /* Bar foreground. */
122 grub_video_fill_rect (grub_gui_map_color (self
->fg_color
),
128 draw_pixmap_bar (grub_gui_progress_bar_t self
)
130 grub_gfxmenu_box_t bar
= self
->bar_box
;
131 grub_gfxmenu_box_t hl
= self
->highlight_box
;
132 int w
= self
->bounds
.width
;
133 int h
= self
->bounds
.height
;
134 int bar_l_pad
= bar
->get_left_pad (bar
);
135 int bar_r_pad
= bar
->get_right_pad (bar
);
136 int bar_t_pad
= bar
->get_top_pad (bar
);
137 int bar_b_pad
= bar
->get_bottom_pad (bar
);
138 int bar_h_pad
= bar_l_pad
+ bar_r_pad
;
139 int bar_v_pad
= bar_t_pad
+ bar_b_pad
;
140 int tracklen
= w
- bar_h_pad
;
141 int trackheight
= h
- bar_v_pad
;
142 bar
->set_content_size (bar
, tracklen
, trackheight
);
144 int barwidth
= (tracklen
145 * (self
->value
- self
->start
)
146 / (self
->end
- self
->start
));
147 hl
->set_content_size (hl
, barwidth
, h
- bar_v_pad
);
149 bar
->draw (bar
, 0, 0);
150 hl
->draw (hl
, bar_l_pad
, bar_t_pad
);
154 draw_text (grub_gui_progress_bar_t self
)
156 const char *text
= self
->text
;
157 if (text
&& self
->show_text
)
159 grub_font_t font
= self
->font
;
160 grub_video_color_t text_color
= grub_gui_map_color (self
->text_color
);
161 int width
= self
->bounds
.width
;
162 int height
= self
->bounds
.height
;
164 /* Center the text. */
165 int text_width
= grub_font_get_string_width (font
, text
);
166 int x
= (width
- text_width
) / 2;
167 int y
= ((height
- grub_font_get_descent (font
)) / 2
168 + grub_font_get_ascent (font
) / 2);
169 grub_font_draw_string (text
, font
, text_color
, x
, y
);
174 progress_bar_paint (void *vself
)
176 grub_gui_progress_bar_t self
= vself
;
180 grub_video_rect_t vpsave
;
181 grub_gui_set_viewport (&self
->bounds
, &vpsave
);
183 if (check_pixmaps (self
))
184 draw_pixmap_bar (self
);
186 draw_filled_rect_bar (self
);
190 grub_gui_restore_viewport (&vpsave
);
194 progress_bar_set_parent (void *vself
, grub_gui_container_t parent
)
196 grub_gui_progress_bar_t self
= vself
;
197 self
->parent
= parent
;
200 static grub_gui_container_t
201 progress_bar_get_parent (void *vself
)
203 grub_gui_progress_bar_t self
= vself
;
208 progress_bar_set_bounds (void *vself
, const grub_video_rect_t
*bounds
)
210 grub_gui_progress_bar_t self
= vself
;
211 self
->bounds
= *bounds
;
215 progress_bar_get_bounds (void *vself
, grub_video_rect_t
*bounds
)
217 grub_gui_progress_bar_t self
= vself
;
218 *bounds
= self
->bounds
;
222 progress_bar_get_preferred_size (void *vself
, int *width
, int *height
)
224 grub_gui_progress_bar_t self
= vself
;
229 /* Allow preferred dimensions to override the progress_bar dimensions. */
230 if (self
->preferred_width
>= 0)
231 *width
= self
->preferred_width
;
232 if (self
->preferred_height
>= 0)
233 *height
= self
->preferred_height
;
237 progress_bar_set_property (void *vself
, const char *name
, const char *value
)
239 grub_gui_progress_bar_t self
= vself
;
240 if (grub_strcmp (name
, "value") == 0)
242 self
->value
= grub_strtol (value
, 0, 10);
244 else if (grub_strcmp (name
, "start") == 0)
246 self
->start
= grub_strtol (value
, 0, 10);
248 else if (grub_strcmp (name
, "end") == 0)
250 self
->end
= grub_strtol (value
, 0, 10);
252 else if (grub_strcmp (name
, "text") == 0)
254 grub_free (self
->text
);
257 self
->text
= grub_strdup (value
);
259 else if (grub_strcmp (name
, "font") == 0)
261 self
->font
= grub_font_get (value
);
263 else if (grub_strcmp (name
, "text_color") == 0)
265 grub_gui_parse_color (value
, &self
->text_color
);
267 else if (grub_strcmp (name
, "border_color") == 0)
269 grub_gui_parse_color (value
, &self
->border_color
);
271 else if (grub_strcmp (name
, "bg_color") == 0)
273 grub_gui_parse_color (value
, &self
->bg_color
);
275 else if (grub_strcmp (name
, "fg_color") == 0)
277 grub_gui_parse_color (value
, &self
->fg_color
);
279 else if (grub_strcmp (name
, "bar_style") == 0)
281 self
->need_to_recreate_pixmaps
= 1;
282 grub_free (self
->bar_pattern
);
283 self
->bar_pattern
= value
? grub_strdup (value
) : 0;
285 else if (grub_strcmp (name
, "highlight_style") == 0)
287 self
->need_to_recreate_pixmaps
= 1;
288 grub_free (self
->highlight_pattern
);
289 self
->highlight_pattern
= value
? grub_strdup (value
) : 0;
291 else if (grub_strcmp (name
, "theme_dir") == 0)
293 self
->need_to_recreate_pixmaps
= 1;
294 grub_free (self
->theme_dir
);
295 self
->theme_dir
= value
? grub_strdup (value
) : 0;
297 else if (grub_strcmp (name
, "preferred_size") == 0)
301 if (grub_gui_parse_2_tuple (value
, &w
, &h
) != GRUB_ERR_NONE
)
303 self
->preferred_width
= w
;
304 self
->preferred_height
= h
;
306 else if (grub_strcmp (name
, "visible") == 0)
308 self
->visible
= grub_strcmp (value
, "false") != 0;
310 else if (grub_strcmp (name
, "show_text") == 0)
312 self
->show_text
= grub_strcmp (value
, "false") != 0;
314 else if (grub_strcmp (name
, "id") == 0)
316 grub_free (self
->id
);
318 self
->id
= grub_strdup (value
);
325 static struct grub_gui_component_ops progress_bar_ops
=
327 .destroy
= progress_bar_destroy
,
328 .get_id
= progress_bar_get_id
,
329 .is_instance
= progress_bar_is_instance
,
330 .paint
= progress_bar_paint
,
331 .set_parent
= progress_bar_set_parent
,
332 .get_parent
= progress_bar_get_parent
,
333 .set_bounds
= progress_bar_set_bounds
,
334 .get_bounds
= progress_bar_get_bounds
,
335 .get_preferred_size
= progress_bar_get_preferred_size
,
336 .set_property
= progress_bar_set_property
340 grub_gui_progress_bar_new (void)
342 grub_gui_progress_bar_t self
;
343 self
= grub_malloc (sizeof (*self
));
346 self
->progress_bar
= &progress_bar_ops
;
350 self
->bounds
.width
= 0;
351 self
->bounds
.height
= 0;
353 self
->preferred_width
= -1;
354 self
->preferred_height
= -1;
360 self
->text
= grub_strdup ("");
361 self
->font
= grub_font_get ("Helvetica 10");
362 grub_gui_color_t black
= { .red
= 0, .green
= 0, .blue
= 0, .alpha
= 255 };
363 grub_gui_color_t gray
= { .red
= 128, .green
= 128, .blue
= 128, .alpha
= 255 };
364 grub_gui_color_t lightgray
= { .red
= 200, .green
= 200, .blue
= 200, .alpha
= 255 };
365 self
->text_color
= black
;
366 self
->border_color
= black
;
367 self
->bg_color
= gray
;
368 self
->fg_color
= lightgray
;
371 self
->need_to_recreate_pixmaps
= 0;
372 self
->bar_pattern
= 0;
373 self
->highlight_pattern
= 0;
375 self
->highlight_box
= 0;
377 return (grub_gui_component_t
) self
;