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
|
- Bullshit graphical effects
|
||||||
- Multi platform support
|
- 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
|
## Build Dependencies
|
||||||
|
|
||||||
- Go 1.10.3+
|
- Go 1.10.3+
|
||||||
|
|
|
@ -270,7 +270,7 @@ func (buffer *Buffer) Clear() {
|
||||||
func (buffer *Buffer) getCurrentLine() *Line {
|
func (buffer *Buffer) getCurrentLine() *Line {
|
||||||
|
|
||||||
if buffer.cursorY >= buffer.ViewHeight() {
|
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()) {
|
if len(buffer.lines) < int(buffer.ViewHeight()) {
|
||||||
|
@ -377,8 +377,96 @@ func (buffer *Buffer) EraseDisplayToCursor() {
|
||||||
|
|
||||||
func (buffer *Buffer) ResizeView(width uint16, height uint16) {
|
func (buffer *Buffer) ResizeView(width uint16, height uint16) {
|
||||||
defer buffer.emitDisplayChange()
|
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.viewWidth = width
|
||||||
buffer.viewHeight = height
|
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
|
package buffer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -268,11 +269,6 @@ func TestCarriageReturnOnLineThatDoesntExist(t *testing.T) {
|
||||||
assert.Equal(t, uint16(3), b.cursorY)
|
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) {
|
func TestGetCell(t *testing.T) {
|
||||||
b := NewBuffer(80, 20, CellAttributes{})
|
b := NewBuffer(80, 20, CellAttributes{})
|
||||||
b.Write([]rune("Hello\r\nthere\r\nsomething...")...)
|
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, "hello\x00\x00\x00\x00\x00", lines[0].String())
|
||||||
assert.Equal(t, "\x00\x00\x00\x00\x00", lines[1].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) {
|
func (line *Line) setWrapped(wrapped bool) {
|
||||||
line.wrapped = wrapped
|
line.wrapped = wrapped
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue