Got scroll container working

This commit is contained in:
Sasha Koshka 2023-01-31 18:39:17 -05:00
parent 541d0f4204
commit 9b22e80f05
10 changed files with 52 additions and 42 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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(),

View File

@ -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)
}

View File

@ -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()

View File

@ -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) {

View File

@ -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:] {

View File

@ -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() }

View File

@ -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() }