Syncing Up
This commit is contained in:
parent
4082154523
commit
97aa2ce9d0
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/boltdb/bolt"
|
"github.com/boltdb/bolt"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -266,11 +267,10 @@ func deleteKey(path []string) error {
|
|||||||
return errors.New("deleteKey: Invalid Path")
|
return errors.New("deleteKey: Invalid Path")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
refreshDatabase()
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func refreshDatabase() {
|
func refreshDatabase() *BoltDB {
|
||||||
// Reload the database into memBolt
|
// Reload the database into memBolt
|
||||||
memBolt = new(BoltDB)
|
memBolt = new(BoltDB)
|
||||||
db.View(func(tx *bolt.Tx) error {
|
db.View(func(tx *bolt.Tx) error {
|
||||||
@ -287,6 +287,7 @@ func refreshDatabase() {
|
|||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
return memBolt
|
||||||
}
|
}
|
||||||
|
|
||||||
func readBucket(b *bolt.Bucket) (*BoltBucket, error) {
|
func readBucket(b *bolt.Bucket) (*BoltBucket, error) {
|
||||||
@ -320,3 +321,83 @@ func updatePaths(b *BoltBucket) {
|
|||||||
b.pairs[i].path = append(b.path, b.pairs[i].key)
|
b.pairs[i].path = append(b.path, b.pairs[i].key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
func renameBucket(path []string, name string) error {
|
||||||
|
err := db.Update(func(tx *bolt.Tx) error {
|
||||||
|
// len(b.path)-1 is the key we need to delete, the rest are buckets leading to that key
|
||||||
|
b := tx.Bucket([]byte(path[0]))
|
||||||
|
if b != nil {
|
||||||
|
if len(path) > 1 {
|
||||||
|
for i := range path[1 : len(path)-1] {
|
||||||
|
b = b.Bucket([]byte(path[i+1]))
|
||||||
|
if b == nil {
|
||||||
|
return errors.New("updatePairValue: Invalid Path")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Now update the last key in the path
|
||||||
|
err := b.Put([]byte(path[len(path)-1]), []byte(v))
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
return errors.New("renameBucket: Invalid Path")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
refreshDatabase()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
func updatePairValue(path []string, v string) error {
|
||||||
|
err := db.Update(func(tx *bolt.Tx) error {
|
||||||
|
// len(b.path)-1 is the key we need to delete, the rest are buckets leading to that key
|
||||||
|
b := tx.Bucket([]byte(path[0]))
|
||||||
|
if b != nil {
|
||||||
|
if len(path) > 1 {
|
||||||
|
for i := range path[1 : len(path)-1] {
|
||||||
|
b = b.Bucket([]byte(path[i+1]))
|
||||||
|
if b == nil {
|
||||||
|
return errors.New("updatePairValue: Invalid Path")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Now update the last key in the path
|
||||||
|
err := b.Put([]byte(path[len(path)-1]), []byte(v))
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
return errors.New("updatePairValue: Invalid Path")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func insertBucket(path []string, n string) error {
|
||||||
|
// Inserts a new bucket named 'n' at 'path[len(path)-2]
|
||||||
|
err := db.Update(func(tx *bolt.Tx) error {
|
||||||
|
if len(path) == 1 {
|
||||||
|
// insert at root
|
||||||
|
_, err := tx.CreateBucket([]byte(n))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("insertBucket: %s", err)
|
||||||
|
}
|
||||||
|
} else if len(path) > 1 {
|
||||||
|
var err error
|
||||||
|
b := tx.Bucket([]byte(path[0]))
|
||||||
|
if b != nil {
|
||||||
|
if len(path) > 2 {
|
||||||
|
for i := range path[1 : len(path)-2] {
|
||||||
|
b = b.Bucket([]byte(path[i+1]))
|
||||||
|
if b == nil {
|
||||||
|
return fmt.Errorf("insertBucket: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err := b.CreateBucket([]byte(n))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("insertBucket: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
@ -64,13 +64,15 @@ func (screen *AboutScreen) drawScreen(style Style) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
commands1 := [...]Command{
|
commands1 := [...]Command{
|
||||||
{"h", "close parent"},
|
{"h,←", "close parent"},
|
||||||
{"j", "down"},
|
{"j,↓", "down"},
|
||||||
{"k", "up"},
|
{"k,↑", "up"},
|
||||||
{"l", "open item"},
|
{"l,→", "open item"},
|
||||||
|
|
||||||
{"g", "goto top"},
|
{"g", "goto top"},
|
||||||
{"G", "goto bottom"},
|
{"G", "goto bottom"},
|
||||||
|
{"ctrl+f", "jump half-screen down"},
|
||||||
|
{"ctrl+b", "jump half-screen up"},
|
||||||
}
|
}
|
||||||
|
|
||||||
commands2 := [...]Command{
|
commands2 := [...]Command{
|
||||||
|
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/nsf/termbox-go"
|
"github.com/nsf/termbox-go"
|
||||||
|
"gogs.bullercodeworks.com/brian/termbox-util"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,6 +21,27 @@ type BrowserScreen struct {
|
|||||||
current_path []string
|
current_path []string
|
||||||
current_type int
|
current_type int
|
||||||
message string
|
message string
|
||||||
|
mode BrowserMode
|
||||||
|
input_modal *InputModal
|
||||||
|
}
|
||||||
|
|
||||||
|
type BrowserMode int
|
||||||
|
|
||||||
|
const (
|
||||||
|
MODE_BROWSE = iota
|
||||||
|
MODE_CHANGE_VAL
|
||||||
|
MODE_INSERT_BUCKET
|
||||||
|
MODE_INSERT_PAIR
|
||||||
|
)
|
||||||
|
|
||||||
|
type InputModal struct {
|
||||||
|
x int
|
||||||
|
y int
|
||||||
|
width int
|
||||||
|
height int
|
||||||
|
text string
|
||||||
|
curr_val string
|
||||||
|
current_cursor int
|
||||||
}
|
}
|
||||||
|
|
||||||
type BoltType int
|
type BoltType int
|
||||||
@ -30,89 +52,82 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (screen *BrowserScreen) handleKeyEvent(event termbox.Event) int {
|
func (screen *BrowserScreen) handleKeyEvent(event termbox.Event) int {
|
||||||
|
if screen.mode == MODE_BROWSE {
|
||||||
|
return screen.handleBrowseKeyEvent(event)
|
||||||
|
} else if screen.mode == MODE_CHANGE_VAL {
|
||||||
|
return screen.handleInputKeyEvent(event)
|
||||||
|
} else if screen.mode == MODE_INSERT_BUCKET {
|
||||||
|
return screen.handleInsertBucketKeyEvent(event)
|
||||||
|
}
|
||||||
|
return BROWSER_SCREEN_INDEX
|
||||||
|
}
|
||||||
|
|
||||||
|
func (screen *BrowserScreen) handleBrowseKeyEvent(event termbox.Event) int {
|
||||||
if event.Ch == '?' {
|
if event.Ch == '?' {
|
||||||
// About
|
// About
|
||||||
return ABOUT_SCREEN_INDEX
|
return ABOUT_SCREEN_INDEX
|
||||||
|
|
||||||
} else if event.Ch == 'q' || event.Key == termbox.KeyEsc || event.Key == termbox.KeyCtrlC {
|
} else if event.Ch == 'q' || event.Key == termbox.KeyEsc || event.Key == termbox.KeyCtrlC {
|
||||||
// Quit
|
// Quit
|
||||||
return EXIT_SCREEN_INDEX
|
return EXIT_SCREEN_INDEX
|
||||||
|
|
||||||
} else if event.Ch == 'g' {
|
} else if event.Ch == 'g' {
|
||||||
// Jump to Beginning
|
// Jump to Beginning
|
||||||
screen.current_path = screen.db.getNextVisiblePath(nil)
|
screen.current_path = screen.db.getNextVisiblePath(nil)
|
||||||
|
|
||||||
} else if event.Ch == 'G' {
|
} else if event.Ch == 'G' {
|
||||||
// Jump to End
|
// Jump to End
|
||||||
screen.current_path = screen.db.getPrevVisiblePath(nil)
|
screen.current_path = screen.db.getPrevVisiblePath(nil)
|
||||||
|
|
||||||
} else if event.Key == termbox.KeyCtrlF {
|
} else if event.Key == termbox.KeyCtrlF {
|
||||||
// Jump forward half a screen
|
// Jump forward half a screen
|
||||||
_, h := termbox.Size()
|
_, h := termbox.Size()
|
||||||
half := h / 2
|
half := h / 2
|
||||||
vis_paths, err := screen.db.buildVisiblePathSlice(nil)
|
screen.jumpCursorDown(half)
|
||||||
if err == nil {
|
|
||||||
find_path := strings.Join(screen.current_path, "/")
|
|
||||||
start_jump := false
|
|
||||||
for i := range vis_paths {
|
|
||||||
if vis_paths[i] == find_path {
|
|
||||||
start_jump = true
|
|
||||||
}
|
|
||||||
if start_jump {
|
|
||||||
half -= 1
|
|
||||||
if half == 0 {
|
|
||||||
screen.current_path = strings.Split(vis_paths[i], "/")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if strings.Join(screen.current_path, "/") == find_path {
|
|
||||||
screen.current_path = screen.db.getPrevVisiblePath(nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if event.Key == termbox.KeyCtrlB {
|
} else if event.Key == termbox.KeyCtrlB {
|
||||||
// Jump back half a screen
|
|
||||||
_, h := termbox.Size()
|
_, h := termbox.Size()
|
||||||
half := h / 2
|
half := h / 2
|
||||||
vis_paths, err := screen.db.buildVisiblePathSlice(nil)
|
screen.jumpCursorUp(half)
|
||||||
if err == nil {
|
|
||||||
find_path := strings.Join(screen.current_path, "/")
|
|
||||||
start_jump := false
|
|
||||||
for i := range vis_paths {
|
|
||||||
if vis_paths[len(vis_paths)-1-i] == find_path {
|
|
||||||
start_jump = true
|
|
||||||
}
|
|
||||||
if start_jump {
|
|
||||||
half -= 1
|
|
||||||
if half == 0 {
|
|
||||||
screen.current_path = strings.Split(vis_paths[len(vis_paths)-1-i], "/")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if strings.Join(screen.current_path, "/") == find_path {
|
|
||||||
screen.current_path = screen.db.getNextVisiblePath(nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if event.Ch == 'j' || event.Key == termbox.KeyArrowDown {
|
} else if event.Ch == 'j' || event.Key == termbox.KeyArrowDown {
|
||||||
screen.moveCursorDown()
|
screen.moveCursorDown()
|
||||||
|
|
||||||
} else if event.Ch == 'k' || event.Key == termbox.KeyArrowUp {
|
} else if event.Ch == 'k' || event.Key == termbox.KeyArrowUp {
|
||||||
screen.moveCursorUp()
|
screen.moveCursorUp()
|
||||||
|
|
||||||
|
} else if event.Ch == 'p' {
|
||||||
|
screen.insertPair()
|
||||||
|
|
||||||
|
} else if event.Ch == 'b' {
|
||||||
|
screen.insertBucket()
|
||||||
|
|
||||||
} else if event.Ch == 'e' {
|
} else if event.Ch == 'e' {
|
||||||
screen.queued_command = "edit"
|
_, p, _ := screen.db.getGenericFromPath(screen.current_path)
|
||||||
|
if p != nil {
|
||||||
|
screen.createEditModal()
|
||||||
|
}
|
||||||
|
screen.message = "Cannot edit a bucket yet"
|
||||||
|
|
||||||
} else if event.Key == termbox.KeyEnter {
|
} else if event.Key == termbox.KeyEnter {
|
||||||
b, p, _ := screen.db.getGenericFromPath(screen.current_path)
|
b, p, _ := screen.db.getGenericFromPath(screen.current_path)
|
||||||
if b != nil {
|
if b != nil {
|
||||||
toggleOpenBucket(screen.current_path)
|
toggleOpenBucket(screen.current_path)
|
||||||
} else if p != nil {
|
} else if p != nil {
|
||||||
} else {
|
screen.createEditModal()
|
||||||
screen.message = "Not sure what to do here..."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if event.Ch == 'l' || event.Key == termbox.KeyArrowRight {
|
} else if event.Ch == 'l' || event.Key == termbox.KeyArrowRight {
|
||||||
b, p, _ := screen.db.getGenericFromPath(screen.current_path)
|
b, p, _ := screen.db.getGenericFromPath(screen.current_path)
|
||||||
// Select the current item
|
// Select the current item
|
||||||
if b != nil {
|
if b != nil {
|
||||||
toggleOpenBucket(screen.current_path)
|
toggleOpenBucket(screen.current_path)
|
||||||
} else if p != nil {
|
} else if p != nil {
|
||||||
|
screen.createEditModal()
|
||||||
} else {
|
} else {
|
||||||
screen.message = "Not sure what to do here..."
|
screen.message = "Not sure what to do here..."
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if event.Ch == 'h' || event.Key == termbox.KeyArrowLeft {
|
} else if event.Ch == 'h' || event.Key == termbox.KeyArrowLeft {
|
||||||
// If we are _on_ a bucket that's open, close it
|
// If we are _on_ a bucket that's open, close it
|
||||||
b, _, e := screen.db.getGenericFromPath(screen.current_path)
|
b, _, e := screen.db.getGenericFromPath(screen.current_path)
|
||||||
@ -130,12 +145,121 @@ func (screen *BrowserScreen) handleKeyEvent(event termbox.Event) int {
|
|||||||
closeBucket(screen.current_path)
|
closeBucket(screen.current_path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if event.Ch == 'D' {
|
} else if event.Ch == 'D' {
|
||||||
deleteKey(screen.current_path)
|
deleteKey(screen.current_path)
|
||||||
|
screen.current_path = screen.current_path[:len(screen.current_path)-1]
|
||||||
}
|
}
|
||||||
return BROWSER_SCREEN_INDEX
|
return BROWSER_SCREEN_INDEX
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (screen *BrowserScreen) handleInputKeyEvent(event termbox.Event) int {
|
||||||
|
if event.Key == termbox.KeyEsc {
|
||||||
|
screen.mode = MODE_BROWSE
|
||||||
|
} else if event.Key == termbox.KeyEnter {
|
||||||
|
b, p, e := screen.db.getGenericFromPath(screen.current_path)
|
||||||
|
if e == nil {
|
||||||
|
if b != nil {
|
||||||
|
screen.message = "Cannot edit bucket"
|
||||||
|
} else if p != nil {
|
||||||
|
if err := updatePairValue(screen.current_path, screen.input_modal.curr_val); err != nil {
|
||||||
|
screen.message = fmt.Sprint(err)
|
||||||
|
} else {
|
||||||
|
p.val = screen.input_modal.curr_val
|
||||||
|
}
|
||||||
|
screen.mode = MODE_BROWSE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if event.Key == termbox.KeyBackspace || event.Key == termbox.KeyBackspace2 || event.Key == termbox.KeyDelete {
|
||||||
|
screen.input_modal.curr_val = screen.input_modal.curr_val[:len(screen.input_modal.curr_val)-1]
|
||||||
|
} else {
|
||||||
|
screen.input_modal.curr_val += string(event.Ch)
|
||||||
|
}
|
||||||
|
return BROWSER_SCREEN_INDEX
|
||||||
|
}
|
||||||
|
|
||||||
|
func (screen *BrowserScreen) handleInsertBucketKeyEvent(event termbox.Event) int {
|
||||||
|
if event.Key == termbox.KeyEsc {
|
||||||
|
screen.mode = MODE_BROWSE
|
||||||
|
} else if event.Key == termbox.KeyEnter {
|
||||||
|
b, p, e := screen.db.getGenericFromPath(screen.current_path)
|
||||||
|
if e == nil {
|
||||||
|
if b != nil {
|
||||||
|
if err := insertBucket(screen.current_path, screen.input_modal.curr_val); err != nil {
|
||||||
|
screen.message = fmt.Sprint(err)
|
||||||
|
} else {
|
||||||
|
if b.parent != nil {
|
||||||
|
//b.parent.buckets = append(b.parent.buckets, BoltBucket{name: screen.input_modal.curr_val
|
||||||
|
} else {
|
||||||
|
//screen.db.buckets = append(screen.db.buckets, BoltBucket{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
screen.mode = MODE_BROWSE
|
||||||
|
} else if p != nil {
|
||||||
|
if err := updatePairValue(screen.current_path, screen.input_modal.curr_val); err != nil {
|
||||||
|
screen.message = fmt.Sprint(err)
|
||||||
|
} else {
|
||||||
|
p.val = screen.input_modal.curr_val
|
||||||
|
}
|
||||||
|
screen.mode = MODE_BROWSE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if event.Key == termbox.KeyBackspace || event.Key == termbox.KeyBackspace2 || event.Key == termbox.KeyDelete {
|
||||||
|
screen.input_modal.curr_val = screen.input_modal.curr_val[:len(screen.input_modal.curr_val)-1]
|
||||||
|
} else {
|
||||||
|
screen.input_modal.curr_val += string(event.Ch)
|
||||||
|
}
|
||||||
|
return BROWSER_SCREEN_INDEX
|
||||||
|
}
|
||||||
|
|
||||||
|
func (screen *BrowserScreen) jumpCursorUp(distance int) bool {
|
||||||
|
// Jump up 'distance' lines
|
||||||
|
vis_paths, err := screen.db.buildVisiblePathSlice(nil)
|
||||||
|
if err == nil {
|
||||||
|
find_path := strings.Join(screen.current_path, "/")
|
||||||
|
start_jump := false
|
||||||
|
for i := range vis_paths {
|
||||||
|
if vis_paths[len(vis_paths)-1-i] == find_path {
|
||||||
|
start_jump = true
|
||||||
|
}
|
||||||
|
if start_jump {
|
||||||
|
distance -= 1
|
||||||
|
if distance == 0 {
|
||||||
|
screen.current_path = strings.Split(vis_paths[len(vis_paths)-1-i], "/")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if strings.Join(screen.current_path, "/") == find_path {
|
||||||
|
screen.current_path = screen.db.getNextVisiblePath(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
func (screen *BrowserScreen) jumpCursorDown(distance int) bool {
|
||||||
|
vis_paths, err := screen.db.buildVisiblePathSlice(nil)
|
||||||
|
if err == nil {
|
||||||
|
find_path := strings.Join(screen.current_path, "/")
|
||||||
|
start_jump := false
|
||||||
|
for i := range vis_paths {
|
||||||
|
if vis_paths[i] == find_path {
|
||||||
|
start_jump = true
|
||||||
|
}
|
||||||
|
if start_jump {
|
||||||
|
distance -= 1
|
||||||
|
if distance == 0 {
|
||||||
|
screen.current_path = strings.Split(vis_paths[i], "/")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if strings.Join(screen.current_path, "/") == find_path {
|
||||||
|
screen.current_path = screen.db.getPrevVisiblePath(nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (screen *BrowserScreen) moveCursorUp() bool {
|
func (screen *BrowserScreen) moveCursorUp() bool {
|
||||||
new_path := screen.db.getPrevVisiblePath(screen.current_path)
|
new_path := screen.db.getPrevVisiblePath(screen.current_path)
|
||||||
if new_path != nil {
|
if new_path != nil {
|
||||||
@ -160,16 +284,41 @@ func (screen *BrowserScreen) drawScreen(style Style) {
|
|||||||
screen.drawRightPane(style)
|
screen.drawRightPane(style)
|
||||||
screen.drawHeader(style)
|
screen.drawHeader(style)
|
||||||
screen.drawFooter(style)
|
screen.drawFooter(style)
|
||||||
|
if screen.mode == MODE_CHANGE_VAL {
|
||||||
|
screen.drawInput(style)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (screen *BrowserScreen) drawInput(style Style) {
|
||||||
|
box_x := screen.input_modal.x
|
||||||
|
box_y := screen.input_modal.y
|
||||||
|
box_width := screen.input_modal.width
|
||||||
|
box_height := screen.input_modal.height
|
||||||
|
|
||||||
|
termbox_util.FillWithChar(' ', box_x, box_y, box_x+box_width,
|
||||||
|
box_y+box_height, style.default_fg, style.default_bg,
|
||||||
|
)
|
||||||
|
termbox_util.DrawBorder(box_x, box_y, box_x+box_width, box_y+box_height, style.default_fg, style.default_bg)
|
||||||
|
|
||||||
|
termbox_util.DrawStringAtPoint(screen.input_modal.text, box_x+1,
|
||||||
|
box_y+1, style.default_fg|termbox.AttrBold, style.default_bg|termbox.AttrBold,
|
||||||
|
)
|
||||||
|
termbox_util.DrawBorder(box_x+2, box_y+2, box_x+box_width-2, box_y+4, style.default_fg, style.default_bg)
|
||||||
|
|
||||||
|
termbox_util.DrawStringAtPoint(screen.input_modal.curr_val, box_x+2, box_y+3, style.title_fg, style.title_bg)
|
||||||
|
termbox.SetCell(box_x+1+len(screen.input_modal.curr_val)+1, box_y+1, ' ', style.title_bg, style.title_fg)
|
||||||
|
|
||||||
|
termbox_util.DrawStringAtPoint(termbox_util.AlignText("'Enter' to Accept, 'ESC' to cancel", box_width-2, ALIGN_CENTER), box_x+2, box_y+5, style.default_fg, style.default_bg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (screen *BrowserScreen) drawHeader(style Style) {
|
func (screen *BrowserScreen) drawHeader(style Style) {
|
||||||
width, _ := termbox.Size()
|
width, _ := termbox.Size()
|
||||||
spaces := strings.Repeat(" ", (width / 2))
|
spaces := strings.Repeat(" ", (width / 2))
|
||||||
drawStringAtPoint(fmt.Sprintf("%s%s%s", spaces, PROGRAM_NAME, spaces), 0, 0, style.title_fg, style.title_bg)
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("%s%s%s", spaces, PROGRAM_NAME, spaces), 0, 0, style.title_fg, style.title_bg)
|
||||||
}
|
}
|
||||||
func (screen *BrowserScreen) drawFooter(style Style) {
|
func (screen *BrowserScreen) drawFooter(style Style) {
|
||||||
_, height := termbox.Size()
|
_, height := termbox.Size()
|
||||||
drawStringAtPoint(fmt.Sprintf("%s(%d) - %s", screen.current_path, screen.current_type, screen.message), 0, height-1, style.default_fg, style.default_bg)
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("%s(%d) - %s", screen.current_path, screen.current_type, screen.message), 0, height-1, style.default_fg, style.default_bg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (screen *BrowserScreen) drawLeftPane(style Style) {
|
func (screen *BrowserScreen) drawLeftPane(style Style) {
|
||||||
@ -178,7 +327,9 @@ func (screen *BrowserScreen) drawLeftPane(style Style) {
|
|||||||
w = w / 2
|
w = w / 2
|
||||||
}
|
}
|
||||||
screen.view_port.number_of_rows = h - 2
|
screen.view_port.number_of_rows = h - 2
|
||||||
_, y := 1, 2
|
|
||||||
|
termbox_util.FillWithChar('=', 0, 1, w, 1, style.default_fg, style.default_bg)
|
||||||
|
y := 2
|
||||||
screen.view_port.first_row = y
|
screen.view_port.first_row = y
|
||||||
if len(screen.current_path) == 0 {
|
if len(screen.current_path) == 0 {
|
||||||
screen.current_path = screen.db.getNextVisiblePath(nil)
|
screen.current_path = screen.db.getNextVisiblePath(nil)
|
||||||
@ -197,12 +348,11 @@ func (screen *BrowserScreen) drawLeftPane(style Style) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tree_offset := 0
|
tree_offset := 0
|
||||||
half_screen := screen.view_port.number_of_rows / 2
|
max_cursor := screen.view_port.number_of_rows * 2 / 3
|
||||||
if cur_path_spot > half_screen {
|
if cur_path_spot > max_cursor {
|
||||||
tree_offset = cur_path_spot - half_screen
|
tree_offset = cur_path_spot - max_cursor
|
||||||
}
|
}
|
||||||
|
|
||||||
screen.message = fmt.Sprintf("Offset: %d", tree_offset)
|
|
||||||
for i := range screen.db.buckets {
|
for i := range screen.db.buckets {
|
||||||
// The drawBucket function returns how many lines it took up
|
// The drawBucket function returns how many lines it took up
|
||||||
bkt_h := screen.drawBucket(&screen.db.buckets[i], style, (y - tree_offset))
|
bkt_h := screen.drawBucket(&screen.db.buckets[i], style, (y - tree_offset))
|
||||||
@ -211,47 +361,27 @@ func (screen *BrowserScreen) drawLeftPane(style Style) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (screen *BrowserScreen) drawRightPane(style Style) {
|
func (screen *BrowserScreen) drawRightPane(style Style) {
|
||||||
w, _ := termbox.Size()
|
w, h := termbox.Size()
|
||||||
vis_slice, err := screen.db.buildVisiblePathSlice(nil)
|
if w >= 80 {
|
||||||
if err == nil {
|
// Screen is wide enough, split it
|
||||||
for i := range vis_slice {
|
termbox_util.FillWithChar('=', 0, 1, w, 1, style.default_fg, style.default_bg)
|
||||||
if strings.Join(screen.current_path, "/") == vis_slice[i] {
|
termbox_util.FillWithChar('|', (w / 2), screen.view_port.first_row-1, (w / 2), h, style.default_fg, style.default_bg)
|
||||||
drawStringAtPoint(vis_slice[i], (w/2)+2, i+1, style.title_fg, style.title_bg)
|
|
||||||
} else {
|
b, p, err := screen.db.getGenericFromPath(screen.current_path)
|
||||||
drawStringAtPoint(vis_slice[i], (w/2)+2, i+1, style.default_fg, style.default_bg)
|
if err == nil {
|
||||||
|
start_x := (w / 2) + 2
|
||||||
|
start_y := 2
|
||||||
|
if b != nil {
|
||||||
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("Path: %s", strings.Join(b.path, "/")), start_x, start_y, style.default_fg, style.default_bg)
|
||||||
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("Buckets: %d", len(b.buckets)), start_x, start_y+1, style.default_fg, style.default_bg)
|
||||||
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("Pairs: %d", len(b.pairs)), start_x, start_y+2, style.default_fg, style.default_bg)
|
||||||
|
} else if p != nil {
|
||||||
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("Path: %s", strings.Join(p.path, "/")), start_x, start_y, style.default_fg, style.default_bg)
|
||||||
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("Key: %s", p.key), start_x, start_y+1, style.default_fg, style.default_bg)
|
||||||
|
termbox_util.DrawStringAtPoint(fmt.Sprintf("Value: %s", p.val), start_x, start_y+2, style.default_fg, style.default_bg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
w, h := termbox.Size()
|
|
||||||
if w >= 80 {
|
|
||||||
// Screen is wide enough, split it
|
|
||||||
fillWithChar('|', (w / 2), screen.view_port.first_row-1, (w / 2), h, style.default_fg, style.default_bg)
|
|
||||||
|
|
||||||
b, p, err := screen.db.getGenericFromPath(screen.current_path)
|
|
||||||
if err == nil {
|
|
||||||
start_x := (w / 2) + 1
|
|
||||||
parent_str := "/"
|
|
||||||
if b != nil {
|
|
||||||
if b.parent != nil {
|
|
||||||
parent_str = b.parent.name
|
|
||||||
}
|
|
||||||
drawStringAtPoint(fmt.Sprintf("Parent: %s", parent_str), start_x, 1, style.default_fg, style.default_bg)
|
|
||||||
drawStringAtPoint(fmt.Sprintf("Buckets: %d", len(b.buckets)), start_x, 2, style.default_fg, style.default_bg)
|
|
||||||
drawStringAtPoint(fmt.Sprintf("Pairs: %d", len(b.pairs)), start_x, 3, style.default_fg, style.default_bg)
|
|
||||||
drawStringAtPoint(fmt.Sprintf("Path: %s", strings.Join(b.path, "/")), start_x, 4, style.default_fg, style.default_bg)
|
|
||||||
} else if p != nil {
|
|
||||||
if p.parent != nil {
|
|
||||||
parent_str = p.parent.name
|
|
||||||
}
|
|
||||||
drawStringAtPoint(fmt.Sprintf("Parent: %s", parent_str), start_x, 1, style.default_fg, style.default_bg)
|
|
||||||
drawStringAtPoint(fmt.Sprintf("Key: %s", p.key), start_x, 2, style.default_fg, style.default_bg)
|
|
||||||
drawStringAtPoint(fmt.Sprintf("Value: %s", p.val), start_x, 3, style.default_fg, style.default_bg)
|
|
||||||
drawStringAtPoint(fmt.Sprintf("Path: %s", strings.Join(p.path, "/")), start_x, 4, style.default_fg, style.default_bg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* drawBucket
|
/* drawBucket
|
||||||
@ -279,7 +409,7 @@ func (screen *BrowserScreen) drawBucket(bkt *BoltBucket, style Style, y int) int
|
|||||||
bkt_string = bkt_string + "- " + bkt.name + " "
|
bkt_string = bkt_string + "- " + bkt.name + " "
|
||||||
bkt_string = fmt.Sprintf("%s%s", bkt_string, strings.Repeat(" ", (w-len(bkt_string))))
|
bkt_string = fmt.Sprintf("%s%s", bkt_string, strings.Repeat(" ", (w-len(bkt_string))))
|
||||||
|
|
||||||
drawStringAtPoint(bkt_string, 0, (y + used_lines), bucket_fg, bucket_bg)
|
termbox_util.DrawStringAtPoint(bkt_string, 0, (y + used_lines), bucket_fg, bucket_bg)
|
||||||
used_lines += 1
|
used_lines += 1
|
||||||
|
|
||||||
for i := range bkt.buckets {
|
for i := range bkt.buckets {
|
||||||
@ -291,7 +421,7 @@ func (screen *BrowserScreen) drawBucket(bkt *BoltBucket, style Style, y int) int
|
|||||||
} else {
|
} else {
|
||||||
bkt_string = bkt_string + "+ " + bkt.name
|
bkt_string = bkt_string + "+ " + bkt.name
|
||||||
bkt_string = fmt.Sprintf("%s%s", bkt_string, strings.Repeat(" ", (w-len(bkt_string))))
|
bkt_string = fmt.Sprintf("%s%s", bkt_string, strings.Repeat(" ", (w-len(bkt_string))))
|
||||||
drawStringAtPoint(bkt_string, 0, (y + used_lines), bucket_fg, bucket_bg)
|
termbox_util.DrawStringAtPoint(bkt_string, 0, (y + used_lines), bucket_fg, bucket_bg)
|
||||||
used_lines += 1
|
used_lines += 1
|
||||||
}
|
}
|
||||||
return used_lines
|
return used_lines
|
||||||
@ -312,10 +442,51 @@ func (screen *BrowserScreen) drawPair(bp *BoltPair, style Style, y int) int {
|
|||||||
pair_string := strings.Repeat(" ", screen.db.getDepthFromPath(bp.path)*2)
|
pair_string := strings.Repeat(" ", screen.db.getDepthFromPath(bp.path)*2)
|
||||||
pair_string = fmt.Sprintf("%s%s: %s", pair_string, bp.key, bp.val)
|
pair_string = fmt.Sprintf("%s%s: %s", pair_string, bp.key, bp.val)
|
||||||
pair_string = fmt.Sprintf("%s%s", pair_string, strings.Repeat(" ", (w-len(pair_string))))
|
pair_string = fmt.Sprintf("%s%s", pair_string, strings.Repeat(" ", (w-len(pair_string))))
|
||||||
drawStringAtPoint(pair_string, 0, y, bucket_fg, bucket_bg)
|
termbox_util.DrawStringAtPoint(pair_string, 0, y, bucket_fg, bucket_bg)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (screen *BrowserScreen) createEditModal() bool {
|
||||||
|
b, p, e := screen.db.getGenericFromPath(screen.current_path)
|
||||||
|
if e == nil {
|
||||||
|
w, h := termbox.Size()
|
||||||
|
inp_w, inp_h := (w / 2), 6
|
||||||
|
inp_x, inp_y := ((w / 2) - (inp_w / 2)), ((h / 2) - inp_h)
|
||||||
|
mod := InputModal{x: inp_x, y: inp_y, width: inp_w, height: inp_h}
|
||||||
|
if b != nil {
|
||||||
|
mod.text = termbox_util.AlignText(fmt.Sprintf("Rename Bucket '%s' to:", b.name), inp_w, ALIGN_CENTER)
|
||||||
|
mod.curr_val = b.name
|
||||||
|
} else if p != nil {
|
||||||
|
mod.text = termbox_util.AlignText(fmt.Sprintf("Input new value for '%s':", p.key), inp_w, ALIGN_CENTER)
|
||||||
|
mod.curr_val = p.val
|
||||||
|
}
|
||||||
|
screen.input_modal = &mod
|
||||||
|
screen.mode = MODE_CHANGE_VAL
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (screen *BrowserScreen) insertBucket() bool {
|
||||||
|
//b, _, e := screen.db.getGenericFromPath(screen.current_path)
|
||||||
|
//if e == nil {
|
||||||
|
w, h := termbox.Size()
|
||||||
|
inp_w, inp_h := (w / 2), 6
|
||||||
|
inp_x, inp_y := ((w / 2) - (inp_w / 2)), ((h / 2) - inp_h)
|
||||||
|
mod := InputModal{x: inp_x, y: inp_y, width: inp_w, height: inp_h}
|
||||||
|
mod.text = termbox_util.AlignText("New Bucket Name:", inp_w, ALIGN_CENTER)
|
||||||
|
mod.curr_val = ""
|
||||||
|
screen.input_modal = &mod
|
||||||
|
screen.mode = MODE_INSERT_BUCKET
|
||||||
|
return true
|
||||||
|
//}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (screen *BrowserScreen) insertPair() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func comparePaths(p1, p2 []string) bool {
|
func comparePaths(p1, p2 []string) bool {
|
||||||
return strings.Join(p1, "/") == strings.Join(p2, "/")
|
return strings.Join(p1, "/") == strings.Join(p2, "/")
|
||||||
}
|
}
|
||||||
|
19
util.go
19
util.go
@ -1,20 +1 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "github.com/nsf/termbox-go"
|
|
||||||
|
|
||||||
func drawStringAtPoint(str string, x int, y int, fg termbox.Attribute, bg termbox.Attribute) int {
|
|
||||||
x_pos := x
|
|
||||||
for _, runeValue := range str {
|
|
||||||
termbox.SetCell(x_pos, y, runeValue, fg, bg)
|
|
||||||
x_pos++
|
|
||||||
}
|
|
||||||
return x_pos - x
|
|
||||||
}
|
|
||||||
|
|
||||||
func fillWithChar(r rune, x1, y1, x2, y2 int, fg termbox.Attribute, bg termbox.Attribute) {
|
|
||||||
for xx := x1; xx <= x2; xx++ {
|
|
||||||
for yx := y1; yx <= y2; yx++ {
|
|
||||||
termbox.SetCell(xx, yx, r, fg, bg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user