mirror of https://github.com/liamg/aminal.git
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:
parent
bc1b3f0dfd
commit
77348c2188
|
@ -326,10 +326,6 @@ func (buffer *Buffer) IsDirty() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (buffer *Buffer) GetScrollOffset() uint {
|
|
||||||
return buffer.terminalState.scrollLinesFromBottom
|
|
||||||
}
|
|
||||||
|
|
||||||
func (buffer *Buffer) HasScrollableRegion() bool {
|
func (buffer *Buffer) HasScrollableRegion() bool {
|
||||||
return buffer.terminalState.topMargin > 0 || buffer.terminalState.bottomMargin < uint(buffer.ViewHeight())-1
|
return buffer.terminalState.topMargin > 0 || buffer.terminalState.bottomMargin < uint(buffer.ViewHeight())-1
|
||||||
}
|
}
|
||||||
|
@ -338,46 +334,48 @@ func (buffer *Buffer) InScrollableRegion() bool {
|
||||||
return buffer.HasScrollableRegion() && uint(buffer.terminalState.cursorY) >= buffer.terminalState.topMargin && uint(buffer.terminalState.cursorY) <= buffer.terminalState.bottomMargin
|
return buffer.HasScrollableRegion() && uint(buffer.terminalState.cursorY) >= buffer.terminalState.topMargin && uint(buffer.terminalState.cursorY) <= buffer.terminalState.bottomMargin
|
||||||
}
|
}
|
||||||
|
|
||||||
func (buffer *Buffer) ScrollDown(lines uint16) {
|
// 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))
|
||||||
|
}
|
||||||
|
return top, bottom
|
||||||
|
}
|
||||||
|
|
||||||
|
func (buffer *Buffer) AreaScrollDown(lines uint16) {
|
||||||
defer buffer.emitDisplayChange()
|
defer buffer.emitDisplayChange()
|
||||||
|
|
||||||
if buffer.Height() < int(buffer.ViewHeight()) {
|
// NOTE: bottom is exclusive
|
||||||
return
|
top, bottom := buffer.getAreaScrollRange()
|
||||||
}
|
|
||||||
|
|
||||||
if uint(lines) > buffer.terminalState.scrollLinesFromBottom {
|
for i := bottom; i > top; {
|
||||||
lines = uint16(buffer.terminalState.scrollLinesFromBottom)
|
i--
|
||||||
|
if i >= top+uint64(lines) {
|
||||||
|
buffer.lines[i] = buffer.lines[i-uint64(lines)]
|
||||||
|
} else {
|
||||||
|
buffer.lines[i] = newLine()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buffer.terminalState.scrollLinesFromBottom -= uint(lines)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (buffer *Buffer) ScrollUp(lines uint16) {
|
func (buffer *Buffer) AreaScrollUp(lines uint16) {
|
||||||
|
|
||||||
defer buffer.emitDisplayChange()
|
defer buffer.emitDisplayChange()
|
||||||
|
|
||||||
if buffer.Height() < int(buffer.ViewHeight()) {
|
// NOTE: bottom is exclusive
|
||||||
return
|
top, bottom := buffer.getAreaScrollRange()
|
||||||
}
|
|
||||||
|
|
||||||
if uint(lines)+buffer.terminalState.scrollLinesFromBottom >= (uint(buffer.Height()) - uint(buffer.ViewHeight())) {
|
for i := top; i < bottom; i++ {
|
||||||
buffer.terminalState.scrollLinesFromBottom = uint(buffer.Height()) - uint(buffer.ViewHeight())
|
from := i + uint64(lines)
|
||||||
} else {
|
if from < bottom {
|
||||||
buffer.terminalState.scrollLinesFromBottom += uint(lines)
|
buffer.lines[i] = buffer.lines[from]
|
||||||
|
} else {
|
||||||
|
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() {
|
|
||||||
defer buffer.emitDisplayChange()
|
|
||||||
buffer.terminalState.scrollLinesFromBottom = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (buffer *Buffer) SaveCursor() {
|
func (buffer *Buffer) SaveCursor() {
|
||||||
copiedAttr := buffer.terminalState.CursorAttr
|
copiedAttr := buffer.terminalState.CursorAttr
|
||||||
buffer.savedCursorAttr = &copiedAttr
|
buffer.savedCursorAttr = &copiedAttr
|
||||||
|
@ -595,15 +593,7 @@ func (buffer *Buffer) Index() {
|
||||||
if uint(buffer.terminalState.cursorY) < buffer.terminalState.bottomMargin {
|
if uint(buffer.terminalState.cursorY) < buffer.terminalState.bottomMargin {
|
||||||
buffer.terminalState.cursorY++
|
buffer.terminalState.cursorY++
|
||||||
} else {
|
} else {
|
||||||
|
buffer.AreaScrollUp(1)
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -625,25 +615,9 @@ func (buffer *Buffer) ReverseIndex() {
|
||||||
|
|
||||||
defer buffer.emitDisplayChange()
|
defer buffer.emitDisplayChange()
|
||||||
|
|
||||||
if buffer.InScrollableRegion() {
|
if uint(buffer.terminalState.cursorY) == buffer.terminalState.topMargin {
|
||||||
|
buffer.AreaScrollDown(1)
|
||||||
if uint(buffer.terminalState.cursorY) > buffer.terminalState.topMargin {
|
} else if buffer.terminalState.cursorY > 0 {
|
||||||
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 {
|
|
||||||
buffer.terminalState.cursorY--
|
buffer.terminalState.cursorY--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,3 +110,15 @@ func (terminalState *TerminalState) TabReset() {
|
||||||
i += TabStep
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -13,9 +13,9 @@ import (
|
||||||
func (gui *GUI) glfwScrollCallback(w *glfw.Window, xoff float64, yoff float64) {
|
func (gui *GUI) glfwScrollCallback(w *glfw.Window, xoff float64, yoff float64) {
|
||||||
|
|
||||||
if yoff > 0 {
|
if yoff > 0 {
|
||||||
gui.terminal.ScrollUp(1)
|
gui.terminal.ScreenScrollUp(1)
|
||||||
} else {
|
} else {
|
||||||
gui.terminal.ScrollDown(1)
|
gui.terminal.ScreenScrollDown(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -299,7 +299,7 @@ func csiScrollUpHandler(params []string, terminal *Terminal) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
terminal.logger.Debugf("Scrolling up %d", distance)
|
terminal.logger.Debugf("Scrolling up %d", distance)
|
||||||
terminal.ScrollUp(uint16(distance))
|
terminal.AreaScrollUp(uint16(distance))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,7 +370,7 @@ func csiScrollDownHandler(params []string, terminal *Terminal) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
terminal.logger.Debugf("Scrolling down %d", distance)
|
terminal.logger.Debugf("Scrolling down %d", distance)
|
||||||
terminal.ScrollDown(uint16(distance))
|
terminal.AreaScrollDown(uint16(distance))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ func screenStateHandler(pty chan rune, terminal *Terminal) error {
|
||||||
// hide cursor?
|
// hide cursor?
|
||||||
buffer := terminal.ActiveBuffer()
|
buffer := terminal.ActiveBuffer()
|
||||||
terminal.ResetVerticalMargins()
|
terminal.ResetVerticalMargins()
|
||||||
buffer.ScrollToEnd()
|
terminal.ScrollToEnd()
|
||||||
|
|
||||||
// Fill the whole screen with E's
|
// Fill the whole screen with E's
|
||||||
count := buffer.ViewHeight() * buffer.ViewWidth()
|
count := buffer.ViewHeight() * buffer.ViewWidth()
|
||||||
|
|
|
@ -154,12 +154,22 @@ func (terminal *Terminal) UsingMainBuffer() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (terminal *Terminal) GetScrollOffset() uint {
|
func (terminal *Terminal) GetScrollOffset() uint {
|
||||||
return terminal.ActiveBuffer().GetScrollOffset()
|
return terminal.terminalState.GetScrollOffset()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (terminal *Terminal) ScrollDown(lines uint16) {
|
func (terminal *Terminal) ScreenScrollDown(lines uint16) {
|
||||||
terminal.ActiveBuffer().ScrollDown(lines)
|
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) {
|
func (terminal *Terminal) SetCharSize(w float32, h float32) {
|
||||||
|
@ -167,18 +177,41 @@ func (terminal *Terminal) SetCharSize(w float32, h float32) {
|
||||||
terminal.charHeight = h
|
terminal.charHeight = h
|
||||||
}
|
}
|
||||||
|
|
||||||
func (terminal *Terminal) ScrollUp(lines uint16) {
|
func (terminal *Terminal) AreaScrollUp(lines uint16) {
|
||||||
terminal.ActiveBuffer().ScrollUp(lines)
|
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() {
|
func (terminal *Terminal) ScrollPageDown() {
|
||||||
terminal.ActiveBuffer().ScrollPageDown()
|
terminal.ScreenScrollDown(terminal.terminalState.ViewHeight())
|
||||||
}
|
}
|
||||||
func (terminal *Terminal) ScrollPageUp() {
|
func (terminal *Terminal) ScrollPageUp() {
|
||||||
terminal.ActiveBuffer().ScrollPageUp()
|
terminal.ScreenScrollUp(terminal.terminalState.ViewHeight())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (terminal *Terminal) ScrollToEnd() {
|
func (terminal *Terminal) ScrollToEnd() {
|
||||||
terminal.ActiveBuffer().ScrollToEnd()
|
defer terminal.SetDirty()
|
||||||
|
terminal.terminalState.SetScrollOffset(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (terminal *Terminal) GetVisibleLines() []buffer.Line {
|
func (terminal *Terminal) GetVisibleLines() []buffer.Line {
|
||||||
|
|
Loading…
Reference in New Issue