implemented 'area scrolling' (#202)

* implemented 'area scrolling'

* bug fix: area scroll down boundary check

* bug fix: ReverseIndex activates scroll down correctly
This commit is contained in:
rrrooommmaaa 2019-02-11 23:27:08 +03:00 committed by Liam Galvin
parent bc1b3f0dfd
commit 77348c2188
6 changed files with 91 additions and 72 deletions

View File

@ -326,10 +326,6 @@ func (buffer *Buffer) IsDirty() bool {
return true
}
func (buffer *Buffer) GetScrollOffset() uint {
return buffer.terminalState.scrollLinesFromBottom
}
func (buffer *Buffer) HasScrollableRegion() bool {
return buffer.terminalState.topMargin > 0 || buffer.terminalState.bottomMargin < uint(buffer.ViewHeight())-1
}
@ -338,44 +334,46 @@ func (buffer *Buffer) InScrollableRegion() bool {
return buffer.HasScrollableRegion() && uint(buffer.terminalState.cursorY) >= buffer.terminalState.topMargin && uint(buffer.terminalState.cursorY) <= buffer.terminalState.bottomMargin
}
func (buffer *Buffer) ScrollDown(lines uint16) {
defer buffer.emitDisplayChange()
if buffer.Height() < int(buffer.ViewHeight()) {
return
// NOTE: bottom is exclusive
func (buffer *Buffer) getAreaScrollRange() (top uint64, bottom uint64) {
top = buffer.convertViewLineToRawLine(uint16(buffer.terminalState.topMargin))
bottom = buffer.convertViewLineToRawLine(uint16(buffer.terminalState.bottomMargin)) + 1
if bottom > uint64(len(buffer.lines)) {
bottom = uint64(len(buffer.lines))
}
if uint(lines) > buffer.terminalState.scrollLinesFromBottom {
lines = uint16(buffer.terminalState.scrollLinesFromBottom)
}
buffer.terminalState.scrollLinesFromBottom -= uint(lines)
return top, bottom
}
func (buffer *Buffer) ScrollUp(lines uint16) {
func (buffer *Buffer) AreaScrollDown(lines uint16) {
defer buffer.emitDisplayChange()
if buffer.Height() < int(buffer.ViewHeight()) {
return
}
// NOTE: bottom is exclusive
top, bottom := buffer.getAreaScrollRange()
if uint(lines)+buffer.terminalState.scrollLinesFromBottom >= (uint(buffer.Height()) - uint(buffer.ViewHeight())) {
buffer.terminalState.scrollLinesFromBottom = uint(buffer.Height()) - uint(buffer.ViewHeight())
for i := bottom; i > top; {
i--
if i >= top+uint64(lines) {
buffer.lines[i] = buffer.lines[i-uint64(lines)]
} else {
buffer.terminalState.scrollLinesFromBottom += uint(lines)
buffer.lines[i] = newLine()
}
}
}
func (buffer *Buffer) ScrollPageDown() {
buffer.ScrollDown(buffer.terminalState.viewHeight)
}
func (buffer *Buffer) ScrollPageUp() {
buffer.ScrollUp(buffer.terminalState.viewHeight)
}
func (buffer *Buffer) ScrollToEnd() {
func (buffer *Buffer) AreaScrollUp(lines uint16) {
defer buffer.emitDisplayChange()
buffer.terminalState.scrollLinesFromBottom = 0
// NOTE: bottom is exclusive
top, bottom := buffer.getAreaScrollRange()
for i := top; i < bottom; i++ {
from := i + uint64(lines)
if from < bottom {
buffer.lines[i] = buffer.lines[from]
} else {
buffer.lines[i] = newLine()
}
}
}
func (buffer *Buffer) SaveCursor() {
@ -595,15 +593,7 @@ func (buffer *Buffer) Index() {
if uint(buffer.terminalState.cursorY) < buffer.terminalState.bottomMargin {
buffer.terminalState.cursorY++
} else {
topIndex := buffer.convertViewLineToRawLine(uint16(buffer.terminalState.topMargin))
bottomIndex := buffer.convertViewLineToRawLine(uint16(buffer.terminalState.bottomMargin))
for i := topIndex; i < bottomIndex; i++ {
buffer.lines[i] = buffer.lines[i+1]
}
buffer.lines[bottomIndex] = newLine()
buffer.AreaScrollUp(1)
}
return
@ -625,25 +615,9 @@ func (buffer *Buffer) ReverseIndex() {
defer buffer.emitDisplayChange()
if buffer.InScrollableRegion() {
if uint(buffer.terminalState.cursorY) > buffer.terminalState.topMargin {
buffer.terminalState.cursorY--
} else {
topIndex := buffer.convertViewLineToRawLine(uint16(buffer.terminalState.topMargin))
bottomIndex := buffer.convertViewLineToRawLine(uint16(buffer.terminalState.bottomMargin))
for i := bottomIndex; i > topIndex; i-- {
buffer.lines[i] = buffer.lines[i-1]
}
buffer.lines[topIndex] = newLine()
}
return
}
if buffer.terminalState.cursorY > 0 {
if uint(buffer.terminalState.cursorY) == buffer.terminalState.topMargin {
buffer.AreaScrollDown(1)
} else if buffer.terminalState.cursorY > 0 {
buffer.terminalState.cursorY--
}
}

View File

@ -110,3 +110,15 @@ func (terminalState *TerminalState) TabReset() {
i += TabStep
}
}
func (terminalState *TerminalState) ViewHeight() uint16 {
return terminalState.viewHeight
}
func (terminalState *TerminalState) GetScrollOffset() uint {
return terminalState.scrollLinesFromBottom
}
func (terminalState *TerminalState) SetScrollOffset(offset uint) {
terminalState.scrollLinesFromBottom = offset
}

View File

@ -13,9 +13,9 @@ import (
func (gui *GUI) glfwScrollCallback(w *glfw.Window, xoff float64, yoff float64) {
if yoff > 0 {
gui.terminal.ScrollUp(1)
gui.terminal.ScreenScrollUp(1)
} else {
gui.terminal.ScrollDown(1)
gui.terminal.ScreenScrollDown(1)
}
}

View File

@ -299,7 +299,7 @@ func csiScrollUpHandler(params []string, terminal *Terminal) error {
}
}
terminal.logger.Debugf("Scrolling up %d", distance)
terminal.ScrollUp(uint16(distance))
terminal.AreaScrollUp(uint16(distance))
return nil
}
@ -370,7 +370,7 @@ func csiScrollDownHandler(params []string, terminal *Terminal) error {
}
}
terminal.logger.Debugf("Scrolling down %d", distance)
terminal.ScrollDown(uint16(distance))
terminal.AreaScrollDown(uint16(distance))
return nil
}

View File

@ -9,7 +9,7 @@ func screenStateHandler(pty chan rune, terminal *Terminal) error {
// hide cursor?
buffer := terminal.ActiveBuffer()
terminal.ResetVerticalMargins()
buffer.ScrollToEnd()
terminal.ScrollToEnd()
// Fill the whole screen with E's
count := buffer.ViewHeight() * buffer.ViewWidth()

View File

@ -154,12 +154,22 @@ func (terminal *Terminal) UsingMainBuffer() bool {
}
func (terminal *Terminal) GetScrollOffset() uint {
return terminal.ActiveBuffer().GetScrollOffset()
return terminal.terminalState.GetScrollOffset()
}
func (terminal *Terminal) ScrollDown(lines uint16) {
terminal.ActiveBuffer().ScrollDown(lines)
func (terminal *Terminal) ScreenScrollDown(lines uint16) {
defer terminal.SetDirty()
buffer := terminal.ActiveBuffer()
if buffer.Height() < int(buffer.ViewHeight()) {
return
}
offset := terminal.terminalState.GetScrollOffset()
if uint(lines) > offset {
lines = uint16(offset)
}
terminal.terminalState.SetScrollOffset(offset - uint(lines))
}
func (terminal *Terminal) SetCharSize(w float32, h float32) {
@ -167,18 +177,41 @@ func (terminal *Terminal) SetCharSize(w float32, h float32) {
terminal.charHeight = h
}
func (terminal *Terminal) ScrollUp(lines uint16) {
terminal.ActiveBuffer().ScrollUp(lines)
func (terminal *Terminal) AreaScrollUp(lines uint16) {
terminal.ActiveBuffer().AreaScrollUp(lines)
}
func (terminal *Terminal) AreaScrollDown(lines uint16) {
terminal.ActiveBuffer().AreaScrollDown(lines)
}
func (terminal *Terminal) ScreenScrollUp(lines uint16) {
defer terminal.SetDirty()
buffer := terminal.ActiveBuffer()
if buffer.Height() < int(buffer.ViewHeight()) {
return
}
offset := terminal.terminalState.GetScrollOffset()
if uint(lines)+offset >= (uint(buffer.Height()) - uint(buffer.ViewHeight())) {
terminal.terminalState.SetScrollOffset(uint(buffer.Height()) - uint(buffer.ViewHeight()))
} else {
terminal.terminalState.SetScrollOffset(offset + uint(lines))
}
}
func (terminal *Terminal) ScrollPageDown() {
terminal.ActiveBuffer().ScrollPageDown()
terminal.ScreenScrollDown(terminal.terminalState.ViewHeight())
}
func (terminal *Terminal) ScrollPageUp() {
terminal.ActiveBuffer().ScrollPageUp()
terminal.ScreenScrollUp(terminal.terminalState.ViewHeight())
}
func (terminal *Terminal) ScrollToEnd() {
terminal.ActiveBuffer().ScrollToEnd()
defer terminal.SetDirty()
terminal.terminalState.SetScrollOffset(0)
}
func (terminal *Terminal) GetVisibleLines() []buffer.Line {