password.go raw

   1  package gel
   2  
   3  import (
   4  	"github.com/p9c/opts/text"
   5  	icons2 "golang.org/x/exp/shiny/materialdesign/icons"
   6  
   7  	l "github.com/p9c/gio/layout"
   8  )
   9  
  10  type Password struct {
  11  	*Window
  12  	pass                 *Editor
  13  	passInput            *TextInput
  14  	unhideClickable      *Clickable
  15  	unhideButton         *IconButton
  16  	copyClickable        *Clickable
  17  	copyButton           *IconButton
  18  	pasteClickable       *Clickable
  19  	pasteButton          *IconButton
  20  	hide                 bool
  21  	borderColor          string
  22  	borderColorUnfocused string
  23  	borderColorFocused   string
  24  	backgroundColor      string
  25  	focused              bool
  26  	showClickableFn      func(col string)
  27  	password             *text.Opt
  28  	handle               func(pass string)
  29  }
  30  
  31  func (w *Window) Password(
  32  	hint string, password *text.Opt, borderColorFocused,
  33  	borderColorUnfocused, backgroundColor string, handle func(pass string),
  34  ) *Password {
  35  	pass := w.Editor().Mask('•').SingleLine().Submit(true)
  36  	passInput := w.TextInput(pass, hint).Color(borderColorUnfocused)
  37  	p := &Password{
  38  		Window:               w,
  39  		unhideClickable:      w.Clickable(),
  40  		copyClickable:        w.Clickable(),
  41  		pasteClickable:       w.Clickable(),
  42  		pass:                 pass,
  43  		passInput:            passInput,
  44  		borderColorUnfocused: borderColorUnfocused,
  45  		borderColorFocused:   borderColorFocused,
  46  		borderColor:          borderColorUnfocused,
  47  		backgroundColor:      backgroundColor,
  48  		handle:               handle,
  49  		password:             password,
  50  	}
  51  	p.copyButton = w.IconButton(p.copyClickable)
  52  	p.pasteButton = w.IconButton(p.pasteClickable)
  53  	p.unhideButton = w.IconButton(p.unhideClickable).Background("").
  54  		Icon(w.Icon().Color(p.borderColor).Src(&icons2.ActionVisibility))
  55  	p.showClickableFn = func(col string) {
  56  		D.Ln("show clickable clicked")
  57  		p.hide = !p.hide
  58  	}
  59  	copyClickableFn := func() {
  60  		p.ClipboardWriteReqs <- p.pass.Text()
  61  		p.pass.Focus()
  62  	}
  63  	pasteClickableFn := func() {
  64  		p.ClipboardReadReqs <- func(cs string) {
  65  			cs = findSpaceRegexp.ReplaceAllString(cs, " ")
  66  			p.pass.Insert(cs)
  67  			p.pass.changeHook(cs)
  68  			p.pass.Focus()
  69  		}
  70  	}
  71  	p.copyClickable.SetClick(copyClickableFn)
  72  	p.pasteClickable.SetClick(pasteClickableFn)
  73  	p.unhideButton.
  74  		// Color("Primary").
  75  		Icon(
  76  			w.Icon().
  77  				Color(p.borderColor).
  78  				Src(&icons2.ActionVisibility),
  79  		)
  80  	p.pass.Mask('•')
  81  	p.pass.SetFocus(
  82  		func(is bool) {
  83  			if is {
  84  				p.borderColor = p.borderColorFocused
  85  			} else {
  86  				p.borderColor = p.borderColorUnfocused
  87  				p.hide = true
  88  			}
  89  		},
  90  	)
  91  	p.passInput.editor.Mask('•')
  92  	p.hide = true
  93  	p.passInput.Color(p.borderColor)
  94  	p.pass.SetText(p.password.V()).Mask('•').SetSubmit(
  95  		func(txt string) {
  96  			// if !p.hide {
  97  			// 	p.showClickableFn(p.borderColor)
  98  			// }
  99  			// p.showClickableFn(p.borderColor)
 100  			go func() {
 101  				p.handle(txt)
 102  			}()
 103  		},
 104  	).SetChange(
 105  		func(txt string) {
 106  			// send keystrokes to the NSA
 107  		},
 108  	)
 109  	return p
 110  }
 111  
 112  func (p *Password) Fn(gtx l.Context) l.Dimensions {
 113  	// gtx.Constraints.Max.X = int(p.TextSize.Scale(float32(p.size)).True)
 114  	// gtx.Constraints.Min.X = 0
 115  	// cs := gtx.Constraints
 116  	// width := int(p.Theme.TextSize.Scale(p.size).True)
 117  	// gtx.Constraints.Max.X, gtx.Constraints.Min.X = width, width
 118  	return func(gtx l.Context) l.Dimensions {
 119  		p.passInput.Color(p.borderColor).Font("go regular")
 120  		p.unhideButton.Color(p.borderColor)
 121  		p.unhideClickable.SetClick(func() { p.showClickableFn(p.borderColor) })
 122  		visIcon := &icons2.ActionVisibility
 123  		if p.hide {
 124  			p.pass.Mask('•')
 125  		} else {
 126  			visIcon = &icons2.ActionVisibilityOff
 127  			p.pass.Mask(0)
 128  		}
 129  
 130  		return p.Border().
 131  			Width(0.125).
 132  			CornerRadius(0.0).
 133  			Color(p.borderColor).Embed(
 134  			p.Fill(
 135  				p.backgroundColor, l.Center, 0, 0,
 136  				p.Inset(
 137  					0.25,
 138  					p.Flex().
 139  						Flexed(
 140  							1,
 141  							p.Inset(0.25, p.passInput.Color(p.borderColor).HintColor(p.borderColorUnfocused).Fn).Fn,
 142  						).
 143  						Rigid(
 144  							p.copyButton.
 145  								Background("").
 146  								Icon(p.Icon().Color(p.borderColor).Scale(Scales["H6"]).Src(&icons2.ContentContentCopy)).
 147  								ButtonInset(0.25).
 148  								Fn,
 149  						).
 150  						Rigid(
 151  							p.pasteButton.
 152  								Background("").
 153  								Icon(p.Icon().Color(p.borderColor).Scale(Scales["H6"]).Src(&icons2.ContentContentPaste)).
 154  								ButtonInset(0.25).
 155  								Fn,
 156  						).
 157  						Rigid(
 158  							p.unhideButton.
 159  								Background("").
 160  								Icon(p.Icon().Color(p.borderColor).Src(visIcon)).Fn,
 161  						).
 162  						Fn,
 163  				).Fn,
 164  			).Fn,
 165  		).Fn(gtx)
 166  	}(gtx)
 167  }
 168  
 169  func (p *Password) GetPassword() string {
 170  	return p.passInput.editor.Text()
 171  }
 172  
 173  func (p *Password) Wipe() {
 174  	p.passInput.editor.editBuffer.Zero()
 175  	p.passInput.editor.SetText("")
 176  }
 177  
 178  func (p *Password) Focus() {
 179  	p.passInput.editor.Focus()
 180  }
 181  
 182  func (p *Password) Blur() {
 183  	p.passInput.editor.focused = false
 184  }
 185  
 186  func (p *Password) Hide() {
 187  	p.passInput.editor.Mask('*')
 188  }
 189  
 190  func (p *Password) Show() {
 191  	p.passInput.editor.Mask(0)
 192  }
 193