Both boxes are placed beside their cell by one helper, besideCell, which moves a box up rather than over the status line. A golden screen hovers a note on the last row shown.
- commit
- 8ce86008c9f2342750eac4afc8124bc8a2d9798d
- parent
- f4d438dc2cd7a8d8b2976f44ebe5abb834d08ad1
- author
- Dami <dami.etoile@gmail.com>
- kind
- fix risk score 1.3 of 3, Jev's estimate
| M | e2e/ | 13 | ++++++++++++- |
| A | e2e/ | 16 | ++++++++++++++++ |
| A | e2e/ | 16 | ++++++++++++++++ |
| M | internal/ | 12 | +++--------- |
| M | internal/ | 22 | +++++++++++++++------- |
@@ -43,6 +43,17 @@ var noteScreens = []screen{
4343 s.mouse(ghostty.MouseActionMotion, ghostty.MouseButtonUnknown, 6+10+4, gridRow1+2, 0)4444 s.waitFor("┌─ Note ─")4545 }},46+ {name: "note-hover-bottom", opts: options{cols: 60, rows: 16}, setup: func(s *session) {47+ // A note on the last row shown: the box moves up, clear of the48+ // status line.49+ s.keys("<f5>", "B11", "<enter>", "<shift+f2>")50+ s.waitFor("Note on B11:")51+ s.keys("Checked against", "<alt+enter>", "the bank statement", "<alt+enter>", "on the 3rd", "<enter>")52+ s.waitFor("Note Checked against")53+ s.keys("<ctrl+home>")54+ s.mouse(ghostty.MouseActionMotion, ghostty.MouseButtonUnknown, 6+10+4, gridRow1+10, 0)55+ s.waitFor("┌─ Note ─")56+ }},4657 {name: "protect-warning", setup: func(s *session) {4758 protectedBudget(s)4859 s.keys("<esc>", "<down>", "100")@@ -61,7 +72,7 @@ var noteScreens = []screen{
6172 }6273 6374 func init() {64- light := map[string]bool{"note": true, "note-hover": true, "protect-warning": true}75+ light := map[string]bool{"note": true, "note-hover": true, "note-hover-bottom": true, "protect-warning": true}6576 for _, sc := range noteScreens {6677 screens = append(screens, sc)6778 if light[sc.name] {@@ -0,0 +1,16 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">READY</span><span style="background:var(--vt-palette-6)"> </span>2+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">A1</span><span style="background:var(--vt-palette-7)"> </span>3+4+<span style="background:var(--vt-palette-7)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">A</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">B</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">C</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">D</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">E</span><span style="background:var(--vt-palette-7)"> </span>5+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span>6+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span>7+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span>8+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span>9+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span>10+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">6</span><span style="background:var(--vt-palette-7)"> </span>11+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">7</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-8)">┌─</span> <span style="font-weight:bold">Note</span> <span style="color:var(--vt-palette-8)">─────────────────────────┐</span>12+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">8</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-8)">│</span> Checked against <span style="color:var(--vt-palette-8)">│</span>13+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">9</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-8)">│</span> the bank statement <span style="color:var(--vt-palette-8)">│</span>14+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">10</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-8)">│</span> on the 3rd <span style="color:var(--vt-palette-8)">│</span>15+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">11</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-5)">▝</span><span style="color:var(--vt-palette-8)">└────────────────────────────────┘</span>16+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Sheet1</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-0)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-0)">modified</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+K</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">search</span></pre>\ No newline at end of file@@ -0,0 +1,16 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">READY</span><span style="background:var(--vt-palette-6)"> </span>2+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">A1</span><span style="background:var(--vt-palette-8)"> </span>3+4+<span style="background:var(--vt-palette-8)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">A</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">B</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">C</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">D</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">E</span><span style="background:var(--vt-palette-8)"> </span>5+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span>6+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span>7+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span>8+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span>9+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span>10+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">6</span><span style="background:var(--vt-palette-8)"> </span>11+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">7</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">┌─</span> <span style="font-weight:bold">Note</span> <span style="color:var(--vt-palette-8)">─────────────────────────┐</span>12+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">8</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Checked against <span style="color:var(--vt-palette-8)">│</span>13+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">9</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> the bank statement <span style="color:var(--vt-palette-8)">│</span>14+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">10</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> on the 3rd <span style="color:var(--vt-palette-8)">│</span>15+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">11</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-3)">▝</span><span style="color:var(--vt-palette-8)">└────────────────────────────────┘</span>16+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Sheet1</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-8)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-8)">modified</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+K</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">search</span></pre>\ No newline at end of file@@ -129,8 +129,8 @@ const errorBoxWidth = 48
129129 130130 func (b *errorBox) Indicator() string { return "HELP" }131131 132-// Layout places the box as a note's: right of the cell, or left of it133-// when there's no room, wrapped to its width.132+// Layout wraps the explanation to the box's width and places the box133+// as a note's (besideCell), or at the grid's top left on a source's tab.134134 func (b *errorBox) Layout() []overlay.Box {135135 m := b.m136136 inner := min(errorBoxWidth, m.width-2)@@ -143,13 +143,7 @@ func (b *errorBox) Layout() []overlay.Box {
143143 if !b.beside {144144 return []overlay.Box{{ID: errorBoxID, X: 0, Y: gridTop, Lines: framed}}145145 }146- x, y := m.cellPos(b.at)147- x += m.sheet.ColWidth(b.at.Col)148- if x+inner+2 > m.width {149- x = max(x-m.sheet.ColWidth(b.at.Col)-inner-2, 0)150- }151- x, y = m.clampBox(x, y, inner+2, len(framed)+1) // above the status line152- return []overlay.Box{{ID: errorBoxID, X: x, Y: max(y, gridTop), Lines: framed}}146+ return []overlay.Box{m.besideCell(errorBoxID, b.at, framed)}153147 }154148 155149 // Key closes the box, and a key that moves or runs a command does so@@ -126,14 +126,22 @@ func (m *Model) noteBox() (overlay.Box, bool) {
126126 for i, line := range wrapped {127127 rows[i] = m.th.MenuBar.Render(theme.PadRight(" "+strings.TrimRight(line, " "), inner))128128 }129- lines := m.th.Frame(inner, "Note", "", rows)130- x, y := m.cellPos(h.addr)131- x += m.sheet.ColWidth(h.addr.Col)132- if x+inner+2 > m.width { // no room on the right: the left side133- x = max(x-m.sheet.ColWidth(h.addr.Col)-inner-2, 0)129+ return m.besideCell(noteBoxID, h.addr, m.th.Frame(inner, "Note", "", rows)), true130+}131+132+// besideCell places a framed box beside the cell at a, its top on the133+// cell's row: right of the cell, or left of it when there's no room,134+// moved up as far as it must to stay above the status line, and never135+// over the column headers.136+func (m *Model) besideCell(id string, a sheet.Addr, lines []string) overlay.Box {137+ w := ansi.StringWidth(lines[0])138+ x, y := m.cellPos(a)139+ x += m.sheet.ColWidth(a.Col)140+ if x+w > m.width { // no room on the right: the left side141+ x = max(x-m.sheet.ColWidth(a.Col)-w, 0)134142 }135- x, y = m.clampBox(x, y, inner+2, len(lines))136- return overlay.Box{ID: noteBoxID, X: x, Y: max(y, gridTop), Lines: lines}, true143+ x, y = m.clampBox(x, y, w, len(lines)+1) // the status line's row stays clear144+ return overlay.Box{ID: id, X: x, Y: max(y, gridTop), Lines: lines}137145 }138146 139147 const noteBoxID = "note"