expo: Support simple themes
It is a pain to manually set the fonts of all objects to be consistent.
Some spacing settings are also better set globally than by manually
positioning each object.
Add a 'theme' to the expo, to hold this information. For now it includes
only the font size.
Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/boot/expo.c b/boot/expo.c
index 67cae3c..d5e9359 100644
--- a/boot/expo.c
+++ b/boot/expo.c
@@ -231,3 +231,23 @@
return act->type == EXPOACT_NONE ? -EAGAIN : 0;
}
+
+int expo_apply_theme(struct expo *exp, ofnode node)
+{
+ struct scene *scn;
+ struct expo_theme *theme = &exp->theme;
+ int ret;
+
+ log_debug("Applying theme %s\n", ofnode_get_name(node));
+
+ memset(theme, '\0', sizeof(struct expo_theme));
+ ofnode_read_u32(node, "font-size", &theme->font_size);
+
+ list_for_each_entry(scn, &exp->scene_head, sibling) {
+ ret = scene_apply_theme(scn, theme);
+ if (ret)
+ return log_msg_ret("app", ret);
+ }
+
+ return 0;
+}
diff --git a/boot/scene.c b/boot/scene.c
index 6d5e3c1..4dbe12a 100644
--- a/boot/scene.c
+++ b/boot/scene.c
@@ -466,3 +466,31 @@
return 0;
}
+
+int scene_apply_theme(struct scene *scn, struct expo_theme *theme)
+{
+ struct scene_obj *obj;
+ int ret;
+
+ /* Avoid error-checking optional items */
+ scene_txt_set_font(scn, scn->title_id, NULL, theme->font_size);
+
+ list_for_each_entry(obj, &scn->obj_head, sibling) {
+ switch (obj->type) {
+ case SCENEOBJT_NONE:
+ case SCENEOBJT_IMAGE:
+ case SCENEOBJT_MENU:
+ break;
+ case SCENEOBJT_TEXT:
+ scene_txt_set_font(scn, obj->id, NULL,
+ theme->font_size);
+ break;
+ }
+ }
+
+ ret = scene_arrange(scn);
+ if (ret)
+ return log_msg_ret("arr", ret);
+
+ return 0;
+}
diff --git a/boot/scene_internal.h b/boot/scene_internal.h
index 00085a2..3387a90 100644
--- a/boot/scene_internal.h
+++ b/boot/scene_internal.h
@@ -90,6 +90,15 @@
int scene_menu_arrange(struct scene *scn, struct scene_obj_menu *menu);
/**
+ * scene_apply_theme() - Apply a theme to a scene
+ *
+ * @scn: Scene to update
+ * @theme: Theme to apply
+ * Returns: 0 if OK, -ve on error
+ */
+int scene_apply_theme(struct scene *scn, struct expo_theme *theme);
+
+/**
* scene_menu_send_key() - Send a key to a menu for processing
*
* @scn: Scene to use
diff --git a/doc/develop/expo.rst b/doc/develop/expo.rst
index 54861b9..2f48828 100644
--- a/doc/develop/expo.rst
+++ b/doc/develop/expo.rst
@@ -155,8 +155,13 @@
Themes
------
-Expo does not itself support themes. The bootflow_menu implement supposed a
-basic theme, applying font sizes to the various text objects in the expo.
+Expo supports simple themes, for setting the font size, for example. Use the
+expo_apply_theme() function to load a theme, passing a node with the required
+properties:
+
+font-size
+ Font size to use for all text (type: u32)
+
API documentation
-----------------
diff --git a/include/expo.h b/include/expo.h
index 6c45c40..ea8f389 100644
--- a/include/expo.h
+++ b/include/expo.h
@@ -7,6 +7,7 @@
#ifndef __SCENE_H
#define __SCENE_H
+#include <dm/ofnode_decl.h>
#include <linux/list.h>
struct udevice;
@@ -43,6 +44,19 @@
};
/**
+ * struct expo_theme - theme for the expo
+ *
+ * @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
+ */
+struct expo_theme {
+ u32 font_size;
+ u32 menu_inset;
+ u32 menuitem_gap_y;
+};
+
+/**
* struct expo - information about an expo
*
* A group of scenes which can be presented to the user, typically to obtain
@@ -57,6 +71,7 @@
* type set to EXPOACT_NONE if there is no action
* @text_mode: true to use text mode for the menu (no vidconsole)
* @priv: Private data for the controller
+ * @theme: Information about fonts styles, etc.
* @scene_head: List of scenes
* @str_head: list of strings
*/
@@ -69,6 +84,7 @@
struct expo_action action;
bool text_mode;
void *priv;
+ struct expo_theme theme;
struct list_head scene_head;
struct list_head str_head;
};
@@ -583,4 +599,12 @@
*/
int expo_action_get(struct expo *exp, struct expo_action *act);
+/**
+ * expo_apply_theme() - Apply a theme to an expo
+ *
+ * @exp: Expo to update
+ * @node: Node containing the theme
+ */
+int expo_apply_theme(struct expo *exp, ofnode node);
+
#endif /*__SCENE_H */
diff --git a/test/boot/expo.c b/test/boot/expo.c
index 493d050..c0ef03b 100644
--- a/test/boot/expo.c
+++ b/test/boot/expo.c
@@ -226,7 +226,7 @@
}
BOOTSTD_TEST(expo_object, UT_TESTF_DM | UT_TESTF_SCAN_FDT);
-/* Check setting object attributes */
+/* Check setting object attributes and using themes */
static int expo_object_attr(struct unit_test_state *uts)
{
struct scene_obj_menu *menu;
@@ -236,6 +236,7 @@
struct expo *exp;
ulong start_mem;
char name[100];
+ ofnode node;
char *data;
int id;
@@ -273,6 +274,11 @@
ut_asserteq(-ENOENT, scene_menu_set_title(scn, OBJ_TEXT2, OBJ_TEXT));
ut_asserteq(-EINVAL, scene_menu_set_title(scn, OBJ_MENU, OBJ_TEXT2));
+ node = ofnode_path("/bootstd/theme");
+ ut_assert(ofnode_valid(node));
+ ut_assertok(expo_apply_theme(exp, node));
+ ut_asserteq(30, txt->font_size);
+
expo_destroy(exp);
ut_assertok(ut_check_delta(start_mem));