You can choose whether or not you want text to wrap

This commit is contained in:
Sasha Koshka 2023-01-10 21:01:30 -05:00
parent a79f2eaf64
commit 3ddeeb5469
4 changed files with 56 additions and 10 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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()
}

View File

@ -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)
})