From 2503fba46f285c8459b65695def9a5ad2ed06957 Mon Sep 17 00:00:00 2001 From: vilmibm Date: Wed, 14 Jun 2023 15:13:58 -0700 Subject: [PATCH] implement viewport --- main.go | 85 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 11 deletions(-) diff --git a/main.go b/main.go index 46c054d..1cfe492 100644 --- a/main.go +++ b/main.go @@ -21,10 +21,11 @@ const ( ) type UI struct { - Mode mode - App *tview.Application - Fields []field - Nodes []node + Mode mode + App *tview.Application + Fields []field + Nodes []*node + Viewport *viewport // UI things Pages *tview.Pages @@ -54,6 +55,18 @@ func (ui *UI) handleInput(event *tcell.EventKey) *tcell.EventKey { case ':': ui.setMode(modeEx) return nil + case 'h': + ui.Viewport.X-- + return nil + case 'j': + ui.Viewport.Y++ + return nil + case 'k': + ui.Viewport.Y-- + return nil + case 'l': + ui.Viewport.X++ + return nil } case modeEx: case modeFocus: @@ -81,6 +94,31 @@ func (ui *UI) handleExInput(key tcell.Key) { fmt.Fprintf(ui.ExOutput, "did not understand '%s', sorry", text) } +/* + +three coordinate systems: + +- the infinite coordinate plane where nodes live. it is centered at 0,0 but nodes can be placed anywhere. +- the viewport representing what part of the infinite plane the user is looking at. the viewport has an origin in the infinite plane and a width and height +- the screen onto which characters are drawn. always rooted at 0,0; always has a width and a height that matches the width and height of the viewport + +the viewport is the most pressing question. nodes exist in an XY plane and the field view is a viewport onto that plane. + +nodes have a "real" X,Y coordinate pair and a width and a height. the viewport has a width, a height, and point A,B from which it originates. + +Moving the viewport means changing A,B. To see what should be shown on the screen, compare a node's X,Y to A,B. If X+width > A and Y+height > B && X+width < A+width and Y+maxheight < B+maxheight then it should be shown. For each node, it also has coordinates H,J in the screen based on the viewport position. + +But how to reconcile this with tview? can i add all of the nodes to the scene tree then update their H,J as the viewport changes and hope tview just does the right thing? I think I should start there. + +*/ + +type viewport struct { + X int + Y int + W int + H int +} + type field struct { Name string Selected bool @@ -91,13 +129,15 @@ type node struct { Edges []*node X int Y int + widg *tview.TextView + // "screen" x and y are stored on corresponding tview widget as well as width/height } type Edge struct { + nodes []*node } func (e Edge) Draw(screen tcell.Screen) { - screen.SetContent(0, 0, tview.BoxDrawingsLightDiagonalUpperLeftToLowerRight, []rune{}, tcell.StyleDefault) screen.SetContent(1, 1, tview.BoxDrawingsLightDiagonalUpperLeftToLowerRight, []rune{}, tcell.StyleDefault) screen.SetContent(2, 2, tview.BoxDrawingsLightDiagonalUpperLeftToLowerRight, []rune{}, tcell.StyleDefault) @@ -139,7 +179,8 @@ func NewUI() *UI { Mode: modeNormal, App: app, Fields: []field{{"scratch", true}, {"test", false}}, - Nodes: []node{}, + Nodes: []*node{}, + Viewport: &viewport{}, Pages: tview.NewPages(), TopFlex: tview.NewFlex(), Field: tview.NewPages(), @@ -169,14 +210,23 @@ func NewUI() *UI { ui.FieldBar.SetDirection(tview.FlexColumn) - ui.Nodes = append(ui.Nodes, node{ + ui.Nodes = append(ui.Nodes, &node{ Text: "foobar\nbaz\nquux", }) - ui.Nodes = append(ui.Nodes, node{ + ui.Nodes = append(ui.Nodes, &node{ + Text: "the wild box", + }) + ui.Nodes = append(ui.Nodes, &node{ + Text: "cool stories bros", + }) + ui.Nodes = append(ui.Nodes, &node{ + Text: "why not", + }) + ui.Nodes = append(ui.Nodes, &node{ Text: "hello\nthere\nhow", }) - x := 0 + x := 60 y := 0 rand.Seed(time.Now().Unix()) @@ -186,14 +236,27 @@ func NewUI() *UI { b.SetText(n.Text) b.SetBorder(true) b.SetRect(x, y, 10, 5) - x += 20 + n.X = x + n.Y = y + x -= 20 ui.Field.AddPage(fmt.Sprintf("%d", rand.Intn(10000)), b, false, true) + n.widg = b } ui.Field.AddPage("edge", Edge{}, false, true) app.SetBeforeDrawFunc(func(_ tcell.Screen) bool { + // Viewport + _, _, w, h := ui.Field.GetRect() + ui.Viewport.W = w + ui.Viewport.H = h + // Handle nodes - // TODO + for _, n := range ui.Nodes { + _, _, w, h := n.widg.GetRect() + x := n.X - ui.Viewport.X + y := n.Y - ui.Viewport.Y + n.widg.SetRect(x, y, w, h) + } // Handle field bar ui.FieldBar.Clear()