mirror of https://github.com/liamg/aminal.git
fix resizing
This commit is contained in:
parent
844ac645ce
commit
c2b7f94f87
|
@ -18,6 +18,15 @@ Ensure you have your latest graphics card drivers installed before use.
|
|||
- Bullshit graphical effects
|
||||
- Multi platform support
|
||||
|
||||
## What isn't supported?
|
||||
|
||||
- Suspend/Continue (^S, ^Q). This is archaic bullshit that annoys more people than it helps. Basically:
|
||||
|
||||
<span style="display:block;text-align:center">
|
||||

|
||||
</span>
|
||||
|
||||
|
||||
## Build Dependencies
|
||||
|
||||
- Go 1.10.3+
|
||||
|
|
|
@ -270,7 +270,7 @@ func (buffer *Buffer) Clear() {
|
|||
func (buffer *Buffer) getCurrentLine() *Line {
|
||||
|
||||
if buffer.cursorY >= buffer.ViewHeight() {
|
||||
panic(fmt.Sprintf("cursor is outside of view: %d %d", buffer.cursorX, buffer.cursorY))
|
||||
panic(fmt.Sprintf("cursor is outside of view: y=%d h=%d", buffer.cursorY, buffer.viewHeight))
|
||||
}
|
||||
|
||||
if len(buffer.lines) < int(buffer.ViewHeight()) {
|
||||
|
@ -377,8 +377,96 @@ func (buffer *Buffer) EraseDisplayToCursor() {
|
|||
|
||||
func (buffer *Buffer) ResizeView(width uint16, height uint16) {
|
||||
defer buffer.emitDisplayChange()
|
||||
|
||||
if buffer.viewHeight == 0 {
|
||||
buffer.viewWidth = width
|
||||
buffer.viewHeight = height
|
||||
return
|
||||
}
|
||||
|
||||
// @todo scroll to bottom on resize
|
||||
line := buffer.getCurrentLine()
|
||||
cXFromEndOfLine := len(line.cells) - int(buffer.cursorX+1)
|
||||
|
||||
if width < buffer.viewWidth { // wrap lines if we're shrinking
|
||||
for i := 0; i < len(buffer.lines); i++ {
|
||||
line := &buffer.lines[i]
|
||||
//line.Cleanse()
|
||||
if len(line.cells) > int(width) { // only try wrapping a line if it's too long
|
||||
sillyCells := line.cells[width:] // grab the cells we need to wrap
|
||||
line.cells = line.cells[:width]
|
||||
|
||||
// we need to move cut cells to the next line
|
||||
// if the next line is wrapped anyway, we can push them onto the beginning of that line
|
||||
// otherwise, we need add a new wrapped line
|
||||
if i+1 < len(buffer.lines) {
|
||||
nextLine := &buffer.lines[i+1]
|
||||
if nextLine.wrapped {
|
||||
nextLine.cells = append(sillyCells, nextLine.cells...)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
newLine := newLine()
|
||||
newLine.setWrapped(true)
|
||||
newLine.cells = sillyCells
|
||||
after := append([]Line{newLine}, buffer.lines[i+1:]...)
|
||||
buffer.lines = append(buffer.lines[:i+1], after...)
|
||||
|
||||
}
|
||||
}
|
||||
} else if width > buffer.viewWidth { // unwrap lines if we're growing
|
||||
for i := 0; i < len(buffer.lines)-1; i++ {
|
||||
line := &buffer.lines[i]
|
||||
//line.Cleanse()
|
||||
for offset := 1; i+offset < len(buffer.lines); offset++ {
|
||||
nextLine := &buffer.lines[i+offset]
|
||||
//nextLine.Cleanse()
|
||||
if !nextLine.wrapped { // if the next line wasn't wrapped, we don't need to move characters back to this line
|
||||
break
|
||||
}
|
||||
spaceOnLine := int(width) - len(line.cells)
|
||||
if spaceOnLine <= 0 { // no more space to unwrap
|
||||
break
|
||||
}
|
||||
moveCount := spaceOnLine
|
||||
if moveCount > len(nextLine.cells) {
|
||||
moveCount = len(nextLine.cells)
|
||||
}
|
||||
line.cells = append(line.cells, nextLine.cells[:moveCount]...)
|
||||
if moveCount == len(nextLine.cells) {
|
||||
// if we unwrapped all cells off the next line, delete it
|
||||
buffer.lines = append(buffer.lines[:i+offset], buffer.lines[i+offset+1:]...)
|
||||
|
||||
offset--
|
||||
|
||||
} else {
|
||||
// otherwise just remove the characters we moved up a line
|
||||
nextLine.cells = nextLine.cells[moveCount:]
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// @todo handle vertical resize?
|
||||
|
||||
if buffer.Height() < int(buffer.viewHeight) {
|
||||
// we might need to move back up if the buffer is now smaller
|
||||
if int(buffer.cursorY) < buffer.Height()-1 {
|
||||
buffer.cursorY = uint16(buffer.Height() - 1)
|
||||
} else {
|
||||
buffer.cursorY = uint16(buffer.Height() - 1)
|
||||
}
|
||||
} else {
|
||||
buffer.cursorY = buffer.viewHeight - 1
|
||||
}
|
||||
|
||||
buffer.viewWidth = width
|
||||
buffer.viewHeight = height
|
||||
|
||||
// @todo wrap/unwrap
|
||||
// position cursorX
|
||||
line = buffer.getCurrentLine()
|
||||
buffer.cursorX = uint16((len(line.cells) - cXFromEndOfLine) - 1)
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package buffer
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -268,11 +269,6 @@ func TestCarriageReturnOnLineThatDoesntExist(t *testing.T) {
|
|||
assert.Equal(t, uint16(3), b.cursorY)
|
||||
}
|
||||
|
||||
func TestResizeView(t *testing.T) {
|
||||
b := NewBuffer(80, 20, CellAttributes{})
|
||||
b.ResizeView(40, 10)
|
||||
}
|
||||
|
||||
func TestGetCell(t *testing.T) {
|
||||
b := NewBuffer(80, 20, CellAttributes{})
|
||||
b.Write([]rune("Hello\r\nthere\r\nsomething...")...)
|
||||
|
@ -430,3 +426,84 @@ func TestBackspaceWithWrap(t *testing.T) {
|
|||
assert.Equal(t, "hello\x00\x00\x00\x00\x00", lines[0].String())
|
||||
assert.Equal(t, "\x00\x00\x00\x00\x00", lines[1].String())
|
||||
}
|
||||
|
||||
func TestHorizontalResizeView(t *testing.T) {
|
||||
b := NewBuffer(80, 10, CellAttributes{})
|
||||
|
||||
// 60 characters
|
||||
b.Write([]rune(
|
||||
`hellohellohellohellohellohellohellohellohellohellohellohello
|
||||
goodbyegoodbye`)...)
|
||||
|
||||
require.Equal(t, uint16(14), b.cursorX)
|
||||
require.Equal(t, uint16(1), b.cursorY)
|
||||
|
||||
b.ResizeView(40, 10)
|
||||
|
||||
expected := `hellohellohellohellohellohellohellohello
|
||||
hellohellohellohello
|
||||
goodbyegoodbye`
|
||||
|
||||
require.Equal(t, uint16(14), b.cursorX)
|
||||
require.Equal(t, uint16(2), b.cursorY)
|
||||
|
||||
lines := b.GetVisibleLines()
|
||||
strs := []string{}
|
||||
for _, l := range lines {
|
||||
strs = append(strs, l.String())
|
||||
}
|
||||
require.Equal(t, expected, strings.Join(strs, "\n"))
|
||||
|
||||
b.ResizeView(20, 10)
|
||||
|
||||
expected = `hellohellohellohello
|
||||
hellohellohellohello
|
||||
hellohellohellohello
|
||||
goodbyegoodbye`
|
||||
|
||||
lines = b.GetVisibleLines()
|
||||
strs = []string{}
|
||||
for _, l := range lines {
|
||||
strs = append(strs, l.String())
|
||||
}
|
||||
require.Equal(t, expected, strings.Join(strs, "\n"))
|
||||
|
||||
b.ResizeView(10, 10)
|
||||
|
||||
expected = `hellohello
|
||||
hellohello
|
||||
hellohello
|
||||
hellohello
|
||||
hellohello
|
||||
hellohello
|
||||
goodbyegoo
|
||||
dbye`
|
||||
|
||||
lines = b.GetVisibleLines()
|
||||
strs = []string{}
|
||||
for _, l := range lines {
|
||||
strs = append(strs, l.String())
|
||||
}
|
||||
require.Equal(t, expected, strings.Join(strs, "\n"))
|
||||
|
||||
b.ResizeView(80, 20)
|
||||
|
||||
expected = `hellohellohellohellohellohellohellohellohellohellohellohello
|
||||
goodbyegoodbye`
|
||||
|
||||
lines = b.GetVisibleLines()
|
||||
strs = []string{}
|
||||
for _, l := range lines {
|
||||
strs = append(strs, l.String())
|
||||
}
|
||||
require.Equal(t, expected, strings.Join(strs, "\n"))
|
||||
|
||||
require.Equal(t, uint16(1), b.cursorY)
|
||||
require.Equal(t, uint16(14), b.cursorX)
|
||||
}
|
||||
|
||||
/*
|
||||
hellohellohellohellohellohellohellohellohellohellohellohello
|
||||
goodbyegoo
|
||||
dbye
|
||||
*/
|
||||
|
|
|
@ -12,6 +12,21 @@ func newLine() Line {
|
|||
}
|
||||
}
|
||||
|
||||
// Cleanse removes null bytes from the end of the row
|
||||
func (line *Line) Cleanse() {
|
||||
cut := 0
|
||||
for i := len(line.cells) - 1; i >= 0; i-- {
|
||||
if line.cells[i].r != 0 {
|
||||
break
|
||||
}
|
||||
cut++
|
||||
}
|
||||
if cut == 0 {
|
||||
return
|
||||
}
|
||||
line.cells = line.cells[:len(line.cells)-cut]
|
||||
}
|
||||
|
||||
func (line *Line) setWrapped(wrapped bool) {
|
||||
line.wrapped = wrapped
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue