aboutsummaryrefslogtreecommitdiff
path: root/ui/tcell/window.go
diff options
context:
space:
mode:
Diffstat (limited to 'ui/tcell/window.go')
-rw-r--r--ui/tcell/window.go157
1 files changed, 157 insertions, 0 deletions
diff --git a/ui/tcell/window.go b/ui/tcell/window.go
new file mode 100644
index 0000000..fcb146c
--- /dev/null
+++ b/ui/tcell/window.go
@@ -0,0 +1,157 @@
+package uitcell
+
+import (
+ "fmt"
+
+ "github.com/gdamore/tcell"
+ "github.com/prodhe/poe/editor"
+)
+
+// Window is a tagline and a body with an optional underlying file on disk. It is the main component and handles all events apart from the system wide shortcuts.
+type Window struct {
+ x, y, w, h int
+ bufid int64
+ body *View
+ tagline *View
+ col *Column // reference to the column where in
+ hidden bool
+ collapsed bool // not implemented
+ qcnt int // quit count
+}
+
+// NewWindow returns a fresh window associated with the given filename. For special case filenames, look at the package constants.
+func NewWindow(id int64) *Window {
+ win := &Window{
+ bufid: id,
+ body: &View{
+ text: ed.Buffer(id),
+ what: ViewBody,
+ style: bodyStyle,
+ cursorStyle: bodyCursorStyle,
+ hilightStyle: bodyHilightStyle,
+ tabstop: 4,
+ focused: true,
+ },
+ tagline: &View{
+ text: &editor.Buffer{},
+ what: ViewTagline,
+ style: tagStyle,
+ cursorStyle: tagCursorStyle,
+ hilightStyle: tagHilightStyle,
+ tabstop: 4,
+ },
+ }
+
+ fmt.Fprintf(win.tagline, "%s Del ",
+ win.Name(),
+ )
+
+ return win
+}
+
+func AllWindows() []*Window {
+ var ws []*Window
+ for _, col := range workspace.cols {
+ ws = append(ws, col.windows...)
+ }
+ return ws
+}
+
+// FindWindow searches for the given name in current windows and returns a pointer if one already exists. Nil otherwise. Name assumes to be an absolute path.
+func FindWindow(name string) *Window {
+ for _, win := range AllWindows() {
+ if win.Name() == name {
+ return win
+ }
+ }
+ return nil
+}
+
+// Resize will set new values for position and width height. Meant to be used on a resize event for proper recalculation during the Draw().
+func (win *Window) Resize(x, y, w, h int) {
+ win.x, win.y, win.w, win.h = x, y, w, h
+
+ win.tagline.Resize(win.x+3, win.y, win.w-3, 1) // 3 for tagbox
+ win.body.Resize(win.x, win.y+1, win.w, win.h-1)
+}
+
+func (win *Window) UnFocus() {
+ win.body.focused = true
+ win.tagline.focused = false
+}
+
+func (win *Window) Name() string {
+ return win.body.text.Name()
+}
+
+func (win *Window) Dir() string {
+ return win.body.text.WorkDir()
+}
+
+func (win *Window) HandleEvent(ev tcell.Event) {
+ switch ev := ev.(type) {
+ case *tcell.EventMouse:
+ _, my := ev.Position()
+
+ // Set focus to either tagline or body
+ if my > win.tagline.y+win.tagline.h-1 {
+ win.tagline.focused = false
+ } else {
+ win.tagline.focused = true
+ }
+ case *tcell.EventKey:
+ switch ev.Key() {
+ case tcell.KeyCtrlS: // save
+ _, err := win.body.text.SaveFile()
+ if err != nil {
+ printMsg("%s\n", err)
+ }
+ return
+ }
+ }
+
+ // Pass along the event down to current view, if we have not already done something and returned in the switch above.
+ if win.tagline.focused {
+ win.tagline.HandleEvent(ev)
+ } else {
+ win.body.HandleEvent(ev)
+ }
+}
+
+func (win *Window) Draw() {
+ // Draw tag square
+ boxstyle := tagSquareStyle
+ if win.body.dirty {
+ boxstyle = tagSquareModifiedStyle
+ }
+ screen.SetContent(win.x, win.y, ' ', nil, boxstyle)
+ screen.SetContent(win.x+1, win.y, ' ', nil, boxstyle)
+ screen.SetContent(win.x+2, win.y, ' ', nil, win.tagline.style)
+
+ // Tagline
+ win.tagline.Draw()
+
+ // Main text buffer
+ win.body.Draw()
+}
+
+func (win *Window) CanClose() bool {
+ ok := !win.body.dirty || win.qcnt > 0
+ if !ok {
+ name := win.Name()
+ if name == FnEmptyWin {
+ name = "unnamed file"
+ }
+ printMsg("%s modified\n", name)
+ win.qcnt++
+ }
+ return ok
+}
+
+func (win *Window) Close() {
+ if !win.CanClose() {
+ return
+ }
+ ed.CloseBuffer(win.bufid)
+ win.col.CloseWindow(win)
+}