simple_viewer: use UI viewport and SBS title

Also adjust scrollbar margins and height so it matches
the look of normal lists, and hide scrollbars when set
to SCROLLBAR_OFF.

Change-Id: I27f6de7b16cf5ec72e12c7d6377a8772d84947ac
This commit is contained in:
Christian Soffke 2026-04-28 05:36:12 +02:00 committed by Solomon Peachy
parent 2d419b4b93
commit 7ab1a81806
5 changed files with 100 additions and 53 deletions

View file

@ -872,6 +872,9 @@ static const struct plugin_api rockbox_api = {
/* new stuff at the end, sort into place next time
the API gets incompatible */
panicf,
gui_synclist_scroll_stop,
add_event_ex,
remove_event_ex,
};
static int plugin_buffer_handle;
@ -892,6 +895,7 @@ int plugin_load(const char* plugin, const void* parameter)
!strcmp("playing_time.rock", sepch + 1) ||
!strcmp("main_menu_config.rock", sepch + 1) ||
!strcmp("text_viewer.rock", sepch + 1) ||
!strcmp("view_text.rock", sepch + 1) ||
!strcmp("disktidy.rock", sepch + 1) ||
!strcmp("open_plugins.rock", sepch + 1));

View file

@ -1025,6 +1025,17 @@ struct plugin_api {
/* new stuff at the end, sort into place next time
the API gets incompatible */
void (*panicf)(const char *msg, ...);
void (*gui_synclist_scroll_stop)(struct gui_synclist *lists);
bool (*add_event_ex)(unsigned short id, bool oneshot,
void (*handler)(unsigned short id,
void *event_data,
void *user_data),
void *user_data);
void (*remove_event_ex)(unsigned short id,
void (*handler)(unsigned short id,
void *event_data,
void *user_data),
void *user_data);
};
/* plugin header */

View file

@ -29,7 +29,9 @@
struct view_info {
struct font* pf;
struct viewport scrollbar_vp; /* viewport for scrollbar */
struct viewport title_vp;
struct viewport vp;
bool sbs_has_title; /* SBS comes with custom title area */
const char *title;
const char *text; /* displayed text */
int display_lines; /* number of lines can be displayed */
@ -93,17 +95,19 @@ static void calc_line_count(struct view_info *info)
{
ptr = get_next_line(ptr, info);
i++;
if (!scrollbar && i > info->display_lines)
if (!scrollbar && i > info->display_lines &&
rb->global_settings->scrollbar != SCROLLBAR_OFF)
{
ptr = info->text;
i = 0;
info->scrollbar_vp = info->vp;
info->scrollbar_vp.width = rb->global_settings->scrollbar_width;
info->scrollbar_vp.width = rb->global_settings->scrollbar_width + 1;
info->scrollbar_vp.height = info->display_lines * info->pf->height;
info->vp.width -= info->scrollbar_vp.width;
if (rb->global_settings->scrollbar != SCROLLBAR_RIGHT)
info->vp.x = info->scrollbar_vp.width;
if (rb->global_settings->scrollbar == SCROLLBAR_RIGHT)
info->scrollbar_vp.x = info->vp.x + info->vp.width;
else
info->scrollbar_vp.x = info->vp.width;
info->vp.x += info->scrollbar_vp.width;
scrollbar = true;
}
}
@ -137,8 +141,14 @@ static void calc_first_line(struct view_info *info, int line)
static int init_view(struct view_info *info,
const char *title, const char *text)
{
rb->viewport_set_defaults(&info->vp, SCREEN_MAIN);
info->pf = rb->font_get(rb->screens[SCREEN_MAIN]->getuifont());
struct screen* display = rb->screens[SCREEN_MAIN];
int ui_font = display->getuifont();
display->set_viewport(&info->vp);
display->clear_viewport();
info->pf = rb->font_get(ui_font);
info->vp.font = ui_font;
info->display_lines = info->vp.height / info->pf->height;
info->title = title;
@ -147,16 +157,21 @@ static int init_view(struct view_info *info,
info->line = 0;
info->start = 0;
/* no title for small screens. */
if (info->display_lines < 4)
if (!info->sbs_has_title)
{
info->title = NULL;
}
else
{
info->display_lines--;
info->vp.y += info->pf->height;
info->vp.height -= info->pf->height;
/* no title for small screens. */
if (info->display_lines < 4)
info->title = NULL;
else
{
info->display_lines--;
info->title_vp = info->vp;
info->title_vp.height = info->pf->height;
info->vp.height -= info->title_vp.height;
info->vp.y += info->title_vp.height;
}
}
calc_line_count(info);
@ -171,20 +186,19 @@ static void draw_text(struct view_info *info)
int max_show, line;
struct screen* display = rb->screens[SCREEN_MAIN];
/* clear screen */
display->clear_display();
/* display title. */
if(info->title)
if (info->title && !info->sbs_has_title)
{
display->set_viewport(NULL);
display->set_viewport(&info->title_vp);
display->puts(0, 0, info->title);
}
display->set_viewport(&info->vp);
display->clear_viewport();
max_show = MIN(info->line_count - info->line, info->display_lines);
text = info->text + info->start;
display->set_viewport(&info->vp);
for (line = 0; line < max_show; line++)
{
int len;
@ -197,15 +211,17 @@ static void draw_text(struct view_info *info)
display->puts(0, line, output);
text = ptr;
}
if (info->line_count > info->display_lines)
if (info->line_count > info->display_lines &&
rb->global_settings->scrollbar != SCROLLBAR_OFF)
{
display->set_viewport(&info->scrollbar_vp);
rb->gui_scrollbar_draw(display, (info->scrollbar_vp.width? 0: 1), 0,
info->scrollbar_vp.width - 1, info->scrollbar_vp.height,
info->line_count, info->line, info->line + max_show,
VERTICAL);
}
int margin = info->scrollbar_vp.width > 2 ? 2 : 0;
int x = rb->global_settings->scrollbar == SCROLLBAR_RIGHT ? margin : 0;
rb->gui_scrollbar_draw(display, x, 0,
info->scrollbar_vp.width - margin, info->scrollbar_vp.height,
info->line_count, info->line, info->line + max_show, VERTICAL);
}
display->set_viewport(NULL);
display->update();
}
@ -248,6 +264,21 @@ static void scroll_to_bottom(struct view_info *info)
draw_text(info);
}
static void ui_update_cb(unsigned short id, void* param, void* user_data)
{
(void)id;
(void)param;
struct view_info *info = (struct view_info *) user_data;
draw_text(info);
}
static void cleanup(void *parameter)
{
struct view_info *info = (struct view_info *) parameter;
rb->remove_event_ex(GUI_EVENT_NEED_UI_UPDATE, ui_update_cb, info);
rb->viewportmanager_theme_undo(SCREEN_MAIN, false);
}
int view_text(const char *title, const char *text)
{
struct view_info info;
@ -256,13 +287,24 @@ int view_text(const char *title, const char *text)
};
int button;
info.sbs_has_title = rb->sb_set_persistent_title(title, Icon_NOICON, SCREEN_MAIN);
rb->viewportmanager_theme_enable(SCREEN_MAIN, true, &info.vp);
init_view(&info, title, text);
draw_text(&info);
/* handle themes that draw over the UI viewport */
rb->add_event_ex(GUI_EVENT_NEED_UI_UPDATE, false, ui_update_cb, &info);
/* skin engine needs to render title and redraw screen */
if (info.sbs_has_title)
rb->send_event(GUI_EVENT_ACTIONUPDATE, (void*)1);
else
draw_text(&info);
/* wait for keypress */
while(1)
{
button = pluginlib_getaction(TIMEOUT_BLOCK, view_contexts,
/* don't block, so the skin engine can redraw */
button = pluginlib_getaction(HZ/4, view_contexts,
ARRAYLEN(view_contexts));
switch (button)
{
@ -270,7 +312,7 @@ int view_text(const char *title, const char *text)
#if (CONFIG_KEYPAD == IPOD_1G2G_PAD) \
|| (CONFIG_KEYPAD == IPOD_3G_PAD) \
|| (CONFIG_KEYPAD == IPOD_4G_PAD)
return PLUGIN_OK;
goto out;
#endif
case PLA_UP_REPEAT:
#ifdef HAVE_SCROLLWHEEL
@ -291,7 +333,7 @@ int view_text(const char *title, const char *text)
#if (CONFIG_KEYPAD == IPOD_1G2G_PAD) \
|| (CONFIG_KEYPAD == IPOD_3G_PAD) \
|| (CONFIG_KEYPAD == IPOD_4G_PAD)
return PLUGIN_OK;
goto out;
#endif
scroll_up(&info, info.display_lines);
break;
@ -307,13 +349,14 @@ int view_text(const char *title, const char *text)
case PLA_SELECT:
case PLA_EXIT:
case PLA_CANCEL:
return PLUGIN_OK;
goto out;
default:
if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
if ((rb->default_event_handler_ex(button, cleanup,
&info) == SYS_USB_CONNECTED))
return PLUGIN_USB_CONNECTED;
break;
}
}
out:
cleanup(&info);
return PLUGIN_OK;
}

View file

@ -187,7 +187,8 @@ static int browse_file_or_dir(struct dir_stats *stats)
continue;
switch(button)
{
case ACTION_STD_OK:;
case ACTION_STD_OK:
rb->gui_synclist_scroll_stop(&properties_lists);
int sel_pos = rb->gui_synclist_get_sel_pos(&properties_lists);
/* "Show Track Info..." selected? */
@ -197,17 +198,10 @@ static int browse_file_or_dir(struct dir_stats *stats)
return -1;
else
{
const unsigned char* const *props = (props_type == PROPS_DIR) ?
props_dir : props_file;
/* Display field in fullscreen */
FOR_NB_SCREENS(i)
rb->viewportmanager_theme_enable(i, false, NULL);
if (props_type == PROPS_DIR)
view_text((char *) p2str(props_dir[sel_pos]),
(char *) props_dir[sel_pos + 1]);
else
view_text((char *) p2str(props_file[sel_pos]),
(char *) props_file[sel_pos + 1]);
FOR_NB_SCREENS(i)
rb->viewportmanager_theme_undo(i, false);
view_text((char *) p2str(props[sel_pos]), props[sel_pos + 1]);
rb->gui_synclist_set_title(&properties_lists,
rb->str(props_type == PROPS_DIR ?

View file

@ -827,6 +827,7 @@ refresh_info:
{
if (key == ACTION_STD_OK)
{
gui_synclist_scroll_stop(&id3_lists);
int header_id = id3_headers[info.info_id[id3_lists.selected_item/2]];
char* title_and_text[2];
title_and_text[0] = str(header_id);
@ -835,13 +836,7 @@ refresh_info:
title_and_text[1] = (char*)id3_get_or_speak_info(id3_lists.selected_item+1,&info, buffer, sizeof(buffer), false);
if (view_text)
{
FOR_NB_SCREENS(i)
viewportmanager_theme_enable(i, false, NULL);
view_text(title_and_text[0], title_and_text[1]);
FOR_NB_SCREENS(i)
viewportmanager_theme_undo(i, false);
}
else
plugin_load(VIEWERS_DIR"/view_text.rock", title_and_text);
gui_synclist_set_title(&id3_lists, str(LANG_TRACK_INFO), NOICON);