simple_viewer: use UI viewport and SBS title

rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]> Wed, 29 Apr 2026 14:19:49 -0400
Newsgroups gmane.comp.systems.archos.rockbox.cvs
Message-ID <[email protected]>
commit 7ab1a81806e831be134da480b4c5b178167380de
Author: Christian Soffke <[email protected]>
Date:   Tue Apr 28 05:36:12 2026 +0200

    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

diff --git a/apps/plugin.c b/apps/plugin.c
index d787149de2..57f0cb3d97 100644
--- a/apps/plugin.c
+++ b/apps/plugin.c
@@ -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));
 
diff --git a/apps/plugin.h b/apps/plugin.h
index f6c3434692..6abab07cd0 100644
--- a/apps/plugin.h
+++ b/apps/plugin.h
@@ -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 */
diff --git a/apps/plugins/lib/simple_viewer.c b/apps/plugins/lib/simple_viewer.c
index e71efce753..bffea2080a 100644
--- a/apps/plugins/lib/simple_viewer.c
+++ b/apps/plugins/lib/simple_viewer.c
@@ -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;
 }
diff --git a/apps/plugins/properties.c b/apps/plugins/properties.c
index 316b33292a..4eb727b7bb 100644
--- a/apps/plugins/properties.c
+++ b/apps/plugins/properties.c
@@ -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 ?
diff --git a/apps/screens.c b/apps/screens.c
index 6cbd44c3d4..e6031d8f57 100644
--- a/apps/screens.c
+++ b/apps/screens.c
@@ -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);
-- 
rockbox-cvs mailing list
[email protected]
https://lists.haxx.se/mailman/listinfo/rockbox-cvs