Skip to content

Commit b83017e

Browse files
donislawdevclaude
andcommitted
gui: after the outside review of #116 - two guards bounded from both sides, the tip's shade in the palette
Three findings, all three true on the code as it stood: - the fold head's fill was asked to be narrower than its row and wider than nothing, which a one pixel fill satisfies. It is now asked to be at least as wide as the title it lights and narrower than the row; - the pairing of a name with the box under it was measured once, between the first two fields, and applied to every field - a later pair could drift while the first still held. Each name is now measured against the next name down the screen; - the shade under an explanation was a colour written at the call site. It is a name of the palette now, in both variants - its own name rather than the toolkit's Shadow, which this palette answers with nothing on purpose since 2026-08-24. Run: the guards of the touched files and the cheap whole-tree gates (41), gofmt, vet, lint, staticcheck. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent b75d71d commit b83017e

5 files changed

Lines changed: 30 additions & 10 deletions

File tree

‎internal/guard/foldhead_test.go‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,17 @@ func TestTheHeadRowDrawsItsStatesAndTheArrowFollows(t *testing.T) {
202202
// form, which is enormous. The row is still the target - the head is as
203203
// wide as the row - so the two widths are asked for apart: the head wide,
204204
// its fill narrow.
205-
if row, fill := head.Size().Width, back.Size().Width; fill >= row || fill < 1 {
206-
t.Errorf("under the pointer the fill is %.0f px wide on a head %.0f px wide - the fill has to cover the words and not the row", fill, row)
205+
// Bounded from both sides, after the outside review of #116: "narrower
206+
// than the row" alone would have let a one pixel fill through. The fill
207+
// has to be at least as wide as the title it lights, and narrower than
208+
// the row it stands in.
209+
title, ok := labelBox(fold.Object(), "Notes for the manifest")
210+
if !ok {
211+
t.Fatal("the fold's title is not on the screen, so there is nothing to measure the fill against")
212+
}
213+
if row, fill := head.Size().Width, back.Size().Width; fill >= row || fill < title.Width {
214+
t.Errorf("under the pointer the fill is %.0f px wide, the title %.0f and the head %.0f - the fill has to cover the words and stop short of the row",
215+
fill, title.Width, row)
207216
}
208217
if arrow.Resource.Name() == restingArrow {
209218
t.Error("the arrow is inked the same under the pointer as at rest, so it does not follow the row")

‎internal/guard/guitext_test.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ var notWords = map[string]string{
109109
`"•"`: "the marker in front of a list item, a shape rather than a word",
110110
`"panel"`: "our name for a colour, in the palette the toolkit asks by name",
111111
`"label"`: "our name for the ink of a field's name, a colour the palette holds",
112+
`"tipshade"`: "our name for the shade under an explanation, a colour the palette holds",
112113
`"lift"`: "our name for what the pointer does to the filled button, a colour the palette holds",
113114
`"shade"`: "our name for what a press does to the filled button, a colour the palette holds",
114115
`"fyneDo"`: "a migration flag the toolkit reads, never shown",

‎internal/guard/spacingscale_test.go‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,14 @@ func TestANameStandsOverItsBoxOnOneEdgeWithEveryOther(t *testing.T) {
7272
}
7373
}
7474
// The pairing: a name is nearer the box under it than that box is to the
75-
// next name. Asked between neighbours inside one section, because a
76-
// section's edge is a bigger gap for a reason of its own.
77-
between := gapBelowField(t, generate, text.FieldFormat(), text.FieldSize())
78-
for i, gap := range nameGaps {
79-
if gap >= between {
80-
t.Errorf("%q stands %.1f px over its box and the next name stands %.1f px under it, so nothing says which box the name belongs to",
81-
names[i], gap, between)
75+
// next name. Asked for each pair down the screen rather than once at the
76+
// top, after the outside review of #116: measured once, a later pair
77+
// could drift while the first still held.
78+
for i := 0; i+1 < len(names); i++ {
79+
between := gapBelowField(t, generate, names[i], names[i+1])
80+
if nameGaps[i] >= between {
81+
t.Errorf("%q stands %.1f px over its box and %q stands %.1f px under that box, so nothing says which box the name belongs to",
82+
names[i], nameGaps[i], names[i+1], between)
8283
}
8384
}
8485
}

‎internal/gui/parts/parts.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ func tipSurface() *canvas.Rectangle {
289289
// for offsetting shadows. Drawn under tipSurface in a stack, so it shows
290290
// only past the surface's lower edge.
291291
func tipShadow() fyne.CanvasObject {
292-
rect := canvas.NewRectangle(overlay(0x00, 0x00, 0x00, 0x66))
292+
rect := canvas.NewRectangle(PaletteColour(ColorNameTipShade, theme.VariantDark))
293293
rect.CornerRadius = RadiusField
294294
return container.New(shifted{dy: TipShadowDrop}, rect)
295295
}

‎internal/gui/parts/theme.go‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ const ColorNamePanel fyne.ThemeColorName = "panel"
3535
// Owner's decision of 2026-09-21 - see docs/GUI-STRUCTURE-2026-09-21.md.
3636
const ColorNameLabel fyne.ThemeColorName = "label"
3737

38+
// ColorNameTipShade is the shade an explanation casts on the form under it.
39+
// A name of its own rather than the toolkit's Shadow, which this palette
40+
// answers with nothing on purpose (see ColorNameShadow): the toolkit lays its
41+
// shadow under every popup and the format list is where it read as a hard
42+
// band, while an explanation is the one floating thing that wanted one.
43+
const ColorNameTipShade fyne.ThemeColorName = "tipshade"
44+
3845
// ColorNameLift is what the pointer does to a face that is itself light - the
3946
// filled primary button - and ColorNameShade is what a press does to it.
4047
//
@@ -193,6 +200,7 @@ var (
193200
// than as a popup - see parts.Tips - so it never asked the theme for a
194201
// shadow and does not lose one.
195202
theme.ColorNameShadow: color.Transparent,
203+
ColorNameTipShade: overlay(0x00, 0x00, 0x00, 0x66),
196204

197205
// The surface a section is drawn on, and the line round its edge.
198206
//
@@ -294,6 +302,7 @@ var (
294302
// is what separates it.
295303
theme.ColorNameMenuBackground: hex(0xFF, 0xFF, 0xFF),
296304
theme.ColorNameShadow: overlay(0x00, 0x00, 0x00, 0x40),
305+
ColorNameTipShade: overlay(0x00, 0x00, 0x00, 0x40),
297306

298307
// The same two, worked out the same way against a white page. The gap
299308
// between page and input is narrower here - 5.6 L* against 7.7 - so the

0 commit comments

Comments
 (0)