package main import ( "fmt" "os/exec" "strconv" "strings" "time" "gogs.bullercodeworks.com/brian/termbox-util" "github.com/boltdb/bolt" "github.com/nsf/termbox-go" ) var databaseFile string var db *bolt.DB // TabStops const ( tabMain = iota tabNotepad tabError ) type mainScreen struct { initialized bool tabIdx int updateTime time.Time battStat *termboxUtil.ProgressBar notepad *termboxUtil.InputField } func (screen *mainScreen) handleKeyPress(event termbox.Event) int { if event.Type == termbox.EventKey { if event.Key == termbox.KeyTab { screen.tabIdx = (screen.tabIdx + 1) % tabError return mainScreenIndex } switch screen.tabIdx { case tabMain: // Main Screen key handling if event.Key == termbox.KeyEsc { return exitScreenIndex /* } else if event.Ch == 'R' { state.autoUpdate = true } else if event.Ch == '+' { screen.decreaseUpdateFreq() } else if event.Ch == '-' { screen.increaseUpdateFreq() */ } else if event.Ch == 'r' { // Refresh data screen.refreshData() } else if event.Ch == 'q' { return exitScreenIndex } case tabNotepad: // Notepad key handling screen.notepad.HandleKeyPress(event) } } return mainScreenIndex } func (screen *mainScreen) decreaseUpdateFreq() { if state.updateFreq > 60 { state.updateFreq += 60 } else { state.updateFreq += 5 } } func (screen *mainScreen) increaseUpdateFreq() { if state.updateFreq > 60 { state.updateFreq -= 60 } else { state.updateFreq -= 5 } } func (screen *mainScreen) refreshData() { screen.updateTime = time.Now() screen.battStat.SetProgress(getBatteryPct()) } func (screen *mainScreen) performLayout(style style) { if !screen.initialized { w, h := termbox.Size() // Battery Bar screen.battStat = termboxUtil.CreateProgressBar(100, w-14, 1, style.defaultFg, style.defaultBg) screen.battStat.SetColorized(true) // Notepad screen.notepad = termboxUtil.CreateInputField(1, 4, (w / 4), (h / 4), style.defaultFg, style.defaultBg) screen.notepad.SetBordered(true) screen.notepad.SetWrap(true) // TODO: Load saved notepad data screen.refreshData() } if time.Since(time.Now()) <= time.Minute { screen.refreshData() } screen.initialized = true } func (screen *mainScreen) drawScreen(style style) { fg, bg := style.defaultFg, style.defaultBg selFg, selBg := style.cursorFg, style.cursorBg w, h := termbox.Size() // Top Bar if screen.tabIdx == tabMain { fg, bg = selFg, selBg } termboxUtil.DrawStringAtPoint(screen.updateTime.Format("15:04:05 MST"), 0, 0, fg, bg) termboxUtil.DrawStringAtPoint(screen.updateTime.Format("02 Jan 2006"), 0, 1, fg, bg) fg, bg = style.defaultFg, style.defaultBg screen.battStat.Draw() termboxUtil.DrawStringAtPoint(fmt.Sprintf("% 3d%s", screen.battStat.GetPercent(), "%"), screen.battStat.GetX()+screen.battStat.GetWidth(), screen.battStat.GetY(), fg, bg) // Bottom Bar termboxUtil.DrawStringAtPoint(getNetworkProfile(), 0, h-1, fg, bg) refreshText := "(r)efresh" if state.autoUpdate { refreshText = "Auto-Refresh On (" if state.updateFreq >= 60 { refreshText += strconv.Itoa(int(state.updateFreq/time.Minute)) + "m" } else { refreshText += strconv.Itoa(int(state.updateFreq/time.Second)) + "s" } refreshText += ")" } helpTxt := "(q)uit " + refreshText termboxUtil.DrawStringAtPoint(helpTxt, (w - len(helpTxt)), h-1, fg, bg) // Notepad if screen.tabIdx == tabNotepad { fg, bg = selFg, selBg } termboxUtil.DrawStringAtPoint("Notes", screen.notepad.GetX(), screen.notepad.GetY()-1, fg, bg) fg, bg = style.defaultFg, style.defaultBg screen.notepad.Draw() termboxUtil.DrawStringAtPoint(screen.notepad.GetValue(), screen.notepad.GetX()+7, screen.notepad.GetY()-1, fg, bg) } func getBatteryPct() int { powerApp := "upower" powerArg1 := "-i" powerArg2 := "/org/freedesktop/UPower/devices/battery_BAT0" cmd := exec.Command(powerApp, powerArg1, powerArg2) stdout, err := cmd.Output() if err != nil { return -1 } tst := string(stdout) for _, k := range strings.Split(tst, "\n") { pair := strings.Split(k, ":") if len(pair) > 1 { pair[0] = strings.Trim(pair[0], " ") pair[1] = strings.Trim(pair[1], " %") if pair[0] == "percentage" { if pct, err := strconv.Atoi(pair[1]); err == nil { return pct } } } } return -1 } func getNetworkProfile() string { netApp := "netctl" netArg1 := "list" cmd := exec.Command(netApp, netArg1) stdout, err := cmd.Output() if err == nil { tst := string(stdout) for _, k := range strings.Split(tst, "\n") { pair := strings.Split(k, " ") if len(pair) > 1 { if pair[0] == "*" { return pair[1] } } } } return "Network Info Unavailable" } func loadState() { db, err = bolt.Open(databaseFile, 0600, nil) db.View(func(tx *bolt.Tx) error { return tx.ForEach(func(nm []byte, b *bolt.Bucket) error { bb, err := readBucket(b) if err == nil { bb.name = string(nm) } return err }) }) db.Close() } func saveState() { db, err = bolt.Open(databaseFile, 0600, nil) db.Close() }