Merge branch 'makefile' into haiku
[grub2/phcoder.git] / gfxmenu / gui_progress_bar.c
blob440d4b2fcc7f7c1e448f084fa7ac3c0648c8fb55
1 /* gui_progress_bar.c - GUI progress bar component. */
2 /*
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/>.
20 #include <grub/mm.h>
21 #include <grub/misc.h>
22 #include <grub/gui.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;
34 char *id;
35 int preferred_width;
36 int preferred_height;
37 int visible;
38 int start;
39 int end;
40 int value;
41 int show_text;
42 char *text;
43 grub_font_t font;
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;
49 char *theme_dir;
50 int need_to_recreate_pixmaps;
51 char *bar_pattern;
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;
59 static void
60 progress_bar_destroy (void *vself)
62 grub_gui_progress_bar_t self = vself;
63 grub_free (self);
66 static const char *
67 progress_bar_get_id (void *vself)
69 grub_gui_progress_bar_t self = vself;
70 return self->id;
73 static int
74 progress_bar_is_instance (void *vself __attribute__((unused)), const char *type)
76 return grub_strcmp (type, "component") == 0;
79 static int
80 check_pixmaps (grub_gui_progress_bar_t self)
82 if (self->need_to_recreate_pixmaps)
84 grub_gui_recreate_box (&self->bar_box,
85 self->bar_pattern,
86 self->theme_dir);
88 grub_gui_recreate_box (&self->highlight_box,
89 self->highlight_pattern,
90 self->theme_dir);
92 self->need_to_recreate_pixmaps = 0;
95 return (self->bar_box != 0 && self->highlight_box != 0);
98 static void
99 draw_filled_rect_bar (grub_gui_progress_bar_t self)
101 /* Set the progress bar's frame. */
102 grub_video_rect_t f;
103 f.x = 1;
104 f.y = 1;
105 f.width = self->bounds.width - 2;
106 f.height = self->bounds.height - 2;
108 /* Border. */
109 grub_video_fill_rect (grub_gui_map_color (self->border_color),
110 f.x - 1, f.y - 1,
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),
118 f.x + barwidth, f.y,
119 f.width - barwidth, f.height);
121 /* Bar foreground. */
122 grub_video_fill_rect (grub_gui_map_color (self->fg_color),
123 f.x, f.y,
124 barwidth, f.height);
127 static void
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);
153 static void
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);
173 static void
174 progress_bar_paint (void *vself)
176 grub_gui_progress_bar_t self = vself;
177 if (! self->visible)
178 return;
180 grub_video_rect_t vpsave;
181 grub_gui_set_viewport (&self->bounds, &vpsave);
183 if (check_pixmaps (self))
184 draw_pixmap_bar (self);
185 else
186 draw_filled_rect_bar (self);
188 draw_text (self);
190 grub_gui_restore_viewport (&vpsave);
193 static void
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;
204 return self->parent;
207 static void
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;
214 static void
215 progress_bar_get_bounds (void *vself, grub_video_rect_t *bounds)
217 grub_gui_progress_bar_t self = vself;
218 *bounds = self->bounds;
221 static void
222 progress_bar_get_preferred_size (void *vself, int *width, int *height)
224 grub_gui_progress_bar_t self = vself;
226 *width = 200;
227 *height = 28;
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;
236 static grub_err_t
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);
255 if (! value)
256 value = "";
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)
299 int w;
300 int h;
301 if (grub_gui_parse_2_tuple (value, &w, &h) != GRUB_ERR_NONE)
302 return grub_errno;
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);
317 if (value)
318 self->id = grub_strdup (value);
319 else
320 self->id = 0;
322 return grub_errno;
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
339 grub_gui_component_t
340 grub_gui_progress_bar_new (void)
342 grub_gui_progress_bar_t self;
343 self = grub_malloc (sizeof (*self));
344 if (! self)
345 return 0;
346 self->progress_bar = &progress_bar_ops;
347 self->parent = 0;
348 self->bounds.x = 0;
349 self->bounds.y = 0;
350 self->bounds.width = 0;
351 self->bounds.height = 0;
352 self->id = 0;
353 self->preferred_width = -1;
354 self->preferred_height = -1;
355 self->visible = 1;
356 self->start = 0;
357 self->end = 0;
358 self->value = 0;
359 self->show_text = 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;
370 self->theme_dir = 0;
371 self->need_to_recreate_pixmaps = 0;
372 self->bar_pattern = 0;
373 self->highlight_pattern = 0;
374 self->bar_box = 0;
375 self->highlight_box = 0;
377 return (grub_gui_component_t) self;