diff --git a/scrollbar.go b/scrollbar.go index 6e86709..76a5960 100644 --- a/scrollbar.go +++ b/scrollbar.go @@ -65,7 +65,11 @@ func (this *Scrollbar) Link (box tomo.ContentBox) event.Cookie { } func (this *Scrollbar) handleLinkedContentBoundsChange () { - // TODO + if this.layout.linked == 0 { return } + this.layout.value = + this.layout.contentPos() / + (this.layout.contentLength() - this.layout.viewportLength()) + this.SetLayout(this.layout) } // SetValue sets the value of the scrollbar between 0 and 1, where 0 is scrolled @@ -79,13 +83,13 @@ func (this *Scrollbar) SetValue (value float64) { // all the way to the left/top, and 1 is scrolled all the way to the // right/bottom. func (this *Scrollbar) Value () float64 { - // TODO - return 0 + if this.layout.linked == nil { return 0 } + return this.layout.value } // OnValueChange specifies a function to be called when the position of the // scrollbar changes. -func (this *Slider) OnValueChange (callback func ()) event.Cookie { +func (this *Scrollbar) OnValueChange (callback func ()) event.Cookie { return this.on.valueChange.Connect(callback) } @@ -216,7 +220,8 @@ func (this *scrollbarCookie) Close () { type scrollbarLayout struct { vertical bool - linked tomo.ContentBox + value float64 + linked tomo.ContentBox } func (scrollbarLayout) MinimumSize (hints tomo.LayoutHints, boxes []tomo.Box) image.Point { @@ -229,13 +234,40 @@ func (this scrollbarLayout) Arrange (hints tomo.LayoutHints, boxes []tomo.Box) { handle := image.Rectangle { Max: boxes[0].MinimumSize() } gutter := hints.Bounds + // TODO - // - get length of viewport as a percent of length of content - // - apply percent to length of gutter + // - apply (viewportContentRatio) to length of gutter // - constrain to minimum length of handle - // - set handle to length - // - get scroll of content as a percent - // - content pos relative to (content length minus viewport length) - // - apply percent to length of gutter minus length of handler + // - set handle to constrained length + // - apply (value) to length of gutter minus length of handle // - that is the handle position } + +func (this scrollbarLayout) viewportContentRatio () float64 { + if this.linked == nil { return 0 } + return this.viewportLength / this.contentLength +} + +func (this scrollbarLayout) viewportLength () float64 { + if this.vertical { + return float64(this.linked.InnerBounds().Dy()) + } else { + return float64(this.linked.InnerBounds().Dx()) + } +} + +func (this scrollbarLayout) contentLength () float64 { + if this.vertical { + return float64(this.linked.ContentBounds().Dy()) + } else { + return float64(this.linked.ContentBounds().Dx()) + } +} + +func (this scrollbarLayout) contentPos () float64 { + if this.vertical { + return float64(this.linked.ContentBounds().Min.Y) + } else { + return float64(this.linked.ContentBounds().Min.X) + } +}