147 lines
3.8 KiB
Go
147 lines
3.8 KiB
Go
package gel
|
|
|
|
import (
|
|
"image"
|
|
"image/color"
|
|
|
|
"gioui.org/font"
|
|
l "gioui.org/layout"
|
|
"gioui.org/op"
|
|
"gioui.org/op/paint"
|
|
"gioui.org/text"
|
|
"gioui.org/unit"
|
|
|
|
"git.mleku.dev/mleku/prevara/f32color"
|
|
)
|
|
|
|
// TextInput is a simple text input widget
|
|
type TextInput struct {
|
|
*Window
|
|
font font.Font
|
|
textSize unit.Sp
|
|
// Color is the text color.
|
|
color color.NRGBA
|
|
// Hint contains the text displayed when the editor is empty.
|
|
hint string
|
|
// HintColor is the color of hint text.
|
|
hintColor color.NRGBA
|
|
// SelectionColor is the color of the background for selected text.
|
|
selectionColor color.NRGBA
|
|
editor *Editor
|
|
shaper *text.Shaper
|
|
}
|
|
|
|
// TextInput creates a simple text input widget
|
|
func (w *Window) TextInput(editor *Editor, hint string) *TextInput {
|
|
var fon font.Font
|
|
if f, e := w.collection.Font("bariol regular"); e == nil {
|
|
fon = f
|
|
}
|
|
ti := &TextInput{
|
|
Window: w,
|
|
editor: editor,
|
|
textSize: w.TextSize,
|
|
font: fon,
|
|
color: w.Colors.GetNRGBAFromName("DocText"),
|
|
shaper: w.shaper,
|
|
hint: hint,
|
|
hintColor: w.Colors.GetNRGBAFromName("Hint"),
|
|
selectionColor: w.Colors.GetNRGBAFromName("scrim"),
|
|
}
|
|
return ti
|
|
}
|
|
|
|
// Font sets the font for the text input widget
|
|
func (ti *TextInput) Font(fontName string) *TextInput {
|
|
var fon font.Font
|
|
var e error
|
|
if fon, e = ti.Theme.collection.Font(fontName); !E.Chk(e) {
|
|
ti.editor.font = fon
|
|
}
|
|
return ti
|
|
}
|
|
|
|
// TextScale sets the size of the text relative to the base font size
|
|
func (ti *TextInput) TextScale(scale float32) *TextInput {
|
|
ti.textSize = unit.Sp(float32(ti.Theme.TextSize) * scale)
|
|
return ti
|
|
}
|
|
|
|
// Color sets the color to render the text
|
|
func (ti *TextInput) Color(color string) *TextInput {
|
|
ti.color = ti.Theme.Colors.GetNRGBAFromName(color)
|
|
return ti
|
|
}
|
|
|
|
// SelectionColor sets the color to render the text
|
|
func (ti *TextInput) SelectionColor(color string) *TextInput {
|
|
ti.selectionColor = ti.Theme.Colors.GetNRGBAFromName(color)
|
|
return ti
|
|
}
|
|
|
|
// Hint sets the text to show when the box is empty
|
|
func (ti *TextInput) Hint(hint string) *TextInput {
|
|
ti.hint = hint
|
|
return ti
|
|
}
|
|
|
|
// HintColor sets the color of the hint text
|
|
func (ti *TextInput) HintColor(color string) *TextInput {
|
|
ti.hintColor = ti.Theme.Colors.GetNRGBAFromName(color)
|
|
return ti
|
|
}
|
|
|
|
// Fn renders the text input widget
|
|
func (ti *TextInput) Fn(gtx l.Context) l.Dimensions {
|
|
// Save state using the new Push/Pop pattern
|
|
stack := op.Offset(image.Point{}).Push(gtx.Ops)
|
|
defer stack.Pop()
|
|
|
|
disabled := !gtx.Source.Enabled()
|
|
textColor := blendDisabledColor(disabled, ti.color)
|
|
selectionColor := blendDisabledColor(disabled, ti.selectionColor)
|
|
|
|
// If editor is empty, show hint first to determine minimum size
|
|
if ti.editor.Len() == 0 {
|
|
macro := op.Record(gtx.Ops)
|
|
paint.ColorOp{Color: ti.hintColor}.Add(gtx.Ops)
|
|
var maxlines int
|
|
if ti.editor.singleLine {
|
|
maxlines = 1
|
|
}
|
|
tl := Label{
|
|
Window: ti.Window,
|
|
font: ti.font,
|
|
color: ti.hintColor,
|
|
alignment: ti.editor.alignment,
|
|
maxLines: maxlines,
|
|
text: ti.hint,
|
|
textSize: ti.textSize,
|
|
shaper: ti.shaper,
|
|
}
|
|
dims := tl.Fn(gtx)
|
|
call := macro.Stop()
|
|
if w := dims.Size.X; gtx.Constraints.Min.X < w {
|
|
gtx.Constraints.Min.X = w
|
|
}
|
|
if h := dims.Size.Y; gtx.Constraints.Min.Y < h {
|
|
gtx.Constraints.Min.Y = h
|
|
}
|
|
// Layout the editor (even if empty, to handle input)
|
|
editorDims := ti.editor.Layout(gtx, ti.shaper, ti.font, ti.textSize, textColor, selectionColor)
|
|
// Draw the hint since editor is empty
|
|
call.Add(gtx.Ops)
|
|
return editorDims
|
|
}
|
|
|
|
// Layout the editor with text and selection colors
|
|
return ti.editor.Layout(gtx, ti.shaper, ti.font, ti.textSize, textColor, selectionColor)
|
|
}
|
|
|
|
func blendDisabledColor(disabled bool, c color.NRGBA) color.NRGBA {
|
|
if disabled {
|
|
return f32color.Disabled(c)
|
|
}
|
|
return c
|
|
}
|