From 7d4ddaf387f98a6c57697aea6cad1d309e5d8761 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Sun, 16 Apr 2023 14:12:55 -0400 Subject: [PATCH] Scrolling over a ScrollContainer will now scroll it --- backends/x/entity.go | 15 +++++++++++++++ backends/x/event.go | 20 +++++++++++--------- backends/x/system.go | 5 +++++ elements/containers/scroll.go | 18 ++++++++++++++++++ 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/backends/x/entity.go b/backends/x/entity.go index c15a797..bc9c7b0 100644 --- a/backends/x/entity.go +++ b/backends/x/entity.go @@ -81,6 +81,21 @@ func (entity *entity) childAt (point image.Point) *entity { return entity } +func (entity *entity) scrollTargetChildAt (point image.Point) *entity { + for _, child := range entity.children { + if point.In(child.bounds) { + result := child.scrollTargetChildAt(point) + if result != nil { return result } + break + } + } + + if _, ok := entity.element.(tomo.ScrollTarget); ok { + return entity + } + return nil +} + // ----------- Entity ----------- // func (entity *entity) Invalidate () { diff --git a/backends/x/event.go b/backends/x/event.go index 73ea3c1..2f573ba 100644 --- a/backends/x/event.go +++ b/backends/x/event.go @@ -190,20 +190,22 @@ func (window *window) handleButtonPress ( insideWindow := point.In(window.canvas.Bounds()) scrolling := buttonEvent.Detail >= 4 && buttonEvent.Detail <= 7 - underneath := window.system.childAt(point) - if !insideWindow && window.shy && !scrolling { window.Close() } else if scrolling { - if child, ok := underneath.element.(tomo.ScrollTarget); ok { - sum := scrollSum { } - sum.add(buttonEvent.Detail, window, buttonEvent.State) - window.compressScrollSum(buttonEvent, &sum) - child.HandleScroll ( - point.X, point.Y, - float64(sum.x), float64(sum.y)) + underneath := window.system.scrollTargetChildAt(point) + if underneath != nil { + if child, ok := underneath.element.(tomo.ScrollTarget); ok { + sum := scrollSum { } + sum.add(buttonEvent.Detail, window, buttonEvent.State) + window.compressScrollSum(buttonEvent, &sum) + child.HandleScroll ( + point.X, point.Y, + float64(sum.x), float64(sum.y)) + } } } else { + underneath := window.system.childAt(point) if child, ok := underneath.element.(tomo.MouseTarget); ok { window.system.drags[buttonEvent.Detail] = child child.HandleMouseDown ( diff --git a/backends/x/system.go b/backends/x/system.go index 84ffa23..78a43b7 100644 --- a/backends/x/system.go +++ b/backends/x/system.go @@ -123,6 +123,11 @@ func (system *system) childAt (point image.Point) *entity { return system.child.childAt(point) } +func (system *system) scrollTargetChildAt (point image.Point) *entity { + if system.child == nil { return nil } + return system.child.scrollTargetChildAt(point) +} + func (system *system) resizeChildToFit () { system.child.bounds = system.canvas.Bounds() system.child.clippedBounds = system.child.bounds diff --git a/elements/containers/scroll.go b/elements/containers/scroll.go index 5c420c4..b83fc47 100644 --- a/elements/containers/scroll.go +++ b/elements/containers/scroll.go @@ -148,6 +148,16 @@ func (element *Scroll) HandleChildScrollBoundsChange (tomo.Scrollable) { } } +func (element *Scroll) HandleScroll ( + x, y int, + deltaX, deltaY float64, +) { + horizontal, vertical := element.child.ScrollAxes() + if !horizontal { deltaX = 0 } + if !vertical { deltaY = 0 } + element.scrollChildBy(int(deltaX), int(deltaY)) +} + func (element *Scroll) SetTheme (theme tomo.Theme) { if theme == element.theme.Theme { return } element.theme.Theme = theme @@ -195,3 +205,11 @@ func (element *Scroll) updateEnabled () { element.vertical.SetEnabled(vertical) } } + +func (element *Scroll) scrollChildBy (x, y int) { + if element.child == nil { return } + scrollPoint := + element.child.ScrollViewportBounds().Min. + Add(image.Pt(x, y)) + element.child.ScrollTo(scrollPoint) +}