package ui import ( "git.bullercodeworks.com/brian/wandle" "git.bullercodeworks.com/brian/widdles" "github.com/nsf/termbox-go" ) /* * A widdle to prompt the user for a tag key and value */ type PromptForTagWiddle struct { active bool x, y, w, h int origKey, origVal string keyInput *widdles.ToggleField valInput *widdles.ToggleField cancelButton *widdles.Button doneButton *widdles.Button multipleValues bool msg string } var _ widdles.Widdle = (*PromptForTagWiddle)(nil) func NewPromptForTagWiddle(x, y, w, h int, key, val string) *PromptForTagWiddle { keyInp := widdles.NewToggleField("Key", key, 0, 0, 0, 0) keyInp.SetActive(true) return &PromptForTagWiddle{ x: x, y: y, w: w, h: h, origKey: key, origVal: val, keyInput: keyInp, valInput: widdles.NewToggleField("Value", val, 0, 0, 0, 0), cancelButton: widdles.NewButton("Cancel", 0, 0, 0, 0), doneButton: widdles.NewButton("Done", 0, 0, 0, 0), } } func (w *PromptForTagWiddle) Init() wandle.Cmd { return func() wandle.Msg { w.Measure() return nil } } func (w *PromptForTagWiddle) Update(msg wandle.Msg) wandle.Cmd { if w.active { // Make sure a widdle is active var found bool for _, wdl := range []widdles.Widdle{w.keyInput, w.valInput, w.cancelButton, w.doneButton} { if wdl.IsActive() { found = true break } } if !found { w.keyInput.SetActive(true) } if msg, ok := msg.(termbox.Event); ok { return w.handleTermboxEvent(msg) } } return nil } func (w *PromptForTagWiddle) View(style wandle.Style) { title := "Add Tag" if w.origKey != "" { title = "Edit Tag" } wandle.TitledBorderFilled(title, w.x, w.y, w.x+w.w, w.y+w.h, style, wandle.BRD_CSIMPLE) w.keyInput.View(style) w.valInput.View(style) if w.multipleValues { red := wandle.NewStyle( termbox.RGBToAttribute(uint8(200), uint8(0), uint8(0)), termbox.RGBToAttribute(uint8(0), uint8(0), uint8(0)), ) wandle.Print(w.valInput.GetX(), w.valInput.GetY()+1, red, "Changing a tag on timers that have different values!") } w.cancelButton.View(style) w.doneButton.View(style) wandle.Print(w.x+1, w.y+w.h-2, style, w.msg) } func (w *PromptForTagWiddle) IsActive() bool { return w.active } func (w *PromptForTagWiddle) SetActive(b bool) { w.active = b } func (w *PromptForTagWiddle) Focusable() bool { return true } func (w *PromptForTagWiddle) SetX(x int) { w.x = x w.Measure() } func (w *PromptForTagWiddle) GetX() int { return w.x } func (w *PromptForTagWiddle) SetY(y int) { w.y = y w.Measure() } func (w *PromptForTagWiddle) GetY() int { return w.y } func (w *PromptForTagWiddle) SetHeight(h int) { w.h = h w.Measure() } func (w *PromptForTagWiddle) GetHeight() int { //if w.h == widdles.AUTO_SIZE { } return w.h } func (w *PromptForTagWiddle) SetWidth(v int) { w.w = v w.Measure() } func (w *PromptForTagWiddle) GetWidth() int { //if w.w == widdles.AUTO_SIZE { } return w.w } func (w *PromptForTagWiddle) Measure() { w.keyInput.SetX(w.x + 1) w.keyInput.SetY(w.y + 1) w.keyInput.SetWidth(w.w - 2) w.keyInput.SetHeight(1) w.valInput.SetX(w.x + 1) w.valInput.SetY(w.y + 2) w.valInput.SetWidth(w.w - 2) w.valInput.SetHeight(1) w.doneButton.SetX(w.x + w.w - 9) w.doneButton.SetY(w.y + w.h - 1) w.doneButton.SetWidth(8) w.doneButton.SetHeight(1) w.cancelButton.SetX(w.doneButton.GetX() - 12) w.cancelButton.SetY(w.y + w.h - 1) w.cancelButton.SetWidth(10) w.cancelButton.SetHeight(1) } func (w *PromptForTagWiddle) handleTermboxEvent(msg termbox.Event) wandle.Cmd { if msg.Key == termbox.KeyEnter { if w.keyInput.IsEditable() { w.keyInput.SetActive(false) w.keyInput.SetEditable(false) w.valInput.SetActive(true) w.valInput.SetEditable(true) return wandle.EmptyCmd } else if w.valInput.IsEditable() { w.valInput.SetActive(false) w.valInput.SetEditable(false) if w.keyInput.GetValue() != "" && w.valInput.GetValue() != "" { w.doneButton.SetActive(true) } else { w.cancelButton.SetActive(true) } return wandle.EmptyCmd } } widdles := []widdles.Widdle{w.keyInput, w.valInput, w.cancelButton, w.doneButton} for _, wdl := range widdles { if wdl.IsActive() { if ret := wdl.Update(msg); ret != nil { return ret } } } if msg.Ch == 'j' || msg.Key == termbox.KeyArrowDown || msg.Key == termbox.KeyArrowRight { for i := range widdles { if widdles[i].IsActive() { return func() wandle.Msg { widdles[i].SetActive(false) next := ((i + 1) + len(widdles)) % len(widdles) widdles[next].SetActive(true) return nil } } } } else if msg.Ch == 'k' || msg.Key == termbox.KeyArrowUp || msg.Key == termbox.KeyArrowLeft { for i := range widdles { if widdles[i].IsActive() { return func() wandle.Msg { widdles[i].SetActive(false) next := ((i - 1) + len(widdles)) % len(widdles) widdles[next].SetActive(true) return nil } } } } return nil } func (w *PromptForTagWiddle) SetTag(key, val string) { w.origKey, w.origVal = key, val w.keyInput.SetValue(key) if key == "" && val == "" { w.keyInput.SetEditable(true) } w.valInput.SetValue(val) } func (w *PromptForTagWiddle) GetTag() (string, string) { return w.keyInput.GetValue(), w.valInput.GetValue() } func (w *PromptForTagWiddle) SetMultiVal(v bool) { w.multipleValues = v } func (w *PromptForTagWiddle) ClearCancelCommand() { w.SetCancelCommand(wandle.EmptyCmd) } func (w *PromptForTagWiddle) SetCancelCommand(cmd func() wandle.Msg) { w.cancelButton.SetCommand(cmd) } func (w *PromptForTagWiddle) ClearDoneCommand() { w.SetDoneCommand(wandle.EmptyCmd) } func (w *PromptForTagWiddle) SetDoneCommand(cmd func() wandle.Msg) { w.doneButton.SetCommand(cmd) } func (w *PromptForTagWiddle) Done() { w.origKey, w.origVal = "", "" w.multipleValues = false w.keyInput.SetValue("") w.valInput.SetValue("") w.ClearCancelCommand() w.ClearDoneCommand() w.SetActive(false) }