Added mouse wheel implementation (scrollbar & overflow).

Fixed bug in length of scrollbar handle.
This commit is contained in:
Sander Schobers 2019-03-05 22:42:57 +01:00
parent 19daffd110
commit ff2ece7d06
7 changed files with 33 additions and 2 deletions

View File

@ -57,7 +57,7 @@ func (r *Renderer) PushEvents(t ui.EventTarget, wait bool) {
case *allg5.MouseButtonUpEvent: case *allg5.MouseButtonUpEvent:
t.Handle(&ui.MouseButtonUpEvent{MouseEvent: mouseEvent(e.MouseEvent), Button: ui.MouseButton(e.Button)}) t.Handle(&ui.MouseButtonUpEvent{MouseEvent: mouseEvent(e.MouseEvent), Button: ui.MouseButton(e.Button)})
case *allg5.MouseMoveEvent: case *allg5.MouseMoveEvent:
t.Handle(&ui.MouseMoveEvent{MouseEvent: mouseEvent(e.MouseEvent)}) t.Handle(&ui.MouseMoveEvent{MouseEvent: mouseEvent(e.MouseEvent), MouseWheel: float32(e.DeltaZ)})
} }
ev = r.eq.Get() ev = r.eq.Get()
} }

View File

@ -11,6 +11,7 @@ type Control interface {
Render(Context) Render(Context)
Bounds() geom.RectangleF32 Bounds() geom.RectangleF32
Offset() geom.PointF32
OnClick(ClickFn) OnClick(ClickFn)
OnDragStart(DragStartFn) OnDragStart(DragStartFn)
OnDragMove(DragMoveFn) OnDragMove(DragMoveFn)

View File

@ -97,6 +97,8 @@ func (c *ControlBase) IsOver() bool { return c.over }
func (c *ControlBase) IsPressed() bool { return c.pressed } func (c *ControlBase) IsPressed() bool { return c.pressed }
func (c *ControlBase) Offset() geom.PointF32 { return c.offset }
func (c *ControlBase) OnClick(fn ClickFn) { func (c *ControlBase) OnClick(fn ClickFn) {
c.onClick = fn c.onClick = fn
} }

View File

@ -47,4 +47,5 @@ func (e *MouseEvent) Pos() geom.PointF32 {
type MouseMoveEvent struct { type MouseMoveEvent struct {
MouseEvent MouseEvent
MouseWheel float32
} }

View File

@ -14,6 +14,7 @@ type overflow struct {
barWidth float32 barWidth float32
desired geom.PointF32 desired geom.PointF32
bounds geom.RectangleF32 bounds geom.RectangleF32
offset geom.PointF32
buffer Image buffer Image
hor *Scrollbar hor *Scrollbar
@ -61,6 +62,7 @@ func (o *overflow) Arrange(ctx Context, bounds geom.RectangleF32, offset geom.Po
o.barWidth = ctx.Style().Dimensions.ScrollbarWidth o.barWidth = ctx.Style().Dimensions.ScrollbarWidth
o.desired = o.Content.DesiredSize(ctx) o.desired = o.Content.DesiredSize(ctx)
o.bounds = bounds o.bounds = bounds
o.offset = offset
var hor, ver = o.shouldScroll(bounds) var hor, ver = o.shouldScroll(bounds)
var contentX, contentY float32 = 0, 0 var contentX, contentY float32 = 0, 0
@ -92,9 +94,23 @@ func (o *overflow) Handle(ctx Context, e Event) {
if ver { if ver {
o.ver.Handle(ctx, e) o.ver.Handle(ctx, e)
} }
switch e := e.(type) {
case *MouseMoveEvent:
if ver {
var contentO = o.Content.Offset()
var content = o.Content.Bounds()
content.Min = contentO
content.Max = content.Max.Add(contentO)
if e.MouseWheel != 0 && e.Pos().In(content) {
o.ver.Offset = geom.Max32(0, geom.Min32(o.ver.Content-content.Dy(), o.ver.Offset-36*e.MouseWheel))
}
}
}
o.Content.Handle(ctx, e) o.Content.Handle(ctx, e)
} }
func (o *overflow) Offset() geom.PointF32 { return o.offset }
func (o *overflow) Render(ctx Context) { func (o *overflow) Render(ctx Context) {
var renderer = ctx.Renderer() var renderer = ctx.Renderer()

View File

@ -28,6 +28,8 @@ func (p *Proxy) Bounds() geom.RectangleF32 {
return p.Content.Bounds() return p.Content.Bounds()
} }
func (p *Proxy) Offset() geom.PointF32 { return p.Content.Offset() }
func (p *Proxy) OnClick(fn ClickFn) { func (p *Proxy) OnClick(fn ClickFn) {
p.Content.OnClick(fn) p.Content.OnClick(fn)
} }

View File

@ -43,6 +43,12 @@ func (s *Scrollbar) DesiredSize(ctx Context) geom.PointF32 {
func (s *Scrollbar) Handle(ctx Context, e Event) { func (s *Scrollbar) Handle(ctx Context, e Event) {
s.handle.Handle(ctx, e) s.handle.Handle(ctx, e)
switch e := e.(type) {
case *MouseMoveEvent:
if e.MouseWheel != 0 && e.Pos().Sub(s.offset).In(s.bounds) {
s.Offset = geom.Max32(0, geom.Min32(s.Content-s.Orientation.SizeParallel(s.bounds), s.Offset-36*e.MouseWheel))
}
}
s.ControlBase.Handle(ctx, e) s.ControlBase.Handle(ctx, e)
} }
@ -56,8 +62,11 @@ func (s *Scrollbar) updateBar(ctx Context) {
var handleLength = length var handleLength = length
var handleOffset = s.Orientation.LengthParallel(s.bounds.Min) var handleOffset = s.Orientation.LengthParallel(s.bounds.Min)
if s.Content > length { if s.Content > length {
handleLength = geom.Max32(2*width, length/s.Content) handleLength = geom.Max32(2*width, length*length/s.Content)
var hidden = s.Content - length var hidden = s.Content - length
if s.Offset > hidden {
s.Offset = hidden
}
var offset = geom.Min32(1, s.Offset/hidden) var offset = geom.Min32(1, s.Offset/hidden)
handleOffset = handleOffset + offset*(length-handleLength) handleOffset = handleOffset + offset*(length-handleLength)
} }