From 9b22e80f054e0f6f62a510724d24d3d9418ebf20 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Tue, 31 Jan 2023 18:39:17 -0500 Subject: [PATCH] Got scroll container working --- elements/basic/checkbox.go | 6 +++--- elements/basic/scrollcontainer.go | 20 ++++++++++++++++---- elements/basic/switch.go | 8 ++++---- elements/basic/textbox.go | 9 +++++---- elements/fun/clock.go | 8 ++++---- elements/testing/artist.go | 4 ++-- elements/testing/mouse.go | 8 ++++---- layouts/dialog.go | 25 ++++++++++++------------- layouts/horizontal.go | 3 +-- layouts/vertical.go | 3 +-- 10 files changed, 52 insertions(+), 42 deletions(-) diff --git a/elements/basic/checkbox.go b/elements/basic/checkbox.go index 839bf21..c4a0f78 100644 --- a/elements/basic/checkbox.go +++ b/elements/basic/checkbox.go @@ -134,7 +134,7 @@ func (element *Checkbox) SetText (text string) { func (element *Checkbox) draw () { bounds := element.Bounds() - boxBounds := image.Rect(0, 0, bounds.Dy(), bounds.Dy()) + boxBounds := image.Rect(0, 0, bounds.Dy(), bounds.Dy()).Add(bounds.Min) backgroundPattern, _ := theme.BackgroundPattern(theme.PatternState { Case: checkboxCase, @@ -150,9 +150,9 @@ func (element *Checkbox) draw () { artist.FillRectangle(element, pattern, boxBounds) textBounds := element.drawer.LayoutBounds() - offset := image.Point { + offset := bounds.Min.Add(image.Point { X: bounds.Dy() + theme.Padding(), - } + }) offset.Y -= textBounds.Min.Y offset.X -= textBounds.Min.X diff --git a/elements/basic/scrollcontainer.go b/elements/basic/scrollcontainer.go index f5cb8c3..c9491e1 100644 --- a/elements/basic/scrollcontainer.go +++ b/elements/basic/scrollcontainer.go @@ -57,7 +57,7 @@ func NewScrollContainer (horizontal, vertical bool) (element *ScrollContainer) { func (element *ScrollContainer) handleResize () { element.recalculate() - element.child.DrawTo(tomo.Cut(element, element.child.Bounds())) + element.resizeChildToFit() element.draw() } @@ -91,7 +91,7 @@ func (element *ScrollContainer) Adopt (child tomo.Scrollable) { element.vertical.enabled = element.child.ScrollAxes() if element.core.HasImage() { - element.child.DrawTo(tomo.Cut(element, element.child.Bounds())) + element.resizeChildToFit() } } } @@ -113,7 +113,8 @@ func (element *ScrollContainer) HandleMouseDown (x, y int, button tomo.Button) { if point.In(element.horizontal.bar) { element.horizontal.dragging = true element.horizontal.dragOffset = - point.Sub(element.horizontal.bar.Min).X + x - element.horizontal.bar.Min.X + + element.Bounds().Min.X element.dragHorizontalBar(point) } else if point.In(element.horizontal.gutter) { @@ -128,7 +129,8 @@ func (element *ScrollContainer) HandleMouseDown (x, y int, button tomo.Button) { } else if point.In(element.vertical.bar) { element.vertical.dragging = true element.vertical.dragOffset = - point.Sub(element.vertical.bar.Min).Y + y - element.vertical.bar.Min.Y + + element.Bounds().Min.Y element.dragVerticalBar(point) } else if point.In(element.vertical.gutter) { @@ -268,6 +270,14 @@ func (element *ScrollContainer) clearChildEventHandlers (child tomo.Scrollable) } } +func (element *ScrollContainer) resizeChildToFit () { + childBounds := image.Rect ( + 0, 0, + element.childWidth, + element.childHeight).Add(element.Bounds().Min) + element.child.DrawTo(tomo.Cut(element, childBounds)) +} + func (element *ScrollContainer) recalculate () { _, gutterInsetHorizontal := theme.GutterPattern(theme.PatternState { Case: scrollBarHorizontalCase, @@ -300,6 +310,7 @@ func (element *ScrollContainer) recalculate () { // if enabled, give substance to the gutters if horizontal.exists { + horizontal.gutter.Min.X = bounds.Min.X horizontal.gutter.Min.Y = bounds.Max.Y - thicknessHorizontal horizontal.gutter.Max.X = bounds.Max.X horizontal.gutter.Max.Y = bounds.Max.Y @@ -312,6 +323,7 @@ func (element *ScrollContainer) recalculate () { if vertical.exists { vertical.gutter.Min.X = bounds.Max.X - thicknessVertical vertical.gutter.Max.X = bounds.Max.X + vertical.gutter.Min.Y = bounds.Min.Y vertical.gutter.Max.Y = bounds.Max.Y if horizontal.exists { vertical.gutter.Max.Y -= thicknessHorizontal diff --git a/elements/basic/switch.go b/elements/basic/switch.go index d3ac782..a30523a 100644 --- a/elements/basic/switch.go +++ b/elements/basic/switch.go @@ -141,8 +141,8 @@ func (element *Switch) calculateMinimumSize () { func (element *Switch) draw () { bounds := element.Bounds() - handleBounds := image.Rect(0, 0, bounds.Dy(), bounds.Dy()) - gutterBounds := image.Rect(0, 0, bounds.Dy() * 2, bounds.Dy()) + handleBounds := image.Rect(0, 0, bounds.Dy(), bounds.Dy()).Add(bounds.Min) + gutterBounds := image.Rect(0, 0, bounds.Dy() * 2, bounds.Dy()).Add(bounds.Min) backgroundPattern, _ := theme.BackgroundPattern(theme.PatternState { Case: switchCase, }) @@ -179,9 +179,9 @@ func (element *Switch) draw () { artist.FillRectangle(element, handlePattern, handleBounds) textBounds := element.drawer.LayoutBounds() - offset := image.Point { + offset := bounds.Min.Add(image.Point { X: bounds.Dy() * 2 + theme.Padding(), - } + }) offset.Y -= textBounds.Min.Y offset.X -= textBounds.Min.X diff --git a/elements/basic/textbox.go b/elements/basic/textbox.go index 67cccef..b1028b1 100644 --- a/elements/basic/textbox.go +++ b/elements/basic/textbox.go @@ -258,6 +258,7 @@ func (element *TextBox) scrollToCursor () { if !element.core.HasImage() { return } bounds := element.Bounds().Inset(theme.Padding()) + bounds = bounds.Sub(bounds.Min) bounds.Max.X -= element.valueDrawer.Em().Round() cursorPosition := element.valueDrawer.PositionOf(element.cursor) cursorPosition.X -= element.scroll @@ -285,10 +286,10 @@ func (element *TextBox) draw () { if len(element.text) == 0 && !element.Focused() { // draw placeholder textBounds := element.placeholderDrawer.LayoutBounds() - offset := image.Point { + offset := bounds.Min.Add (image.Point { X: theme.Padding() + inset[3], Y: theme.Padding() + inset[0], - } + }) foreground, _ := theme.ForegroundPattern(theme.PatternState { Case: textBoxCase, Disabled: true, @@ -300,10 +301,10 @@ func (element *TextBox) draw () { } else { // draw input value textBounds := element.valueDrawer.LayoutBounds() - offset := image.Point { + offset := bounds.Min.Add (image.Point { X: theme.Padding() + inset[3] - element.scroll, Y: theme.Padding() + inset[0], - } + }) foreground, _ := theme.ForegroundPattern(theme.PatternState { Case: textBoxCase, Disabled: !element.Enabled(), diff --git a/elements/fun/clock.go b/elements/fun/clock.go index e41c930..facbc8f 100644 --- a/elements/fun/clock.go +++ b/elements/fun/clock.go @@ -84,12 +84,12 @@ func (element *AnalogClock) radialLine ( bounds := element.Bounds() width := float64(bounds.Dx()) / 2 height := float64(bounds.Dy()) / 2 - min := image.Pt ( + min := element.Bounds().Min.Add(image.Pt ( int(math.Cos(radian) * inner * width + width), - int(math.Sin(radian) * inner * height + height)) - max := image.Pt ( + int(math.Sin(radian) * inner * height + height))) + max := element.Bounds().Min.Add(image.Pt ( int(math.Cos(radian) * outer * width + width), - int(math.Sin(radian) * outer * height + height)) + int(math.Sin(radian) * outer * height + height))) // println(min.String(), max.String()) artist.Line(element, source, 1, min, max) } diff --git a/elements/testing/artist.go b/elements/testing/artist.go index 145c629..f9a2290 100644 --- a/elements/testing/artist.go +++ b/elements/testing/artist.go @@ -26,8 +26,8 @@ func NewArtist () (element *Artist) { func (element *Artist) draw () { bounds := element.Bounds() - element.cellBounds.Max.X = bounds.Dx() / 5 - element.cellBounds.Max.Y = (bounds.Dy() - 48) / 8 + element.cellBounds.Max.X = bounds.Min.X + bounds.Dx() / 5 + element.cellBounds.Max.Y = bounds.Min.Y + (bounds.Dy() - 48) / 8 drawStart := time.Now() diff --git a/elements/testing/mouse.go b/elements/testing/mouse.go index c0cdece..421029c 100644 --- a/elements/testing/mouse.go +++ b/elements/testing/mouse.go @@ -36,12 +36,12 @@ func (element *Mouse) draw () { bounds) artist.Line ( element, artist.NewUniform(color.White), 1, - image.Pt(1, 1), - image.Pt(bounds.Dx() - 2, bounds.Dy() - 2)) + bounds.Min.Add(image.Pt(1, 1)), + bounds.Min.Add(image.Pt(bounds.Dx() - 2, bounds.Dy() - 2))) artist.Line ( element, artist.NewUniform(color.White), 1, - image.Pt(1, bounds.Dy() - 2), - image.Pt(bounds.Dx() - 2, 1)) + bounds.Min.Add(image.Pt(1, bounds.Dy() - 2)), + bounds.Min.Add(image.Pt(bounds.Dx() - 2, 1))) } func (element *Mouse) HandleMouseDown (x, y int, button tomo.Button) { diff --git a/layouts/dialog.go b/layouts/dialog.go index fa82d20..f782bb1 100644 --- a/layouts/dialog.go +++ b/layouts/dialog.go @@ -18,13 +18,12 @@ type Dialog struct { Pad bool } -// Arrange arranges a list of entries into a dialog. -func (layout Dialog) Arrange (entries []tomo.LayoutEntry, width, height int) { - if layout.Pad { - width -= theme.Margin() * 2 - height -= theme.Margin() * 2 - } +// FIXME +// Arrange arranges a list of entries into a dialog. +func (layout Dialog) Arrange (entries []tomo.LayoutEntry, bounds image.Rectangle) { + if layout.Pad { bounds = bounds.Inset(theme.Margin()) } + controlRowWidth, controlRowHeight := 0, 0 if len(entries) > 1 { controlRowWidth, @@ -37,19 +36,19 @@ func (layout Dialog) Arrange (entries []tomo.LayoutEntry, width, height int) { entries[0].Bounds.Min.X += theme.Margin() entries[0].Bounds.Min.Y += theme.Margin() } - mainHeight := height - controlRowHeight + mainHeight := bounds.Dy() - controlRowHeight if layout.Gap { mainHeight -= theme.Margin() } mainBounds := entries[0].Bounds - if mainBounds.Dy() != mainHeight || mainBounds.Dx() != width { + if mainBounds.Dy() != mainHeight || mainBounds.Dx() != bounds.Dx() { entries[0].Bounds.Max = - mainBounds.Min.Add(image.Pt(width, mainHeight)) + mainBounds.Min.Add(image.Pt(bounds.Dx(), mainHeight)) } } if len(entries) > 1 { - freeSpace := width + freeSpace := bounds.Dx() expandingElements := 0 // count the number of expanding elements and the amount of free @@ -71,15 +70,15 @@ func (layout Dialog) Arrange (entries []tomo.LayoutEntry, width, height int) { } // determine starting position and dimensions for control row - x, y := 0, height - controlRowHeight + x, y := 0, bounds.Dy() - controlRowHeight if expandingElements == 0 { - x = width - controlRowWidth + x = bounds.Dx() - controlRowWidth } if layout.Pad { x += theme.Margin() y += theme.Margin() } - height -= controlRowHeight + bounds.Max.Y -= controlRowHeight // set the size and position of each element in the control row for index, entry := range entries[1:] { diff --git a/layouts/horizontal.go b/layouts/horizontal.go index 93339fc..3d29518 100644 --- a/layouts/horizontal.go +++ b/layouts/horizontal.go @@ -22,10 +22,9 @@ func (layout Horizontal) Arrange (entries []tomo.LayoutEntry, bounds image.Recta // get width of expanding elements expandingElementWidth := layout.expandingElementWidth(entries, bounds.Dx()) - - dot := bounds.Min // set the size and position of each element + dot := bounds.Min for index, entry := range entries { if index > 0 && layout.Gap { dot.X += theme.Margin() } diff --git a/layouts/vertical.go b/layouts/vertical.go index a400e46..f76b96d 100644 --- a/layouts/vertical.go +++ b/layouts/vertical.go @@ -50,9 +50,8 @@ func (layout Vertical) Arrange (entries []tomo.LayoutEntry, bounds image.Rectang expandingElementHeight = freeSpace / expandingElements } - dot := bounds.Min - // set the size and position of each element + dot := bounds.Min for index, entry := range entries { if index > 0 && layout.Gap { dot.Y += theme.Margin() }