diff options
author | Simon Glass <sjg@chromium.org> | 2023-06-01 10:22:57 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-07-14 12:54:51 -0400 |
commit | 756c9559e60a0ef8434128205adced937240925d (patch) | |
tree | a9d384616c67c9f9999317a3d253ea37a5b57f5d /boot | |
parent | 3f33b9c722a41e1577df110470521a014713ce2e (diff) | |
download | u-boot-756c9559e60a0ef8434128205adced937240925d.tar.gz u-boot-756c9559e60a0ef8434128205adced937240925d.tar.bz2 u-boot-756c9559e60a0ef8434128205adced937240925d.zip |
expo: Draw popup menus in both opened and closed states
When a popup menu is closed it shows only the selected item. When it is
open it shows a background and all items, with a highlight that can be
moved between the items.
Add the drawing logic for this.
Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'boot')
-rw-r--r-- | boot/scene.c | 66 | ||||
-rw-r--r-- | boot/scene_internal.h | 7 | ||||
-rw-r--r-- | boot/scene_menu.c | 29 |
3 files changed, 100 insertions, 2 deletions
diff --git a/boot/scene.c b/boot/scene.c index 4dbe12a2b7..fb199ef295 100644 --- a/boot/scene.c +++ b/boot/scene.c @@ -345,14 +345,44 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode) } if (ret && ret != -ENOSYS) return log_msg_ret("font", ret); - vidconsole_set_cursor_pos(cons, x, y); str = expo_get_str(exp, txt->str_id); - if (str) + if (str) { + struct video_priv *vid_priv; + struct vidconsole_colour old; + enum colour_idx fore, back; + + if (CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK)) { + fore = VID_BLACK; + back = VID_WHITE; + } else { + fore = VID_LIGHT_GRAY; + back = VID_BLACK; + } + + vid_priv = dev_get_uclass_priv(dev); + if (obj->flags & SCENEOF_POINT) { + vidconsole_push_colour(cons, fore, back, &old); + video_fill_part(dev, x, y, + x + obj->dim.w, y + obj->dim.h, + vid_priv->colour_bg); + } + vidconsole_set_cursor_pos(cons, x, y); vidconsole_put_string(cons, str); + if (obj->flags & SCENEOF_POINT) + vidconsole_pop_colour(cons, &old); + } break; } case SCENEOBJT_MENU: { struct scene_obj_menu *menu = (struct scene_obj_menu *)obj; + + if (exp->popup && (obj->flags & SCENEOF_OPEN)) { + if (!cons) + return -ENOTSUPP; + + /* draw a background behind the menu items */ + scene_menu_render(menu); + } /* * With a vidconsole, the text and item pointer are rendered as * normal objects so we don't need to do anything here. The menu @@ -494,3 +524,35 @@ int scene_apply_theme(struct scene *scn, struct expo_theme *theme) return 0; } + +void scene_set_highlight_id(struct scene *scn, uint id) +{ + scn->highlight_id = id; +} + +void scene_highlight_first(struct scene *scn) +{ + struct scene_obj *obj; + + list_for_each_entry(obj, &scn->obj_head, sibling) { + switch (obj->type) { + case SCENEOBJT_MENU: + scene_set_highlight_id(scn, obj->id); + return; + default: + break; + } + } +} + +int scene_set_open(struct scene *scn, uint id, bool open) +{ + int ret; + + ret = scene_obj_flag_clrset(scn, id, SCENEOF_OPEN, + open ? SCENEOF_OPEN : 0); + if (ret) + return log_msg_ret("flg", ret); + + return 0; +} diff --git a/boot/scene_internal.h b/boot/scene_internal.h index 3387a90761..2544c961da 100644 --- a/boot/scene_internal.h +++ b/boot/scene_internal.h @@ -154,6 +154,13 @@ int scene_render(struct scene *scn); int scene_send_key(struct scene *scn, int key, struct expo_action *event); /** + * scene_menu_render() - Render the background behind a menu + * + * @menu: Menu to render + */ +void scene_menu_render(struct scene_obj_menu *menu); + +/** * scene_menu_calc_dims() - Calculate the dimensions of a menu * * Updates the width and height of the menu based on its contents diff --git a/boot/scene_menu.c b/boot/scene_menu.c index 892099557a..20ded91fb3 100644 --- a/boot/scene_menu.c +++ b/boot/scene_menu.c @@ -515,3 +515,32 @@ int scene_menu_display(struct scene_obj_menu *menu) return -ENOTSUPP; } + +void scene_menu_render(struct scene_obj_menu *menu) +{ + struct expo *exp = menu->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; + struct vidconsole_colour old; + enum colour_idx fore, back; + + if (CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK)) { + fore = VID_BLACK; + back = VID_WHITE; + } else { + fore = VID_LIGHT_GRAY; + back = VID_BLACK; + } + + scene_menu_calc_bbox(menu, &bbox, &label_bbox); + vidconsole_push_colour(cons, fore, back, &old); + vid_priv = dev_get_uclass_priv(dev); + video_fill_part(dev, label_bbox.x0 - theme->menu_inset, + label_bbox.y0 - theme->menu_inset, + label_bbox.x1, label_bbox.y1 + theme->menu_inset, + vid_priv->colour_fg); + vidconsole_pop_colour(cons, &old); +} |