aboutsummaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorPetter Rodhelind <petter.rodhelind@gmail.com>2021-03-06 20:14:06 +0100
committerPetter Rodhelind <petter.rodhelind@gmail.com>2021-03-06 20:14:06 +0100
commita0591e399d5228ce27a2ca55acb5376c2b76ccac (patch)
tree7a33238367ff49288c3b0cd627588e5119613ae6 /ui
parent816aa1dd19ca760a94bb7b9d54e768c6aa3af332 (diff)
downloadpoe-master.tar.gz
poe-master.tar.bz2
poe-master.zip
Manage columns in a sane way.HEADmasterdev
Diffstat (limited to 'ui')
-rw-r--r--ui/tcell/layout.go76
-rw-r--r--ui/tcell/style.go19
-rw-r--r--ui/tcell/tcell.go118
-rw-r--r--ui/tcell/view.go18
-rw-r--r--ui/tcell/window.go1
5 files changed, 182 insertions, 50 deletions
diff --git a/ui/tcell/layout.go b/ui/tcell/layout.go
index 7a1fa6a..8a96e4b 100644
--- a/ui/tcell/layout.go
+++ b/ui/tcell/layout.go
@@ -1,17 +1,29 @@
package uitcell
+import (
+ "fmt"
+
+ "github.com/prodhe/poe/editor"
+)
+
+const (
+ RuneVerticalLine = '\u2502' // \u007c = |, \u23b8, \u2502
+)
+
type Workspace struct {
x, y, w, h int
+ tagline *View
cols []*Column
}
type Column struct {
x, y, w, h int
+ tagline *View
windows []*Window
}
// Add adds a new column and resizes.
-func (wrk *Workspace) AddCol() {
+func (wrk *Workspace) AddCol() *Column {
nx, ny := wrk.x, wrk.y
nw, nh := wrk.w, wrk.h
@@ -21,10 +33,32 @@ func (wrk *Workspace) AddCol() {
wrk.cols[len(wrk.cols)-1].w /= 2
}
- newcol := &Column{nx, ny, nw, nh, nil}
- wrk.cols = append(wrk.cols, newcol)
+ newcol := &Column{
+ x: nx,
+ y: ny,
+ w: nw,
+ h: nh,
+ tagline: &View{
+ text: &editor.Buffer{},
+ what: ViewColumn,
+ style: bodyStyle,
+ cursorStyle: bodyCursorStyle,
+ hilightStyle: bodyHilightStyle,
+ tabstop: 4,
+ },
+ windows: nil,
+ }
+ fmt.Fprintf(newcol.tagline, "%s", "New Delcol ")
+
+ if len(wrk.cols) > 1 {
+ wrk.cols = append(wrk.cols[:len(wrk.cols)-1], newcol, wrk.cols[len(wrk.cols)-1])
+ } else {
+ wrk.cols = append(wrk.cols, newcol)
+ }
wrk.Resize(wrk.x, wrk.y, wrk.w, wrk.h) // for re-arranging side effects
+
+ return newcol
}
func (wrk *Workspace) CloseCol(c *Column) {
@@ -53,6 +87,8 @@ func (wrk *Workspace) LastCol() *Column {
func (wrk *Workspace) Resize(x, y, w, h int) {
wrk.x, wrk.y, wrk.w, wrk.h = x, y, w, h
+ wrk.tagline.x, wrk.tagline.y, wrk.tagline.w = x, y, w
+ wrk.tagline.h = 1
n := len(wrk.cols)
if n == 0 {
@@ -69,22 +105,22 @@ func (wrk *Workspace) Resize(x, y, w, h int) {
if n > 1 {
firstvertline = 1
}
- wrk.cols[i].Resize(x, y, (w/n)+remainder-(n-1)-firstvertline, h)
+ wrk.cols[i].Resize(x, y+1, (w/n)+remainder-(n-1)-firstvertline, h)
continue
}
// +i-n-1 on x so we do not draw on last vert line of previous col
- wrk.cols[i].Resize((w/n)*i+remainder+i-(n-1), y, (w/n)-1, h)
+ wrk.cols[i].Resize((w/n)*i+remainder+i-(n-1), y+1, (w/n)-1, h)
}
}
func (wrk *Workspace) Draw() {
+ wrk.tagline.Draw()
for _, col := range wrk.cols {
col.Draw()
// draw vertical lines between cols
- for x, y := col.x+col.w+1, wrk.y; y < wrk.y+wrk.h; y++ {
- // 2502
- screen.SetContent(x, y, '\u007c', nil, vertlineStyle)
+ for x, y := col.x+col.w+1, wrk.y+1; y < wrk.y+wrk.h; y++ {
+ screen.SetContent(x, y, RuneVerticalLine, nil, vertlineStyle)
}
}
}
@@ -106,15 +142,10 @@ func (c *Column) CloseWindow(w *Window) {
c.windows = c.windows[:j]
if CurWin == w {
- // If we are not out of windows in our own column, pick another or exit
+ // If we are not out of windows in our own column, pick another or do nothing
if len(c.windows) > 0 {
CurWin = c.windows[j-1]
} else {
- // remove column
- if c != workspace.Col(0) {
- workspace.CloseCol(c)
- }
-
// clear clutter
screen.Clear()
@@ -128,6 +159,8 @@ func (c *Column) CloseWindow(w *Window) {
func (c *Column) Resize(x, y, w, h int) {
c.x, c.y = x, y
c.w, c.h = w, h
+ c.tagline.x, c.tagline.y = x, y
+ c.tagline.w, c.tagline.h = w, 1
c.ResizeWindows()
}
@@ -141,15 +174,26 @@ func (c *Column) ResizeWindows() {
}
for i, win := range c.windows {
if i == 0 {
- win.Resize(c.x, c.y, c.w, (c.h/n)+remainder)
+ win.Resize(c.x, c.y+1, c.w, (c.h/n)+remainder)
continue
}
- win.Resize(c.x, c.y+(c.h/n)*i+remainder, c.w, c.h/n)
+ win.Resize(c.x, c.y+1+(c.h/n)*i+remainder, c.w, c.h/n)
}
}
func (c *Column) Draw() {
+ c.tagline.Draw()
for _, win := range c.windows {
win.Draw()
}
+ if len(c.windows) == 0 {
+ x, y := c.x, c.y+1
+ for ; y < c.y+c.h; y++ {
+ x = c.x + c.w
+ for x >= c.x {
+ screen.SetContent(x, y, ' ', nil, bodyStyle)
+ x--
+ }
+ }
+ }
}
diff --git a/ui/tcell/style.go b/ui/tcell/style.go
index fec3390..528dbe6 100644
--- a/ui/tcell/style.go
+++ b/ui/tcell/style.go
@@ -25,12 +25,18 @@ var (
// initStyles initializes the different styles (colors for background/foreground).
func initStyles() error {
bodyStyle = tcell.StyleDefault
+ // bodyCursorStyle = tcell.StyleDefault
bodyHilightStyle = bodyStyle.Reverse(true)
- unprintableStyle = bodyStyle.
- Foreground(tcell.ColorRed)
+
tagStyle = tcell.StyleDefault.Reverse(true)
- vertlineStyle = bodyStyle.Reverse(false)
+ tagCursorStyle = tcell.StyleDefault.Reverse(true)
+ tagHilightStyle = tagStyle.Reverse(false)
+ tagSquareStyle = tcell.StyleDefault.Reverse(true)
+ tagSquareModifiedStyle = tcell.StyleDefault.Reverse(true)
+ vertlineStyle = bodyStyle.Reverse(false)
+ unprintableStyle = bodyStyle.
+ Foreground(tcell.ColorRed)
return nil
}
@@ -39,8 +45,7 @@ func setStyleAcme() error {
bodyStyle = tcell.StyleDefault.
Background(tcell.NewHexColor(0xffffea)).
Foreground(tcell.ColorBlack.TrueColor())
- bodyCursorStyle = bodyStyle.
- Background(tcell.NewHexColor(0xeaea9e))
+ // bodyCursorStyle = bodyStyle.Background(tcell.NewHexColor(0xeaea9e))
bodyHilightStyle = bodyStyle.
Background(tcell.NewHexColor(0xeeee9e))
unprintableStyle = bodyStyle.
@@ -48,9 +53,7 @@ func setStyleAcme() error {
tagStyle = tcell.StyleDefault.
Background(tcell.NewHexColor(0xeaffff)).
Foreground(tcell.ColorBlack.TrueColor())
- tagCursorStyle = tagStyle.
- Background(tcell.NewHexColor(0x8888cc)).
- Foreground(tcell.ColorBlack.TrueColor())
+ // tagCursorStyle = tagStyle.Background(tcell.NewHexColor(0x8888cc)).Foreground(tcell.ColorBlack.TrueColor())
tagHilightStyle = tagStyle.
Background(tcell.NewHexColor(0x9eeeee))
tagSquareStyle = tagStyle.
diff --git a/ui/tcell/tcell.go b/ui/tcell/tcell.go
index 9783a86..c274380 100644
--- a/ui/tcell/tcell.go
+++ b/ui/tcell/tcell.go
@@ -19,6 +19,7 @@ var (
screen tcell.Screen
ed editor.Editor
workspace *Workspace
+ CurCol *Column
CurWin *Window
poecmds map[string]commandFunc
@@ -42,6 +43,10 @@ func (t *Tcell) Init(e editor.Editor) error {
return err
}
+ if err := setStyleAcme(); err != nil {
+ return err
+ }
+
if err := initWorkspace(); err != nil {
return err
}
@@ -72,14 +77,21 @@ func (t *Tcell) Close() {
func printMsg(format string, a ...interface{}) {
// get output window
- poename := CurWin.Dir() + string(filepath.Separator) + FnMessageWin
+ var poename string
+
+ if CurWin != nil {
+ poename = CurWin.Dir()
+ } else {
+ poename = ed.WorkDir()
+ }
+ poename += string(filepath.Separator) + FnMessageWin
poename = filepath.Clean(poename)
poewin := FindWindow(poename)
if poewin == nil {
id, buf := ed.NewBuffer()
- buf.NewFile(CurWin.Dir() + string(filepath.Separator) + FnMessageWin)
+ buf.NewFile(poename)
poewin = NewWindow(id)
poewin.body.what = ViewScratch
@@ -114,7 +126,17 @@ func initScreen() error {
}
func initWorkspace() error {
- workspace = &Workspace{} // first resize event will set proper dimensions
+ workspace = &Workspace{ // first resize event will set proper dimensions
+ tagline: &View{
+ text: &editor.Buffer{},
+ what: ViewMenu,
+ style: tagStyle,
+ cursorStyle: tagCursorStyle,
+ hilightStyle: tagHilightStyle,
+ tabstop: 4,
+ },
+ }
+ fmt.Fprintf(workspace.tagline, "%s", "Newcol Exit ")
workspace.AddCol()
if ids, _ := ed.Buffers(); len(ids) == 0 {
workspace.AddCol()
@@ -134,8 +156,9 @@ func initWindows() error {
func initCommands() {
poecmds = map[string]commandFunc{
- "New": CmdNew,
"Newcol": CmdNewcol,
+ "Delcol": CmdDelcol,
+ "New": CmdNew,
"Del": CmdDel,
"Get": CmdGet,
"Exit": CmdExit,
@@ -182,10 +205,46 @@ outer:
default: // let the focused view handle event
if CurWin != nil {
CurWin.HandleEvent(e)
+ } else if CurCol != nil {
+ CurCol.tagline.HandleEvent(e)
+ } else {
+ workspace.tagline.HandleEvent(e)
}
}
case *tcell.EventMouse:
+ screen.HideCursor()
mx, my := e.Position()
+ if CurCol != nil {
+ CurCol.tagline.focused = false
+ }
+ if CurWin != nil {
+ CurWin.UnFocus()
+ }
+ CurCol = nil
+ CurWin = nil
+
+ if my < 1 {
+ workspace.tagline.focused = true
+ workspace.tagline.HandleEvent(e)
+ } else {
+ workspace.tagline.focused = false
+ }
+
+ for _, col := range workspace.cols {
+ if mx >= col.x && mx < col.x+col.w &&
+ my >= col.y && my < col.y+col.h {
+ CurCol = col
+ }
+ }
+
+ if CurCol != nil {
+ if my == CurCol.y {
+ CurCol.tagline.focused = true
+ CurCol.tagline.HandleEvent(e)
+ } else {
+ CurCol.tagline.focused = false
+ }
+ }
// find which window to send the event to
for _, win := range AllWindows() {
@@ -238,44 +297,63 @@ func CmdOpen(fn string) {
screen.Clear()
var win *Window
win = FindWindow(fn)
- if win == nil { //only load windows that do no already exists
- id, buf := ed.NewBuffer()
- buf.NewFile(fn)
- buf.ReadFile()
- win := NewWindow(id)
- col := workspace.Col(0)
- if buf.IsDir() {
- col = workspace.LastCol()
+
+ if win != nil { //only load windows that do no already exists
+ return
+ }
+
+ id, buf := ed.NewBuffer()
+ buf.NewFile(fn)
+ buf.ReadFile()
+ win = NewWindow(id)
+ var col *Column
+ if !buf.IsDir() {
+ // add file window second to last or the first
+ if len(workspace.cols) > 2 {
+ col = workspace.Col(len(workspace.cols) - 2)
+ } else {
+ col = workspace.Col(0)
}
- col.AddWindow(win)
+ } else {
+ // add all dirs to last column
+ col = workspace.LastCol()
}
+ col.AddWindow(win)
}
func CmdNew() {
screen.Clear()
id, _ := ed.NewBuffer()
win := NewWindow(id)
- workspace.LastCol().AddWindow(win)
+ CurCol.AddWindow(win)
}
func CmdDel() {
- if len(AllWindows()) == 1 {
- CmdExit()
- return
- }
CurWin.Close()
+ screen.HideCursor()
}
func CmdNewcol() {
workspace.AddCol()
- CmdNew()
+ screen.Clear()
+}
+
+func CmdDelcol() {
+ if len(workspace.cols) < 2 {
+ CmdExit()
+ } else if CurCol != nil {
+ workspace.CloseCol(CurCol)
+ } else if CurWin != nil {
+ workspace.CloseCol(CurWin.col)
+ }
+ screen.Clear()
}
func CmdGet() {
screen.Clear()
wins := AllWindows()
for _, win := range wins {
- if win.tagline.focused {
+ if win.tagline.focused || win.body.focused {
q0, q1 := win.body.text.Dot()
win.body.text.Destroy()
win.body.text.ReadFile()
diff --git a/ui/tcell/view.go b/ui/tcell/view.go
index 73f1453..55490b9 100644
--- a/ui/tcell/view.go
+++ b/ui/tcell/view.go
@@ -16,6 +16,7 @@ import (
const (
ViewMenu int = iota
+ ViewColumn
ViewTagline
ViewBody
ViewScratch
@@ -235,7 +236,7 @@ func (v *View) ScrollTo(offset int) {
}
func (b *View) Draw() {
- //screen.HideCursor()
+ // screen.HideCursor()
x, y := b.x, b.y
@@ -261,7 +262,7 @@ func (b *View) Draw() {
// highlight cursor if on screen
if (q0 == q1 && i == q0) && b.focused {
- //style = b.cursorStyle
+ // style = b.cursorStyle
screen.ShowCursor(x, y)
}
@@ -512,9 +513,6 @@ func (v *View) HandleEvent(ev tcell.Event) {
ed.WorkDir(), CurWin.Dir(), CurWin.Name(),
CurWin.w, CurWin.h, sh, sw)
return
- case tcell.KeyCtrlN: // new column
- CmdNewcol()
- return
case tcell.KeyCtrlC: // copy to clipboard
str := v.text.ReadDot()
if str == "" {
@@ -533,6 +531,10 @@ func (v *View) HandleEvent(ev tcell.Event) {
v.text.Write([]byte(s))
return
case tcell.KeyCtrlQ: // close window
+ if v.what == ViewColumn || v.what == ViewMenu {
+ CmdDelcol() // calls CmdExit if cols < 2
+ return
+ }
CmdDel()
return
default:
@@ -575,7 +577,11 @@ func ButtonSecondary(v *View, mx, my int) {
return
}
if fn != "" && fn[0] != filepath.Separator {
- fn = CurWin.Dir() + string(filepath.Separator) + fn
+ if CurWin != nil {
+ fn = CurWin.Dir() + string(filepath.Separator) + fn
+ } else {
+ fn = ed.WorkDir() + string(filepath.Separator) + fn
+ }
fn = filepath.Clean(fn)
}
diff --git a/ui/tcell/window.go b/ui/tcell/window.go
index ee2de88..28c66f9 100644
--- a/ui/tcell/window.go
+++ b/ui/tcell/window.go
@@ -127,6 +127,7 @@ func (win *Window) HandleEvent(ev tcell.Event) {
win.tagline.focused = false
} else {
win.tagline.focused = true
+ win.body.focused = false
}
case *tcell.EventKey:
switch ev.Key() {