From 3ddeeb546926ccc75f7a867dcbc77fcfc1ce89a3 Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Tue, 10 Jan 2023 21:01:30 -0500 Subject: [PATCH] You can choose whether or not you want text to wrap --- artist/text.go | 15 +++++++++++ elements/basic/label.go | 45 ++++++++++++++++++++++++++++----- examples/label/main.go | 2 +- examples/verticalLayout/main.go | 4 +-- 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/artist/text.go b/artist/text.go index ef75143..500c552 100644 --- a/artist/text.go +++ b/artist/text.go @@ -137,6 +137,21 @@ func (drawer *TextDrawer) LayoutBounds () (bounds image.Rectangle) { return } +// Em returns the width of an emspace. +func (drawer *TextDrawer) Em () (width fixed.Int26_6) { + if drawer.face == nil { return } + width, _ = drawer.face.GlyphAdvance('M') + return +} + +// LineHeight returns the height of one line. +func (drawer *TextDrawer) LineHeight () (height fixed.Int26_6) { + if drawer.face == nil { return } + metrics := drawer.face.Metrics() + height = metrics.Height + return +} + func (drawer *TextDrawer) recalculate () { drawer.layoutClean = true drawer.layout = nil diff --git a/elements/basic/label.go b/elements/basic/label.go index 01728ab..4a6bb04 100644 --- a/elements/basic/label.go +++ b/elements/basic/label.go @@ -6,28 +6,29 @@ import "git.tebibyte.media/sashakoshka/tomo/theme" import "git.tebibyte.media/sashakoshka/tomo/artist" import "git.tebibyte.media/sashakoshka/tomo/elements/core" +// Label is a simple text box. type Label struct { *core.Core core core.CoreControl - + + wrap bool text string drawer artist.TextDrawer } -func NewLabel (text string) (element *Label) { +// NewLabel creates a new label. If wrap is set to true, the text inside will be +// wrapped. +func NewLabel (text string, wrap bool) (element *Label) { element = &Label { } element.Core, element.core = core.NewCore(element) face := theme.FontFaceRegular() element.drawer.SetFace(face) + element.SetWrap(wrap) element.SetText(text) - metrics := face.Metrics() - emspace, _ := face.GlyphAdvance('M') - intEmspace := emspace.Round() - if intEmspace < 1 { intEmspace = theme.Padding()} - element.core.SetMinimumSize(intEmspace, metrics.Height.Round()) return } +// Handle handles and event. func (element *Label) Handle (event tomo.Event) { switch event.(type) { case tomo.EventResize: @@ -42,17 +43,47 @@ func (element *Label) Handle (event tomo.Event) { return } +// SetText sets the label's text. func (element *Label) SetText (text string) { if element.text == text { return } element.text = text element.drawer.SetText(text) + element.updateMinimumSize() + if element.core.HasImage () { element.draw() element.core.PushAll() } } +// SetWrap sets wether or not the label's text wraps. If the text is set to +// wrap, the element will have a minimum size of a single character and +// automatically wrap its text. If the text is set to not wrap, the element will +// have a minimum size that fits its text. +func (element *Label) SetWrap (wrap bool) { + if wrap == element.wrap { return } + element.wrap = wrap + element.updateMinimumSize() + + if element.core.HasImage () { + element.draw() + element.core.PushAll() + } +} + +func (element *Label) updateMinimumSize () { + if element.wrap { + em := element.drawer.Em().Round() + if em < 1 { em = theme.Padding() } + element.core.SetMinimumSize ( + em, element.drawer.LineHeight().Round()) + } else { + bounds := element.drawer.LayoutBounds() + element.core.SetMinimumSize(bounds.Dx(), bounds.Dy()) + } +} + func (element *Label) AdvanceSelection (direction int) (ok bool) { return } diff --git a/examples/label/main.go b/examples/label/main.go index 7c6a1f8..3e5611e 100644 --- a/examples/label/main.go +++ b/examples/label/main.go @@ -11,7 +11,7 @@ func main () { func run () { window, _ := tomo.NewWindow(480, 360) window.SetTitle("example label") - window.Adopt(basic.NewLabel(text)) + window.Adopt(basic.NewLabel(text, true)) window.OnClose(tomo.Stop) window.Show() } diff --git a/examples/verticalLayout/main.go b/examples/verticalLayout/main.go index b111aac..01c296e 100644 --- a/examples/verticalLayout/main.go +++ b/examples/verticalLayout/main.go @@ -16,12 +16,12 @@ func run () { container := basic.NewContainer(layouts.Vertical { true, true }) window.Adopt(container) - label := basic.NewLabel("it is a label hehe") + label := basic.NewLabel("it is a label hehe", false) button := basic.NewButton("drawing pad") okButton := basic.NewButton("OK") button.OnClick (func () { container.DisownAll() - container.Adopt(basic.NewLabel("Draw here:"), false) + container.Adopt(basic.NewLabel("Draw here:", false), false) container.Adopt(basic.NewTest(), true) container.Adopt(okButton, false) })