Commiting for C&C
This commit is contained in:
parent
56f12e4a58
commit
e0affc82d4
@ -1,6 +1,7 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -39,8 +40,8 @@ type listTimersScreen struct {
|
|||||||
|
|
||||||
selected map[int]bool
|
selected map[int]bool
|
||||||
|
|
||||||
inputDialog *widdles.InputDialog
|
confirm *widdles.ConfirmDialog
|
||||||
filter string
|
filter string
|
||||||
|
|
||||||
choiceMenu *widdles.MenuV
|
choiceMenu *widdles.MenuV
|
||||||
tagEditor *PromptForTagWiddle
|
tagEditor *PromptForTagWiddle
|
||||||
@ -53,13 +54,12 @@ type listTimersScreen struct {
|
|||||||
type ListTimersMsg ScreenMsg
|
type ListTimersMsg ScreenMsg
|
||||||
|
|
||||||
func NewListTimersScreen(u *Ui) *listTimersScreen {
|
func NewListTimersScreen(u *Ui) *listTimersScreen {
|
||||||
w, h := termbox.Size()
|
|
||||||
s := listTimersScreen{
|
s := listTimersScreen{
|
||||||
ui: u,
|
ui: u,
|
||||||
menu: widdles.NewTopMenu(0, 0, 0),
|
menu: widdles.NewTopMenu(0, 0, 0),
|
||||||
scrollbar: widdles.NewScrollbar(w-2, 2, 1, h-2),
|
scrollbar: widdles.NewScrollbar(0, 0, 0, 0),
|
||||||
selected: make(map[int]bool),
|
selected: make(map[int]bool),
|
||||||
inputDialog: widdles.NewInputDialog("", ""),
|
confirm: widdles.NewConfirmDialog("", ""),
|
||||||
|
|
||||||
choiceMenu: widdles.NewMenuV(0, 0, 0, 0),
|
choiceMenu: widdles.NewMenuV(0, 0, 0, 0),
|
||||||
tagEditor: NewPromptForTagWiddle(0, 0, widdles.AUTO_SIZE, widdles.AUTO_SIZE, "", ""),
|
tagEditor: NewPromptForTagWiddle(0, 0, widdles.AUTO_SIZE, widdles.AUTO_SIZE, "", ""),
|
||||||
@ -78,7 +78,7 @@ func (s *listTimersScreen) Init() wandle.Cmd {
|
|||||||
settingsOption.SetCommand(s.ui.GotoScreen(SettingsId))
|
settingsOption.SetCommand(s.ui.GotoScreen(SettingsId))
|
||||||
fileMenu.AddOption(settingsOption)
|
fileMenu.AddOption(settingsOption)
|
||||||
quitOption := widdles.NewMenuItem("Quit")
|
quitOption := widdles.NewMenuItem("Quit")
|
||||||
quitOption.Hotkey = termbox.KeyCtrlC
|
quitOption.SetHotkey(widdles.NewHotkey(termbox.KeyCtrlC))
|
||||||
quitOption.SetCommand(func() wandle.Msg { return wandle.Quit() })
|
quitOption.SetCommand(func() wandle.Msg { return wandle.Quit() })
|
||||||
fileMenu.AddOption(quitOption)
|
fileMenu.AddOption(quitOption)
|
||||||
s.menu.Measure()
|
s.menu.Measure()
|
||||||
@ -87,11 +87,10 @@ func (s *listTimersScreen) Init() wandle.Cmd {
|
|||||||
s.fullList = timertxt.NewTimerList()
|
s.fullList = timertxt.NewTimerList()
|
||||||
s.fullList.AddTimers(s.timerList.GetTimerSlice())
|
s.fullList.AddTimers(s.timerList.GetTimerSlice())
|
||||||
s.fullList.AddTimers(s.doneList.GetTimerSlice())
|
s.fullList.AddTimers(s.doneList.GetTimerSlice())
|
||||||
s.fullFilterList = s.fullList
|
|
||||||
s.timerFilterList, s.doneFilterList = s.timerList, s.doneList
|
s.timerFilterList, s.doneFilterList = s.timerList, s.doneList
|
||||||
s.fullFilterList.Sort(timertxt.SORT_START_DATE_DESC)
|
|
||||||
s.timerFilterList.Sort(timertxt.SORT_START_DATE_DESC)
|
s.timerFilterList.Sort(timertxt.SORT_START_DATE_DESC)
|
||||||
s.doneFilterList.Sort(timertxt.SORT_START_DATE_DESC)
|
s.doneFilterList.Sort(timertxt.SORT_START_DATE_DESC)
|
||||||
|
s.updateFullFilterList()
|
||||||
w, h := termbox.Size()
|
w, h := termbox.Size()
|
||||||
s.choiceMenu.SetBorder(wandle.BRD_CSIMPLE)
|
s.choiceMenu.SetBorder(wandle.BRD_CSIMPLE)
|
||||||
s.choiceMenu.SetX((w / 2) - 7)
|
s.choiceMenu.SetX((w / 2) - 7)
|
||||||
@ -103,6 +102,11 @@ func (s *listTimersScreen) Init() wandle.Cmd {
|
|||||||
s.tagEditor.SetY(h / 4)
|
s.tagEditor.SetY(h / 4)
|
||||||
s.tagEditor.SetWidth(w / 2)
|
s.tagEditor.SetWidth(w / 2)
|
||||||
s.tagEditor.SetHeight(h / 2)
|
s.tagEditor.SetHeight(h / 2)
|
||||||
|
s.confirm.EnableHotkeys()
|
||||||
|
s.confirm.SetX(w / 4)
|
||||||
|
s.confirm.SetY(h / 4)
|
||||||
|
s.confirm.SetWidth(w / 2)
|
||||||
|
s.confirm.SetHeight(h / 2)
|
||||||
s.updateFullFilterList()
|
s.updateFullFilterList()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -163,10 +167,13 @@ func (s *listTimersScreen) View(style wandle.Style) {
|
|||||||
y++
|
y++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wandle.Print(1, h-1, style, "[A]ctive toggle, [p]roject(+), [c]ontext(@), [t]ags(:)")
|
selectedStatus := fmt.Sprintf("%s", s.getSelectedTimerDuration())
|
||||||
if len(s.selected) > 0 {
|
if len(s.selected) > 0 {
|
||||||
wandle.Print(39, h-1, style, fmt.Sprintf("(%d selected)", len(s.selected)))
|
selectedStatus = fmt.Sprintf("%s (%d / %d selected)", selectedStatus, len(s.selected), s.fullFilterList.Size())
|
||||||
}
|
}
|
||||||
|
wandle.Print(1, h-2, style, selectedStatus)
|
||||||
|
help := "[T]oggle Display, [p]roject(+), [c]ontext(@), [t]ags(:), [A]rchive Selected, [Ctrl+A]: Select All/None, [Ctrl+I]: Invert Selection"
|
||||||
|
wandle.Print(1, h-1, style, help)
|
||||||
|
|
||||||
s.scrollbar.View(style)
|
s.scrollbar.View(style)
|
||||||
if s.menu.IsActive() {
|
if s.menu.IsActive() {
|
||||||
@ -178,6 +185,9 @@ func (s *listTimersScreen) View(style wandle.Style) {
|
|||||||
if s.tagEditor.IsActive() {
|
if s.tagEditor.IsActive() {
|
||||||
s.tagEditor.View(style)
|
s.tagEditor.View(style)
|
||||||
}
|
}
|
||||||
|
if s.confirm.IsActive() {
|
||||||
|
s.confirm.View(style)
|
||||||
|
}
|
||||||
wandle.Print(1, h-2, style, s.msg)
|
wandle.Print(1, h-2, style, s.msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,11 +196,13 @@ func (s *listTimersScreen) ViewTimer(x, y int, style wandle.Style, tmr *timertxt
|
|||||||
for _, k := range util.SortedTagKeyList(tmr.AdditionalTags) {
|
for _, k := range util.SortedTagKeyList(tmr.AdditionalTags) {
|
||||||
tags = append(tags, fmt.Sprintf("%s:%s", k, tmr.AdditionalTags[k]))
|
tags = append(tags, fmt.Sprintf("%s:%s", k, tmr.AdditionalTags[k]))
|
||||||
}
|
}
|
||||||
|
|
||||||
wandle.Print(x, y, style, fmt.Sprintf("%s %s %s %s %s", tmr.StartDate.Format(time.Stamp), tmr.Duration(), tmr.Contexts, tmr.Projects, strings.Join(tags, "; ")))
|
wandle.Print(x, y, style, fmt.Sprintf("%s %s %s %s %s", tmr.StartDate.Format(time.Stamp), tmr.Duration(), tmr.Contexts, tmr.Projects, strings.Join(tags, "; ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *listTimersScreen) handleTermboxEvent(msg termbox.Event) wandle.Cmd {
|
func (s *listTimersScreen) handleTermboxEvent(msg termbox.Event) wandle.Cmd {
|
||||||
|
if s.confirm.IsActive() {
|
||||||
|
return s.confirm.Update(msg)
|
||||||
|
}
|
||||||
if s.choiceMenu.IsActive() {
|
if s.choiceMenu.IsActive() {
|
||||||
return s.choiceMenu.Update(msg)
|
return s.choiceMenu.Update(msg)
|
||||||
}
|
}
|
||||||
@ -219,9 +231,11 @@ func (s *listTimersScreen) handleTermboxEvent(msg termbox.Event) wandle.Cmd {
|
|||||||
if s.cursor < s.fullFilterList.Size()-1 {
|
if s.cursor < s.fullFilterList.Size()-1 {
|
||||||
s.cursor++
|
s.cursor++
|
||||||
}
|
}
|
||||||
} else if msg.Ch == 'A' {
|
} else if msg.Ch == 'T' {
|
||||||
s.activeToggle = (s.activeToggle + 1) % activeToggleErr
|
s.activeToggle = (s.activeToggle + 1) % activeToggleErr
|
||||||
s.updateFullFilterList()
|
s.updateFullFilterList()
|
||||||
|
} else if msg.Ch == 'A' {
|
||||||
|
return s.showArchiveSelected()
|
||||||
} else if msg.Key == termbox.KeyArrowUp || msg.Ch == 'k' {
|
} else if msg.Key == termbox.KeyArrowUp || msg.Ch == 'k' {
|
||||||
if s.cursor > 0 {
|
if s.cursor > 0 {
|
||||||
s.cursor--
|
s.cursor--
|
||||||
@ -251,47 +265,131 @@ func (s *listTimersScreen) handleTermboxEvent(msg termbox.Event) wandle.Cmd {
|
|||||||
// TODO: Prompt for choice: Add/Edit/Remove
|
// TODO: Prompt for choice: Add/Edit/Remove
|
||||||
ctxts := s.fullList.GetContexts()
|
ctxts := s.fullList.GetContexts()
|
||||||
_ = ctxts
|
_ = ctxts
|
||||||
|
} else if msg.Key == termbox.KeyCtrlA {
|
||||||
|
if len(s.selected) != s.fullFilterList.Size() {
|
||||||
|
// Select None
|
||||||
|
for k := range s.selected {
|
||||||
|
delete(s.selected, k)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Select All
|
||||||
|
for i := 0; i < s.fullFilterList.Size(); i++ {
|
||||||
|
s.selected[i] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 0; i < s.fullFilterList.Size(); i++ {
|
||||||
|
if v := s.selected[i]; v {
|
||||||
|
delete(s.selected, i)
|
||||||
|
} else {
|
||||||
|
s.selected[i] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if msg.Key == termbox.KeyCtrlI {
|
||||||
|
for i := 0; i < s.fullFilterList.Size(); i++ {
|
||||||
|
if v := s.selected[i]; v {
|
||||||
|
delete(s.selected, i)
|
||||||
|
} else {
|
||||||
|
s.selected[i] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *listTimersScreen) showArchiveSelected() wandle.Cmd {
|
||||||
|
return func() wandle.Msg {
|
||||||
|
if len(s.selected) > 0 {
|
||||||
|
s.confirm.SetTitle(fmt.Sprintf("Archive %d Timers?", len(s.selected)))
|
||||||
|
s.confirm.SetMessage("Are you sure you want to archive these timers?")
|
||||||
|
} else {
|
||||||
|
s.confirm.SetTitle("Archive Timer?")
|
||||||
|
s.confirm.SetMessage("Are you sure you want to archive this timer?")
|
||||||
|
}
|
||||||
|
s.confirm.SetOkCommand(func() wandle.Msg {
|
||||||
|
s.confirm.SetVisible(false)
|
||||||
|
return s.doArchiveSelected()
|
||||||
|
})
|
||||||
|
s.confirm.SetCancelCommand(func() wandle.Msg {
|
||||||
|
s.confirm.SetVisible(false)
|
||||||
|
return wandle.EmptyCmd
|
||||||
|
})
|
||||||
|
s.confirm.SetVisible(true)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (s *listTimersScreen) doArchiveSelected() wandle.Cmd {
|
||||||
|
return func() wandle.Msg {
|
||||||
|
selected := len(s.selected)
|
||||||
|
if selected == 0 {
|
||||||
|
if s.cursor < s.fullFilterList.Size() {
|
||||||
|
var selTimer *timertxt.Timer
|
||||||
|
if selTimer, s.err = s.fullFilterList.GetTimer(s.cursor); s.err == nil {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := range s.selected {
|
||||||
|
if tmr, err := s.fullFilterList.GetTimer(i); err == nil {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
//return wandle.EmptyCmd
|
||||||
|
}
|
||||||
|
|
||||||
func (s *listTimersScreen) showEditTagsChoice() wandle.Cmd {
|
func (s *listTimersScreen) showEditTagsChoice() wandle.Cmd {
|
||||||
tags := s.getSelectedTimerTags()
|
tags := s.getSelectedTimerTags()
|
||||||
var showTagEditor = func(key, val string) wandle.Cmd {
|
var showTagEditor = func(key, val string, multival bool) wandle.Cmd {
|
||||||
return func() wandle.Msg {
|
return func() wandle.Msg {
|
||||||
s.tagEditor.SetTag(key, val)
|
s.tagEditor.SetTag(key, val)
|
||||||
// TODO: Set Done & Cancel Commands
|
s.tagEditor.SetDoneCommand(func() wandle.Msg {
|
||||||
|
s.updateTagOnSelectedTimers(s.tagEditor.GetTag())
|
||||||
|
s.tagEditor.Done()
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
s.tagEditor.SetCancelCommand(func() wandle.Msg {
|
||||||
|
s.tagEditor.SetActive(false)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
s.choiceMenu.SetActive(false)
|
s.choiceMenu.SetActive(false)
|
||||||
s.tagEditor.SetActive(true)
|
s.tagEditor.SetActive(true)
|
||||||
|
s.tagEditor.SetMultiVal(multival)
|
||||||
return wandle.EmptyCmd
|
return wandle.EmptyCmd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.choiceMenu.SetTitle("")
|
s.choiceMenu.SetTitle("")
|
||||||
s.choiceMenu.ClearOptions()
|
s.choiceMenu.ClearOptions()
|
||||||
addTag := widdles.NewMenuItem("Add New Tag")
|
addTag := widdles.NewMenuItem("[A]dd New Tag")
|
||||||
addTag.SetCommand(showTagEditor("", ""))
|
addTag.SetHotkey(widdles.NewHotkeyCh('a'))
|
||||||
|
addTag.SetCommand(showTagEditor("", "", false))
|
||||||
s.choiceMenu.AddOption(addTag)
|
s.choiceMenu.AddOption(addTag)
|
||||||
editTag := widdles.NewMenuItem("Edit Tag")
|
editTag := widdles.NewMenuItem("[E]dit Tag")
|
||||||
|
editTag.SetHotkey(widdles.NewHotkeyCh('e'))
|
||||||
editTag.SetEnabled(len(tags) > 0)
|
editTag.SetEnabled(len(tags) > 0)
|
||||||
editTag.SetCommand(func() wandle.Msg {
|
editTag.SetCommand(func() wandle.Msg {
|
||||||
s.choiceMenu.ClearOptions()
|
s.choiceMenu.ClearOptions()
|
||||||
s.choiceMenu.SetTitle("Choose Tag to Edit")
|
s.choiceMenu.SetTitle("Choose Tag to Edit")
|
||||||
for k, v := range tags {
|
for k, v := range tags {
|
||||||
var vals string
|
var vals string
|
||||||
|
var multival bool
|
||||||
if len(v) == 1 {
|
if len(v) == 1 {
|
||||||
vals = v[0]
|
vals = v[0]
|
||||||
} else {
|
} else {
|
||||||
vals = "..."
|
vals = ""
|
||||||
|
multival = true
|
||||||
}
|
}
|
||||||
opt := widdles.NewMenuItem(fmt.Sprintf("%s (%s)", k, vals))
|
opt := widdles.NewMenuItem(fmt.Sprintf("%s (%s)", k, vals))
|
||||||
opt.SetCommand(showTagEditor(k, vals))
|
opt.SetCommand(showTagEditor(k, vals, multival))
|
||||||
s.choiceMenu.AddOption(opt)
|
s.choiceMenu.AddOption(opt)
|
||||||
}
|
}
|
||||||
return wandle.EmptyCmd
|
return wandle.EmptyCmd
|
||||||
})
|
})
|
||||||
s.choiceMenu.AddOption(editTag)
|
s.choiceMenu.AddOption(editTag)
|
||||||
removeTag := widdles.NewMenuItem("Remove Tag")
|
removeTag := widdles.NewMenuItem("[R]emove Tag")
|
||||||
|
removeTag.SetHotkey(widdles.NewHotkeyCh('r'))
|
||||||
removeTag.SetCommand(func() wandle.Msg {
|
removeTag.SetCommand(func() wandle.Msg {
|
||||||
s.choiceMenu.ClearOptions()
|
s.choiceMenu.ClearOptions()
|
||||||
s.choiceMenu.SetTitle("Choose Tag to Remove")
|
s.choiceMenu.SetTitle("Choose Tag to Remove")
|
||||||
@ -330,12 +428,13 @@ func (s *listTimersScreen) gotoSettingsScreen() wandle.Msg {
|
|||||||
func (s *listTimersScreen) getSelectedTimerTags() map[string][]string {
|
func (s *listTimersScreen) getSelectedTimerTags() map[string][]string {
|
||||||
ret := make(map[string][]string)
|
ret := make(map[string][]string)
|
||||||
selected := len(s.selected)
|
selected := len(s.selected)
|
||||||
var selTimer *timertxt.Timer
|
|
||||||
if selected == 0 {
|
if selected == 0 {
|
||||||
if s.cursor < s.fullFilterList.Size() {
|
if s.cursor < s.fullFilterList.Size() {
|
||||||
selTimer, s.err = s.fullFilterList.GetTimer(s.cursor)
|
var selTimer *timertxt.Timer
|
||||||
for k, v := range selTimer.AdditionalTags {
|
if selTimer, s.err = s.fullFilterList.GetTimer(s.cursor); s.err == nil {
|
||||||
ret[k] = []string{v}
|
for k, v := range selTimer.AdditionalTags {
|
||||||
|
ret[k] = []string{v}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -351,15 +450,47 @@ func (s *listTimersScreen) getSelectedTimerTags() map[string][]string {
|
|||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
func (s *listTimersScreen) updateTagOnSelectedTimers(key, val string) {
|
||||||
|
selected := len(s.selected)
|
||||||
|
if selected == 0 {
|
||||||
|
if s.cursor < s.fullFilterList.Size() {
|
||||||
|
var selTimer *timertxt.Timer
|
||||||
|
if selTimer, s.err = s.fullFilterList.GetTimer(s.cursor); s.err == nil {
|
||||||
|
selTimer.AdditionalTags[key] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i := range s.selected {
|
||||||
|
if tmr, err := s.fullFilterList.GetTimer(i); err == nil {
|
||||||
|
tmr.AdditionalTags[key] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var errText string
|
||||||
|
if err := s.ui.program.WriteTimerList(); err != nil {
|
||||||
|
errText = fmt.Sprintf("Errors Writing Lists (%v)", err)
|
||||||
|
}
|
||||||
|
if err := s.ui.program.WriteDoneList(); err != nil {
|
||||||
|
if len(errText) == 0 {
|
||||||
|
errText = fmt.Sprintf("Errors Writing Lists (%v)", err)
|
||||||
|
} else {
|
||||||
|
errText = fmt.Sprintf("%s (%v)", errText, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(errText) > 0 {
|
||||||
|
s.err = errors.New(errText)
|
||||||
|
}
|
||||||
|
}
|
||||||
func (s *listTimersScreen) getSelectedTimerProjects() []string {
|
func (s *listTimersScreen) getSelectedTimerProjects() []string {
|
||||||
var ret []string
|
var ret []string
|
||||||
selected := len(s.selected)
|
selected := len(s.selected)
|
||||||
var selTimer *timertxt.Timer
|
|
||||||
if selected == 0 {
|
if selected == 0 {
|
||||||
if s.cursor < s.fullFilterList.Size() {
|
if s.cursor < s.fullFilterList.Size() {
|
||||||
selTimer, s.err = s.fullFilterList.GetTimer(s.cursor)
|
var selTimer *timertxt.Timer
|
||||||
for _, v := range selTimer.Projects {
|
if selTimer, s.err = s.fullFilterList.GetTimer(s.cursor); s.err == nil {
|
||||||
ret = append(ret, v)
|
for _, v := range selTimer.Projects {
|
||||||
|
ret = append(ret, v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -378,12 +509,13 @@ func (s *listTimersScreen) getSelectedTimerProjects() []string {
|
|||||||
func (s *listTimersScreen) getSelectedTimerContexts() []string {
|
func (s *listTimersScreen) getSelectedTimerContexts() []string {
|
||||||
var ret []string
|
var ret []string
|
||||||
selected := len(s.selected)
|
selected := len(s.selected)
|
||||||
var selTimer *timertxt.Timer
|
|
||||||
if selected == 0 {
|
if selected == 0 {
|
||||||
if s.cursor < s.fullFilterList.Size() {
|
if s.cursor < s.fullFilterList.Size() {
|
||||||
selTimer, s.err = s.fullFilterList.GetTimer(s.cursor)
|
var selTimer *timertxt.Timer
|
||||||
for _, v := range selTimer.Contexts {
|
if selTimer, s.err = s.fullFilterList.GetTimer(s.cursor); s.err == nil {
|
||||||
ret = append(ret, v)
|
for _, v := range selTimer.Contexts {
|
||||||
|
ret = append(ret, v)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -399,3 +531,21 @@ func (s *listTimersScreen) getSelectedTimerContexts() []string {
|
|||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
func (s *listTimersScreen) getSelectedTimerDuration() time.Duration {
|
||||||
|
selected := len(s.selected)
|
||||||
|
if selected == 0 {
|
||||||
|
if s.cursor < s.fullFilterList.Size() {
|
||||||
|
var selTimer *timertxt.Timer
|
||||||
|
if selTimer, s.err = s.fullFilterList.GetTimer(s.cursor); s.err == nil {
|
||||||
|
return util.Round(selTimer.Duration())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var ret time.Duration
|
||||||
|
for i := range s.selected {
|
||||||
|
if tmr, err := s.fullFilterList.GetTimer(i); err == nil {
|
||||||
|
ret = util.AddDurations(ret, util.Round(tmr.Duration()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
@ -29,7 +29,7 @@ func (s *settingsScreen) Init() wandle.Cmd {
|
|||||||
// Set up the top menu
|
// Set up the top menu
|
||||||
fileMenu := s.menu.NewSubMenu("File")
|
fileMenu := s.menu.NewSubMenu("File")
|
||||||
quitOption := widdles.NewMenuItem("Quit")
|
quitOption := widdles.NewMenuItem("Quit")
|
||||||
quitOption.Hotkey = termbox.KeyCtrlC
|
quitOption.SetHotkey(widdles.NewHotkey(termbox.KeyCtrlC))
|
||||||
quitOption.SetCommand(func() wandle.Msg { return wandle.Quit() })
|
quitOption.SetCommand(func() wandle.Msg { return wandle.Quit() })
|
||||||
fileMenu.AddOption(quitOption)
|
fileMenu.AddOption(quitOption)
|
||||||
gotoMenu := s.menu.NewSubMenu("Goto")
|
gotoMenu := s.menu.NewSubMenu("Goto")
|
||||||
|
@ -21,6 +21,8 @@ type PromptForTagWiddle struct {
|
|||||||
cancelButton *widdles.Button
|
cancelButton *widdles.Button
|
||||||
doneButton *widdles.Button
|
doneButton *widdles.Button
|
||||||
|
|
||||||
|
multipleValues bool
|
||||||
|
|
||||||
msg string
|
msg string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +74,13 @@ func (w *PromptForTagWiddle) View(style wandle.Style) {
|
|||||||
wandle.TitledBorderFilled(title, w.x, w.y, w.x+w.w, w.y+w.h, style, wandle.BRD_CSIMPLE)
|
wandle.TitledBorderFilled(title, w.x, w.y, w.x+w.w, w.y+w.h, style, wandle.BRD_CSIMPLE)
|
||||||
w.keyInput.View(style)
|
w.keyInput.View(style)
|
||||||
w.valInput.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.cancelButton.View(style)
|
||||||
w.doneButton.View(style)
|
w.doneButton.View(style)
|
||||||
wandle.Print(w.x+1, w.y+w.h-2, style, w.msg)
|
wandle.Print(w.x+1, w.y+w.h-2, style, w.msg)
|
||||||
@ -188,8 +197,22 @@ func (w *PromptForTagWiddle) SetTag(key, val string) {
|
|||||||
}
|
}
|
||||||
w.valInput.SetValue(val)
|
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) ClearCancelCommand() { w.SetCancelCommand(wandle.EmptyCmd) }
|
||||||
func (w *PromptForTagWiddle) SetCancelCommand(cmd func() wandle.Msg) { w.cancelButton.SetCommand(cmd) }
|
func (w *PromptForTagWiddle) SetCancelCommand(cmd func() wandle.Msg) { w.cancelButton.SetCommand(cmd) }
|
||||||
func (w *PromptForTagWiddle) ClearDoneCommand() { w.SetDoneCommand(wandle.EmptyCmd) }
|
func (w *PromptForTagWiddle) ClearDoneCommand() { w.SetDoneCommand(wandle.EmptyCmd) }
|
||||||
func (w *PromptForTagWiddle) SetDoneCommand(cmd func() wandle.Msg) { w.doneButton.SetCommand(cmd) }
|
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)
|
||||||
|
}
|
||||||
|
@ -102,6 +102,12 @@ func DurationToDecimal(dur time.Duration) float64 {
|
|||||||
mins := dur.Minutes() - (dur.Hours() * 60)
|
mins := dur.Minutes() - (dur.Hours() * 60)
|
||||||
return dur.Hours() + (mins / 60)
|
return dur.Hours() + (mins / 60)
|
||||||
}
|
}
|
||||||
|
func AddDurations(dur1, dur2 time.Duration) time.Duration {
|
||||||
|
return time.Duration(int64(dur1) + int64(dur2))
|
||||||
|
}
|
||||||
|
func SubDurations(dur1, dur2 time.Duration) time.Duration {
|
||||||
|
return time.Duration(int64(dur1) - int64(dur2))
|
||||||
|
}
|
||||||
|
|
||||||
// GetContextsFromSlice pulls all '@' (contexts) out of the
|
// GetContextsFromSlice pulls all '@' (contexts) out of the
|
||||||
// string slice and return those contexts and the remaining
|
// string slice and return those contexts and the remaining
|
||||||
|
Loading…
Reference in New Issue
Block a user