input.go raw

   1  package gel
   2  
   3  import (
   4  	"regexp"
   5  
   6  	"golang.org/x/exp/shiny/materialdesign/icons"
   7  
   8  	l "github.com/p9c/gio/layout"
   9  )
  10  
  11  type Input struct {
  12  	*Window
  13  	editor               *Editor
  14  	input                *TextInput
  15  	clearClickable       *Clickable
  16  	clearButton          *IconButton
  17  	copyClickable        *Clickable
  18  	copyButton           *IconButton
  19  	pasteClickable       *Clickable
  20  	pasteButton          *IconButton
  21  	GetText              func() string
  22  	SetText              func(string)
  23  	SetPasteFunc         func() bool
  24  	borderColor          string
  25  	borderColorUnfocused string
  26  	borderColorFocused   string
  27  	backgroundColor      string
  28  	focused              bool
  29  }
  30  
  31  var findSpaceRegexp = regexp.MustCompile(`\s+`)
  32  
  33  func (w *Window) Input(
  34  	txt, hint, borderColorFocused, borderColorUnfocused, backgroundColor string,
  35  	submit, change func(txt string),
  36  ) *Input {
  37  	editor := w.Editor().SingleLine().Submit(false)
  38  	input := w.TextInput(editor, hint).TextScale(1)
  39  	p := &Input{
  40  		Window:               w,
  41  		clearClickable:       w.Clickable(),
  42  		copyClickable:        w.Clickable(),
  43  		pasteClickable:       w.Clickable(),
  44  		editor:               editor,
  45  		input:                input,
  46  		borderColorUnfocused: borderColorUnfocused,
  47  		borderColorFocused:   borderColorFocused,
  48  		backgroundColor:      backgroundColor,
  49  	}
  50  	p.GetText = func() string {
  51  		return p.editor.Text()
  52  	}
  53  	p.SetText = func(s string) {
  54  		p.editor.SetText(s)
  55  	}
  56  	p.clearButton = w.IconButton(p.clearClickable)
  57  	p.copyButton = w.IconButton(p.copyClickable)
  58  	p.pasteButton = w.IconButton(p.pasteClickable)
  59  	clearClickableFn := func() {
  60  		p.editor.SetText("")
  61  		p.editor.changeHook("")
  62  		p.editor.Focus()
  63  	}
  64  	copyClickableFn := func() {
  65  		p.ClipboardWriteReqs <- p.editor.Text()
  66  		p.editor.Focus()
  67  	}
  68  	pasteClickableFn := func() {
  69  		p.ClipboardReadReqs <- func(cs string) {
  70  			cs = findSpaceRegexp.ReplaceAllString(cs, " ")
  71  			p.editor.Insert(cs)
  72  			p.editor.changeHook(cs)
  73  			p.editor.Focus()
  74  		}
  75  	}
  76  	p.clearButton.
  77  		Icon(
  78  			w.Icon().
  79  				Color("DocText").
  80  				Src(&icons.ContentBackspace),
  81  		)
  82  	p.copyButton.
  83  		Icon(
  84  			w.Icon().
  85  				Color("DocText").
  86  				Src(&icons.ContentContentCopy),
  87  		)
  88  	p.pasteButton.
  89  		Icon(
  90  			w.Icon().
  91  				Color("DocText").
  92  				Src(&icons.ContentContentPaste),
  93  		)
  94  	p.input.Color("DocText")
  95  	p.clearClickable.SetClick(clearClickableFn)
  96  	p.copyClickable.SetClick(copyClickableFn)
  97  	p.pasteClickable.SetClick(pasteClickableFn)
  98  	p.editor.SetText(txt).SetSubmit(
  99  		func(txt string) {
 100  			go func() {
 101  				submit(txt)
 102  			}()
 103  		},
 104  	).SetChange(
 105  		change,
 106  	)
 107  	p.editor.SetFocus(
 108  		func(is bool) {
 109  			if is {
 110  				p.borderColor = p.borderColorFocused
 111  			} else {
 112  				p.borderColor = p.borderColorUnfocused
 113  			}
 114  		},
 115  	)
 116  	return p
 117  }
 118  
 119  // Fn renders the input widget
 120  func (in *Input) Fn(gtx l.Context) l.Dimensions {
 121  	// gtx.Constraints.Max.X = int(in.TextSize.Scale(float32(in.size)).True)
 122  	// gtx.Constraints.Min.X = 0
 123  	// width := int(in.Theme.TextSize.Scale(in.size).True)
 124  	// gtx.Constraints.Max.X, gtx.Constraints.Min.X = width, width
 125  	return in.Border().
 126  		Width(0.125).
 127  		CornerRadius(0.0).
 128  		Color(in.borderColor).
 129  		Embed(
 130  			in.Fill(
 131  				in.backgroundColor, l.Center, in.TextSize.V, 0,
 132  				in.Inset(
 133  					0.25,
 134  					in.Flex().
 135  						Flexed(
 136  							1,
 137  							in.Inset(0.125, in.input.Color("DocText").Fn).Fn,
 138  						).
 139  						Rigid(
 140  							in.copyButton.
 141  								Background("").
 142  								Icon(in.Icon().Color(in.borderColor).Scale(Scales["H6"]).Src(&icons.ContentContentCopy)).
 143  								ButtonInset(0.25).
 144  								Fn,
 145  						).
 146  						Rigid(
 147  							in.pasteButton.
 148  								Background("").
 149  								Icon(in.Icon().Color(in.borderColor).Scale(Scales["H6"]).Src(&icons.ContentContentPaste)).
 150  								ButtonInset(0.25).
 151  								Fn,
 152  						).
 153  						Rigid(
 154  							in.clearButton.
 155  								Background("").
 156  								Icon(in.Icon().Color(in.borderColor).Scale(Scales["H6"]).Src(&icons.ContentBackspace)).
 157  								ButtonInset(0.25).
 158  								Fn,
 159  						).
 160  						Fn,
 161  				).Fn,
 162  			).Fn,
 163  		).Fn(gtx)
 164  }
 165