feat(FormItem): Replace `SetFormAttributes` with `SetAttributes`

BREAKING CHANGE:
`SetFormAttributes` has been removed. To migrate your project, use `SetAttributes` which expects any combination of attribute setters.
Example:
`formItem.SetAttributes(cview.WithLabelWidth(10), cview.WithLabelColor(tcell.ColorYellow))`
or
`formItem.SetAttributes(cview.WithBackgroundColor(tcell.ColorBlack))`
This commit is contained in:
Andreas Bieber 2020-09-19 20:15:27 +02:00
parent 1d019e9697
commit 70857602a5
4 changed files with 231 additions and 70 deletions

View File

@ -135,6 +135,24 @@ func (c *CheckBox) GetMessage() string {
return c.message
}
// SetAttributes sets the given attributes on the check box.
func (c *CheckBox) SetAttributes(attributes ...FormItemAttribute) {
allAttributes := newFormItemAttributes()
for _, attribute := range attributes {
attribute.apply(allAttributes)
}
allAttributes.setLabelWidth(&c.labelWidth)
allAttributes.setBackgroundColor(&c.backgroundColor)
allAttributes.setLabelColor(&c.labelColor)
allAttributes.setLabelColorFocused(&c.labelColorFocused)
allAttributes.setFieldTextColor(&c.fieldTextColor)
allAttributes.setFieldTextColorFocused(&c.fieldTextColorFocused)
allAttributes.setFieldBackgroundColor(&c.fieldBackgroundColor)
allAttributes.setFieldBackgroundColorFocused(&c.fieldBackgroundColorFocused)
allAttributes.setFinishedFunc(&c.finished)
}
// SetLabelWidth sets the screen width of the label. A value of 0 will cause the
// primitive to use the width of the label string.
func (c *CheckBox) SetLabelWidth(width int) *CheckBox {
@ -145,6 +163,12 @@ func (c *CheckBox) SetLabelWidth(width int) *CheckBox {
return c
}
// SetBackgroundColor sets the background color.
func (c *CheckBox) SetBackgroundColor(color tcell.Color) *CheckBox {
c.Box.SetBackgroundColor(color)
return c
}
// SetLabelColor sets the color of the label.
func (c *CheckBox) SetLabelColor(color tcell.Color) *CheckBox {
c.Lock()
@ -199,22 +223,6 @@ func (c *CheckBox) SetFieldTextColorFocused(color tcell.Color) *CheckBox {
return c
}
// SetFormAttributes sets attributes shared by all form items.
func (c *CheckBox) SetFormAttributes(labelWidth int, bgColor, labelColor, labelColorFocused, fieldTextColor, fieldTextColorFocused, fieldBgColor, fieldBgColorFocused tcell.Color) FormItem {
c.Lock()
defer c.Unlock()
c.labelWidth = labelWidth
c.backgroundColor = bgColor
c.labelColor = labelColor
c.labelColorFocused = labelColorFocused
c.fieldTextColor = fieldTextColor
c.fieldTextColorFocused = fieldTextColorFocused
c.fieldBackgroundColor = fieldBgColor
c.fieldBackgroundColorFocused = fieldBgColorFocused
return c
}
// GetFieldHeight returns the height of the field.
func (c *CheckBox) GetFieldHeight() int {
return 1
@ -259,7 +267,7 @@ func (c *CheckBox) SetDoneFunc(handler func(key tcell.Key)) *CheckBox {
}
// SetFinishedFunc sets a callback invoked when the user leaves this form item.
func (c *CheckBox) SetFinishedFunc(handler func(key tcell.Key)) FormItem {
func (c *CheckBox) SetFinishedFunc(handler func(key tcell.Key)) *CheckBox {
c.Lock()
defer c.Unlock()

View File

@ -266,6 +266,24 @@ func (d *DropDown) GetLabel() string {
return d.label
}
// SetAttributes sets the given attributes on the drop down.
func (d *DropDown) SetAttributes(attributes ...FormItemAttribute) {
allAttributes := newFormItemAttributes()
for _, attribute := range attributes {
attribute.apply(allAttributes)
}
allAttributes.setLabelWidth(&d.labelWidth)
allAttributes.setBackgroundColor(&d.backgroundColor)
allAttributes.setLabelColor(&d.labelColor)
allAttributes.setLabelColorFocused(&d.labelColorFocused)
allAttributes.setFieldTextColor(&d.fieldTextColor)
allAttributes.setFieldTextColorFocused(&d.fieldTextColorFocused)
allAttributes.setFieldBackgroundColor(&d.fieldBackgroundColor)
allAttributes.setFieldBackgroundColorFocused(&d.fieldBackgroundColorFocused)
allAttributes.setFinishedFunc(&d.finished)
}
// SetLabelWidth sets the screen width of the label. A value of 0 will cause the
// primitive to use the width of the label string.
func (d *DropDown) SetLabelWidth(width int) *DropDown {
@ -276,6 +294,12 @@ func (d *DropDown) SetLabelWidth(width int) *DropDown {
return d
}
// SetBackgroundColor sets the background color.
func (d *DropDown) SetBackgroundColor(color tcell.Color) *DropDown {
d.Box.SetBackgroundColor(color)
return d
}
// SetLabelColor sets the color of the label.
func (d *DropDown) SetLabelColor(color tcell.Color) *DropDown {
d.Lock()
@ -377,22 +401,6 @@ func (d *DropDown) SetPrefixTextColor(color tcell.Color) *DropDown {
return d
}
// SetFormAttributes sets attributes shared by all form items.
func (d *DropDown) SetFormAttributes(labelWidth int, bgColor, labelColor, labelColorFocused, fieldTextColor, fieldTextColorFocused, fieldBgColor, fieldBgColorFocused tcell.Color) FormItem {
d.Lock()
defer d.Unlock()
d.labelWidth = labelWidth
d.backgroundColor = bgColor
d.labelColor = labelColor
d.labelColorFocused = labelColorFocused
d.fieldTextColor = fieldTextColor
d.fieldTextColorFocused = fieldTextColorFocused
d.fieldBackgroundColor = fieldBgColor
d.fieldBackgroundColorFocused = fieldBgColorFocused
return d
}
// SetFieldWidth sets the screen width of the options area. A value of 0 means
// extend to as long as the longest option text.
func (d *DropDown) SetFieldWidth(width int) *DropDown {
@ -514,7 +522,7 @@ func (d *DropDown) SetDoneFunc(handler func(key tcell.Key)) *DropDown {
}
// SetFinishedFunc sets a callback invoked when the user leaves this form item.
func (d *DropDown) SetFinishedFunc(handler func(key tcell.Key)) FormItem {
func (d *DropDown) SetFinishedFunc(handler func(key tcell.Key)) *DropDown {
d.Lock()
defer d.Unlock()

175
form.go
View File

@ -11,6 +11,149 @@ import (
// horizontal layouts.
var DefaultFormFieldWidth = 10
// FormItemAttribute represents a form attribute.
type FormItemAttribute interface {
apply(attributes *formItemAttributes)
}
// formItemAttributes is a set of attribute setters to be applied.
type formItemAttributes struct {
setLabelWidth func(width *int)
setBackgroundColor func(color *tcell.Color)
setLabelColor func(color *tcell.Color)
setLabelColorFocused func(color *tcell.Color)
setFieldTextColor func(color *tcell.Color)
setFieldTextColorFocused func(color *tcell.Color)
setFieldBackgroundColor func(color *tcell.Color)
setFieldBackgroundColorFocused func(color *tcell.Color)
setFinishedFunc func(handler *func(key tcell.Key))
}
func newFormItemAttributes() *formItemAttributes {
return &formItemAttributes{
setLabelWidth: func(_ *int) {},
setBackgroundColor: func(_ *tcell.Color) {},
setLabelColor: func(_ *tcell.Color) {},
setLabelColorFocused: func(_ *tcell.Color) {},
setFieldTextColor: func(_ *tcell.Color) {},
setFieldTextColorFocused: func(_ *tcell.Color) {},
setFieldBackgroundColor: func(_ *tcell.Color) {},
setFieldBackgroundColorFocused: func(_ *tcell.Color) {},
setFinishedFunc: func(_ *func(key tcell.Key)) {},
}
}
// funcFormItemAttribute holds the attribute setter.
type funcFormItemAttribute struct {
f func(*formItemAttributes)
}
// apply invokes the attribute setter.
func (fdo *funcFormItemAttribute) apply(do *formItemAttributes) {
fdo.f(do)
}
// newFuncAttribute creates a new funcFormItemAttribute.
func newFuncAttribute(f func(*formItemAttributes)) *funcFormItemAttribute {
return &funcFormItemAttribute{
f: f,
}
}
// WithLabelWidth creates a form item attribute promise with the given value to be set.
// When applied, sets the screen width of the label. A value of 0 will cause the
// primitive to use the width of the label string.
func WithLabelWidth(labelWidth int) FormItemAttribute {
return newFuncAttribute(func(o *formItemAttributes) {
o.setLabelWidth = func(width *int) {
*width = labelWidth
}
})
}
// WithBackgroundColor creates a form item attribute promise with the given value to be set.
// When applied, sets the background color.
func WithBackgroundColor(color tcell.Color) FormItemAttribute {
return newFuncAttribute(func(o *formItemAttributes) {
o.setBackgroundColor = func(backgroundColor *tcell.Color) {
*backgroundColor = color
}
})
}
// WithLabelColor creates a form item attribute promise with the given value to be set.
// When applied, sets the color of the label.
func WithLabelColor(color tcell.Color) FormItemAttribute {
return newFuncAttribute(func(o *formItemAttributes) {
o.setLabelColor = func(labelColor *tcell.Color) {
*labelColor = color
}
})
}
// WithLabelColorFocused creates a form item attribute promise with the given value to be set.
// When applied, sets the color of the label when focused.
func WithLabelColorFocused(color tcell.Color) FormItemAttribute {
return newFuncAttribute(func(o *formItemAttributes) {
o.setLabelColorFocused = func(labelColorFocused *tcell.Color) {
*labelColorFocused = color
}
})
}
// WithFieldTextColor creates a form item attribute promise with the given value to be set.
// When applied, sets the text color of the input area.
func WithFieldTextColor(color tcell.Color) FormItemAttribute {
return newFuncAttribute(func(o *formItemAttributes) {
o.setFieldTextColor = func(fieldTextColor *tcell.Color) {
*fieldTextColor = color
}
})
}
// WithFieldTextColorFocused creates a form item attribute promise with the given value to be set.
// When applied, sets the text color of the input area when focused.
func WithFieldTextColorFocused(color tcell.Color) FormItemAttribute {
return newFuncAttribute(func(o *formItemAttributes) {
o.setFieldTextColorFocused = func(fieldTextColorFocused *tcell.Color) {
*fieldTextColorFocused = color
}
})
}
// WithFieldBackgroundColor creates a form item attribute promise with the given value to be set.
// When applied, sets the background color of the input area.
func WithFieldBackgroundColor(color tcell.Color) FormItemAttribute {
return newFuncAttribute(func(o *formItemAttributes) {
o.setFieldBackgroundColor = func(fieldBackgroundColor *tcell.Color) {
*fieldBackgroundColor = color
}
})
}
// WithFieldBackgroundColorFocused creates a form item attribute promise with the given value to be set.
// When applied, sets the background color of the input area when focused.
func WithFieldBackgroundColorFocused(color tcell.Color) FormItemAttribute {
return newFuncAttribute(func(o *formItemAttributes) {
o.setFieldBackgroundColorFocused = func(fieldBackgroundColorFocused *tcell.Color) {
*fieldBackgroundColorFocused = color
}
})
}
// WithFieldBackgroundColorFocused creates a form item attribute promise with the given value to be set.
// When applied, sets the handler function for when the user finished
// entering data into the item. The handler may receive events for the
// Enter key (we're done), the Escape key (cancel input), the Tab key (move to
// next field), and the Backtab key (move to previous field).
func WithFinishedFunc(handler func(key tcell.Key)) FormItemAttribute {
return newFuncAttribute(func(o *formItemAttributes) {
o.setFinishedFunc = func(finishedFunc *func(key tcell.Key)) {
*finishedFunc = handler
}
})
}
// FormItem is the interface all form items must implement to be able to be
// included in a form.
type FormItem interface {
@ -19,8 +162,8 @@ type FormItem interface {
// GetLabel returns the item's label text.
GetLabel() string
// SetFormAttributes sets a number of item attributes at once.
SetFormAttributes(labelWidth int, bgColor, labelColor, labelColorFocused, fieldTextColor, fieldTextColorFocused, fieldBgColor, fieldBgColorFocused tcell.Color) FormItem
// SetAttributes sets the given attributes on the form item.
SetAttributes(attributes ...FormItemAttribute)
// GetFieldWidth returns the width of the form item's field (the area which
// is manipulated by the user) in number of screen cells. A value of 0
@ -30,12 +173,6 @@ type FormItem interface {
// GetFieldHeight returns the height of the form item.
GetFieldHeight() int
// SetFinishedFunc sets the handler function for when the user finished
// entering data into the item. The handler may receive events for the
// Enter key (we're done), the Escape key (cancel input), the Tab key (move to
// next field), and the Backtab key (move to previous field).
SetFinishedFunc(handler func(key tcell.Key)) FormItem
}
// Form allows you to combine multiple one-line form elements into a vertical
@ -619,16 +756,16 @@ func (f *Form) Draw(screen tcell.Screen) {
if x+itemWidth >= rightLimit {
itemWidth = rightLimit - x
}
item.SetFormAttributes(
labelWidth,
f.backgroundColor,
f.labelColor,
f.labelColorFocused,
f.fieldTextColor,
f.fieldTextColorFocused,
f.fieldBackgroundColor,
f.fieldBackgroundColorFocused,
)
item.SetAttributes(
WithLabelWidth(labelWidth),
WithBackgroundColor(f.backgroundColor),
WithLabelColor(f.labelColor),
WithLabelColorFocused(f.labelColorFocused),
WithFieldTextColor(f.fieldTextColor),
WithFieldTextColorFocused(f.fieldTextColorFocused),
WithFieldBackgroundColor(f.fieldBackgroundColor),
WithFieldBackgroundColorFocused(f.fieldBackgroundColorFocused))
// Save position.
positions[index].x = x
@ -812,7 +949,7 @@ func (f *Form) Focus(delegate func(p Primitive)) {
if f.focusedElement < len(f.items) {
// We're selecting an item.
item := f.items[f.focusedElement]
item.SetFinishedFunc(handler)
item.SetAttributes(WithFinishedFunc(handler))
f.Unlock()
delegate(item)
} else {

View File

@ -198,6 +198,24 @@ func (i *InputField) GetLabel() string {
return i.label
}
// SetAttributes sets the given attributes on the input field.
func (i *InputField) SetAttributes(attributes ...FormItemAttribute) {
allAttributes := newFormItemAttributes()
for _, attribute := range attributes {
attribute.apply(allAttributes)
}
allAttributes.setLabelWidth(&i.labelWidth)
allAttributes.setBackgroundColor(&i.backgroundColor)
allAttributes.setLabelColor(&i.labelColor)
allAttributes.setLabelColorFocused(&i.labelColorFocused)
allAttributes.setFieldTextColor(&i.fieldTextColor)
allAttributes.setFieldTextColorFocused(&i.fieldTextColorFocused)
allAttributes.setFieldBackgroundColor(&i.fieldBackgroundColor)
allAttributes.setFieldBackgroundColorFocused(&i.fieldBackgroundColorFocused)
allAttributes.setFinishedFunc(&i.finished)
}
// SetLabelWidth sets the screen width of the label. A value of 0 will cause the
// primitive to use the width of the label string.
func (i *InputField) SetLabelWidth(width int) *InputField {
@ -208,6 +226,12 @@ func (i *InputField) SetLabelWidth(width int) *InputField {
return i
}
// SetBackgroundColor sets the background color.
func (i *InputField) SetBackgroundColor(color tcell.Color) *InputField {
i.Box.SetBackgroundColor(color)
return i
}
// SetPlaceholder sets the text to be displayed when the input text is empty.
func (i *InputField) SetPlaceholder(text string) *InputField {
i.Lock()
@ -352,22 +376,6 @@ func (i *InputField) ResetFieldNote() *InputField {
return i
}
// SetFormAttributes sets attributes shared by all form items.
func (i *InputField) SetFormAttributes(labelWidth int, bgColor, labelColor, labelColorFocused, fieldTextColor, fieldTextColorFocused, fieldBgColor, fieldBgColorFocused tcell.Color) FormItem {
i.Lock()
defer i.Unlock()
i.labelWidth = labelWidth
i.backgroundColor = bgColor
i.labelColor = labelColor
i.labelColorFocused = labelColorFocused
i.fieldTextColor = fieldTextColor
i.fieldTextColorFocused = fieldTextColorFocused
i.fieldBackgroundColor = fieldBgColor
i.fieldBackgroundColorFocused = fieldBgColorFocused
return i
}
// SetFieldWidth sets the screen width of the input area. A value of 0 means
// extend as much as possible.
func (i *InputField) SetFieldWidth(width int) *InputField {
@ -549,7 +557,7 @@ func (i *InputField) SetDoneFunc(handler func(key tcell.Key)) *InputField {
}
// SetFinishedFunc sets a callback invoked when the user leaves this form item.
func (i *InputField) SetFinishedFunc(handler func(key tcell.Key)) FormItem {
func (i *InputField) SetFinishedFunc(handler func(key tcell.Key)) *InputField {
i.Lock()
defer i.Unlock()