TerminalView: The last lines are now automatically relayouted when the width of the terminal changes.
[GB.FORM.TERMINAL] * NEW: TerminalView: The last lines are now automatically relayouted when the width of the terminal changes. * BUG: TerminalView: The padding is now correctly taking into account when computing the terminal character width.
This commit is contained in:
parent
e4da796e5b
commit
a8b9bf14b6
3 changed files with 212 additions and 8 deletions
|
@ -1,12 +1,14 @@
|
|||
' Gambas class file
|
||||
|
||||
Fast
|
||||
Fast Unsafe
|
||||
|
||||
Public Text As String
|
||||
Public Length As Integer
|
||||
|
||||
Private Attr As New Integer[]
|
||||
|
||||
Public NewLine As Boolean
|
||||
|
||||
Private $bCompressed As Boolean
|
||||
|
||||
Private Enum FLAG_BG, FLAG_FG, FLAG_BOLD, FLAG_DIM, FLAG_REV, FLAG_UND, FLAG_BLK
|
||||
|
@ -35,7 +37,7 @@ Private Sub Uncompress()
|
|||
|
||||
End
|
||||
|
||||
Private Sub Compress()
|
||||
Private Sub Compress(bFull As Boolean)
|
||||
|
||||
Dim I As Integer
|
||||
Dim iAttr As Integer
|
||||
|
@ -59,8 +61,13 @@ Private Sub Compress()
|
|||
|
||||
If iCount Then aAttr.Add(iOldAttr Or Lsl(iCount - 1, 8))
|
||||
|
||||
Attr = aAttr
|
||||
If bFull And If Attr.Count < Length Then
|
||||
iCount = Length - Attr.Count
|
||||
aAttr.Add(Lsl(iCount - 1, 8))
|
||||
Endif
|
||||
|
||||
$bCompressed = True
|
||||
Attr = aAttr
|
||||
|
||||
End
|
||||
|
||||
|
@ -128,16 +135,72 @@ End
|
|||
|
||||
Public Sub GetAttr() As Integer[]
|
||||
|
||||
If Not $bCompressed Then Compress()
|
||||
If Not $bCompressed Then Compress(False)
|
||||
Return Attr
|
||||
|
||||
End
|
||||
|
||||
Public Sub GetFullAttr() As Integer[]
|
||||
|
||||
If $bCompressed Then Uncompress()
|
||||
Compress(True)
|
||||
Return Attr
|
||||
|
||||
End
|
||||
|
||||
Public Sub InitAttr(aInit As Integer[])
|
||||
|
||||
Dim L As Integer
|
||||
Dim I As Integer
|
||||
Dim iAttr As Integer
|
||||
Dim iCount As Integer
|
||||
Dim C As Integer
|
||||
Dim aAttr As Integer[]
|
||||
Dim aTemp As Integer[]
|
||||
Dim N As Integer
|
||||
|
||||
L = Length
|
||||
aAttr = New Integer[]
|
||||
|
||||
For I = 0 To aInit.Max
|
||||
|
||||
If L = 0 Then Break
|
||||
|
||||
iAttr = aInit[0]
|
||||
iCount = (Lsr(iAttr, 8) And 255) + 1
|
||||
C = Min(L, iCount)
|
||||
iAttr = iAttr And &HFFFF00FF
|
||||
aTemp = New Integer[C]
|
||||
aTemp.Fill(iAttr)
|
||||
aAttr.Insert(aTemp)
|
||||
|
||||
L -= C
|
||||
If C = iCount Then
|
||||
aInit.Remove(0)
|
||||
Else
|
||||
iCount -= C
|
||||
aInit[0] = iAttr Or Lsl(iCount - 1, 8)
|
||||
Endif
|
||||
|
||||
Next
|
||||
|
||||
For I = aAttr.Max DownTo 0
|
||||
If aAttr[I] Then Break
|
||||
Next
|
||||
|
||||
If I < aAttr.Max Then aAttr.Remove(I + 1, -1)
|
||||
|
||||
Attr = aAttr
|
||||
$bCompressed = False
|
||||
|
||||
End
|
||||
|
||||
|
||||
Public Sub Clear()
|
||||
|
||||
Text = ""
|
||||
Length = 0
|
||||
NewLine = False
|
||||
Attr.Clear
|
||||
$bCompressed = False
|
||||
|
||||
|
|
|
@ -91,6 +91,9 @@ Public Lines As New CTerminalLine[]
|
|||
Private $W As Integer
|
||||
Private $H As Integer
|
||||
|
||||
' If a line had to be broken
|
||||
Private $bBrokenLine As Boolean
|
||||
|
||||
' Cursor position
|
||||
Private $X As Integer
|
||||
Private $Y As Integer
|
||||
|
@ -144,18 +147,127 @@ End
|
|||
Public Sub Clear()
|
||||
|
||||
Lines.Clear
|
||||
$bBrokenLine = False
|
||||
GetView()._UpdateSize
|
||||
Goto(0, 0)
|
||||
|
||||
End
|
||||
|
||||
Fast Private Sub Relayout(W As Integer)
|
||||
|
||||
Dim aAttr As Integer[]
|
||||
Dim aLines As String[]
|
||||
Dim I As Integer
|
||||
Dim hLine As CTerminalLine
|
||||
Dim sText As String
|
||||
Dim SY As Integer
|
||||
Dim L As Integer
|
||||
Dim sLine As String
|
||||
Dim hView As TerminalView
|
||||
Dim D As Integer
|
||||
|
||||
hView = GetView()
|
||||
|
||||
'fTimer = Timer
|
||||
aAttr = New Integer[]
|
||||
aLines = New String[]
|
||||
|
||||
D = Lines.Count - 10000
|
||||
If D < 0 Then D = 0
|
||||
|
||||
SY = -1
|
||||
|
||||
For I = D To Lines.Max
|
||||
If I = $Y Then SY = aLines.Count
|
||||
hLine = Lines[I]
|
||||
If hLine Then
|
||||
sText &= hLine.Text
|
||||
aAttr.Insert(hLine.GetFullAttr())
|
||||
If hLine.NewLine Then
|
||||
aLines.Add(sText)
|
||||
sText = ""
|
||||
'aAttr.Insert(&H00000100)
|
||||
Endif
|
||||
Endif
|
||||
Next
|
||||
|
||||
aLines.Add(sText)
|
||||
'Debug "#1 "; Timer - fTimer;; $X;; $Y
|
||||
|
||||
'fTimer = Timer
|
||||
|
||||
'SX = $X
|
||||
'SY = $Y
|
||||
|
||||
hView._DisableUpdateSize()
|
||||
|
||||
Lines.Remove(D, -1)
|
||||
If D = 0 Then $bBrokenLine = False
|
||||
'GetView()._UpdateSize
|
||||
'Goto(0, D)
|
||||
|
||||
L = D
|
||||
For I = 0 To aLines.Max
|
||||
|
||||
If I = SY Then $Y = L
|
||||
|
||||
sLine = aLines[I]
|
||||
While String.Len(sLine) > W
|
||||
With GetLine(L)
|
||||
.Text = String.Left(sLine, W)
|
||||
.Length = W
|
||||
End With
|
||||
sLine = String.Mid$(sLine, W + 1)
|
||||
Inc L
|
||||
$bBrokenLine = True
|
||||
|
||||
If I = SY Then
|
||||
If $X >= W Then
|
||||
$X -= W
|
||||
$Y = L
|
||||
Endif
|
||||
Endif
|
||||
|
||||
Wend
|
||||
|
||||
With GetLine(L)
|
||||
.Text = sLine
|
||||
.Length = String.Len(sLine)
|
||||
.NewLine = I < aLines.Max
|
||||
End With
|
||||
Inc L
|
||||
|
||||
Next
|
||||
|
||||
'Debug "#2 "; Timer - fTimer;; $X;; $Y
|
||||
|
||||
'fTimer = Timer
|
||||
|
||||
For I = D To Lines.Max
|
||||
Lines[I].InitAttr(aAttr)
|
||||
Next
|
||||
|
||||
'Debug "#3 "; Timer - fTimer
|
||||
|
||||
hView._EnableUpdateSize()
|
||||
hView._UpdateSize
|
||||
'hView.EnsureVisible()
|
||||
|
||||
End
|
||||
|
||||
Public Sub Resize(W As Integer, H As Integer) As Boolean
|
||||
|
||||
If W <> $W Or If H <> $H Then
|
||||
|
||||
If Not GetView().AlternateScreen And If Lines.Count < 100000 Then
|
||||
If $bBrokenLine Or If W < $W Then
|
||||
Relayout(W)
|
||||
Endif
|
||||
Endif
|
||||
|
||||
$W = W
|
||||
$H = H
|
||||
$X = Min($X, $W - 1)
|
||||
$Y = ScreenTop() + Max(0, Min($Y - ScreenTop(), $H - 1))
|
||||
|
||||
$X1 = 0
|
||||
$Y1 = 0
|
||||
$X2 = 0
|
||||
|
@ -163,6 +275,7 @@ Public Sub Resize(W As Integer, H As Integer) As Boolean
|
|||
'Debug "$Y = "; $Y
|
||||
$iScrollStart = -1
|
||||
$iScrollEnd = -1
|
||||
|
||||
If GetView().AlternateScreen Then
|
||||
If Lines.Count > $H Then
|
||||
Lines.Resize($H)
|
||||
|
@ -170,12 +283,17 @@ Public Sub Resize(W As Integer, H As Integer) As Boolean
|
|||
Endif
|
||||
Endif
|
||||
$hLineCache = Null
|
||||
|
||||
$X = Min($X, $W - 1)
|
||||
$Y = ScreenTop() + Max(0, Min($Y - ScreenTop(), $H - 1))
|
||||
|
||||
Return True
|
||||
|
||||
Endif
|
||||
|
||||
End
|
||||
|
||||
Public Sub GetLine(Y As Integer) As CTerminalLine
|
||||
Fast Public Sub GetLine(Y As Integer) As CTerminalLine
|
||||
|
||||
Dim hLine As CTerminalLine
|
||||
|
||||
|
@ -234,6 +352,7 @@ Private Sub Insert(sText As String, Optional X As Integer = $X)
|
|||
sText = String.Mid$(sText, iLen + 1)
|
||||
Endif
|
||||
If WrapMode Then
|
||||
$bBrokenLine = True
|
||||
Index()
|
||||
$X = 0
|
||||
Insert(sText)
|
||||
|
@ -323,6 +442,11 @@ Public Sub Print(sText As String)
|
|||
End
|
||||
|
||||
Private Sub NewLine()
|
||||
|
||||
Dim hLine As CTerminalLine
|
||||
|
||||
hLine = GetLine($Y)
|
||||
hLine.NewLine = True
|
||||
|
||||
If NewlineMode Then $X = 0
|
||||
Index()
|
||||
|
@ -854,6 +978,8 @@ Private Sub DrawLine(hView As TerminalView, L As Integer, X As Integer, Y As Int
|
|||
|
||||
If Paint.W > X Then Paint.FillRect(X, Y, Paint.W - X, LH, hView.Background)
|
||||
|
||||
'If hLine.NewLine Then Paint.FillRect(Paint.W - 1, Y, 1, 4, Color.Yellow)
|
||||
|
||||
Return
|
||||
|
||||
DRAW_TEXT:
|
||||
|
|
|
@ -135,6 +135,7 @@ Private $bIgnoreNextAnimation As Boolean
|
|||
Private $bReadOnly As Boolean
|
||||
|
||||
Private Const PADDING As Integer = 2
|
||||
Private $iDisableUpdateSize As Integer
|
||||
|
||||
'Private $bDoubleFont As Boolean = True
|
||||
|
||||
|
@ -254,7 +255,21 @@ Public Sub _RefreshLine(Y As Integer)
|
|||
|
||||
End
|
||||
|
||||
Public Sub _DisableUpdateSize()
|
||||
|
||||
Inc $iDisableUpdateSize
|
||||
|
||||
End
|
||||
|
||||
Public Sub _EnableUpdateSize()
|
||||
|
||||
Dec $iDisableUpdateSize
|
||||
|
||||
End
|
||||
|
||||
Public Sub _UpdateSize()
|
||||
|
||||
If $iDisableUpdateSize Then Return
|
||||
|
||||
$hScroll.MinValue = 0
|
||||
$hScroll.MaxValue = Max(0, $hScreen.Lines.Count - $H)
|
||||
|
@ -272,7 +287,7 @@ Private Sub UpdateScreen()
|
|||
|
||||
If $bAutoResize Then
|
||||
|
||||
W = Me.W
|
||||
W = Me.W - PADDING * 2
|
||||
If Me.Border Then W -= 2
|
||||
If $bShowScrollBar Then W -= $hScroll.W
|
||||
W = Max(2, W \ $CW)
|
||||
|
|
Loading…
Reference in a new issue