summaryrefslogtreecommitdiff
path: root/boot/scene.c
diff options
context:
space:
mode:
Diffstat (limited to 'boot/scene.c')
-rw-r--r--boot/scene.c477
1 files changed, 379 insertions, 98 deletions
diff --git a/boot/scene.c b/boot/scene.c
index fb82ffe768c..fa8f540bfb0 100644
--- a/boot/scene.c
+++ b/boot/scene.c
@@ -8,6 +8,7 @@
#define LOG_CATEGORY LOGC_EXPO
+#include <alist.h>
#include <dm.h>
#include <expo.h>
#include <malloc.h>
@@ -31,8 +32,7 @@ int scene_new(struct expo *exp, const char *name, uint id, struct scene **scnp)
return log_msg_ret("name", -ENOMEM);
}
- abuf_init(&scn->buf);
- if (!abuf_realloc(&scn->buf, EXPO_MAX_CHARS + 1)) {
+ if (!abuf_init_size(&scn->buf, EXPO_MAX_CHARS + 1)) {
free(scn->name);
free(scn);
return log_msg_ret("buf", -ENOMEM);
@@ -143,6 +143,32 @@ int scene_img(struct scene *scn, const char *name, uint id, char *data,
return img->obj.id;
}
+int scene_txt_generic_init(struct expo *exp, struct scene_txt_generic *gen,
+ const char *name, uint str_id, const char *str)
+{
+ int ret;
+
+ if (str) {
+ ret = expo_str(exp, name, str_id, str);
+ if (ret < 0)
+ return log_msg_ret("str", ret);
+ if (str_id && ret != str_id)
+ return log_msg_ret("id", -EEXIST);
+ str_id = ret;
+ } else {
+ ret = resolve_id(exp, str_id);
+ if (ret < 0)
+ return log_msg_ret("nst", ret);
+ if (str_id && ret != str_id)
+ return log_msg_ret("nid", -EEXIST);
+ }
+
+ gen->str_id = str_id;
+ alist_init_struct(&gen->lines, struct vidconsole_mline);
+
+ return 0;
+}
+
int scene_txt(struct scene *scn, const char *name, uint id, uint str_id,
struct scene_obj_txt **txtp)
{
@@ -155,8 +181,9 @@ int scene_txt(struct scene *scn, const char *name, uint id, uint str_id,
if (ret < 0)
return log_msg_ret("obj", ret);
- txt->str_id = str_id;
-
+ ret = scene_txt_generic_init(scn->expo, &txt->gen, name, str_id, NULL);
+ if (ret)
+ return log_msg_ret("stg", ret);
if (txtp)
*txtp = txt;
@@ -169,27 +196,41 @@ int scene_txt_str(struct scene *scn, const char *name, uint id, uint str_id,
struct scene_obj_txt *txt;
int ret;
- ret = expo_str(scn->expo, name, str_id, str);
- if (ret < 0)
- return log_msg_ret("str", ret);
- if (str_id && ret != str_id)
- return log_msg_ret("id", -EEXIST);
- str_id = ret;
-
ret = scene_obj_add(scn, name, id, SCENEOBJT_TEXT,
sizeof(struct scene_obj_txt),
(struct scene_obj **)&txt);
if (ret < 0)
return log_msg_ret("obj", ret);
- txt->str_id = str_id;
-
+ ret = scene_txt_generic_init(scn->expo, &txt->gen, name, str_id, str);
+ if (ret)
+ return log_msg_ret("tsg", ret);
if (txtp)
*txtp = txt;
return txt->obj.id;
}
+int scene_box(struct scene *scn, const char *name, uint id, uint width,
+ struct scene_obj_box **boxp)
+{
+ struct scene_obj_box *box;
+ int ret;
+
+ ret = scene_obj_add(scn, name, id, SCENEOBJT_BOX,
+ sizeof(struct scene_obj_box),
+ (struct scene_obj **)&box);
+ if (ret < 0)
+ return log_msg_ret("obj", ret);
+
+ box->width = width;
+
+ if (boxp)
+ *boxp = box;
+
+ return box->obj.id;
+}
+
int scene_txt_set_font(struct scene *scn, uint id, const char *font_name,
uint font_size)
{
@@ -198,8 +239,8 @@ int scene_txt_set_font(struct scene *scn, uint id, const char *font_name,
txt = scene_obj_find(scn, id, SCENEOBJT_TEXT);
if (!txt)
return log_msg_ret("find", -ENOENT);
- txt->font_name = font_name;
- txt->font_size = font_size;
+ txt->gen.font_name = font_name;
+ txt->gen.font_size = font_size;
return 0;
}
@@ -207,12 +248,17 @@ int scene_txt_set_font(struct scene *scn, uint id, const char *font_name,
int scene_obj_set_pos(struct scene *scn, uint id, int x, int y)
{
struct scene_obj *obj;
+ int w, h;
obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
if (!obj)
return log_msg_ret("find", -ENOENT);
- obj->dim.x = x;
- obj->dim.y = y;
+ w = obj->bbox.x1 - obj->bbox.x0;
+ h = obj->bbox.y1 - obj->bbox.y0;
+ obj->bbox.x0 = x;
+ obj->bbox.y0 = y;
+ obj->bbox.x1 = obj->bbox.x0 + w;
+ obj->bbox.y1 = obj->bbox.y0 + h;
return 0;
}
@@ -224,8 +270,62 @@ int scene_obj_set_size(struct scene *scn, uint id, int w, int h)
obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
if (!obj)
return log_msg_ret("find", -ENOENT);
- obj->dim.w = w;
- obj->dim.h = h;
+ obj->bbox.x1 = obj->bbox.x0 + w;
+ obj->bbox.y1 = obj->bbox.y0 + h;
+ obj->flags |= SCENEOF_SIZE_VALID;
+
+ return 0;
+}
+
+int scene_obj_set_width(struct scene *scn, uint id, int w)
+{
+ struct scene_obj *obj;
+
+ obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
+ if (!obj)
+ return log_msg_ret("find", -ENOENT);
+ obj->bbox.x1 = obj->bbox.x0 + w;
+
+ return 0;
+}
+
+int scene_obj_set_bbox(struct scene *scn, uint id, int x0, int y0, int x1,
+ int y1)
+{
+ struct scene_obj *obj;
+
+ obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
+ if (!obj)
+ return log_msg_ret("find", -ENOENT);
+ obj->bbox.x0 = x0;
+ obj->bbox.y0 = y0;
+ obj->bbox.x1 = x1;
+ obj->bbox.y1 = y1;
+ obj->flags |= SCENEOF_SIZE_VALID;
+
+ return 0;
+}
+
+int scene_obj_set_halign(struct scene *scn, uint id, enum scene_obj_align aln)
+{
+ struct scene_obj *obj;
+
+ obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
+ if (!obj)
+ return log_msg_ret("osh", -ENOENT);
+ obj->horiz = aln;
+
+ return 0;
+}
+
+int scene_obj_set_valign(struct scene *scn, uint id, enum scene_obj_align aln)
+{
+ struct scene_obj *obj;
+
+ obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
+ if (!obj)
+ return log_msg_ret("osv", -ENOENT);
+ obj->vert = aln;
return 0;
}
@@ -255,6 +355,49 @@ int scene_obj_flag_clrset(struct scene *scn, uint id, uint clr, uint set)
return 0;
}
+static void handle_alignment(enum scene_obj_align horiz,
+ enum scene_obj_align vert,
+ struct scene_obj_bbox *bbox,
+ struct scene_obj_dims *dims,
+ int xsize, int ysize,
+ struct scene_obj_offset *offset)
+{
+ int width, height;
+
+ if (bbox->x1 == SCENEOB_DISPLAY_MAX)
+ bbox->x1 = xsize ?: 1280;
+ if (bbox->y1 == SCENEOB_DISPLAY_MAX)
+ bbox->y1 = ysize ?: 1024;
+
+ width = bbox->x1 - bbox->x0;
+ height = bbox->y1 - bbox->y0;
+
+ switch (horiz) {
+ case SCENEOA_CENTRE:
+ offset->xofs = (width - dims->x) / 2;
+ break;
+ case SCENEOA_RIGHT:
+ offset->xofs = width - dims->x;
+ break;
+ case SCENEOA_LEFT:
+ offset->xofs = 0;
+ break;
+ }
+
+ switch (vert) {
+ case SCENEOA_CENTRE:
+ offset->yofs = (height - dims->y) / 2;
+ break;
+ case SCENEOA_BOTTOM:
+ offset->yofs = height - dims->y;
+ break;
+ case SCENEOA_TOP:
+ default:
+ offset->yofs = 0;
+ break;
+ }
+}
+
int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
{
struct scene_obj *obj;
@@ -267,6 +410,7 @@ int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
case SCENEOBJT_NONE:
case SCENEOBJT_MENU:
case SCENEOBJT_TEXTLINE:
+ case SCENEOBJT_BOX:
break;
case SCENEOBJT_IMAGE: {
struct scene_obj_img *img = (struct scene_obj_img *)obj;
@@ -278,14 +422,20 @@ int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
*widthp = width;
return height;
}
- case SCENEOBJT_TEXT: {
- struct scene_obj_txt *txt = (struct scene_obj_txt *)obj;
+ case SCENEOBJT_TEXT:
+ case SCENEOBJT_TEXTEDIT: {
+ struct scene_txt_generic *gen;
struct expo *exp = scn->expo;
struct vidconsole_bbox bbox;
+ int len, ret, limit;
const char *str;
- int len, ret;
- str = expo_get_str(exp, txt->str_id);
+ if (obj->type == SCENEOBJT_TEXT)
+ gen = &((struct scene_obj_txt *)obj)->gen;
+ else
+ gen = &((struct scene_obj_txtedit *)obj)->gen;
+
+ str = expo_get_str(exp, gen->str_id);
if (!str)
return log_msg_ret("str", -ENOENT);
len = strlen(str);
@@ -297,8 +447,12 @@ int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
return 16;
}
- ret = vidconsole_measure(scn->expo->cons, txt->font_name,
- txt->font_size, str, -1, &bbox, NULL);
+ limit = obj->flags & SCENEOF_SIZE_VALID ?
+ obj->bbox.x1 - obj->bbox.x0 : -1;
+
+ ret = vidconsole_measure(scn->expo->cons, gen->font_name,
+ gen->font_size, str, limit, &bbox,
+ &gen->lines);
if (ret)
return log_msg_ret("mea", ret);
if (widthp)
@@ -317,12 +471,14 @@ 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;
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;
@@ -341,24 +497,113 @@ 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 = cur_item ? &bbox[SCENEBB_curitem] : &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);
}
}
+static int scene_txt_render(struct expo *exp, struct udevice *dev,
+ struct udevice *cons, struct scene_obj *obj,
+ struct scene_txt_generic *gen, int x, int y,
+ int menu_inset)
+{
+ const struct vidconsole_mline *mline, *last;
+ struct video_priv *vid_priv;
+ struct vidconsole_colour old;
+ enum colour_idx fore, back;
+ struct scene_obj_dims dims;
+ struct scene_obj_bbox bbox;
+ const char *str;
+ int ret;
+
+ if (!cons)
+ return -ENOTSUPP;
+
+ if (gen->font_name || gen->font_size) {
+ ret = vidconsole_select_font(cons, gen->font_name,
+ gen->font_size);
+ } else {
+ ret = vidconsole_select_font(cons, NULL, 0);
+ }
+ if (ret && ret != -ENOSYS)
+ return log_msg_ret("font", ret);
+ str = expo_get_str(exp, gen->str_id);
+ if (!str)
+ return 0;
+
+ vid_priv = dev_get_uclass_priv(dev);
+ if (vid_priv->white_on_black) {
+ fore = VID_BLACK;
+ back = VID_WHITE;
+ } else {
+ fore = VID_LIGHT_GRAY;
+ back = VID_BLACK;
+ }
+
+ 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 - inset, y,
+ obj->bbox.x1, obj->bbox.y1,
+ vid_priv->colour_bg);
+ }
+
+ mline = alist_get(&gen->lines, 0, typeof(*mline));
+ last = alist_get(&gen->lines, gen->lines.count - 1, typeof(*mline));
+ if (mline)
+ dims.y = last->bbox.y1 - mline->bbox.y0;
+ bbox.y0 = obj->bbox.y0;
+ bbox.y1 = obj->bbox.y1;
+
+ if (!mline) {
+ vidconsole_set_cursor_pos(cons, x, y);
+ vidconsole_put_string(cons, str);
+ }
+
+ alist_for_each(mline, &gen->lines) {
+ struct scene_obj_offset offset;
+
+ bbox.x0 = obj->bbox.x0;
+ bbox.x1 = obj->bbox.x1;
+ dims.x = mline->bbox.x1 - mline->bbox.x0;
+ handle_alignment(obj->horiz, obj->vert, &bbox, &dims,
+ obj->bbox.x1 - obj->bbox.x0,
+ obj->bbox.y1 - obj->bbox.y0, &offset);
+
+ x = obj->bbox.x0 + offset.xofs;
+ y = obj->bbox.y0 + offset.yofs + mline->bbox.y0;
+ if (y > bbox.y1)
+ break; /* clip this line and any following */
+ vidconsole_set_cursor_pos(cons, x, y);
+ vidconsole_put_stringn(cons, str + mline->start, mline->len);
+ }
+ if (obj->flags & SCENEOF_POINT)
+ vidconsole_pop_colour(cons, &old);
+
+ return 0;
+}
+
/**
* scene_obj_render() - Render an object
*
+ * @obj: Object to render
+ * @text_mode: true to use text mode
+ * Return: 0 if OK, -ve on error
*/
static int scene_obj_render(struct scene_obj *obj, bool text_mode)
{
@@ -367,10 +612,12 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode)
const struct expo_theme *theme = &exp->theme;
struct udevice *dev = exp->display;
struct udevice *cons = text_mode ? NULL : exp->cons;
+ struct video_priv *vid_priv;
int x, y, ret;
- x = obj->dim.x;
- y = obj->dim.y;
+ y = obj->bbox.y0;
+ x = obj->bbox.x0 + obj->ofs.xofs;
+ vid_priv = dev_get_uclass_priv(dev);
switch (obj->type) {
case SCENEOBJT_NONE:
@@ -388,59 +635,26 @@ static int scene_obj_render(struct scene_obj *obj, bool text_mode)
}
case SCENEOBJT_TEXT: {
struct scene_obj_txt *txt = (struct scene_obj_txt *)obj;
- const char *str;
-
- if (!cons)
- return -ENOTSUPP;
- if (txt->font_name || txt->font_size) {
- ret = vidconsole_select_font(cons,
- txt->font_name,
- txt->font_size);
- } else {
- ret = vidconsole_select_font(cons, NULL, 0);
- }
- if (ret && ret != -ENOSYS)
- return log_msg_ret("font", ret);
- str = expo_get_str(exp, txt->str_id);
- if (str) {
- struct video_priv *vid_priv;
- struct vidconsole_colour old;
- enum colour_idx fore, back;
-
- vid_priv = dev_get_uclass_priv(dev);
- if (vid_priv->white_on_black) {
- fore = VID_BLACK;
- back = VID_WHITE;
- } else {
- fore = VID_LIGHT_GRAY;
- back = VID_BLACK;
- }
-
- if (obj->flags & SCENEOF_POINT) {
- vidconsole_push_colour(cons, fore, back, &old);
- video_fill_part(dev, x - theme->menu_inset, 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);
- }
+ ret = scene_txt_render(exp, dev, cons, obj, &txt->gen, x, y,
+ theme->menu_inset);
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;
+ 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
@@ -457,9 +671,23 @@ 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;
+
+ video_draw_box(dev, obj->bbox.x0, obj->bbox.y0, obj->bbox.x1,
+ obj->bbox.y1, box->width, vid_priv->colour_fg);
break;
}
+ case SCENEOBJT_TEXTEDIT: {
+ struct scene_obj_txtedit *ted = (struct scene_obj_txtedit *)obj;
+
+ ret = scene_txt_render(exp, dev, cons, obj, &ted->gen, x, y,
+ theme->menu_inset);
+ break;
+ }
+ }
return 0;
}
@@ -477,6 +705,8 @@ int scene_calc_arrange(struct scene *scn, struct expo_arrange_info *arr)
case SCENEOBJT_NONE:
case SCENEOBJT_IMAGE:
case SCENEOBJT_TEXT:
+ case SCENEOBJT_BOX:
+ case SCENEOBJT_TEXTEDIT:
break;
case SCENEOBJT_MENU: {
struct scene_obj_menu *menu;
@@ -510,18 +740,33 @@ int scene_calc_arrange(struct scene *scn, struct expo_arrange_info *arr)
int scene_arrange(struct scene *scn)
{
struct expo_arrange_info arr;
+ int xsize = 0, ysize = 0;
struct scene_obj *obj;
+ struct udevice *dev;
int ret;
+ dev = scn->expo->display;
+ if (dev) {
+ struct video_priv *priv = dev_get_uclass_priv(dev);
+
+ xsize = priv->xsize;
+ ysize = priv->ysize;
+ }
+
ret = scene_calc_arrange(scn, &arr);
if (ret < 0)
return log_msg_ret("arr", ret);
list_for_each_entry(obj, &scn->obj_head, sibling) {
+ handle_alignment(obj->horiz, obj->vert, &obj->bbox, &obj->dims,
+ xsize, ysize, &obj->ofs);
+
switch (obj->type) {
case SCENEOBJT_NONE:
case SCENEOBJT_IMAGE:
case SCENEOBJT_TEXT:
+ case SCENEOBJT_BOX:
+ case SCENEOBJT_TEXTEDIT:
break;
case SCENEOBJT_MENU: {
struct scene_obj_menu *menu;
@@ -567,6 +812,8 @@ int scene_render_deps(struct scene *scn, uint id)
case SCENEOBJT_NONE:
case SCENEOBJT_IMAGE:
case SCENEOBJT_TEXT:
+ case SCENEOBJT_BOX:
+ case SCENEOBJT_TEXTEDIT:
break;
case SCENEOBJT_MENU:
scene_menu_render_deps(scn,
@@ -686,6 +933,7 @@ int scene_send_key(struct scene *scn, int key, struct expo_action *event)
case SCENEOBJT_NONE:
case SCENEOBJT_IMAGE:
case SCENEOBJT_TEXT:
+ case SCENEOBJT_BOX:
break;
case SCENEOBJT_MENU: {
struct scene_obj_menu *menu;
@@ -705,6 +953,9 @@ int scene_send_key(struct scene *scn, int key, struct expo_action *event)
return log_msg_ret("key", ret);
break;
}
+ case SCENEOBJT_TEXTEDIT:
+ /* TODO(sjg@chromium.org): Implement this */
+ break;
}
return 0;
}
@@ -724,25 +975,27 @@ 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:
case SCENEOBJT_IMAGE:
case SCENEOBJT_TEXT:
+ case SCENEOBJT_BOX:
+ case SCENEOBJT_TEXTEDIT:
return -ENOSYS;
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;
}
}
@@ -759,6 +1012,8 @@ int scene_calc_dims(struct scene *scn, bool do_menus)
switch (obj->type) {
case SCENEOBJT_NONE:
case SCENEOBJT_TEXT:
+ case SCENEOBJT_BOX:
+ case SCENEOBJT_TEXTEDIT:
case SCENEOBJT_IMAGE: {
int width;
@@ -766,8 +1021,13 @@ int scene_calc_dims(struct scene *scn, bool do_menus)
ret = scene_obj_get_hw(scn, obj->id, &width);
if (ret < 0)
return log_msg_ret("get", ret);
- obj->dim.w = width;
- obj->dim.h = ret;
+ obj->dims.x = width;
+ obj->dims.y = ret;
+ if (!(obj->flags & SCENEOF_SIZE_VALID)) {
+ obj->bbox.x1 = obj->bbox.x0 + width;
+ obj->bbox.y1 = obj->bbox.y0 + ret;
+ obj->flags |= SCENEOF_SIZE_VALID;
+ }
}
break;
}
@@ -812,8 +1072,13 @@ int scene_apply_theme(struct scene *scn, struct expo_theme *theme)
case SCENEOBJT_NONE:
case SCENEOBJT_IMAGE:
case SCENEOBJT_MENU:
+ case SCENEOBJT_BOX:
case SCENEOBJT_TEXTLINE:
break;
+ case SCENEOBJT_TEXTEDIT:
+ scene_txted_set_font(scn, obj->id, NULL,
+ theme->font_size);
+ break;
case SCENEOBJT_TEXT:
scene_txt_set_font(scn, obj->id, NULL,
theme->font_size);
@@ -854,6 +1119,8 @@ static int scene_obj_open(struct scene *scn, struct scene_obj *obj)
case SCENEOBJT_IMAGE:
case SCENEOBJT_MENU:
case SCENEOBJT_TEXT:
+ case SCENEOBJT_BOX:
+ case SCENEOBJT_TEXTEDIT:
break;
case SCENEOBJT_TEXTLINE:
ret = scene_textline_open(scn,
@@ -905,28 +1172,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->dim.x - inset);
- bbox->y0 = min(bbox->y0, obj->dim.y);
- bbox->x1 = max(bbox->x1, obj->dim.x + obj->dim.w + inset);
- bbox->y1 = max(bbox->y1, obj->dim.y + obj->dim.h);
- } else {
- bbox->x0 = obj->dim.x - inset;
- bbox->y0 = obj->dim.y;
- bbox->x1 = obj->dim.x + obj->dim.w + inset;
- bbox->y1 = obj->dim.y + obj->dim.h;
- 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;
}