/* gui.h - GUI components header file. */ /* * VAS_EBOOT -- GRand Unified Bootloader * Copyright (C) 2008,2009 Free Software Foundation, Inc. * * VAS_EBOOT is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VAS_EBOOT is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VAS_EBOOT. If not, see . */ #include #include #include #include #include #include #ifndef VAS_EBOOT_GUI_H #define VAS_EBOOT_GUI_H 1 /* The component ID identifying GUI components to be updated as the timeout status changes. */ #define VAS_EBOOT_GFXMENU_TIMEOUT_COMPONENT_ID "__timeout__" typedef struct VasEBoot_gui_component *VasEBoot_gui_component_t; typedef struct VasEBoot_gui_container *VasEBoot_gui_container_t; typedef struct VasEBoot_gui_list *VasEBoot_gui_list_t; typedef void (*VasEBoot_gui_component_callback) (VasEBoot_gui_component_t component, void *userdata); /* Component interface. */ struct VasEBoot_gui_component_ops { void (*destroy) (void *self); const char * (*get_id) (void *self); int (*is_instance) (void *self, const char *type); void (*paint) (void *self, const VasEBoot_video_rect_t *bounds); void (*set_parent) (void *self, VasEBoot_gui_container_t parent); VasEBoot_gui_container_t (*get_parent) (void *self); void (*set_bounds) (void *self, const VasEBoot_video_rect_t *bounds); void (*get_bounds) (void *self, VasEBoot_video_rect_t *bounds); void (*get_minimal_size) (void *self, unsigned *width, unsigned *height); VasEBoot_err_t (*set_property) (void *self, const char *name, const char *value); void (*repaint) (void *self, int second_pass); }; struct VasEBoot_gui_container_ops { void (*add) (void *self, VasEBoot_gui_component_t comp); void (*remove) (void *self, VasEBoot_gui_component_t comp); void (*iterate_children) (void *self, VasEBoot_gui_component_callback cb, void *userdata); }; struct VasEBoot_gui_list_ops { void (*set_view_info) (void *self, VasEBoot_gfxmenu_view_t view); void (*refresh_list) (void *self, VasEBoot_gfxmenu_view_t view); }; struct VasEBoot_gui_progress_ops { void (*set_state) (void *self, int visible, int start, int current, int end); }; typedef void (*VasEBoot_gfxmenu_set_state_t) (void *self, int visible, int start, int current, int end); struct VasEBoot_gfxmenu_timeout_notify { struct VasEBoot_gfxmenu_timeout_notify *next; VasEBoot_gfxmenu_set_state_t set_state; VasEBoot_gui_component_t self; }; extern struct VasEBoot_gfxmenu_timeout_notify *VasEBoot_gfxmenu_timeout_notifications; static inline VasEBoot_err_t VasEBoot_gfxmenu_timeout_register (VasEBoot_gui_component_t self, VasEBoot_gfxmenu_set_state_t set_state) { struct VasEBoot_gfxmenu_timeout_notify *ne = VasEBoot_malloc (sizeof (*ne)); if (!ne) return VasEBoot_errno; ne->set_state = set_state; ne->self = self; ne->next = VasEBoot_gfxmenu_timeout_notifications; VasEBoot_gfxmenu_timeout_notifications = ne; return VAS_EBOOT_ERR_NONE; } static inline void VasEBoot_gfxmenu_timeout_unregister (VasEBoot_gui_component_t self) { struct VasEBoot_gfxmenu_timeout_notify **p, *q; for (p = &VasEBoot_gfxmenu_timeout_notifications, q = *p; q; p = &(q->next), q = q->next) if (q->self == self) { *p = q->next; VasEBoot_free (q); break; } } typedef signed VasEBoot_fixed_signed_t; #define VAS_EBOOT_FIXED_1 0x10000 /* Special care is taken to round to nearest integer and not just truncate. */ static inline signed VasEBoot_divide_round (signed a, signed b) { int neg = 0; signed ret; if (b < 0) { b = -b; neg = !neg; } if (a < 0) { a = -a; neg = !neg; } ret = (unsigned) (a + b / 2) / (unsigned) b; return neg ? -ret : ret; } static inline signed VasEBoot_fixed_sfs_divide (signed a, VasEBoot_fixed_signed_t b) { return VasEBoot_divide_round (a * VAS_EBOOT_FIXED_1, b); } static inline VasEBoot_fixed_signed_t VasEBoot_fixed_fsf_divide (VasEBoot_fixed_signed_t a, signed b) { return VasEBoot_divide_round (a, b); } static inline signed VasEBoot_fixed_sfs_multiply (signed a, VasEBoot_fixed_signed_t b) { return (a * b) / VAS_EBOOT_FIXED_1; } static inline signed VasEBoot_fixed_to_signed (VasEBoot_fixed_signed_t in) { return in / VAS_EBOOT_FIXED_1; } static inline VasEBoot_fixed_signed_t VasEBoot_signed_to_fixed (signed in) { return in * VAS_EBOOT_FIXED_1; } struct VasEBoot_gui_component { struct VasEBoot_gui_component_ops *ops; signed x; VasEBoot_fixed_signed_t xfrac; signed y; VasEBoot_fixed_signed_t yfrac; signed w; VasEBoot_fixed_signed_t wfrac; signed h; VasEBoot_fixed_signed_t hfrac; }; struct VasEBoot_gui_progress { struct VasEBoot_gui_component component; struct VasEBoot_gui_progress_ops *ops; }; struct VasEBoot_gui_container { struct VasEBoot_gui_component component; struct VasEBoot_gui_container_ops *ops; }; struct VasEBoot_gui_list { struct VasEBoot_gui_component component; struct VasEBoot_gui_list_ops *ops; }; /* Interfaces to concrete component classes. */ VasEBoot_gui_container_t VasEBoot_gui_canvas_new (void); VasEBoot_gui_container_t VasEBoot_gui_vbox_new (void); VasEBoot_gui_container_t VasEBoot_gui_hbox_new (void); VasEBoot_gui_component_t VasEBoot_gui_label_new (void); VasEBoot_gui_component_t VasEBoot_gui_image_new (void); VasEBoot_gui_component_t VasEBoot_gui_progress_bar_new (void); VasEBoot_gui_component_t VasEBoot_gui_list_new (void); VasEBoot_gui_component_t VasEBoot_gui_circular_progress_new (void); /* Manipulation functions. */ /* Visit all components with the specified ID. */ void VasEBoot_gui_find_by_id (VasEBoot_gui_component_t root, const char *id, VasEBoot_gui_component_callback cb, void *userdata); /* Visit all components. */ void VasEBoot_gui_iterate_recursively (VasEBoot_gui_component_t root, VasEBoot_gui_component_callback cb, void *userdata); /* Helper functions. */ static __inline void VasEBoot_gui_save_viewport (VasEBoot_video_rect_t *r) { VasEBoot_video_get_viewport ((unsigned *) &r->x, (unsigned *) &r->y, (unsigned *) &r->width, (unsigned *) &r->height); } static __inline void VasEBoot_gui_restore_viewport (const VasEBoot_video_rect_t *r) { VasEBoot_video_set_viewport (r->x, r->y, r->width, r->height); } /* Set a new viewport relative the the current one, saving the current viewport in OLD so it can be later restored. */ static __inline void VasEBoot_gui_set_viewport (const VasEBoot_video_rect_t *r, VasEBoot_video_rect_t *old) { VasEBoot_gui_save_viewport (old); VasEBoot_video_set_viewport (old->x + r->x, old->y + r->y, r->width, r->height); } static inline int VasEBoot_video_have_common_points (const VasEBoot_video_rect_t *a, const VasEBoot_video_rect_t *b) { if (!((a->x <= b->x && b->x <= a->x + a->width) || (b->x <= a->x && a->x <= b->x + b->width))) return 0; if (!((a->y <= b->y && b->y <= a->y + a->height) || (b->y <= a->y && a->y <= b->y + b->height))) return 0; return 1; } static inline int VasEBoot_video_bounds_inside_region (const VasEBoot_video_rect_t *b, const VasEBoot_video_rect_t *r) { if (r->x > b->x || r->x + r->width < b->x + b->width) return 0; if (r->y > b->y || r->y + r->height < b->y + b->height) return 0; return 1; } #endif /* ! VAS_EBOOT_GUI_H */