From 41a24756f97394c3afdebea83801b733665ce847 Mon Sep 17 00:00:00 2001 From: Andreas Bieber Date: Wed, 16 Sep 2020 16:29:12 +0200 Subject: [PATCH] feat(FormItems): Allow specifying colors for focused state --- button.go | 32 +++++++++--------- checkbox.go | 77 +++++++++++++++++++++++++++++++++++-------- dropdown.go | 88 +++++++++++++++++++++++++++++++++++++------------ form.go | 91 ++++++++++++++++++++++++++++++++++++++++++++------- inputfield.go | 76 +++++++++++++++++++++++++++++++++++------- 5 files changed, 289 insertions(+), 75 deletions(-) diff --git a/button.go b/button.go index bcfd873..63b2079 100644 --- a/button.go +++ b/button.go @@ -17,10 +17,10 @@ type Button struct { labelColor tcell.Color // The label color when the button is in focus. - labelColorActivated tcell.Color + labelColorFocused tcell.Color // The background color when the button is in focus. - backgroundColorActivated tcell.Color + backgroundColorFocused tcell.Color // An optional function which is called when the button was selected. selected func() @@ -37,11 +37,11 @@ func NewButton(label string) *Button { box := NewBox().SetBackgroundColor(Styles.ContrastBackgroundColor) box.SetRect(0, 0, TaggedStringWidth(label)+4, 1) return &Button{ - Box: box, - label: label, - labelColor: Styles.PrimaryTextColor, - labelColorActivated: Styles.InverseTextColor, - backgroundColorActivated: Styles.PrimaryTextColor, + Box: box, + label: label, + labelColor: Styles.PrimaryTextColor, + labelColorFocused: Styles.InverseTextColor, + backgroundColorFocused: Styles.PrimaryTextColor, } } @@ -71,23 +71,23 @@ func (b *Button) SetLabelColor(color tcell.Color) *Button { return b } -// SetLabelColorActivated sets the color of the button text when the button is +// SetLabelColorFocused sets the color of the button text when the button is // in focus. -func (b *Button) SetLabelColorActivated(color tcell.Color) *Button { +func (b *Button) SetLabelColorFocused(color tcell.Color) *Button { b.Lock() defer b.Unlock() - b.labelColorActivated = color + b.labelColorFocused = color return b } -// SetBackgroundColorActivated sets the background color of the button text when +// SetBackgroundColorFocused sets the background color of the button text when // the button is in focus. -func (b *Button) SetBackgroundColorActivated(color tcell.Color) *Button { +func (b *Button) SetBackgroundColorFocused(color tcell.Color) *Button { b.Lock() defer b.Unlock() - b.backgroundColorActivated = color + b.backgroundColorFocused = color return b } @@ -124,8 +124,8 @@ func (b *Button) Draw(screen tcell.Screen) { borderColor := b.borderColor backgroundColor := b.backgroundColor if b.focus.HasFocus() { - b.backgroundColor = b.backgroundColorActivated - b.borderColor = b.labelColorActivated + b.backgroundColor = b.backgroundColorFocused + b.borderColor = b.labelColorFocused defer func() { b.borderColor = borderColor }() @@ -141,7 +141,7 @@ func (b *Button) Draw(screen tcell.Screen) { y = y + height/2 labelColor := b.labelColor if b.focus.HasFocus() { - labelColor = b.labelColorActivated + labelColor = b.labelColorFocused } Print(screen, b.label, x, y, width, AlignCenter, labelColor) } diff --git a/checkbox.go b/checkbox.go index f58504e..3141faa 100644 --- a/checkbox.go +++ b/checkbox.go @@ -27,12 +27,21 @@ type CheckBox struct { // The label color. labelColor tcell.Color + // The label color when focused. + labelColorFocused tcell.Color + // The background color of the input area. fieldBackgroundColor tcell.Color + // The background color of the input area when focused. + fieldBackgroundColorFocused tcell.Color + // The text color of the input area. fieldTextColor tcell.Color + // The text color of the input area when focused. + fieldTextColorFocused tcell.Color + // An optional function which is called when the user changes the checked // state of this checkbox. changed func(checked bool) @@ -55,11 +64,14 @@ type CheckBox struct { // NewCheckBox returns a new input field. func NewCheckBox() *CheckBox { return &CheckBox{ - Box: NewBox(), - labelColor: Styles.SecondaryTextColor, - fieldBackgroundColor: Styles.ContrastBackgroundColor, - fieldTextColor: Styles.PrimaryTextColor, - checkedRune: Styles.CheckBoxCheckedRune, + Box: NewBox(), + labelColor: Styles.SecondaryTextColor, + labelColorFocused: Styles.SecondaryTextColor, + fieldBackgroundColor: Styles.ContrastBackgroundColor, + fieldBackgroundColorFocused: Styles.ContrastBackgroundColor, + fieldTextColor: Styles.PrimaryTextColor, + fieldTextColorFocused: Styles.PrimaryTextColor, + checkedRune: Styles.CheckBoxCheckedRune, } } @@ -142,6 +154,15 @@ func (c *CheckBox) SetLabelColor(color tcell.Color) *CheckBox { return c } +// SetLabelColorFocused sets the color of the label when focused. +func (c *CheckBox) SetLabelColorFocused(color tcell.Color) *CheckBox { + c.Lock() + defer c.Unlock() + + c.labelColorFocused = color + return c +} + // SetFieldBackgroundColor sets the background color of the input area. func (c *CheckBox) SetFieldBackgroundColor(color tcell.Color) *CheckBox { c.Lock() @@ -151,6 +172,15 @@ func (c *CheckBox) SetFieldBackgroundColor(color tcell.Color) *CheckBox { return c } +// SetFieldBackgroundColorFocused sets the background color of the input area when focused. +func (c *CheckBox) SetFieldBackgroundColorFocused(color tcell.Color) *CheckBox { + c.Lock() + defer c.Unlock() + + c.fieldBackgroundColorFocused = color + return c +} + // SetFieldTextColor sets the text color of the input area. func (c *CheckBox) SetFieldTextColor(color tcell.Color) *CheckBox { c.Lock() @@ -160,16 +190,28 @@ func (c *CheckBox) SetFieldTextColor(color tcell.Color) *CheckBox { return c } +// SetFieldTextColorFocused sets the text color of the input area when focused. +func (c *CheckBox) SetFieldTextColorFocused(color tcell.Color) *CheckBox { + c.Lock() + defer c.Unlock() + + c.fieldTextColorFocused = color + return c +} + // SetFormAttributes sets attributes shared by all form items. -func (c *CheckBox) SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem { +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.labelColor = labelColor c.backgroundColor = bgColor + c.labelColor = labelColor + c.labelColorFocused = labelColorFocused c.fieldTextColor = fieldTextColor + c.fieldTextColorFocused = fieldTextColorFocused c.fieldBackgroundColor = fieldBgColor + c.fieldBackgroundColorFocused = fieldBgColorFocused return c } @@ -227,6 +269,16 @@ func (c *CheckBox) Draw(screen tcell.Screen) { c.Lock() defer c.Unlock() + // Select colors + labelColor := c.labelColor + fieldBackgroundColor := c.fieldBackgroundColor + fieldTextColor := c.fieldTextColor + if c.GetFocusable().HasFocus() { + labelColor = c.labelColorFocused + fieldBackgroundColor = c.fieldBackgroundColorFocused + fieldTextColor = c.fieldTextColorFocused + } + // Prepare x, y, width, height := c.GetInnerRect() rightLimit := x + width @@ -240,18 +292,15 @@ func (c *CheckBox) Draw(screen tcell.Screen) { if labelWidth > rightLimit-x { labelWidth = rightLimit - x } - Print(screen, c.label, x, y, labelWidth, AlignLeft, c.labelColor) + Print(screen, c.label, x, y, labelWidth, AlignLeft, labelColor) x += labelWidth } else { - _, drawnWidth := Print(screen, c.label, x, y, rightLimit-x, AlignLeft, c.labelColor) + _, drawnWidth := Print(screen, c.label, x, y, rightLimit-x, AlignLeft, labelColor) x += drawnWidth } // Draw checkbox. - fieldStyle := tcell.StyleDefault.Background(c.fieldBackgroundColor).Foreground(c.fieldTextColor) - if c.focus.HasFocus() { - fieldStyle = fieldStyle.Background(c.fieldTextColor).Foreground(c.fieldBackgroundColor) - } + fieldStyle := tcell.StyleDefault.Background(fieldBackgroundColor).Foreground(fieldTextColor) checkedRune := c.checkedRune if !c.checked { @@ -262,7 +311,7 @@ func (c *CheckBox) Draw(screen tcell.Screen) { screen.SetContent(x+2, y, ' ', nil, fieldStyle) if c.message != "" { - Print(screen, c.message, x+4, y, len(c.message), AlignLeft, c.labelColor) + Print(screen, c.message, x+4, y, len(c.message), AlignLeft, labelColor) } } diff --git a/dropdown.go b/dropdown.go index b2f4932..ee8c01a 100644 --- a/dropdown.go +++ b/dropdown.go @@ -49,12 +49,21 @@ type DropDown struct { // The label color. labelColor tcell.Color + // The label color when focused. + labelColorFocused tcell.Color + // The background color of the input area. fieldBackgroundColor tcell.Color + // The background color of the input area when focused. + fieldBackgroundColorFocused tcell.Color + // The text color of the input area. fieldTextColor tcell.Color + // The text color of the input area when focused. + fieldTextColorFocused tcell.Color + // The color for prefixes. prefixTextColor tcell.Color @@ -96,13 +105,16 @@ func NewDropDown() *DropDown { SetBackgroundColor(Styles.MoreContrastBackgroundColor) d := &DropDown{ - Box: NewBox(), - currentOption: -1, - list: list, - labelColor: Styles.SecondaryTextColor, - fieldBackgroundColor: Styles.ContrastBackgroundColor, - fieldTextColor: Styles.PrimaryTextColor, - prefixTextColor: Styles.ContrastSecondaryTextColor, + Box: NewBox(), + currentOption: -1, + list: list, + labelColor: Styles.SecondaryTextColor, + labelColorFocused: Styles.SecondaryTextColor, + fieldBackgroundColor: Styles.ContrastBackgroundColor, + fieldBackgroundColorFocused: Styles.ContrastBackgroundColor, + fieldTextColor: Styles.PrimaryTextColor, + fieldTextColorFocused: Styles.PrimaryTextColor, + prefixTextColor: Styles.ContrastSecondaryTextColor, } d.focus = d @@ -211,6 +223,15 @@ func (d *DropDown) SetLabelColor(color tcell.Color) *DropDown { return d } +// SetLabelColorFocused sets the color of the label when focused. +func (d *DropDown) SetLabelColorFocused(color tcell.Color) *DropDown { + d.Lock() + defer d.Unlock() + + d.labelColorFocused = color + return d +} + // SetFieldBackgroundColor sets the background color of the options area. func (d *DropDown) SetFieldBackgroundColor(color tcell.Color) *DropDown { d.Lock() @@ -220,6 +241,15 @@ func (d *DropDown) SetFieldBackgroundColor(color tcell.Color) *DropDown { return d } +// SetFieldBackgroundColorFocused sets the background color of the options area when focused. +func (d *DropDown) SetFieldBackgroundColorFocused(color tcell.Color) *DropDown { + d.Lock() + defer d.Unlock() + + d.fieldBackgroundColorFocused = color + return d +} + // SetFieldTextColor sets the text color of the options area. func (d *DropDown) SetFieldTextColor(color tcell.Color) *DropDown { d.Lock() @@ -229,6 +259,15 @@ func (d *DropDown) SetFieldTextColor(color tcell.Color) *DropDown { return d } +// SetFieldTextColorFocused sets the text color of the options area when focused. +func (d *DropDown) SetFieldTextColorFocused(color tcell.Color) *DropDown { + d.Lock() + defer d.Unlock() + + d.fieldTextColorFocused = color + return d +} + // SetPrefixTextColor sets the color of the prefix string. The prefix string is // shown when the user starts typing text, which directly selects the first // option that starts with the typed string. @@ -241,15 +280,18 @@ func (d *DropDown) SetPrefixTextColor(color tcell.Color) *DropDown { } // SetFormAttributes sets attributes shared by all form items. -func (d *DropDown) SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem { +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.labelColor = labelColor d.backgroundColor = bgColor + d.labelColor = labelColor + d.labelColorFocused = labelColorFocused d.fieldTextColor = fieldTextColor + d.fieldTextColorFocused = fieldTextColorFocused d.fieldBackgroundColor = fieldBgColor + d.fieldBackgroundColorFocused = fieldBgColorFocused return d } @@ -360,6 +402,16 @@ func (d *DropDown) Draw(screen tcell.Screen) { d.Lock() defer d.Unlock() + // Select colors + labelColor := d.labelColor + fieldBackgroundColor := d.fieldBackgroundColor + fieldTextColor := d.fieldTextColor + if hasFocus { + labelColor = d.labelColorFocused + fieldBackgroundColor = d.fieldBackgroundColorFocused + fieldTextColor = d.fieldTextColorFocused + } + // Prepare. x, y, width, height := d.GetInnerRect() rightLimit := x + width @@ -373,10 +425,10 @@ func (d *DropDown) Draw(screen tcell.Screen) { if labelWidth > rightLimit-x { labelWidth = rightLimit - x } - Print(screen, d.label, x, y, labelWidth, AlignLeft, d.labelColor) + Print(screen, d.label, x, y, labelWidth, AlignLeft, labelColor) x += labelWidth } else { - _, drawnWidth := Print(screen, d.label, x, y, rightLimit-x, AlignLeft, d.labelColor) + _, drawnWidth := Print(screen, d.label, x, y, rightLimit-x, AlignLeft, labelColor) x += drawnWidth } @@ -409,10 +461,7 @@ func (d *DropDown) Draw(screen tcell.Screen) { if rightLimit-x < fieldWidth { fieldWidth = rightLimit - x } - fieldStyle := tcell.StyleDefault.Background(d.fieldBackgroundColor) - if hasFocus && !d.open { - fieldStyle = fieldStyle.Background(d.fieldTextColor) - } + fieldStyle := tcell.StyleDefault.Background(fieldBackgroundColor) for index := 0; index < fieldWidth; index++ { screen.SetContent(x+index, y, ' ', nil, fieldStyle) } @@ -423,21 +472,18 @@ func (d *DropDown) Draw(screen tcell.Screen) { currentOptionPrefixWidth := TaggedStringWidth(d.currentOptionPrefix) prefixWidth := stringWidth(d.prefix) listItemText := d.options[d.list.GetCurrentItem()].Text - Print(screen, d.currentOptionPrefix, x, y, fieldWidth, AlignLeft, d.fieldTextColor) + Print(screen, d.currentOptionPrefix, x, y, fieldWidth, AlignLeft, fieldTextColor) Print(screen, d.prefix, x+currentOptionPrefixWidth, y, fieldWidth-currentOptionPrefixWidth, AlignLeft, d.prefixTextColor) if len(d.prefix) < len(listItemText) { - Print(screen, listItemText[len(d.prefix):]+d.currentOptionSuffix, x+prefixWidth+currentOptionPrefixWidth, y, fieldWidth-prefixWidth-currentOptionPrefixWidth, AlignLeft, d.fieldTextColor) + Print(screen, listItemText[len(d.prefix):]+d.currentOptionSuffix, x+prefixWidth+currentOptionPrefixWidth, y, fieldWidth-prefixWidth-currentOptionPrefixWidth, AlignLeft, fieldTextColor) } } else { - color := d.fieldTextColor + color := fieldTextColor text := d.noSelection if d.currentOption >= 0 && d.currentOption < len(d.options) { text = d.currentOptionPrefix + d.options[d.currentOption].Text + d.currentOptionSuffix } // Just show the current selection. - if hasFocus && !d.open { - color = d.fieldBackgroundColor - } Print(screen, text, x, y, fieldWidth, AlignLeft, color) } diff --git a/form.go b/form.go index ff8c472..4d8adf4 100644 --- a/form.go +++ b/form.go @@ -20,7 +20,7 @@ type FormItem interface { GetLabel() string // SetFormAttributes sets a number of item attributes at once. - SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem + SetFormAttributes(labelWidth int, bgColor, labelColor, labelColorFocused, fieldTextColor, fieldTextColorFocused, fieldBgColor, fieldBgColorFocused tcell.Color) FormItem // 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 @@ -69,18 +69,33 @@ type Form struct { // The label color. labelColor tcell.Color + // The label color when focused. + labelColorFocused tcell.Color + // The background color of the input area. fieldBackgroundColor tcell.Color + // The background color of the input area when focused. + fieldBackgroundColorFocused tcell.Color + // The text color of the input area. fieldTextColor tcell.Color + // The text color of the input area when focused. + fieldTextColorFocused tcell.Color + // The background color of the buttons. buttonBackgroundColor tcell.Color + // The background color of the buttons when focused. + buttonBackgroundColorFocused tcell.Color + // The color of the button text. buttonTextColor tcell.Color + // The color of the button text when focused. + buttonTextColorFocused tcell.Color + // An optional function which is called when the user hits Escape. cancel func() @@ -92,17 +107,21 @@ func NewForm() *Form { box := NewBox().SetBorderPadding(1, 1, 1, 1) f := &Form{ - Box: box, - itemPadding: 1, - labelColor: Styles.SecondaryTextColor, - fieldBackgroundColor: Styles.ContrastBackgroundColor, - fieldTextColor: Styles.PrimaryTextColor, - buttonBackgroundColor: Styles.ContrastBackgroundColor, - buttonTextColor: Styles.PrimaryTextColor, + Box: box, + itemPadding: 1, + labelColor: Styles.SecondaryTextColor, + labelColorFocused: Styles.SecondaryTextColor, + fieldBackgroundColor: Styles.ContrastBackgroundColor, + fieldBackgroundColorFocused: Styles.ContrastBackgroundColor, + fieldTextColor: Styles.PrimaryTextColor, + fieldTextColorFocused: Styles.PrimaryTextColor, + buttonBackgroundColor: Styles.ContrastBackgroundColor, + buttonBackgroundColorFocused: Styles.PrimaryTextColor, + buttonTextColor: Styles.PrimaryTextColor, + buttonTextColorFocused: Styles.ContrastBackgroundColor, } f.focus = f - return f } @@ -138,6 +157,15 @@ func (f *Form) SetLabelColor(color tcell.Color) *Form { return f } +// SetLabelColorFocused sets the color of the labels when focused. +func (f *Form) SetLabelColorFocused(color tcell.Color) *Form { + f.Lock() + defer f.Unlock() + + f.labelColorFocused = color + return f +} + // SetFieldBackgroundColor sets the background color of the input areas. func (f *Form) SetFieldBackgroundColor(color tcell.Color) *Form { f.Lock() @@ -147,6 +175,15 @@ func (f *Form) SetFieldBackgroundColor(color tcell.Color) *Form { return f } +// SetFieldBackgroundColorFocused sets the background color of the input areas when focused. +func (f *Form) SetFieldBackgroundColorFocused(color tcell.Color) *Form { + f.Lock() + defer f.Unlock() + + f.fieldBackgroundColorFocused = color + return f +} + // SetFieldTextColor sets the text color of the input areas. func (f *Form) SetFieldTextColor(color tcell.Color) *Form { f.Lock() @@ -156,6 +193,15 @@ func (f *Form) SetFieldTextColor(color tcell.Color) *Form { return f } +// SetFieldTextColorFocused sets the text color of the input areas when focused. +func (f *Form) SetFieldTextColorFocused(color tcell.Color) *Form { + f.Lock() + defer f.Unlock() + + f.fieldTextColorFocused = color + return f +} + // SetButtonsAlign sets how the buttons align horizontally, one of AlignLeft // (the default), AlignCenter, and AlignRight. This is only func (f *Form) SetButtonsAlign(align int) *Form { @@ -175,6 +221,15 @@ func (f *Form) SetButtonBackgroundColor(color tcell.Color) *Form { return f } +// SetButtonBackgroundColorFocused sets the background color of the buttons when focused. +func (f *Form) SetButtonBackgroundColorFocused(color tcell.Color) *Form { + f.Lock() + defer f.Unlock() + + f.buttonBackgroundColorFocused = color + return f +} + // SetButtonTextColor sets the color of the button texts. func (f *Form) SetButtonTextColor(color tcell.Color) *Form { f.Lock() @@ -184,6 +239,15 @@ func (f *Form) SetButtonTextColor(color tcell.Color) *Form { return f } +// SetButtonTextColorFocused sets the color of the button texts when focused. +func (f *Form) SetButtonTextColorFocused(color tcell.Color) *Form { + f.Lock() + defer f.Unlock() + + f.buttonTextColorFocused = color + return f +} + // SetFocus shifts the focus to the form element with the given index, counting // non-button items first and buttons last. Note that this index is only used // when the form itself receives focus. @@ -537,10 +601,13 @@ func (f *Form) Draw(screen tcell.Screen) { } item.SetFormAttributes( labelWidth, - f.labelColor, f.backgroundColor, + f.labelColor, + f.labelColorFocused, f.fieldTextColor, + f.fieldTextColorFocused, f.fieldBackgroundColor, + f.fieldBackgroundColorFocused, ) // Save position. @@ -603,8 +670,8 @@ func (f *Form) Draw(screen tcell.Screen) { buttonWidth = space } button.SetLabelColor(f.buttonTextColor). - SetLabelColorActivated(f.buttonBackgroundColor). - SetBackgroundColorActivated(f.buttonTextColor). + SetLabelColorFocused(f.buttonBackgroundColor). + SetBackgroundColorFocused(f.buttonTextColor). SetBackgroundColor(f.buttonBackgroundColor) buttonIndex := index + len(f.items) diff --git a/inputfield.go b/inputfield.go index 7039a20..df92d92 100644 --- a/inputfield.go +++ b/inputfield.go @@ -43,12 +43,21 @@ type InputField struct { // The label color. labelColor tcell.Color + // The label color when focused. + labelColorFocused tcell.Color + // The background color of the input area. fieldBackgroundColor tcell.Color + // The background color of the input area when focused. + fieldBackgroundColorFocused tcell.Color + // The text color of the input area. fieldTextColor tcell.Color + // The text color of the input area when focused. + fieldTextColorFocused tcell.Color + // The text color of the placeholder. placeholderTextColor tcell.Color @@ -103,11 +112,14 @@ type InputField struct { // NewInputField returns a new input field. func NewInputField() *InputField { return &InputField{ - Box: NewBox(), - labelColor: Styles.SecondaryTextColor, - fieldBackgroundColor: Styles.ContrastBackgroundColor, - fieldTextColor: Styles.PrimaryTextColor, - placeholderTextColor: Styles.ContrastSecondaryTextColor, + Box: NewBox(), + labelColor: Styles.SecondaryTextColor, + labelColorFocused: Styles.SecondaryTextColor, + fieldBackgroundColor: Styles.ContrastBackgroundColor, + fieldBackgroundColorFocused: Styles.ContrastBackgroundColor, + fieldTextColor: Styles.PrimaryTextColor, + fieldTextColorFocused: Styles.PrimaryTextColor, + placeholderTextColor: Styles.ContrastSecondaryTextColor, } } @@ -180,6 +192,15 @@ func (i *InputField) SetLabelColor(color tcell.Color) *InputField { return i } +// SetLabelColorFocused sets the color of the label when focused. +func (i *InputField) SetLabelColorFocused(color tcell.Color) *InputField { + i.Lock() + defer i.Unlock() + + i.labelColorFocused = color + return i +} + // SetFieldBackgroundColor sets the background color of the input area. func (i *InputField) SetFieldBackgroundColor(color tcell.Color) *InputField { i.Lock() @@ -189,6 +210,15 @@ func (i *InputField) SetFieldBackgroundColor(color tcell.Color) *InputField { return i } +// SetFieldBackgroundColorFocused sets the background color of the input area when focused. +func (i *InputField) SetFieldBackgroundColorFocused(color tcell.Color) *InputField { + i.Lock() + defer i.Unlock() + + i.fieldBackgroundColorFocused = color + return i +} + // SetFieldTextColor sets the text color of the input area. func (i *InputField) SetFieldTextColor(color tcell.Color) *InputField { i.Lock() @@ -198,6 +228,15 @@ func (i *InputField) SetFieldTextColor(color tcell.Color) *InputField { return i } +// SetFieldTextColorFocused sets the text color of the input area when focused. +func (i *InputField) SetFieldTextColorFocused(color tcell.Color) *InputField { + i.Lock() + defer i.Unlock() + + i.fieldTextColorFocused = color + return i +} + // SetPlaceholderTextColor sets the text color of placeholder text. func (i *InputField) SetPlaceholderTextColor(color tcell.Color) *InputField { i.Lock() @@ -208,15 +247,18 @@ func (i *InputField) SetPlaceholderTextColor(color tcell.Color) *InputField { } // SetFormAttributes sets attributes shared by all form items. -func (i *InputField) SetFormAttributes(labelWidth int, labelColor, bgColor, fieldTextColor, fieldBgColor tcell.Color) FormItem { +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.labelColor = labelColor i.backgroundColor = bgColor + i.labelColor = labelColor + i.labelColorFocused = labelColorFocused i.fieldTextColor = fieldTextColor + i.fieldTextColorFocused = fieldTextColorFocused i.fieldBackgroundColor = fieldBgColor + i.fieldBackgroundColorFocused = fieldBgColorFocused return i } @@ -392,6 +434,16 @@ func (i *InputField) Draw(screen tcell.Screen) { i.Lock() defer i.Unlock() + // Select colors + labelColor := i.labelColor + fieldBackgroundColor := i.fieldBackgroundColor + fieldTextColor := i.fieldTextColor + if i.GetFocusable().HasFocus() { + labelColor = i.labelColorFocused + fieldBackgroundColor = i.fieldBackgroundColorFocused + fieldTextColor = i.fieldTextColorFocused + } + // Prepare x, y, width, height := i.GetInnerRect() rightLimit := x + width @@ -405,10 +457,10 @@ func (i *InputField) Draw(screen tcell.Screen) { if labelWidth > rightLimit-x { labelWidth = rightLimit - x } - Print(screen, i.label, x, y, labelWidth, AlignLeft, i.labelColor) + Print(screen, i.label, x, y, labelWidth, AlignLeft, labelColor) x += labelWidth } else { - _, drawnWidth := Print(screen, i.label, x, y, rightLimit-x, AlignLeft, i.labelColor) + _, drawnWidth := Print(screen, i.label, x, y, rightLimit-x, AlignLeft, labelColor) x += drawnWidth } @@ -421,7 +473,7 @@ func (i *InputField) Draw(screen tcell.Screen) { if rightLimit-x < fieldWidth { fieldWidth = rightLimit - x } - fieldStyle := tcell.StyleDefault.Background(i.fieldBackgroundColor) + fieldStyle := tcell.StyleDefault.Background(fieldBackgroundColor) for index := 0; index < fieldWidth; index++ { screen.SetContent(x+index, y, ' ', nil, fieldStyle) } @@ -440,7 +492,7 @@ func (i *InputField) Draw(screen tcell.Screen) { } if fieldWidth >= stringWidth(text) { // We have enough space for the full text. - Print(screen, Escape(text), x, y, fieldWidth, AlignLeft, i.fieldTextColor) + Print(screen, Escape(text), x, y, fieldWidth, AlignLeft, fieldTextColor) i.offset = 0 iterateString(text, func(main rune, comb []rune, textPos, textWidth, screenPos, screenWidth int) bool { if textPos >= i.cursorPos { @@ -478,7 +530,7 @@ func (i *InputField) Draw(screen tcell.Screen) { } return false }) - Print(screen, Escape(text[i.offset:]), x, y, fieldWidth, AlignLeft, i.fieldTextColor) + Print(screen, Escape(text[i.offset:]), x, y, fieldWidth, AlignLeft, fieldTextColor) } }