Add shared internal UI toolkit for both readers

This commit is contained in:
ak47 committed 2026-11-12 01:27:42 -05:00
1 parent 672caca854
commit e49ba198d7
34 files changed
+3471

No files matched your search

+60
View File
@@ -0,0 +1,60 @@
// Copyright (c) 2026 Storm Dragon
// SPDX-License-Identifier: GPL-3.0-or-later
// Package grid owns selection movement and announcements for both form layouts.
package grid
import (
"git.stormux.org/storm/screenreader-common/internalui/message"
"strconv"
)
// Move navigates the filtered positions, preserving the column where possible.
// The host maps the returned position back to its stable item identity.
func Move(position, count, columns int, key string) (int, bool) {
if count <= 0 || columns <= 0 {
return position, false
}
switch key {
case "left":
position = max(0, position-1)
case "right":
position = min(count-1, position+1)
case "up":
if position >= columns {
position -= columns
}
case "down":
if position/columns < (count-1)/columns {
position = min(count-1, position+columns)
}
case "home":
position = 0
case "end":
position = count - 1
case "pageup":
position = max(0, position-columns*5)
case "pagedown":
position = min(count-1, position+columns*5)
default:
return position, false
}
return position, true
}
// Describe is shared speech policy. Layouts choose which optional details to
// request; localization belongs to the session, never to a global catalog.
func Describe(label string, position, count, columns int, coordinates, itemPosition bool, messages message.Messages) string {
row, column := strconv.Itoa(position/columns+1), strconv.Itoa(position%columns+1)
item, total := strconv.Itoa(position+1), strconv.Itoa(count)
switch {
case coordinates && itemPosition:
return messages.Format("{0}. row {1}, column {2}. {3} of {4}", label, row, column, item, total)
case coordinates:
return messages.Format("{0}. row {1}, column {2}", label, row, column)
case itemPosition:
return messages.Format("{0}. {1} of {2}", label, item, total)
default:
return label
}
}