int cedit_arange(struct expo *exp, struct video_priv *vpriv, uint scene_id)
{
+ struct expo_arrange_info arr;
struct scene_obj_txt *txt;
struct scene_obj *obj;
struct scene *scn;
- int y;
+ int y, ret;
scn = expo_lookup_scene_id(exp, scene_id);
if (!scn)
if (txt)
scene_obj_set_pos(scn, txt->obj.id, 200, 10);
+ memset(&arr, '\0', sizeof(arr));
+ ret = scene_calc_arrange(scn, &arr);
+ if (ret < 0)
+ return log_msg_ret("arr", ret);
+
y = 100;
list_for_each_entry(obj, &scn->obj_head, sibling) {
switch (obj->type) {
break;
case SCENEOBJT_MENU:
scene_obj_set_pos(scn, obj->id, 50, y);
- scene_menu_arrange(scn, (struct scene_obj_menu *)obj);
+ scene_menu_arrange(scn, &arr,
+ (struct scene_obj_menu *)obj);
y += 50;
break;
case SCENEOBJT_TEXTLINE:
scene_obj_set_pos(scn, obj->id, 50, y);
- scene_textline_arrange(scn,
+ scene_textline_arrange(scn, &arr,
(struct scene_obj_textline *)obj);
y += 50;
break;
ofnode_read_u32(node, "font-size", &theme->font_size);
ofnode_read_u32(node, "menu-inset", &theme->menu_inset);
ofnode_read_u32(node, "menuitem-gap-y", &theme->menuitem_gap_y);
+ ofnode_read_u32(node, "menu-title-margin-x",
+ &theme->menu_title_margin_x);
list_for_each_entry(scn, &exp->scene_head, sibling) {
ret = scene_apply_theme(scn, theme);
return 0;
}
+int scene_calc_arrange(struct scene *scn, struct expo_arrange_info *arr)
+{
+ struct scene_obj *obj;
+
+ arr->label_width = 0;
+ list_for_each_entry(obj, &scn->obj_head, sibling) {
+ uint label_id = 0;
+ int width;
+
+ switch (obj->type) {
+ case SCENEOBJT_NONE:
+ case SCENEOBJT_IMAGE:
+ case SCENEOBJT_TEXT:
+ break;
+ case SCENEOBJT_MENU: {
+ struct scene_obj_menu *menu;
+
+ menu = (struct scene_obj_menu *)obj,
+ label_id = menu->title_id;
+ break;
+ }
+ case SCENEOBJT_TEXTLINE: {
+ struct scene_obj_textline *tline;
+
+ tline = (struct scene_obj_textline *)obj,
+ label_id = tline->label_id;
+ break;
+ }
+ }
+
+ if (label_id) {
+ int ret;
+
+ ret = scene_obj_get_hw(scn, label_id, &width);
+ if (ret < 0)
+ return log_msg_ret("hei", ret);
+ arr->label_width = max(arr->label_width, width);
+ }
+ }
+
+ return 0;
+}
+
int scene_arrange(struct scene *scn)
{
+ struct expo_arrange_info arr;
struct scene_obj *obj;
int ret;
+ ret = scene_calc_arrange(scn, &arr);
+ if (ret < 0)
+ return log_msg_ret("arr", ret);
+
list_for_each_entry(obj, &scn->obj_head, sibling) {
switch (obj->type) {
case SCENEOBJT_NONE:
struct scene_obj_menu *menu;
menu = (struct scene_obj_menu *)obj,
- ret = scene_menu_arrange(scn, menu);
+ ret = scene_menu_arrange(scn, &arr, menu);
if (ret)
return log_msg_ret("arr", ret);
break;
struct scene_obj_textline *tline;
tline = (struct scene_obj_textline *)obj,
- ret = scene_textline_arrange(scn, tline);
+ ret = scene_textline_arrange(scn, &arr, tline);
if (ret)
return log_msg_ret("arr", ret);
break;
* if not already done
*
* @scn: Scene to update
+ * @arr: Arrangement information
* @menu: Menu to process
* Returns: 0 if OK, -ve on error
*/
-int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu);
+int scene_menu_arrange(struct scene *scn, struct expo_arrange_info *arr,
+ struct scene_obj_menu *menu);
/**
* scene_textline_arrange() - Set the position of things in a textline
* positioned correctly relative to the textline.
*
* @scn: Scene to update
+ * @arr: Arrangement information
* @tline: textline to process
* Returns: 0 if OK, -ve on error
*/
-int scene_textline_arrange(struct scene *scn, struct scene_obj_textline *tline);
+int scene_textline_arrange(struct scene *scn, struct expo_arrange_info *arr,
+ struct scene_obj_textline *tline);
/**
* scene_apply_theme() - Apply a theme to a scene
*/
int scene_textline_close(struct scene *scn, struct scene_obj_textline *tline);
+/**
+ * scene_calc_arrange() - Calculate sizes needed to arrange a scene
+ *
+ * Checks the size of some objects and stores this info to help with a later
+ * scene arrangement
+ *
+ * @scn: Scene to check
+ * @arr: Place to put scene-arrangement info
+ * Returns: 0 if OK, -ve on error
+ */
+int scene_calc_arrange(struct scene *scn, struct expo_arrange_info *arr);
+
#endif /* __SCENE_INTERNAL_H */
return 0;
}
-int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu)
+int scene_menu_arrange(struct scene *scn, struct expo_arrange_info *arr,
+ struct scene_obj_menu *menu)
{
const bool open = menu->obj.flags & SCENEOF_OPEN;
struct expo *exp = scn->expo;
x = menu->obj.dim.x;
y = menu->obj.dim.y;
if (menu->title_id) {
+ int width;
+
ret = scene_obj_set_pos(scn, menu->title_id, menu->obj.dim.x, y);
if (ret < 0)
return log_msg_ret("tit", ret);
- ret = scene_obj_get_hw(scn, menu->title_id, NULL);
+ ret = scene_obj_get_hw(scn, menu->title_id, &width);
if (ret < 0)
return log_msg_ret("hei", ret);
if (stack)
- x += 200;
+ x += arr->label_width + theme->menu_title_margin_x;
else
y += ret * 2;
}
return 0;
}
-int scene_textline_arrange(struct scene *scn, struct scene_obj_textline *tline)
+int scene_textline_arrange(struct scene *scn, struct expo_arrange_info *arr,
+ struct scene_obj_textline *tline)
{
const bool open = tline->obj.flags & SCENEOF_OPEN;
bool point;
menuitem-gap-y
Number of pixels between menu items
+menu-title-margin-x
+ Number of pixels between right side of menu title to the left size of the
+ menu labels
+
Pop-up mode
-----------
* @font_size: Default font size for all text
* @menu_inset: Inset width (on each side and top/bottom) for menu items
* @menuitem_gap_y: Gap between menu items in pixels
+ * @menu_title_margin_x: Gap between right side of menu title and left size of
+ * menu label
*/
struct expo_theme {
u32 font_size;
u32 menu_inset;
u32 menuitem_gap_y;
+ u32 menu_title_margin_x;
};
/**
uint pos;
};
+/**
+ * struct expo_arrange_info - Information used when arranging a scene
+ *
+ * @label_width: Maximum width of labels in scene
+ */
+struct expo_arrange_info {
+ int label_width;
+};
+
/**
* expo_new() - create a new expo
*