mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-02 09:46:37 +03:00
expo: Support highlighting menu items
Expo normally uses a pointer to show the current item. Add support for highlighting as well, since this makes it easier for the user to see the current item. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
@@ -126,6 +126,7 @@ int cedit_prepare(struct expo *exp, struct udevice *vid_dev,
|
||||
return log_msg_ret("sid", ret);
|
||||
|
||||
exp->popup = true;
|
||||
exp->show_highlight = true;
|
||||
|
||||
/* This is not supported for now */
|
||||
if (0)
|
||||
|
||||
31
boot/scene.c
31
boot/scene.c
@@ -466,8 +466,10 @@ int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
|
||||
* @obj: Object to render
|
||||
* @box_only: true to show a box around the object, but keep the normal
|
||||
* background colour inside
|
||||
* @cur_item: true to render the background only for the current menu item
|
||||
*/
|
||||
static void scene_render_background(struct scene_obj *obj, bool box_only)
|
||||
static void scene_render_background(struct scene_obj *obj, bool box_only,
|
||||
bool cur_item)
|
||||
{
|
||||
struct vidconsole_bbox bbox[SCENEBB_count], *sel;
|
||||
struct expo *exp = obj->scene->expo;
|
||||
@@ -493,7 +495,7 @@ static void scene_render_background(struct scene_obj *obj, bool box_only)
|
||||
if (scene_obj_calc_bbox(obj, bbox))
|
||||
return;
|
||||
|
||||
sel = &bbox[SCENEBB_label];
|
||||
sel = cur_item ? &bbox[SCENEBB_curitem] : &bbox[SCENEBB_label];
|
||||
if (!sel->valid)
|
||||
return;
|
||||
|
||||
@@ -547,9 +549,13 @@ static int scene_txt_render(struct expo *exp, struct udevice *dev,
|
||||
}
|
||||
|
||||
if (obj->flags & SCENEOF_POINT) {
|
||||
int inset;
|
||||
|
||||
inset = exp->popup ? menu_inset : 0;
|
||||
vidconsole_push_colour(cons, fore, back, &old);
|
||||
video_fill_part(dev, x - menu_inset, y, obj->bbox.x1,
|
||||
obj->bbox.y1, vid_priv->colour_bg);
|
||||
video_fill_part(dev, x - inset, y,
|
||||
obj->bbox.x1, obj->bbox.y1,
|
||||
vid_priv->colour_bg);
|
||||
}
|
||||
|
||||
mline = alist_get(&gen->lines, 0, typeof(*mline));
|
||||
@@ -632,13 +638,18 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode)
|
||||
case SCENEOBJT_MENU: {
|
||||
struct scene_obj_menu *menu = (struct scene_obj_menu *)obj;
|
||||
|
||||
if (exp->popup && (obj->flags & SCENEOF_OPEN)) {
|
||||
if (!cons)
|
||||
return -ENOTSUPP;
|
||||
if (exp->popup) {
|
||||
if (obj->flags & SCENEOF_OPEN) {
|
||||
if (!cons)
|
||||
return -ENOTSUPP;
|
||||
|
||||
/* draw a background behind the menu items */
|
||||
scene_render_background(obj, false);
|
||||
/* draw a background behind the menu items */
|
||||
scene_render_background(obj, false, false);
|
||||
}
|
||||
} else if (exp->show_highlight) {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
/*
|
||||
* With a vidconsole, the text and item pointer are rendered as
|
||||
* normal objects so we don't need to do anything here. The menu
|
||||
@@ -655,7 +666,7 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode)
|
||||
}
|
||||
case SCENEOBJT_TEXTLINE:
|
||||
if (obj->flags & SCENEOF_OPEN)
|
||||
scene_render_background(obj, true);
|
||||
scene_render_background(obj, true, false);
|
||||
break;
|
||||
case SCENEOBJT_BOX: {
|
||||
struct scene_obj_box *box = (struct scene_obj_box *)obj;
|
||||
|
||||
@@ -87,7 +87,7 @@ struct scene_menitem *scene_menuitem_find_val(const struct scene_obj_menu *menu,
|
||||
static int update_pointers(struct scene_obj_menu *menu, uint id, bool point)
|
||||
{
|
||||
struct scene *scn = menu->obj.scene;
|
||||
const bool stack = scn->expo->popup;
|
||||
const bool stack = scn->expo->show_highlight;
|
||||
const struct scene_menitem *item;
|
||||
int ret;
|
||||
|
||||
@@ -108,9 +108,17 @@ static int update_pointers(struct scene_obj_menu *menu, uint id, bool point)
|
||||
}
|
||||
|
||||
if (stack) {
|
||||
uint id;
|
||||
int val;
|
||||
|
||||
point &= scn->highlight_id == menu->obj.id;
|
||||
scene_obj_flag_clrset(scn, item->label_id, SCENEOF_POINT,
|
||||
point ? SCENEOF_POINT : 0);
|
||||
val = point ? SCENEOF_POINT : 0;
|
||||
id = item->desc_id;
|
||||
if (!id)
|
||||
id = item->label_id;
|
||||
if (!id)
|
||||
id = item->key_id;
|
||||
scene_obj_flag_clrset(scn, id, SCENEOF_POINT, val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -106,6 +106,7 @@ struct expo_theme {
|
||||
* type set to EXPOACT_NONE if there is no action
|
||||
* @text_mode: true to use text mode for the menu (no vidconsole)
|
||||
* @popup: true to use popup menus, instead of showing all items
|
||||
* @show_highlight: show a highlight bar on the selected menu item
|
||||
* @priv: Private data for the controller
|
||||
* @done: Indicates that a cedit session is complete and the user has quit
|
||||
* @save: Indicates that cedit data should be saved, rather than discarded
|
||||
@@ -123,6 +124,7 @@ struct expo {
|
||||
struct expo_action action;
|
||||
bool text_mode;
|
||||
bool popup;
|
||||
bool show_highlight;
|
||||
void *priv;
|
||||
bool done;
|
||||
bool save;
|
||||
|
||||
@@ -666,6 +666,13 @@ static int expo_render_image(struct unit_test_state *uts)
|
||||
ut_assertok(scene_arrange(scn));
|
||||
ut_asserteq(0, scn->highlight_id);
|
||||
|
||||
scene_set_highlight_id(scn, OBJ_MENU);
|
||||
ut_assertok(scene_arrange(scn));
|
||||
ut_asserteq(OBJ_MENU, scn->highlight_id);
|
||||
ut_assertok(expo_render(exp));
|
||||
|
||||
ut_asserteq(19704, video_compress_fb(uts, dev, false));
|
||||
|
||||
/* move down */
|
||||
ut_assertok(expo_send_key(exp, BKEY_DOWN));
|
||||
|
||||
@@ -719,6 +726,12 @@ static int expo_render_image(struct unit_test_state *uts)
|
||||
/* make sure there was no console output */
|
||||
ut_assert_console_end();
|
||||
|
||||
/* now try with the highlight */
|
||||
exp->show_highlight = true;
|
||||
ut_assertok(scene_arrange(scn));
|
||||
ut_assertok(expo_render(exp));
|
||||
ut_asserteq(18844, video_compress_fb(uts, dev, false));
|
||||
|
||||
/* now try in text mode */
|
||||
expo_set_text_mode(exp, true);
|
||||
ut_assertok(expo_render(exp));
|
||||
|
||||
Reference in New Issue
Block a user