mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-05-05 20:56:12 +02:00
expo: Make bounding-box calculation more flexible
In some cases it is useful to obtain more than just two bounding boxes from a menu, e.g. to line up all descriptions vertically. Use an array to obtain bounding-box information and calculate it separately for each item. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
f04026a59f
commit
baaf090734
61
boot/scene.c
61
boot/scene.c
@ -325,9 +325,9 @@ int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
|
||||
*/
|
||||
static void scene_render_background(struct scene_obj *obj, bool box_only)
|
||||
{
|
||||
struct vidconsole_bbox bbox[SCENEBB_count], *sel;
|
||||
struct expo *exp = obj->scene->expo;
|
||||
const struct expo_theme *theme = &exp->theme;
|
||||
struct vidconsole_bbox bbox, label_bbox;
|
||||
struct udevice *dev = exp->display;
|
||||
struct video_priv *vid_priv;
|
||||
struct udevice *cons = exp->cons;
|
||||
@ -346,17 +346,20 @@ static void scene_render_background(struct scene_obj *obj, bool box_only)
|
||||
}
|
||||
|
||||
/* see if this object wants to render a background */
|
||||
if (scene_obj_calc_bbox(obj, &bbox, &label_bbox))
|
||||
if (scene_obj_calc_bbox(obj, bbox))
|
||||
return;
|
||||
|
||||
sel = &bbox[SCENEBB_label];
|
||||
if (!sel->valid)
|
||||
return;
|
||||
|
||||
vidconsole_push_colour(cons, fore, back, &old);
|
||||
video_fill_part(dev, label_bbox.x0 - inset, label_bbox.y0 - inset,
|
||||
label_bbox.x1 + inset, label_bbox.y1 + inset,
|
||||
video_fill_part(dev, sel->x0 - inset, sel->y0 - inset,
|
||||
sel->x1 + inset, sel->y1 + inset,
|
||||
vid_priv->colour_fg);
|
||||
vidconsole_pop_colour(cons, &old);
|
||||
if (box_only) {
|
||||
video_fill_part(dev, label_bbox.x0, label_bbox.y0,
|
||||
label_bbox.x1, label_bbox.y1,
|
||||
video_fill_part(dev, sel->x0, sel->y0, sel->x1, sel->y1,
|
||||
vid_priv->colour_bg);
|
||||
}
|
||||
}
|
||||
@ -729,8 +732,7 @@ int scene_send_key(struct scene *scn, int key, struct expo_action *event)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scene_obj_calc_bbox(struct scene_obj *obj, struct vidconsole_bbox *bbox,
|
||||
struct vidconsole_bbox *label_bbox)
|
||||
int scene_obj_calc_bbox(struct scene_obj *obj, struct vidconsole_bbox bbox[])
|
||||
{
|
||||
switch (obj->type) {
|
||||
case SCENEOBJT_NONE:
|
||||
@ -740,14 +742,15 @@ int scene_obj_calc_bbox(struct scene_obj *obj, struct vidconsole_bbox *bbox,
|
||||
case SCENEOBJT_MENU: {
|
||||
struct scene_obj_menu *menu = (struct scene_obj_menu *)obj;
|
||||
|
||||
scene_menu_calc_bbox(menu, bbox, label_bbox);
|
||||
scene_menu_calc_bbox(menu, bbox);
|
||||
break;
|
||||
}
|
||||
case SCENEOBJT_TEXTLINE: {
|
||||
struct scene_obj_textline *tline;
|
||||
|
||||
tline = (struct scene_obj_textline *)obj;
|
||||
scene_textline_calc_bbox(tline, bbox, label_bbox);
|
||||
scene_textline_calc_bbox(tline, &bbox[SCENEBB_all],
|
||||
&bbox[SCENEBB_label]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -915,28 +918,42 @@ int scene_iter_objs(struct scene *scn, expo_scene_obj_iterator iter,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scene_bbox_join(const struct vidconsole_bbox *src, int inset,
|
||||
struct vidconsole_bbox *dst)
|
||||
{
|
||||
if (dst->valid) {
|
||||
dst->x0 = min(dst->x0, src->x0 - inset);
|
||||
dst->y0 = min(dst->y0, src->y0);
|
||||
dst->x1 = max(dst->x1, src->x1 + inset);
|
||||
dst->y1 = max(dst->y1, src->y1);
|
||||
} else {
|
||||
dst->x0 = src->x0 - inset;
|
||||
dst->y0 = src->y0;
|
||||
dst->x1 = src->x1 + inset;
|
||||
dst->y1 = src->y1;
|
||||
dst->valid = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scene_bbox_union(struct scene *scn, uint id, int inset,
|
||||
struct vidconsole_bbox *bbox)
|
||||
{
|
||||
struct scene_obj *obj;
|
||||
struct vidconsole_bbox local;
|
||||
|
||||
if (!id)
|
||||
return 0;
|
||||
obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
|
||||
if (!obj)
|
||||
return log_msg_ret("obj", -ENOENT);
|
||||
if (bbox->valid) {
|
||||
bbox->x0 = min(bbox->x0, obj->bbox.x0 - inset);
|
||||
bbox->y0 = min(bbox->y0, obj->bbox.y0);
|
||||
bbox->x1 = max(bbox->x1, obj->bbox.x1 + inset);
|
||||
bbox->y1 = max(bbox->y1, obj->bbox.y1);
|
||||
} else {
|
||||
bbox->x0 = obj->bbox.x0 - inset;
|
||||
bbox->y0 = obj->bbox.y0;
|
||||
bbox->x1 = obj->bbox.x1 + inset;
|
||||
bbox->y1 = obj->bbox.y1;
|
||||
bbox->valid = true;
|
||||
}
|
||||
local.x0 = obj->bbox.x0;
|
||||
local.y0 = obj->bbox.y0;
|
||||
local.x1 = obj->bbox.x1;
|
||||
local.y1 = obj->bbox.y1;
|
||||
local.valid = true;
|
||||
scene_bbox_join(&local, inset, bbox);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -13,6 +13,27 @@ struct vidconsole_bbox;
|
||||
|
||||
typedef int (*expo_scene_obj_iterator)(struct scene_obj *obj, void *priv);
|
||||
|
||||
/**
|
||||
* enum scene_bbox_t - Parts of an object which can have a bounding box
|
||||
*
|
||||
* Objects can provide any or all of these bounding boxes
|
||||
*
|
||||
* @SCENEBB_label: Menu-item label
|
||||
* @SCENEBB_key: Menu-item key label
|
||||
* @SCENEBB_desc: Menu-item Description
|
||||
* @SCENEBB_curitem: Current item (pointed to)
|
||||
* @SCENEBB_all: All the above objects combined
|
||||
*/
|
||||
enum scene_bbox_t {
|
||||
SCENEBB_label,
|
||||
SCENEBB_key,
|
||||
SCENEBB_desc,
|
||||
SCENEBB_curitem,
|
||||
SCENEBB_all,
|
||||
|
||||
SCENEBB_count,
|
||||
};
|
||||
|
||||
/**
|
||||
* expo_lookup_scene_id() - Look up a scene ID
|
||||
*
|
||||
@ -291,6 +312,19 @@ struct scene_menitem *scene_menuitem_find_seq(const struct scene_obj_menu *menu,
|
||||
struct scene_menitem *scene_menuitem_find_val(const struct scene_obj_menu *menu,
|
||||
int val);
|
||||
|
||||
/**
|
||||
* scene_bbox_join() - update bouding box with a given src box
|
||||
*
|
||||
* Updates @dst so that it encompasses the bounding box @src
|
||||
*
|
||||
* @src: Input bounding box
|
||||
* @inset: Amount of inset to use for width
|
||||
* @dst: Bounding box to update
|
||||
* Return: 0 if OK, -ve on error
|
||||
*/
|
||||
int scene_bbox_join(const struct vidconsole_bbox *src, int inset,
|
||||
struct vidconsole_bbox *dst);
|
||||
|
||||
/**
|
||||
* scene_bbox_union() - update bouding box with the demensions of an object
|
||||
*
|
||||
@ -319,13 +353,11 @@ int scene_textline_calc_dims(struct scene_obj_textline *tline);
|
||||
* scene_menu_calc_bbox() - Calculate bounding boxes for the menu
|
||||
*
|
||||
* @menu: Menu to process
|
||||
* @bbox: Returns bounding box of menu including prompts
|
||||
* @label_bbox: Returns bounding box of labels
|
||||
* @bbox: List of bounding box to fill in
|
||||
* Return: 0 if OK, -ve on error
|
||||
*/
|
||||
void scene_menu_calc_bbox(struct scene_obj_menu *menu,
|
||||
struct vidconsole_bbox *bbox,
|
||||
struct vidconsole_bbox *label_bbox);
|
||||
struct vidconsole_bbox *bbox);
|
||||
|
||||
/**
|
||||
* scene_textline_calc_bbox() - Calculate bounding box for the textline
|
||||
@ -343,12 +375,10 @@ void scene_textline_calc_bbox(struct scene_obj_textline *menu,
|
||||
* scene_obj_calc_bbox() - Calculate bounding boxes for an object
|
||||
*
|
||||
* @obj: Object to process
|
||||
* @bbox: Returns bounding box of object including prompts
|
||||
* @label_bbox: Returns bounding box of labels (active area)
|
||||
* @bbox: Returns bounding boxes for object
|
||||
* Return: 0 if OK, -ve on error
|
||||
*/
|
||||
int scene_obj_calc_bbox(struct scene_obj *obj, struct vidconsole_bbox *bbox,
|
||||
struct vidconsole_bbox *label_bbox);
|
||||
int scene_obj_calc_bbox(struct scene_obj *obj, struct vidconsole_bbox *bbox);
|
||||
|
||||
/**
|
||||
* scene_textline_open() - Open a textline object
|
||||
|
||||
@ -139,55 +139,74 @@ static int menu_point_to_item(struct scene_obj_menu *menu, uint item_id)
|
||||
}
|
||||
|
||||
void scene_menu_calc_bbox(struct scene_obj_menu *menu,
|
||||
struct vidconsole_bbox *bbox,
|
||||
struct vidconsole_bbox *label_bbox)
|
||||
struct vidconsole_bbox *bbox)
|
||||
{
|
||||
const struct expo_theme *theme = &menu->obj.scene->expo->theme;
|
||||
const struct scene_menitem *item;
|
||||
int inset = theme->menu_inset;
|
||||
int i;
|
||||
|
||||
bbox->valid = false;
|
||||
scene_bbox_union(menu->obj.scene, menu->title_id, 0, bbox);
|
||||
for (i = 0; i < SCENEBB_count; i++)
|
||||
bbox[i].valid = false;
|
||||
|
||||
label_bbox->valid = false;
|
||||
scene_bbox_union(menu->obj.scene, menu->title_id, 0,
|
||||
&bbox[SCENEBB_all]);
|
||||
|
||||
list_for_each_entry(item, &menu->item_head, sibling) {
|
||||
scene_bbox_union(menu->obj.scene, item->label_id,
|
||||
theme->menu_inset, bbox);
|
||||
scene_bbox_union(menu->obj.scene, item->key_id, 0, bbox);
|
||||
scene_bbox_union(menu->obj.scene, item->desc_id, 0, bbox);
|
||||
scene_bbox_union(menu->obj.scene, item->preview_id, 0, bbox);
|
||||
struct vidconsole_bbox local;
|
||||
|
||||
/* Get the bounding box of all labels */
|
||||
scene_bbox_union(menu->obj.scene, item->label_id,
|
||||
theme->menu_inset, label_bbox);
|
||||
local.valid = false;
|
||||
scene_bbox_union(menu->obj.scene, item->label_id, inset,
|
||||
&local);
|
||||
scene_bbox_union(menu->obj.scene, item->key_id, 0, &local);
|
||||
scene_bbox_union(menu->obj.scene, item->desc_id, 0, &local);
|
||||
scene_bbox_union(menu->obj.scene, item->preview_id, 0, &local);
|
||||
|
||||
scene_bbox_join(&local, 0, &bbox[SCENEBB_all]);
|
||||
|
||||
/* Get the bounding box of all individual fields */
|
||||
scene_bbox_union(menu->obj.scene, item->label_id, inset,
|
||||
&bbox[SCENEBB_label]);
|
||||
scene_bbox_union(menu->obj.scene, item->key_id, inset,
|
||||
&bbox[SCENEBB_key]);
|
||||
scene_bbox_union(menu->obj.scene, item->desc_id, inset,
|
||||
&bbox[SCENEBB_desc]);
|
||||
|
||||
if (menu->cur_item_id == item->id)
|
||||
scene_bbox_join(&local, 0, &bbox[SCENEBB_curitem]);
|
||||
}
|
||||
|
||||
/*
|
||||
* subtract the final menuitem's gap to keep the insert the same top
|
||||
* and bottom
|
||||
* subtract the final menuitem's gap to keep the inset the same top and
|
||||
* bottom
|
||||
*/
|
||||
label_bbox->y1 -= theme->menuitem_gap_y;
|
||||
bbox[SCENEBB_label].y1 -= theme->menuitem_gap_y;
|
||||
}
|
||||
|
||||
int scene_menu_calc_dims(struct scene_obj_menu *menu)
|
||||
{
|
||||
struct vidconsole_bbox bbox, label_bbox;
|
||||
struct vidconsole_bbox bbox[SCENEBB_count], *cur;
|
||||
const struct scene_menitem *item;
|
||||
|
||||
scene_menu_calc_bbox(menu, &bbox, &label_bbox);
|
||||
scene_menu_calc_bbox(menu, bbox);
|
||||
|
||||
/* Make all labels the same size */
|
||||
if (label_bbox.valid) {
|
||||
cur = &bbox[SCENEBB_label];
|
||||
if (cur->valid) {
|
||||
list_for_each_entry(item, &menu->item_head, sibling) {
|
||||
scene_obj_set_size(menu->obj.scene, item->label_id,
|
||||
label_bbox.x1 - label_bbox.x0,
|
||||
label_bbox.y1 - label_bbox.y0);
|
||||
cur->x1 - cur->x0,
|
||||
cur->y1 - cur->y0);
|
||||
}
|
||||
}
|
||||
|
||||
if (bbox.valid) {
|
||||
menu->obj.dims.x = bbox.x1 - bbox.x0;
|
||||
menu->obj.dims.y = bbox.y1 - bbox.y0;
|
||||
cur = &bbox[SCENEBB_all];
|
||||
if (cur->valid) {
|
||||
menu->obj.dims.x = cur->x1 - cur->x0;
|
||||
menu->obj.dims.y = cur->y1 - cur->y0;
|
||||
|
||||
menu->obj.bbox.x1 = cur->x1;
|
||||
menu->obj.bbox.y1 = cur->y1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user