Author: rinrab
Date: Sun Apr 12 19:01:02 2026
New Revision: 1933001
Log:
svnbrowse: Use curses WINDOWs to position layout elements on screen.
* subversion/svnbrowse/svnbrowse.c
(svn_browse__view_t): Store screen and areas for list and infobar controls,
removing a TODO comment.
(view_cleanup): Implement the cleanup handler.
(view_layout): New function thar recalculates the layout.
(view_make): Accept the parent window as an argument to initialize the view.
Setup pool cleanup.
(view_on_event): Call view_layout() to update layout each update. Now we can
use the size of view->list directly to get the height of the scrollable area.
(view_draw_item, view_draw_info_bar): Draw on a WINDOW passed as an argument.
Curses API has the same functions that work with that WINDOW. They are all
prefixed with a 'w'.
(view_draw): Pass a window to view_draw_item() and view_draw_info_bar().
(sub_main): Pass stdscr when creating a view.
Modified:
subversion/trunk/subversion/svnbrowse/svnbrowse.c
Modified: subversion/trunk/subversion/svnbrowse/svnbrowse.c
==============================================================================
--- subversion/trunk/subversion/svnbrowse/svnbrowse.c Sun Apr 12 18:50:01 2026 (r1933000)
+++ subversion/trunk/subversion/svnbrowse/svnbrowse.c Sun Apr 12 19:01:02 2026 (r1933001)
@@ -125,23 +125,54 @@ enum {
};
typedef struct svn_browse__view_t {
- /* TODO: store information about terminal screen (a WINDOW* in curses world) */
svn_browse__model_t *model;
+ WINDOW *screen;
+ WINDOW *infobar;
+ WINDOW *list;
} svn_browse__view_t;
+static apr_status_t
+view_cleanup(void *ctx)
+{
+ svn_browse__view_t *view = ctx;
+ delwin(view->infobar);
+ delwin(view->list);
+ return APR_SUCCESS;
+}
+
+static void
+view_layout(svn_browse__view_t *view)
+{
+ int infobar_height = 1;
+ int cols = getmaxx(view->screen);
+ int rows = getmaxy(view->screen);
+
+ delwin(view->infobar);
+ delwin(view->list);
+
+ view->infobar = subwin(view->screen, infobar_height, cols, 0, 0);
+ view->list = subwin(view->screen, rows - infobar_height, cols,
+ infobar_height, 0);
+}
+
static svn_browse__view_t *
-view_make(svn_browse__model_t *model, apr_pool_t *result_pool)
+view_make(svn_browse__model_t *model, WINDOW *win, apr_pool_t *result_pool)
{
svn_browse__view_t *view = apr_pcalloc(result_pool, sizeof(*view));
view->model = model;
+ view->screen = win;
+ view_layout(view);
+ apr_pool_cleanup_register(result_pool, view, view_cleanup, NULL);
return view;
}
static svn_error_t *
view_on_event(svn_browse__view_t *view, int ch, apr_pool_t *scratch_pool)
{
+ view_layout(view);
+
/* scrollable height is one row less than the whole view */
- int scrollsize = getmaxy(stdscr) - 1;
+ int scrollsize = getmaxy(view->list);
/* ch is received from getch() which would read the next character/key with
* the following additional rules:
@@ -304,32 +335,35 @@ get_item_style(svn_node_kind_t kind, svn
}
static void
-view_draw_item(const svn_browse__item_t *item, int y, svn_boolean_t selected,
- apr_pool_t *scratch_pool)
+view_draw_item(const svn_browse__item_t *item, WINDOW *win, int y,
+ svn_boolean_t selected, apr_pool_t *scratch_pool)
{
int attrs = 0;
const char *prefix;
move(y, 0);
- attrset(get_item_style(item->dirent->kind, selected));
+ wattrset(win, get_item_style(item->dirent->kind, selected));
/* 12 + 12 + (20 + 1) + 2 = 47 */
- addch(' ');
- addstr(rightpad(format_node_name(item, scratch_pool),
- COLS - 47, scratch_pool));
-
- attrset(get_item_style(svn_node_file, selected));
- addstr(leftpad(format_node_size(item, scratch_pool), 12, scratch_pool));
- addstr(leftpad(apr_psprintf(scratch_pool, "r%ld", item->dirent->created_rev),
- 12, scratch_pool));
- addch(' ');
- addstr(rightpad(item->dirent->last_author, 20, scratch_pool));
- addch(' ');
+ waddch(win, ' ');
+ waddstr(win, rightpad(format_node_name(item, scratch_pool),
+ getmaxx(win) - 47, scratch_pool));
+
+ wattrset(win, get_item_style(svn_node_file, selected));
+ waddstr(win,
+ leftpad(format_node_size(item, scratch_pool), 12, scratch_pool));
+ waddstr(win, leftpad(apr_psprintf(scratch_pool, "r%ld",
+ item->dirent->created_rev),
+ 12, scratch_pool));
+ waddch(win, ' ');
+ waddstr(win, rightpad(item->dirent->last_author, 20, scratch_pool));
+ waddch(win, ' ');
}
static void
-view_draw_info_bar(svn_browse__view_t *view, apr_pool_t *scratch_pool)
+view_draw_info_bar(svn_browse__view_t *view, WINDOW *win,
+ apr_pool_t *scratch_pool)
{
const char *abspath = svn_path_url_add_component2(
view->model->root, view->model->current->relpath, scratch_pool);
@@ -337,12 +371,13 @@ view_draw_info_bar(svn_browse__view_t *v
const char *prefix = " ";
const char *suffix = "Apache Subversion ";
- move(0, 0);
- attrset(COLOR_PAIR(COLOR_PAIR_INFO_BAR));
- addstr(prefix);
- addstr(rightpad(apr_psprintf(scratch_pool, "URL: %s", abspath),
- COLS - strlen(prefix) - strlen(suffix), scratch_pool));
- addstr(suffix);
+ wmove(win, 0, 0);
+ wattrset(win, COLOR_PAIR(COLOR_PAIR_INFO_BAR));
+ waddstr(win, prefix);
+ waddstr(win, rightpad(apr_psprintf(scratch_pool, "URL: %s", abspath),
+ getmaxx(win) - strlen(prefix) - strlen(suffix),
+ scratch_pool));
+ waddstr(win, suffix);
}
static void
@@ -350,7 +385,7 @@ view_draw(svn_browse__view_t *view, apr_
{
int i;
- view_draw_info_bar(view, pool);
+ view_draw_info_bar(view, view->infobar, pool);
for (i = 0; i < view->model->current->list->nelts; i++)
{
@@ -360,7 +395,7 @@ view_draw(svn_browse__view_t *view, apr_
int y = i - view->model->current->scroller_offset;
if (0 <= y && y < LINES)
- view_draw_item(item, y + 1, selected, pool);
+ view_draw_item(item, view->list, y + 1, selected, pool);
}
}
@@ -598,7 +633,7 @@ sub_main(int *code, int argc, const char
init_pair(COLOR_PAIR_FILE, -1, -1);
init_pair(COLOR_PAIR_FILE_SELECTED, -1, COLOR_PRIMARY);
- view = view_make(ctx, pool);
+ view = view_make(ctx, stdscr, pool);
iterpool = svn_pool_create(pool);
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.