Set each couplet in a dim rounded card, on every screen size
Each line of verse now sits in its own soft card (surface-container-high, 12dp corners), so the eye finds where one couplet ends and the next begins, and the couplet's chevron, actions and summary visibly belong to it. On OLED black that step is all but black, so the card takes the next one up there. Prose stays bare: a paragraph in a box reads as a quotation. Text keeps at least 6:1 on the card in every theme. The phone layout is otherwise unchanged. Updates the Couplet notes, the stylesheet and wireframes 4-8, and adds wireframe 9 for the phone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RhmDdrN5hgWrgRcFLAMsV6
@ -7,6 +7,10 @@ import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.shrinkHorizontally
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.gestures.detectTapGestures
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@ -251,6 +255,9 @@ fun PoemScreen(
|
||||
}
|
||||
}
|
||||
|
||||
/** The positions that make a line of verse; anything else (Single, Paragraph, Comment) is prose. */
|
||||
private val VERSE_POSITIONS = setOf(Verse.RIGHT, Verse.LEFT, Verse.CENTERED_1, Verse.CENTERED_2)
|
||||
|
||||
/** A word someone tapped: what to look up, the couplet it came from, and where it sits in its verse. */
|
||||
private data class WordTap(val word: String, val passage: Bookmark, val verse: Int, val range: IntRange)
|
||||
|
||||
@ -379,7 +386,26 @@ private fun Couplet(
|
||||
val oneLine = sideBySide && couplet.size == 2 &&
|
||||
couplet[0].position == Verse.RIGHT && couplet[1].position == Verse.LEFT
|
||||
|
||||
Column(modifier = Modifier.fillMaxWidth().padding(vertical = 6.dp)) {
|
||||
// Each line of verse sits in its own soft card, so the eye finds where one couplet ends and
|
||||
// the next begins, and the couplet's actions visibly belong to it. Prose (Golestan,
|
||||
// Nowruznameh) stays bare: a paragraph in a box reads as a quotation, not as the text.
|
||||
val isVerse = couplet.all { it.position in VERSE_POSITIONS }
|
||||
val colors = MaterialTheme.colorScheme
|
||||
// A step lighter than the page. On OLED black the usual step is all but black itself, so
|
||||
// the card takes the next one up: still dim, but there.
|
||||
val cardColor =
|
||||
if (colors.surface == Color.Black) colors.surfaceContainerHighest else colors.surfaceContainerHigh
|
||||
val card = if (isVerse) {
|
||||
Modifier
|
||||
.padding(vertical = 4.dp)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.background(cardColor)
|
||||
.padding(horizontal = 12.dp, vertical = 8.dp)
|
||||
} else {
|
||||
Modifier.padding(vertical = 6.dp)
|
||||
}
|
||||
|
||||
Column(modifier = Modifier.fillMaxWidth().then(card)) {
|
||||
if (oneLine) {
|
||||
Row(modifier = Modifier.fillMaxWidth()) {
|
||||
couplet.forEachIndexed { index, verse ->
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# ColumnBrowser
|
||||
|
||||
The layout for tablets and unfolded foldables. A narrow column of poets sits on the right. Beside it is a column for each level of the open book (books › chapters › poems), and the open page fills the rest of the screen on the left. Phones keep today's navigation. Built in `app/src/main/java/com/ganjoor/android/ui/ColumnBrowser.kt`; wireframes are in `design/wireframes/` (1–8).
|
||||
The layout for tablets and unfolded foldables. A narrow column of poets sits on the right. Beside it is a column for each level of the open book (books › chapters › poems), and the open page fills the rest of the screen on the left. Phones keep today's navigation. Built in `app/src/main/java/com/ganjoor/android/ui/ColumnBrowser.kt`; wireframes are in `design/wireframes/` (1–9).
|
||||
|
||||
## Window sizes
|
||||
|
||||
|
||||
@ -4,7 +4,9 @@ One line of poetry: two hemistichs stacked on a phone, the first pushed to the s
|
||||
|
||||
- **Consumer provides:** the couplet's verses (each with its position), the reading style from settings (`poem-naskh` or `poem-nastaliq` at the reader's size and weight), and handlers for a tapped word and for the actions.
|
||||
- Alignment by verse position: first hemistich `start`, second `end`, centred verses `center`, prose (single/paragraph/comment) `justify` so Golestan and Nowruznameh fill the column.
|
||||
- `space-6` above and below each couplet. Text is `on-surface`.
|
||||
- Every line of verse sits in its own **card**: `surface-container-high` (`surface-container-highest` on OLED black, where the usual step is all but black), `radius-md` (12dp) corners, 12dp/8dp inner padding and 4dp above and below. The card holds the couplet's options chevron, its actions and its summary, so they visibly belong to it. Text is `on-surface`, at least 6:1 on the card in every theme.
|
||||
- Prose (Single, Paragraph or Comment positions: Golestan, Nowruznameh) has no card; it keeps `space-6` above and below. A paragraph in a box would read as a quotation.
|
||||
- The cards are the same on phones, tablets and foldables (wireframes 4–9).
|
||||
- Tapping a word opens the dictionary sheet; tapping between words, or the 32px chevron (`touch-compact`, 20px icon, `on-surface-variant`), opens the couplet's actions: **Save this passage**, **Copy**, **Share** as TextButtons. Save keeps the link back to the poem; Copy doesn't.
|
||||
- Long-press belongs to text selection — never bind actions to it here.
|
||||
- With summaries on, Ganjoor's couplet summary sits underneath in `body-small` / `on-surface-variant`.
|
||||
|
||||
@ -28,7 +28,8 @@
|
||||
.gj-metre { font-size: 12px; line-height: 16px; letter-spacing: .4px; color: var(--on-surface-variant); }
|
||||
|
||||
/* Couplet: two hemistichs stacked; first to the start, second to the end. */
|
||||
.gj-couplet { padding: var(--space-6) 0; }
|
||||
.gj-couplet { margin: var(--space-4) 0; padding: var(--space-8) var(--space-12); border-radius: var(--radius-md); background: var(--surface-container-high); }
|
||||
.gj-couplet.is-prose { margin: 0; padding: var(--space-6) 0; background: none; }
|
||||
.gj-verse { font-family: var(--font-naskh); font-size: 22px; line-height: 1.8; color: var(--on-surface); margin: 0; }
|
||||
.gj-couplet.is-nastaliq .gj-verse { font-family: var(--font-nastaliq); line-height: 2.4; }
|
||||
.gj-verse.is-first { text-align: start; }
|
||||
|
||||
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 110 KiB |
BIN
design/wireframes/9-phone-couplets.png
Normal file
|
After Width: | Height: | Size: 78 KiB |