clui/label.go

174 lines
4.3 KiB
Go
Raw Normal View History

2015-09-21 20:54:39 -07:00
package clui
2015-10-16 10:27:43 -07:00
import (
2015-10-20 09:43:56 -07:00
xs "github.com/huandu/xstrings"
2019-05-07 10:36:30 +03:00
мКнст "./пакКонстанты"
2015-10-16 10:27:43 -07:00
)
2015-09-21 20:54:39 -07:00
2015-10-28 17:57:05 -07:00
/*
Label is a decorative control that can display text in horizontal
or vertical direction. Other available text features are alignment
and multi-line ability. Text can be single- or multi-colored with
tags inside the text. Multi-colored strings have limited support
of alignment feature: if text is longer than Label width the text
is always left aligned
*/
2015-10-16 10:27:43 -07:00
type Label struct {
BaseControl
2019-05-07 10:36:30 +03:00
direction мКнст.Direction
2018-08-04 21:18:33 -07:00
multiline bool
2019-05-07 10:36:30 +03:00
textDisplay мКнст.Align
2015-09-21 20:54:39 -07:00
}
2015-10-28 17:57:05 -07:00
/*
2019-05-07 11:21:00 +03:00
CreateLabel creates a new label.
2015-10-28 17:57:05 -07:00
view - is a View that manages the control
parent - is container that keeps the control. The same View can be a view and a parent at the same time.
w and h - are minimal size of the control.
title - is Label title.
scale - the way of scaling the control when the parent is resized. Use DoNotScale constant if the
control should keep its original size.
*/
func CreateLabel(parent Control, w, h int, title string, scale int) *Label {
2015-10-16 10:27:43 -07:00
c := new(Label)
c.BaseControl = NewBaseControl()
2015-09-21 20:54:39 -07:00
2019-05-07 10:58:24 +03:00
if w == мКнст.AutoSize {
2015-10-20 09:43:56 -07:00
w = xs.Len(title)
}
2019-05-07 10:58:24 +03:00
if h == мКнст.AutoSize {
2015-10-20 09:43:56 -07:00
h = 1
}
2015-10-16 10:27:43 -07:00
c.parent = parent
2015-09-21 20:54:39 -07:00
2015-10-16 10:27:43 -07:00
c.SetTitle(title)
c.SetSize(w, h)
c.SetConstraints(w, h)
c.SetScale(scale)
2015-10-16 10:27:43 -07:00
c.tabSkip = true
2019-05-07 10:58:24 +03:00
c.textDisplay = мКнст.AlignLeft
2015-09-21 20:54:39 -07:00
2015-10-16 10:27:43 -07:00
if parent != nil {
parent.AddChild(c)
2015-09-21 20:54:39 -07:00
}
2015-10-16 10:27:43 -07:00
return c
2015-09-21 20:54:39 -07:00
}
2015-10-28 17:57:05 -07:00
// Direction returns direction of text output: vertical or horizontal
2019-05-07 10:36:30 +03:00
func (l *Label) Direction() мКнст.Direction {
return l.direction
}
2015-10-28 17:57:05 -07:00
// SetDirection sets the text output direction
2019-05-07 10:36:30 +03:00
func (l *Label) SetDirection(dir мКнст.Direction) {
l.direction = dir
}
func (l *Label) Draw() {
2018-03-13 22:14:40 -07:00
if l.hidden {
return
}
PushAttributes()
defer PopAttributes()
2015-10-19 12:05:43 -07:00
2019-05-07 10:58:24 +03:00
fg, bg := RealColor(l.fg, l.Style(), мКнст.ColorText), RealColor(l.bg, l.Style(), мКнст.ColorBack)
2015-10-19 12:05:43 -07:00
if !l.Enabled() {
2019-05-07 10:58:24 +03:00
fg = RealColor(l.fg, l.Style(), мКнст.ColorDisabledText)
2015-10-19 12:05:43 -07:00
}
2015-09-21 20:54:39 -07:00
SetTextColor(fg)
SetBackColor(bg)
FillRect(l.x, l.y, l.width, l.height, ' ')
2015-09-21 20:54:39 -07:00
if l.title == "" {
return
}
2015-10-21 13:59:23 -07:00
if l.multiline {
parser := NewColorParser(l.title, fg, bg)
elem := parser.NextElement()
xx, yy := l.x, l.y
for elem.Type != ElemEndOfText {
if xx >= l.x+l.width || yy >= l.y+l.height {
break
2015-10-21 13:59:23 -07:00
}
if elem.Type == ElemLineBreak {
xx = l.x
yy += 1
} else if elem.Type == ElemPrintable {
SetTextColor(elem.Fg)
SetBackColor(elem.Bg)
putCharUnsafe(xx, yy, elem.Ch)
2019-05-07 10:58:24 +03:00
if l.direction == мКнст.Horizontal {
xx++
if xx >= l.x+l.width {
xx = l.x
2019-05-07 10:58:24 +03:00
yy++
}
} else {
2019-05-07 10:58:24 +03:00
yy++
if yy >= l.y+l.height {
yy = l.y
2019-05-07 10:58:24 +03:00
xx++
}
}
2015-10-21 13:59:23 -07:00
}
elem = parser.NextElement()
2015-10-21 13:59:23 -07:00
}
} else {
2019-05-07 10:58:24 +03:00
if l.direction == мКнст.Horizontal {
shift, str := AlignColorizedText(l.title, l.width, l.align)
2018-08-04 21:18:33 -07:00
if str != l.title && l.align != l.textDisplay {
shift, str = AlignColorizedText(l.title, l.width, l.textDisplay)
}
DrawText(l.x+shift, l.y, str)
2015-10-21 13:59:23 -07:00
} else {
shift, str := AlignColorizedText(l.title, l.height, l.align)
2018-08-04 21:18:33 -07:00
if str != l.title && l.align != l.textDisplay {
shift, str = AlignColorizedText(l.title, l.width, l.textDisplay)
}
DrawTextVertical(l.x, l.y+shift, str)
2015-10-21 13:59:23 -07:00
}
}
2015-09-21 20:54:39 -07:00
}
2015-10-21 13:59:23 -07:00
2015-10-28 17:57:05 -07:00
// Multiline returns if text is displayed on several lines if the
// label title is longer than label width or title contains
// line breaks
2015-10-21 13:59:23 -07:00
func (l *Label) Multiline() bool {
return l.multiline
}
2015-10-28 17:57:05 -07:00
// SetMultiline sets if the label should output text as one line
// or automatically display it in several lines
2015-10-21 13:59:23 -07:00
func (l *Label) SetMultiline(multi bool) {
l.multiline = multi
}
2018-08-04 21:18:33 -07:00
// TextDisplay returns which part of the lable title is displayed in case of
// title is longer than the label:
// - AlignLeft - the head of the title is shown
// - AlignRight - the tail of the title is shown
// The property is used only by single line Label
2019-05-07 10:36:30 +03:00
func (l *Label) TextDisplay() мКнст.Align {
2018-08-04 21:18:33 -07:00
return l.textDisplay
}
// SetTextDisplay sets which part of the title is displayed in case of the title
// is longer than the lable. Only AlignLeft and AlignRigth are valid values
// for the property. Any other value does is skipped and does not affect
// displaying the title
2019-05-07 10:36:30 +03:00
func (l *Label) SetTextDisplay(align мКнст.Align) {
2019-05-07 10:58:24 +03:00
if align != мКнст.AlignLeft && align != мКнст.AlignRight {
2018-08-04 21:18:33 -07:00
return
}
l.textDisplay = align
}