aboutsummaryrefslogtreecommitdiffstats
path: root/src/draw.c
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-26 11:33:31 +0100
committereunhhu <[email protected]>2026-09-26 11:33:31 +0100
commit0d5effd6afe8808296a01db102ca4c247cdcd1af (patch)
tree4f1113880606fb6dda861fd846f8ff40d5c17a63 /src/draw.c
parent3b3e4a221fa47d0109c6ab99be65b5ba48bae254 (diff)
downloadvega-0d5effd6afe8808296a01db102ca4c247cdcd1af.tar.gz
vega-0d5effd6afe8808296a01db102ca4c247cdcd1af.zip
Show filtered lists and their shared focus
A list may now be filtered (each t in tasks where !t.done), and several filtered lists over one list share one focus: the focus view names an item, so Vega asks Pure which row shows it and highlights it only in the list that holds it; the other lists have no focus (null in the web surface's JSON, and the spoken surface names the item where it is). A click or point on a row points at the item that row shows, and the wheel on a list without the focus focuses the row under it. Pure's rows now take a mutable app. examples/today.aup shows what is open and what is done; its CLI output matches a model over random adds, moves, toggles and points into either list, and the web surface leaves the other list without a focus.
Diffstat (limited to 'src/draw.c')
-rw-r--r--src/draw.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/draw.c b/src/draw.c
index 738c2db..31188c7 100644
--- a/src/draw.c
+++ b/src/draw.c
@@ -138,6 +138,7 @@ static void say_focus(FILE *out, PureApp *app, const VegaPart *part) {
size_t length, rows = vega_rows(app, part);
if (!rows) { fprintf(out, "%s is empty.\n", m->view_names[part->view]); return; }
size_t focus = vega_focus(app, part);
+ if (focus >= rows) { fprintf(out, "%s: none of %zu focused.\n", m->view_names[part->view], rows); return; }
fprintf(out, "Item %zu of %zu: ", focus + 1, rows);
VegaTone tone = vega_tone(app, part, focus);
if (tone >= VEGA_ACCENT) fprintf(out, "%s, ", tone_names[tone]);
@@ -164,8 +165,15 @@ void vega_say(FILE *out, PureApp *app, const VegaScreen *screen, bool all) {
char text[VEGA_TEXT];
size_t length;
if (!all) {
- for (unsigned i = 0; i < screen->count; ++i)
- if (screen->parts[i].kind != VEGA_FIELD) { say_focus(out, app, &screen->parts[i]); return; }
+ /* The focused item where a list shows it, else the first list. */
+ const VegaPart *first = NULL;
+ for (unsigned i = 0; i < screen->count; ++i) {
+ const VegaPart *part = &screen->parts[i];
+ if (part->kind == VEGA_FIELD) continue;
+ if (!first) first = part;
+ if (vega_focus(app, part) < vega_rows(app, part)) { say_focus(out, app, part); return; }
+ }
+ if (first) say_focus(out, app, first);
return;
}
if (screen->title >= 0 && vega_text(app, (uint32_t)screen->title, 0, text, &length)) {