diff --git a/gui/action.go b/gui/action.go index fd15178..527420e 100644 --- a/gui/action.go +++ b/gui/action.go @@ -3,6 +3,7 @@ package gui type BufferAction func(*Buffer) bool var actions = map[string]BufferAction{ - "save": Save, - "delete_line": DeleteLine, + "save": Save, + "delete_line": DeleteLine, + "close_buffer": CloseBuffer, } diff --git a/gui/buffer.go b/gui/buffer.go index 77a2427..780e8d8 100644 --- a/gui/buffer.go +++ b/gui/buffer.go @@ -29,6 +29,8 @@ type camera struct { type Buffer struct { BaseComponent + index int + parent *View font *strife.Font contents []*rope.Rope curs *Cursor @@ -37,7 +39,7 @@ type Buffer struct { filePath string } -func NewBuffer(conf *cfg.TomlConfig) *Buffer { +func NewBuffer(conf *cfg.TomlConfig, parent *View, index int) *Buffer { config := conf if config == nil { config = cfg.NewDefaultConfig() @@ -45,6 +47,8 @@ func NewBuffer(conf *cfg.TomlConfig) *Buffer { buffContents := []*rope.Rope{} buff := &Buffer{ + index: index, + parent: parent, contents: buffContents, curs: &Cursor{}, cfg: config, @@ -120,6 +124,13 @@ var shiftAlternative = map[rune]rune{ } 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 unicode.IsLetter(r) { r = unicode.ToUpper(r) @@ -132,6 +143,8 @@ func (b *Buffer) processTextInput(r rune) bool { if proc, ok := actions[actionName]; ok { 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 { 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 // IF the buffer exceeds the window size. lineScrollAmount := 10 - b.cam.y -= lineScrollAmount * last_h + b.cam.y -= lineScrollAmount for i := 0; i < lineScrollAmount; i++ { b.moveUp() } @@ -318,7 +333,7 @@ func (b *Buffer) scrollDown() { // IF the buffer exceeds the window size. lineScrollAmount := 10 - b.cam.y += lineScrollAmount * last_h + b.cam.y += lineScrollAmount for i := 0; i < lineScrollAmount; i++ { 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 { offs := 0 nextLineLen := b.contents[b.curs.y+1].Len() @@ -622,12 +639,11 @@ func (b *Buffer) OnUpdate() bool { // dimensions of the last character we rendered var last_w, last_h int -var lineIndex int = 0 func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) { // 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 { 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 + + // last_h > 0 means we have done + // a render. if int(last_h) > 0 && int(b.h) != 0 { // work out how many lines can fit into // the buffer, and set the source to // slice the line buffer accordingly visibleLines := int(b.h) / int(last_h) if len(b.contents) > visibleLines { - if lineIndex+visibleLines >= len(b.contents) { - lineIndex = len(b.contents) - visibleLines - } - source = b.contents[lineIndex : lineIndex+visibleLines] + // nop } } @@ -707,5 +723,5 @@ func (b *Buffer) renderAt(ctx *strife.Renderer, rx int, ry int) { } 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)) } diff --git a/gui/close_buffer.go b/gui/close_buffer.go new file mode 100644 index 0000000..da7b28c --- /dev/null +++ b/gui/close_buffer.go @@ -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 +} diff --git a/gui/component.go b/gui/component.go index 7ff6956..42886b5 100644 --- a/gui/component.go +++ b/gui/component.go @@ -14,6 +14,7 @@ type Component interface { OnRender(*strife.Renderer) OnDispose() + NumComponents() int AddComponent(c Component) GetComponents() []Component @@ -22,24 +23,42 @@ type Component interface { } type BaseComponent struct { - x, y int - w, h int - components []Component - inputHandler *InputHandler + x, y int + w, h int + components []Component + numComponents int + inputHandler *InputHandler +} + +func (b *BaseComponent) DeleteComponent(index int) { + b.components[index] = nil + b.numComponents-- } func (b *BaseComponent) SetPosition(x, y int) { b.x = x b.y = y for _, c := range b.components { + if c == nil { + continue + } + c.SetPosition(x, y) } } +func (b *BaseComponent) NumComponents() int { + return b.numComponents +} + func (b *BaseComponent) Translate(x, y int) { b.x += x b.y += y for _, c := range b.components { + if c == nil { + continue + } + c.Translate(x, y) } } @@ -48,6 +67,10 @@ func (b *BaseComponent) Resize(w, h int) { b.w = w b.h = h for _, c := range b.components { + if c == nil { + continue + } + c.Resize(w, h) } } @@ -58,6 +81,7 @@ func (b *BaseComponent) GetComponents() []Component { func (b *BaseComponent) AddComponent(c Component) { b.components = append(b.components, c) + b.numComponents++ c.SetInputHandler(b.inputHandler) Init(c) } @@ -73,6 +97,10 @@ func (b *BaseComponent) GetInputHandler() *InputHandler { func Update(c Component) bool { needsRender := c.OnUpdate() for _, child := range c.GetComponents() { + if child == nil { + continue + } + dirty := Update(child) if dirty { needsRender = true @@ -84,6 +112,10 @@ func Update(c Component) bool { func Render(c Component, ctx *strife.Renderer) { c.OnRender(ctx) for _, child := range c.GetComponents() { + if child == nil { + continue + } + Render(child, ctx) } } @@ -91,6 +123,10 @@ func Render(c Component, ctx *strife.Renderer) { func Init(c Component) { c.OnInit() for _, child := range c.GetComponents() { + if child == nil { + continue + } + Init(child) } } @@ -98,6 +134,10 @@ func Init(c Component) { func Dispose(c Component) { c.OnDispose() for _, child := range c.GetComponents() { + if child == nil { + continue + } + Dispose(child) } } diff --git a/gui/palette.go b/gui/palette.go index 8986b96..d64326a 100644 --- a/gui/palette.go +++ b/gui/palette.go @@ -21,7 +21,7 @@ type CommandPalette struct { func NewCommandPalette() *CommandPalette { palette := &CommandPalette{} palette.buffer = &CommandBuffer{ - Buffer: NewBuffer(nil), + Buffer: NewBuffer(nil, nil, 0), } palette.AddComponent(palette.buffer) return palette diff --git a/gui/panel.go b/gui/panel.go index 667bbe2..511cc3c 100644 --- a/gui/panel.go +++ b/gui/panel.go @@ -1,7 +1,7 @@ package gui import ( - "github.com/felixangell/strife" + "github.com/felixangell/strife" ) type Panel struct { @@ -9,7 +9,7 @@ type Panel struct { } func NewPanel(input *InputHandler) *Panel { - panel := &Panel{} + panel := &Panel{} panel.SetInputHandler(input) return panel } diff --git a/gui/view.go b/gui/view.go index b9d1d49..cd2151b 100644 --- a/gui/view.go +++ b/gui/view.go @@ -29,15 +29,20 @@ func (n *View) OnRender(ctx *strife.Renderer) {} func (n *View) OnDispose() {} 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 // note that we +1 the components because // we haven't yet added the panel 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 { - bufferWidth = int(float32(n.w) / float32(numComponents)) + bufferWidth = n.w / numComponents } else { bufferWidth = n.w } @@ -45,11 +50,16 @@ func (n *View) AddBuffer() *Buffer { // setup and add the panel for the buffer panel := NewPanel(n.inputHandler) c.SetInputHandler(n.inputHandler) + panel.AddComponent(c) - n.components = append(n.components, panel) + n.AddComponent(panel) // translate all the components accordingly. for i, p := range n.components { + if p == nil { + continue + } + p.Resize(bufferWidth, n.h) p.SetPosition(bufferWidth*i, 0) } diff --git a/phi-editor b/phi-editor index 0008786..043997f 100755 Binary files a/phi-editor and b/phi-editor differ