diff --git a/filetreeview.go b/filetreeview.go new file mode 100644 index 0000000..9eed1cd --- /dev/null +++ b/filetreeview.go @@ -0,0 +1,114 @@ +package main + +import ( + "fmt" + + "github.com/jroimartin/gocui" +) + +type FileTreeView struct { + name string + gui *gocui.Gui + view *gocui.View + absTreeIndex uint + tree *FileTree +} + +func NewFileTreeView(name string, gui *gocui.Gui, view *gocui.View, tree *FileTree) (treeview *FileTreeView) { + treeview = new(FileTreeView) + + // populate main fields + treeview.name = name + treeview.gui = gui + treeview.view = view + treeview.tree = tree + + // set view options + treeview.view.Editable = false + treeview.view.Wrap = false + treeview.view.Highlight = true + treeview.view.SelBgColor = gocui.ColorGreen + treeview.view.SelFgColor = gocui.ColorBlack + + treeview.render() + + return treeview +} + +func (treeview *FileTreeView) keybindings() error { + if err := treeview.gui.SetKeybinding(treeview.name, gocui.KeyArrowDown, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return treeview.cursorDown() }); err != nil { + return err + } + if err := treeview.gui.SetKeybinding(treeview.name, gocui.KeyArrowUp, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return treeview.cursorUp() }); err != nil { + return err + } + if err := treeview.gui.SetKeybinding(treeview.name, gocui.KeySpace, gocui.ModNone, func(*gocui.Gui, *gocui.View) error { return treeview.toggleCollapse() }); err != nil { + return err + } + return nil +} + +// Mehh, this is just a bad method +func (treeview *FileTreeView) reset(tree *FileTree) error { + treeview.tree = tree + treeview.view.SetCursor(0, 0) + treeview.absTreeIndex = 0 + return treeview.render() +} + +func (treeview *FileTreeView) cursorDown() error { + err := cursorDown(treeview.gui, treeview.view) + if err == nil { + treeview.absTreeIndex++ + } + return nil +} + +func (treeview *FileTreeView) cursorUp() error { + err := cursorUp(treeview.gui, treeview.view) + if err == nil { + treeview.absTreeIndex-- + } + return nil +} + +func (treeview *FileTreeView) getAbsPositionNode() (node *FileNode) { + var visiter func(*FileNode) error + var evaluator func(*FileNode) bool + var dfsCounter uint + + visiter = func(curNode *FileNode) error { + if dfsCounter == treeview.absTreeIndex { + node = curNode + } + dfsCounter++ + return nil + } + + evaluator = func(curNode *FileNode) bool { + return !curNode.collapsed + } + + err := treeview.tree.VisitDepthParentFirst(visiter, evaluator) + if err != nil { + // todo: you guessed it, check errors + } + + return node +} + +func (treeview *FileTreeView) toggleCollapse() error { + node := treeview.getAbsPositionNode() + node.collapsed = !node.collapsed + return treeview.render() +} + +func (treeview *FileTreeView) render() error { + renderString := treeview.tree.String() + treeview.gui.Update(func(g *gocui.Gui) error { + treeview.view.Clear() + _, err := fmt.Fprintln(treeview.view, renderString) + return err + }) + return nil +} diff --git a/layerview.go b/layerview.go new file mode 100644 index 0000000..929ad64 --- /dev/null +++ b/layerview.go @@ -0,0 +1,42 @@ +package main + +import ( + "fmt" + + "github.com/jroimartin/gocui" +) + +func renderSideBar(g *gocui.Gui, v *gocui.View) error { + g.Update(func(g *gocui.Gui) error { + v, _ := g.View("side") + // todo: handle above error. + v.Clear() + //_, err := fmt.Fprintf(v, "FileNode:\n%+v\n\n", getAbsPositionNode()) + for ix, layerName := range data.manifest.Layers { + fmt.Fprintf(v, "%d: %s\n", ix+1, layerName[0:25]) + } + return nil + }) + // todo: blerg + return nil +} + +func cursorDownLayers(g *gocui.Gui, v *gocui.View) error { + if v != nil && int(view.layerIndex) < len(data.manifest.Layers) { + cursorDown(g, v) + view.layerIndex++ + renderSideBar(g, v) + view.treeView.reset(StackRange(data.refTrees, view.layerIndex)) + } + return nil +} + +func cursorUpLayers(g *gocui.Gui, v *gocui.View) error { + if v != nil && int(view.layerIndex) > 0 { + cursorUp(g, v) + view.layerIndex-- + renderSideBar(g, v) + view.treeView.reset(StackRange(data.refTrees, view.layerIndex)) + } + return nil +} diff --git a/main.go b/main.go index 6e83b1b..a948250 100644 --- a/main.go +++ b/main.go @@ -15,11 +15,14 @@ import ( ) var data struct { - tree *FileTree - refTrees []*FileTree - manifest *Manifest - absDFSTreeIndex uint - layerIndex uint + refTrees []*FileTree + manifest *Manifest +} + +var view struct { + treeView *FileTreeView + // layerView *LayerView + layerIndex uint } func check(e error) { @@ -115,31 +118,6 @@ func demo() { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -func getAbsPositionNode() (node *FileNode) { - var visiter func(*FileNode) error - var evaluator func(*FileNode) bool - var dfsCounter uint - - visiter = func(curNode *FileNode) error { - if dfsCounter == data.absDFSTreeIndex { - node = curNode - } - dfsCounter++ - return nil - } - - evaluator = func(curNode *FileNode) bool { - return !curNode.collapsed - } - - err := data.tree.VisitDepthParentFirst(visiter, evaluator) - if err != nil { - // todo: you guessed it, check errors - } - - return node -} - func nextView(g *gocui.Gui, v *gocui.View) error { if v == nil || v.Name() == "side" { _, err := g.SetCurrentView("main") @@ -149,21 +127,6 @@ func nextView(g *gocui.Gui, v *gocui.View) error { return err } -func showCurNodeInSideBar(g *gocui.Gui, v *gocui.View) error { - g.Update(func(g *gocui.Gui) error { - v, _ := g.View("side") - // todo: handle above error. - v.Clear() - //_, err := fmt.Fprintf(v, "FileNode:\n%+v\n\n", getAbsPositionNode()) - for ix, layerName := range data.manifest.Layers { - fmt.Fprintf(v, "%d: %s\n", ix+1, layerName[0:25]) - } - return nil - }) - // todo: blerg - return nil -} - func cursorDown(g *gocui.Gui, v *gocui.View) error { cx, cy := v.Cursor() @@ -195,61 +158,6 @@ func cursorUp(g *gocui.Gui, v *gocui.View) error { return nil } -func cursorDownLayers(g *gocui.Gui, v *gocui.View) error { - if v != nil && int(data.layerIndex) < len(data.manifest.Layers) { - cursorDown(g, v) - data.layerIndex++ - showCurNodeInSideBar(g, v) - data.tree = StackRange(data.refTrees, data.layerIndex) - drawTree(g, v) - } - return nil -} - -func cursorUpLayers(g *gocui.Gui, v *gocui.View) error { - if v != nil && int(data.layerIndex) > 0 { - cursorUp(g, v) - data.layerIndex-- - showCurNodeInSideBar(g, v) - data.tree = StackRange(data.refTrees, data.layerIndex) - drawTree(g, v) - } - return nil -} - -func cursorDownTree(g *gocui.Gui, v *gocui.View) error { - if v != nil { - cursorDown(g, v) - data.absDFSTreeIndex++ - } - return nil -} - -func cursorUpTree(g *gocui.Gui, v *gocui.View) error { - if v != nil { - cursorUp(g, v) - data.absDFSTreeIndex-- - } - return nil -} - -func toggleCollapse(g *gocui.Gui, v *gocui.View) error { - node := getAbsPositionNode() - node.collapsed = !node.collapsed - return drawTree(g, v) -} - -func drawTree(g *gocui.Gui, v *gocui.View) error { - g.Update(func(g *gocui.Gui) error { - v, _ := g.View("main") - // todo: handle above error. - v.Clear() - _, err := fmt.Fprintln(v, data.tree.String()) - return err - }) - return nil -} - func quit(g *gocui.Gui, v *gocui.View) error { return gocui.ErrQuit } @@ -273,15 +181,7 @@ func keybindings(g *gocui.Gui) error { if err := g.SetKeybinding("side", gocui.KeyArrowUp, gocui.ModNone, cursorUpLayers); err != nil { return err } - if err := g.SetKeybinding("main", gocui.KeyArrowDown, gocui.ModNone, cursorDownTree); err != nil { - return err - } - if err := g.SetKeybinding("main", gocui.KeyArrowUp, gocui.ModNone, cursorUpTree); err != nil { - return err - } - if err := g.SetKeybinding("main", gocui.KeySpace, gocui.ModNone, toggleCollapse); err != nil { - return err - } + return nil } @@ -296,28 +196,26 @@ func layout(g *gocui.Gui) error { v.Highlight = true v.SelBgColor = gocui.ColorGreen v.SelFgColor = gocui.ColorBlack - showCurNodeInSideBar(g, v) + renderSideBar(g, v) } if v, err := g.SetView("main", splitCol, -1, maxX, maxY); err != nil { if err != gocui.ErrUnknownView { return err } - v.Editable = false - v.Wrap = false - v.Highlight = true - v.SelBgColor = gocui.ColorGreen - v.SelFgColor = gocui.ColorBlack + + view.treeView = NewFileTreeView("main", g, v, StackRange(data.refTrees, 0)) + view.treeView.keybindings() + if _, err := g.SetCurrentView("main"); err != nil { return err } - drawTree(g, v) } return nil } func main() { demo() - initialize() + initializeData() g, err := gocui.NewGui(gocui.OutputNormal) if err != nil { diff --git a/tar_read.go b/tar_read.go index 635e2b5..68cdcff 100644 --- a/tar_read.go +++ b/tar_read.go @@ -11,7 +11,7 @@ import ( "strings" ) -func initialize() { +func initializeData() { f, err := os.Open("image/cache.tar") if err != nil { fmt.Println(err) @@ -75,7 +75,6 @@ func initialize() { data.manifest = &manifest data.refTrees = trees - data.tree = StackRange(trees, 0) } func getFileList(parentReader *tar.Reader, h *tar.Header) []FileChangeInfo { diff --git a/view.go b/view.go new file mode 100644 index 0000000..6334732 --- /dev/null +++ b/view.go @@ -0,0 +1,8 @@ +package main + +type View interface { + keybindings() error + cursorDown() error + cursorUp() error + render() error +}