implement viewport
parent
f8f5be36f7
commit
2503fba46f
79
main.go
79
main.go
|
@ -24,7 +24,8 @@ type UI struct {
|
||||||
Mode mode
|
Mode mode
|
||||||
App *tview.Application
|
App *tview.Application
|
||||||
Fields []field
|
Fields []field
|
||||||
Nodes []node
|
Nodes []*node
|
||||||
|
Viewport *viewport
|
||||||
|
|
||||||
// UI things
|
// UI things
|
||||||
Pages *tview.Pages
|
Pages *tview.Pages
|
||||||
|
@ -54,6 +55,18 @@ func (ui *UI) handleInput(event *tcell.EventKey) *tcell.EventKey {
|
||||||
case ':':
|
case ':':
|
||||||
ui.setMode(modeEx)
|
ui.setMode(modeEx)
|
||||||
return nil
|
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 modeEx:
|
||||||
case modeFocus:
|
case modeFocus:
|
||||||
|
@ -81,6 +94,31 @@ func (ui *UI) handleExInput(key tcell.Key) {
|
||||||
fmt.Fprintf(ui.ExOutput, "did not understand '%s', sorry", text)
|
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 {
|
type field struct {
|
||||||
Name string
|
Name string
|
||||||
Selected bool
|
Selected bool
|
||||||
|
@ -91,13 +129,15 @@ type node struct {
|
||||||
Edges []*node
|
Edges []*node
|
||||||
X int
|
X int
|
||||||
Y int
|
Y int
|
||||||
|
widg *tview.TextView
|
||||||
|
// "screen" x and y are stored on corresponding tview widget as well as width/height
|
||||||
}
|
}
|
||||||
|
|
||||||
type Edge struct {
|
type Edge struct {
|
||||||
|
nodes []*node
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e Edge) Draw(screen tcell.Screen) {
|
func (e Edge) Draw(screen tcell.Screen) {
|
||||||
|
|
||||||
screen.SetContent(0, 0, tview.BoxDrawingsLightDiagonalUpperLeftToLowerRight, []rune{}, tcell.StyleDefault)
|
screen.SetContent(0, 0, tview.BoxDrawingsLightDiagonalUpperLeftToLowerRight, []rune{}, tcell.StyleDefault)
|
||||||
screen.SetContent(1, 1, tview.BoxDrawingsLightDiagonalUpperLeftToLowerRight, []rune{}, tcell.StyleDefault)
|
screen.SetContent(1, 1, tview.BoxDrawingsLightDiagonalUpperLeftToLowerRight, []rune{}, tcell.StyleDefault)
|
||||||
screen.SetContent(2, 2, tview.BoxDrawingsLightDiagonalUpperLeftToLowerRight, []rune{}, tcell.StyleDefault)
|
screen.SetContent(2, 2, tview.BoxDrawingsLightDiagonalUpperLeftToLowerRight, []rune{}, tcell.StyleDefault)
|
||||||
|
@ -139,7 +179,8 @@ func NewUI() *UI {
|
||||||
Mode: modeNormal,
|
Mode: modeNormal,
|
||||||
App: app,
|
App: app,
|
||||||
Fields: []field{{"scratch", true}, {"test", false}},
|
Fields: []field{{"scratch", true}, {"test", false}},
|
||||||
Nodes: []node{},
|
Nodes: []*node{},
|
||||||
|
Viewport: &viewport{},
|
||||||
Pages: tview.NewPages(),
|
Pages: tview.NewPages(),
|
||||||
TopFlex: tview.NewFlex(),
|
TopFlex: tview.NewFlex(),
|
||||||
Field: tview.NewPages(),
|
Field: tview.NewPages(),
|
||||||
|
@ -169,14 +210,23 @@ func NewUI() *UI {
|
||||||
|
|
||||||
ui.FieldBar.SetDirection(tview.FlexColumn)
|
ui.FieldBar.SetDirection(tview.FlexColumn)
|
||||||
|
|
||||||
ui.Nodes = append(ui.Nodes, node{
|
ui.Nodes = append(ui.Nodes, &node{
|
||||||
Text: "foobar\nbaz\nquux",
|
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",
|
Text: "hello\nthere\nhow",
|
||||||
})
|
})
|
||||||
|
|
||||||
x := 0
|
x := 60
|
||||||
y := 0
|
y := 0
|
||||||
|
|
||||||
rand.Seed(time.Now().Unix())
|
rand.Seed(time.Now().Unix())
|
||||||
|
@ -186,14 +236,27 @@ func NewUI() *UI {
|
||||||
b.SetText(n.Text)
|
b.SetText(n.Text)
|
||||||
b.SetBorder(true)
|
b.SetBorder(true)
|
||||||
b.SetRect(x, y, 10, 5)
|
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)
|
ui.Field.AddPage(fmt.Sprintf("%d", rand.Intn(10000)), b, false, true)
|
||||||
|
n.widg = b
|
||||||
}
|
}
|
||||||
ui.Field.AddPage("edge", Edge{}, false, true)
|
ui.Field.AddPage("edge", Edge{}, false, true)
|
||||||
|
|
||||||
app.SetBeforeDrawFunc(func(_ tcell.Screen) bool {
|
app.SetBeforeDrawFunc(func(_ tcell.Screen) bool {
|
||||||
|
// Viewport
|
||||||
|
_, _, w, h := ui.Field.GetRect()
|
||||||
|
ui.Viewport.W = w
|
||||||
|
ui.Viewport.H = h
|
||||||
|
|
||||||
// Handle nodes
|
// 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
|
// Handle field bar
|
||||||
ui.FieldBar.Clear()
|
ui.FieldBar.Clear()
|
||||||
|
|
Loading…
Reference in New Issue