diff --git a/input.go b/input.go index 6c980fe..0c60f9e 100644 --- a/input.go +++ b/input.go @@ -20,6 +20,7 @@ type TextInput struct { func NewTextInput (text string) *TextInput { this := &TextInput { TextBox: tomo.NewTextBox() } theme.Apply(this, theme.R("objects", "TextInput", "")) + this.SetAlign(tomo.AlignStart, tomo.AlignMiddle) this.SetText(text) this.SetFocusable(true) this.SetSelectable(true) @@ -53,6 +54,9 @@ func (this *TextInput) handleKeyDown (key input.Key, numpad bool) { sel := modifiers.Shift changed := false + // TODO all this (except editing stuff) really should be moved into the + // backend + switch { case key == input.KeyEnter: this.on.enter.Broadcast() diff --git a/label.go b/label.go index 7491e8c..0108a30 100644 --- a/label.go +++ b/label.go @@ -15,4 +15,3 @@ func NewLabel (text string) *Label { this.SetText(text) return this } - diff --git a/scrollbar.go b/scrollbar.go index 826837f..abcfd7d 100644 --- a/scrollbar.go +++ b/scrollbar.go @@ -173,15 +173,15 @@ func (this *Scrollbar) handleMouseDown (button input.Button) { } case input.ButtonMiddle: if above { - this.SetValue(0) + this.scrollBy(-this.pageSize()) } else { - this.SetValue(1) + this.scrollBy(this.pageSize()) } case input.ButtonRight: if above { - this.SetValue(this.Value() - 0.05) + this.scrollBy(-this.stepSize()) } else { - this.SetValue(this.Value() + 0.05) + this.scrollBy(this.stepSize()) } } } @@ -229,6 +229,34 @@ func (this *Scrollbar) fallbackDragOffset () image.Point { } } +func (this *Scrollbar) pageSize () int { + if this.layout.linked == nil { return 0 } + viewport := this.layout.linked.InnerBounds() + if this.layout.vertical { + return viewport.Dy() + } else { + return viewport.Dx() + } +} + +func (this *Scrollbar) stepSize () int { + // FIXME: this should not be hardcoded, need to get base font metrics + // from theme somehow. should be (emspace, lineheight) + return 16 +} + +func (this *Scrollbar) scrollBy (distance int) { + if this.layout.linked == nil { return } + var vector image.Point; if this.layout.vertical { + vector.Y = distance + } else { + vector.X = distance + } + this.layout.linked.ScrollTo ( + this.layout.linked.ContentBounds().Min. + Add(vector)) +} + type scrollbarCookie struct { owner *Scrollbar subCookies []event.Cookie diff --git a/textview.go b/textview.go new file mode 100644 index 0000000..846deb2 --- /dev/null +++ b/textview.go @@ -0,0 +1,27 @@ +package objects + +import "image" +import "git.tebibyte.media/tomo/tomo" +import "git.tebibyte.media/tomo/tomo/theme" + +// TextView is an area for displaying a large amount of multi-line text. +type TextView struct { + tomo.TextBox +} + +// NewTextView creates a new text view. +func NewTextView (text string) *TextView { + this := &TextView { TextBox: tomo.NewTextBox() } + theme.Apply(this, theme.R("objects", "TextView", "")) + this.SetFocusable(true) + this.SetSelectable(true) + this.SetText(text) + this.SetOverflow(false, true) + this.SetWrap(true) + this.OnScroll(this.handleScroll) + return this +} + +func (this *TextView) handleScroll (x, y float64) { + this.ScrollTo(this.ContentBounds().Min.Add(image.Pt(int(x), int(y)))) +}