gioui.org@v0.6.1-0.20240506124620-7a9ce51988ce/widget/material/editor.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  package material
     4  
     5  import (
     6  	"image/color"
     7  
     8  	"gioui.org/font"
     9  	"gioui.org/internal/f32color"
    10  	"gioui.org/layout"
    11  	"gioui.org/op"
    12  	"gioui.org/op/paint"
    13  	"gioui.org/text"
    14  	"gioui.org/unit"
    15  	"gioui.org/widget"
    16  )
    17  
    18  type EditorStyle struct {
    19  	Font font.Font
    20  	// LineHeight controls the distance between the baselines of lines of text.
    21  	// If zero, a sensible default will be used.
    22  	LineHeight unit.Sp
    23  	// LineHeightScale applies a scaling factor to the LineHeight. If zero, a
    24  	// sensible default will be used.
    25  	LineHeightScale float32
    26  	TextSize        unit.Sp
    27  	// Color is the text color.
    28  	Color color.NRGBA
    29  	// Hint contains the text displayed when the editor is empty.
    30  	Hint string
    31  	// HintColor is the color of hint text.
    32  	HintColor color.NRGBA
    33  	// SelectionColor is the color of the background for selected text.
    34  	SelectionColor color.NRGBA
    35  	Editor         *widget.Editor
    36  
    37  	shaper *text.Shaper
    38  }
    39  
    40  func Editor(th *Theme, editor *widget.Editor, hint string) EditorStyle {
    41  	return EditorStyle{
    42  		Editor: editor,
    43  		Font: font.Font{
    44  			Typeface: th.Face,
    45  		},
    46  		TextSize:       th.TextSize,
    47  		Color:          th.Palette.Fg,
    48  		shaper:         th.Shaper,
    49  		Hint:           hint,
    50  		HintColor:      f32color.MulAlpha(th.Palette.Fg, 0xbb),
    51  		SelectionColor: f32color.MulAlpha(th.Palette.ContrastBg, 0x60),
    52  	}
    53  }
    54  
    55  func (e EditorStyle) Layout(gtx layout.Context) layout.Dimensions {
    56  	// Choose colors.
    57  	textColorMacro := op.Record(gtx.Ops)
    58  	paint.ColorOp{Color: e.Color}.Add(gtx.Ops)
    59  	textColor := textColorMacro.Stop()
    60  	hintColorMacro := op.Record(gtx.Ops)
    61  	paint.ColorOp{Color: e.HintColor}.Add(gtx.Ops)
    62  	hintColor := hintColorMacro.Stop()
    63  	selectionColorMacro := op.Record(gtx.Ops)
    64  	paint.ColorOp{Color: blendDisabledColor(!gtx.Enabled(), e.SelectionColor)}.Add(gtx.Ops)
    65  	selectionColor := selectionColorMacro.Stop()
    66  
    67  	var maxlines int
    68  	if e.Editor.SingleLine {
    69  		maxlines = 1
    70  	}
    71  
    72  	macro := op.Record(gtx.Ops)
    73  	tl := widget.Label{
    74  		Alignment:       e.Editor.Alignment,
    75  		MaxLines:        maxlines,
    76  		LineHeight:      e.LineHeight,
    77  		LineHeightScale: e.LineHeightScale,
    78  	}
    79  	dims := tl.Layout(gtx, e.shaper, e.Font, e.TextSize, e.Hint, hintColor)
    80  	call := macro.Stop()
    81  
    82  	if w := dims.Size.X; gtx.Constraints.Min.X < w {
    83  		gtx.Constraints.Min.X = w
    84  	}
    85  	if h := dims.Size.Y; gtx.Constraints.Min.Y < h {
    86  		gtx.Constraints.Min.Y = h
    87  	}
    88  	e.Editor.LineHeight = e.LineHeight
    89  	e.Editor.LineHeightScale = e.LineHeightScale
    90  	dims = e.Editor.Layout(gtx, e.shaper, e.Font, e.TextSize, textColor, selectionColor)
    91  	if e.Editor.Len() == 0 {
    92  		call.Add(gtx.Ops)
    93  	}
    94  	return dims
    95  }
    96  
    97  func blendDisabledColor(disabled bool, c color.NRGBA) color.NRGBA {
    98  	if disabled {
    99  		return f32color.Disabled(c)
   100  	}
   101  	return c
   102  }