diff --git a/artist/bordered.go b/artist/bordered.go index aa405ea..08a2a39 100644 --- a/artist/bordered.go +++ b/artist/bordered.go @@ -86,3 +86,26 @@ func (multi *MultiBordered) recalculate (width, height int) { if bounds.Empty() { break } } } + +// Padded is a pattern that surrounds a central fill pattern with a border that +// can have a different width for each side. +type Padded struct { + Fill Pattern + Stroke Pattern + Sides []int +} + +// AtWhen satisfies the Pattern interface. +func (pattern Padded) AtWhen (x, y, width, height int) (c color.RGBA) { + innerBounds := image.Rect ( + pattern.Sides[3], pattern.Sides[0], + width - pattern.Sides[1], height - pattern.Sides[2]) + if (image.Point { x, y }).In (innerBounds) { + return pattern.Fill.AtWhen ( + x - pattern.Sides[3], + y - pattern.Sides[0], + innerBounds.Dx(), innerBounds.Dy()) + } else { + return pattern.Stroke.AtWhen(x, y, width, height) + } +} diff --git a/elements/basic/list.go b/elements/basic/list.go index 6acb191..2d6ac7a 100644 --- a/elements/basic/list.go +++ b/elements/basic/list.go @@ -366,7 +366,6 @@ func (element *List) updateMinimumSize () { _, inset := theme.ListPattern(theme.PatternState { Case: listCase, }) - minimumWidth += inset[1] + inset[3] minimumHeight += inset[0] + inset[2] element.core.SetMinimumSize(minimumWidth, minimumHeight) @@ -387,24 +386,14 @@ func (element *List) draw () { bounds.Min.X, bounds.Min.Y - element.scroll, } + innerCanvas := tomo.Cut(element, bounds) for index, entry := range element.entries { entryPosition := dot dot.Y += entry.Bounds().Dy() if dot.Y < bounds.Min.Y { continue } if entryPosition.Y > bounds.Max.Y { break } - - if element.selectedEntry == index { - pattern, _ := theme.ItemPattern(theme.PatternState { - Case: listEntryCase, - On: true, - }) - artist.FillRectangle ( - element, - pattern, - entry.Bounds().Add(entryPosition)) - } entry.Draw ( - element, entryPosition, - element.selectedEntry == index && element.Selected()) + innerCanvas, entryPosition, + element.Selected(), element.selectedEntry == index) } } diff --git a/elements/basic/listentry.go b/elements/basic/listentry.go index aa5da13..2e6bfb6 100644 --- a/elements/basic/listentry.go +++ b/elements/basic/listentry.go @@ -56,11 +56,23 @@ func (entry *ListEntry) Draw ( destination tomo.Canvas, offset image.Point, selected bool, + on bool, ) ( updatedRegion image.Rectangle, ) { + pattern, _ := theme.ItemPattern(theme.PatternState { + Case: listEntryCase, + Selected: selected, + On: on, + }) + artist.FillRectangle ( + destination, + pattern, + entry.Bounds().Add(offset)) foreground, _ := theme.ForegroundPattern (theme.PatternState { Case: listEntryCase, + Selected: selected, + On: on, }) return entry.drawer.Draw ( destination, diff --git a/elements/testing/artist.go b/elements/testing/artist.go index 1a919b2..628cd56 100644 --- a/elements/testing/artist.go +++ b/elements/testing/artist.go @@ -20,14 +20,14 @@ type Artist struct { func NewArtist () (element *Artist) { element = &Artist { } element.Core, element.core = core.NewCore(element) - element.core.SetMinimumSize(400, 600) + element.core.SetMinimumSize(480, 600) return } func (element *Artist) Resize (width, height int) { element.core.AllocateCanvas(width, height) bounds := element.Bounds() - element.cellBounds.Max.X = bounds.Dx() / 4 + element.cellBounds.Max.X = bounds.Dx() / 5 element.cellBounds.Max.Y = (bounds.Dy() - 48) / 8 drawStart := time.Now() @@ -68,6 +68,16 @@ func (element *Artist) Resize (width, height int) { }, element.cellAt(3, 0)) + // 4, 0 + artist.FillRectangle ( + element, + artist.Padded { + Stroke: uhex(0xFFFFFFFF), + Fill: uhex(0x666666FF), + Sides: []int { 4, 13, 2, 0 }, + }, + element.cellAt(4, 0)) + // 0, 1 - 3, 1 for x := 0; x < 4; x ++ { artist.FillRectangle ( diff --git a/theme/list.go b/theme/list.go index 894347b..d2ee5b0 100644 --- a/theme/list.go +++ b/theme/list.go @@ -18,23 +18,11 @@ var selectedListPattern = artist.NewMultiBordered ( artist.Stroke { Weight: 1, Pattern: accentPattern }, artist.Stroke { Pattern: artist.NewUniform(hex(0x999C99FF)) }) +// TODO: make these better, making use of the padded pattern. also, create +// selected variations for both of these. var listEntryPattern = artist.NewMultiBordered ( - artist.Stroke { Weight: 1, Pattern: artist.QuadBeveled { - artist.NewUniform(hex(0x999C99FF)), - strokePattern, - artist.NewUniform(hex(0x999C99FF)), - strokePattern, - }}, artist.Stroke { Pattern: artist.NewUniform(hex(0x999C99FF)) }) -var selectedListEntryPattern = artist.NewMultiBordered ( - artist.Stroke { Weight: 1, Pattern: strokePattern }, - artist.Stroke { - Weight: 1, - Pattern: artist.Beveled { - artist.NewUniform(hex(0x3b534eFF)), - artist.NewUniform(hex(0x97a09cFF)), - }, - }, - artist.Stroke { Pattern: artist.NewUniform(hex(0x97a09cFF)) }) +var onListEntryPattern = artist.NewMultiBordered ( + artist.Stroke { Pattern: artist.NewUniform(hex(0x6e8079FF)) }) diff --git a/theme/patterns.go b/theme/patterns.go index b81f46d..451a135 100644 --- a/theme/patterns.go +++ b/theme/patterns.go @@ -63,7 +63,7 @@ type Inset [4]int // further, an empty rectangle near its center will be returned. func (inset Inset) Apply (bigger image.Rectangle) (smaller image.Rectangle) { smaller = bigger - if smaller.Dx() < inset[3] + inset[0] { + if smaller.Dx() < inset[3] + inset[1] { smaller.Min.X = (smaller.Min.X + smaller.Max.X) / 2 smaller.Max.X = smaller.Min.X } else { @@ -71,7 +71,7 @@ func (inset Inset) Apply (bigger image.Rectangle) (smaller image.Rectangle) { smaller.Max.X -= inset[1] } - if smaller.Dy() < inset[1] + inset[2] { + if smaller.Dy() < inset[0] + inset[2] { smaller.Min.Y = (smaller.Min.Y + smaller.Max.Y) / 2 smaller.Max.Y = smaller.Min.Y } else { @@ -131,24 +131,21 @@ func InputPattern (state PatternState) (pattern artist.Pattern, inset Inset) { } } -// TODO: for list and item patterns, have all that bizarre padding/2 information -// in the insets. - // ListPattern returns a background pattern for a list of things. func ListPattern (state PatternState) (pattern artist.Pattern, inset Inset) { if state.Selected { - return selectedListPattern, Inset { 4, 0, 4, 0 } + return selectedListPattern, Inset { 4, 4, 4, 4 } } else { - return listPattern, Inset { 4, 0, 4, 0 } + return listPattern, Inset { 4, 4, 4, 4 } } } // ItemPattern returns a background pattern for a list item. func ItemPattern (state PatternState) (pattern artist.Pattern, inset Inset) { if state.On { - return selectedListEntryPattern, Inset { 4, 8, 4, 8 } + return onListEntryPattern, Inset { 4, 4, 4, 4 } } else { - return listEntryPattern, Inset { 4, 8, 4, 8 } + return listEntryPattern, Inset { 4, 4, 4, 4 } } }