added a close buffer command (ctrl+w);

This commit is contained in:
Felix Angell 2018-04-13 19:10:32 +01:00
parent 9b2dbebcd6
commit dc3985dcbe
8 changed files with 132 additions and 23 deletions

View File

@ -3,6 +3,7 @@ package gui
type BufferAction func(*Buffer) bool type BufferAction func(*Buffer) bool
var actions = map[string]BufferAction{ var actions = map[string]BufferAction{
"save": Save, "save": Save,
"delete_line": DeleteLine, "delete_line": DeleteLine,
"close_buffer": CloseBuffer,
} }

View File

@ -29,6 +29,8 @@ type camera struct {
type Buffer struct { type Buffer struct {
BaseComponent BaseComponent
index int
parent *View
font *strife.Font font *strife.Font
contents []*rope.Rope contents []*rope.Rope
curs *Cursor curs *Cursor
@ -37,7 +39,7 @@ type Buffer struct {
filePath string filePath string
} }
func NewBuffer(conf *cfg.TomlConfig) *Buffer { func NewBuffer(conf *cfg.TomlConfig, parent *View, index int) *Buffer {
config := conf config := conf
if config == nil { if config == nil {
config = cfg.NewDefaultConfig() config = cfg.NewDefaultConfig()
@ -45,6 +47,8 @@ func NewBuffer(conf *cfg.TomlConfig) *Buffer {
buffContents := []*rope.Rope{} buffContents := []*rope.Rope{}
buff := &Buffer{ buff := &Buffer{
index: index,
parent: parent,
contents: buffContents, contents: buffContents,
curs: &Cursor{}, curs: &Cursor{},
cfg: config, cfg: config,
@ -120,6 +124,13 @@ var shiftAlternative = map[rune]rune{
} }
func (b *Buffer) processTextInput(r rune) bool { func (b *Buffer) processTextInput(r rune) bool {
if ALT_DOWN && r == '\t' {
// nop, we dont want to
// insert tabs when we
// alt tab out of view of this app
return true
}
if CAPS_LOCK { if CAPS_LOCK {
if unicode.IsLetter(r) { if unicode.IsLetter(r) {
r = unicode.ToUpper(r) r = unicode.ToUpper(r)
@ -132,6 +143,8 @@ func (b *Buffer) processTextInput(r rune) bool {
if proc, ok := actions[actionName]; ok { if proc, ok := actions[actionName]; ok {
return proc(b) return proc(b)
} }
} else {
log.Println("warning, unimplemented shortcut ctrl+", unicode.ToLower(r), actionName)
} }
} }
@ -141,6 +154,8 @@ func (b *Buffer) processTextInput(r rune) bool {
if proc, ok := actions[actionName]; ok { if proc, ok := actions[actionName]; ok {
return proc(b) return proc(b)
} }
} else {
log.Println("warning, unimplemented shortcut ctrl+", unicode.ToLower(r), actionName)
} }
} }
@ -307,7 +322,7 @@ func (b *Buffer) scrollUp() {
// TODO move the cursor down 45 lines // TODO move the cursor down 45 lines
// IF the buffer exceeds the window size. // IF the buffer exceeds the window size.
lineScrollAmount := 10 lineScrollAmount := 10
b.cam.y -= lineScrollAmount * last_h b.cam.y -= lineScrollAmount
for i := 0; i < lineScrollAmount; i++ { for i := 0; i < lineScrollAmount; i++ {
b.moveUp() b.moveUp()
} }
@ -318,7 +333,7 @@ func (b *Buffer) scrollDown() {
// IF the buffer exceeds the window size. // IF the buffer exceeds the window size.
lineScrollAmount := 10 lineScrollAmount := 10
b.cam.y += lineScrollAmount * last_h b.cam.y += lineScrollAmount
for i := 0; i < lineScrollAmount; i++ { for i := 0; i < lineScrollAmount; i++ {
b.moveDown() b.moveDown()
} }
@ -480,6 +495,8 @@ func (b *Buffer) processActionKey(key int) bool {
} }
} }
log.Println(b.curs.y, " .. ", b.curs.y-b.cam.y)
if b.curs.y < len(b.contents)-1 { if b.curs.y < len(b.contents)-1 {
offs := 0 offs := 0
nextLineLen := b.contents[b.curs.y+1].Len() nextLineLen := b.contents[b.curs.y+1].Len()
@ -622,12 +639,11 @@ func (b *Buffer) OnUpdate() bool {
// dimensions of the last character we rendered // dimensions of the last character we rendered
var last_w, last_h int var last_w, last_h int
var lineIndex int = 0
func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) { func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) {
// BACKGROUND // BACKGROUND
ctx.SetColor(strife.HexRGB(b.cfg.Theme.Background)) ctx.SetColor(strife.HexRGB(b.cfg.Theme.Background))
ctx.Rect(rx, ry, b.w, b.h, strife.Fill) ctx.Rect(b.x, b.y, b.w, b.h, strife.Fill)
if b.cfg.Editor.Highlight_Line { if b.cfg.Editor.Highlight_Line {
ctx.SetColor(strife.Black) // highlight_line_col? ctx.SetColor(strife.Black) // highlight_line_col?
@ -646,16 +662,16 @@ func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) {
} }
source := b.contents source := b.contents
// last_h > 0 means we have done
// a render.
if int(last_h) > 0 && int(b.h) != 0 { if int(last_h) > 0 && int(b.h) != 0 {
// work out how many lines can fit into // work out how many lines can fit into
// the buffer, and set the source to // the buffer, and set the source to
// slice the line buffer accordingly // slice the line buffer accordingly
visibleLines := int(b.h) / int(last_h) visibleLines := int(b.h) / int(last_h)
if len(b.contents) > visibleLines { if len(b.contents) > visibleLines {
if lineIndex+visibleLines >= len(b.contents) { // nop
lineIndex = len(b.contents) - visibleLines
}
source = b.contents[lineIndex : lineIndex+visibleLines]
} }
} }
@ -707,5 +723,5 @@ func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) {
} }
func (b *Buffer) OnRender(ctx *strife.Renderer) { func (b *Buffer) OnRender(ctx *strife.Renderer) {
b.renderAt(ctx, b.x-b.cam.x, b.y-b.cam.y) b.renderAt(ctx, b.x-(b.cam.x*last_w), b.y-(b.cam.y*last_h))
} }

42
gui/close_buffer.go Normal file
View File

@ -0,0 +1,42 @@
package gui
func CloseBuffer(b *Buffer) bool {
// no parent. this can happen sometimes
// for example if we're trying to close
// a buffer illegal, e.g. a palette has
// a buffer
if b.parent == nil {
return false
}
b.parent.DeleteComponent(b.index)
// we need to re-calculate the sizes of everything
// since we've closed a buffer!
// work out the size of the buffer and set it
// note that we +1 the components because
// we haven't yet added the panel
var bufferWidth int
numComponents := b.parent.NumComponents()
if numComponents > 0 {
bufferWidth = b.parent.w / numComponents
} else {
bufferWidth = b.parent.w
}
// translate all the components accordingly.
i := 0
for _, p := range b.parent.components {
if p == nil {
continue
}
p.Resize(bufferWidth, b.parent.h)
p.SetPosition(bufferWidth*i, 0)
i = i + 1
}
return true
}

View File

@ -14,6 +14,7 @@ type Component interface {
OnRender(*strife.Renderer) OnRender(*strife.Renderer)
OnDispose() OnDispose()
NumComponents() int
AddComponent(c Component) AddComponent(c Component)
GetComponents() []Component GetComponents() []Component
@ -22,24 +23,42 @@ type Component interface {
} }
type BaseComponent struct { type BaseComponent struct {
x, y int x, y int
w, h int w, h int
components []Component components []Component
inputHandler *InputHandler numComponents int
inputHandler *InputHandler
}
func (b *BaseComponent) DeleteComponent(index int) {
b.components[index] = nil
b.numComponents--
} }
func (b *BaseComponent) SetPosition(x, y int) { func (b *BaseComponent) SetPosition(x, y int) {
b.x = x b.x = x
b.y = y b.y = y
for _, c := range b.components { for _, c := range b.components {
if c == nil {
continue
}
c.SetPosition(x, y) c.SetPosition(x, y)
} }
} }
func (b *BaseComponent) NumComponents() int {
return b.numComponents
}
func (b *BaseComponent) Translate(x, y int) { func (b *BaseComponent) Translate(x, y int) {
b.x += x b.x += x
b.y += y b.y += y
for _, c := range b.components { for _, c := range b.components {
if c == nil {
continue
}
c.Translate(x, y) c.Translate(x, y)
} }
} }
@ -48,6 +67,10 @@ func (b *BaseComponent) Resize(w, h int) {
b.w = w b.w = w
b.h = h b.h = h
for _, c := range b.components { for _, c := range b.components {
if c == nil {
continue
}
c.Resize(w, h) c.Resize(w, h)
} }
} }
@ -58,6 +81,7 @@ func (b *BaseComponent) GetComponents() []Component {
func (b *BaseComponent) AddComponent(c Component) { func (b *BaseComponent) AddComponent(c Component) {
b.components = append(b.components, c) b.components = append(b.components, c)
b.numComponents++
c.SetInputHandler(b.inputHandler) c.SetInputHandler(b.inputHandler)
Init(c) Init(c)
} }
@ -73,6 +97,10 @@ func (b *BaseComponent) GetInputHandler() *InputHandler {
func Update(c Component) bool { func Update(c Component) bool {
needsRender := c.OnUpdate() needsRender := c.OnUpdate()
for _, child := range c.GetComponents() { for _, child := range c.GetComponents() {
if child == nil {
continue
}
dirty := Update(child) dirty := Update(child)
if dirty { if dirty {
needsRender = true needsRender = true
@ -84,6 +112,10 @@ func Update(c Component) bool {
func Render(c Component, ctx *strife.Renderer) { func Render(c Component, ctx *strife.Renderer) {
c.OnRender(ctx) c.OnRender(ctx)
for _, child := range c.GetComponents() { for _, child := range c.GetComponents() {
if child == nil {
continue
}
Render(child, ctx) Render(child, ctx)
} }
} }
@ -91,6 +123,10 @@ func Render(c Component, ctx *strife.Renderer) {
func Init(c Component) { func Init(c Component) {
c.OnInit() c.OnInit()
for _, child := range c.GetComponents() { for _, child := range c.GetComponents() {
if child == nil {
continue
}
Init(child) Init(child)
} }
} }
@ -98,6 +134,10 @@ func Init(c Component) {
func Dispose(c Component) { func Dispose(c Component) {
c.OnDispose() c.OnDispose()
for _, child := range c.GetComponents() { for _, child := range c.GetComponents() {
if child == nil {
continue
}
Dispose(child) Dispose(child)
} }
} }

View File

@ -21,7 +21,7 @@ type CommandPalette struct {
func NewCommandPalette() *CommandPalette { func NewCommandPalette() *CommandPalette {
palette := &CommandPalette{} palette := &CommandPalette{}
palette.buffer = &CommandBuffer{ palette.buffer = &CommandBuffer{
Buffer: NewBuffer(nil), Buffer: NewBuffer(nil, nil, 0),
} }
palette.AddComponent(palette.buffer) palette.AddComponent(palette.buffer)
return palette return palette

View File

@ -1,7 +1,7 @@
package gui package gui
import ( import (
"github.com/felixangell/strife" "github.com/felixangell/strife"
) )
type Panel struct { type Panel struct {
@ -9,7 +9,7 @@ type Panel struct {
} }
func NewPanel(input *InputHandler) *Panel { func NewPanel(input *InputHandler) *Panel {
panel := &Panel{} panel := &Panel{}
panel.SetInputHandler(input) panel.SetInputHandler(input)
return panel return panel
} }

View File

@ -29,15 +29,20 @@ func (n *View) OnRender(ctx *strife.Renderer) {}
func (n *View) OnDispose() {} func (n *View) OnDispose() {}
func (n *View) AddBuffer() *Buffer { func (n *View) AddBuffer() *Buffer {
c := NewBuffer(n.conf) c := NewBuffer(n.conf, n, n.NumComponents())
// work out the size of the buffer and set it // work out the size of the buffer and set it
// note that we +1 the components because // note that we +1 the components because
// we haven't yet added the panel // we haven't yet added the panel
var bufferWidth int var bufferWidth int
numComponents := len(n.components) + 1
// NOTE: because we're ADDING a component
// here we add 1 to the components since
// we want to calculate the sizes _after_
// we've added this component.
numComponents := n.NumComponents() + 1
if numComponents > 0 { if numComponents > 0 {
bufferWidth = int(float32(n.w) / float32(numComponents)) bufferWidth = n.w / numComponents
} else { } else {
bufferWidth = n.w bufferWidth = n.w
} }
@ -45,11 +50,16 @@ func (n *View) AddBuffer() *Buffer {
// setup and add the panel for the buffer // setup and add the panel for the buffer
panel := NewPanel(n.inputHandler) panel := NewPanel(n.inputHandler)
c.SetInputHandler(n.inputHandler) c.SetInputHandler(n.inputHandler)
panel.AddComponent(c) panel.AddComponent(c)
n.components = append(n.components, panel) n.AddComponent(panel)
// translate all the components accordingly. // translate all the components accordingly.
for i, p := range n.components { for i, p := range n.components {
if p == nil {
continue
}
p.Resize(bufferWidth, n.h) p.Resize(bufferWidth, n.h)
p.SetPosition(bufferWidth*i, 0) p.SetPosition(bufferWidth*i, 0)
} }

Binary file not shown.