@@ -26,16 +26,16 @@ private void TerminalChanged()
26
26
}
27
27
28
28
//用于存放终端数据的缓存
29
- private readonly List < List < TerminalBlock > > _cacheLines = [ ] ;
29
+ private List < List < TerminalBlock > > CacheLines { get ; } = [ ] ;
30
30
31
31
//当前光标位置
32
32
//X从0开始,最大可到达窗口宽度(再增加就需要换行了)
33
33
//Y从0开始,最大可到达窗口高度-1
34
- private int _positionX = 0 ;
35
- private int _positionY = 0 ;
34
+ private int PositionX { get ; set ; } = 0 ;
35
+ private int PositionY { get ; set ; } = 0 ;
36
36
37
37
//当前的颜色、字体等信息,存到TerminalBlock中
38
- private TerminalBlock _currentState = new ( String . Empty ) ;
38
+ private TerminalBlock CurrentState { get ; set ; } = new ( String . Empty ) ;
39
39
40
40
//MaxCacheLines表示终端缓存的行数,超过这个行数后会删除最上面的行
41
41
private readonly int _maxCacheLines = Utils . Setting . TerminalBufferLines ;
@@ -48,25 +48,25 @@ private void TerminalChanged()
48
48
private void AddLine ( )
49
49
{
50
50
//添加行
51
- _cacheLines . Add ( [ ] ) ;
51
+ CacheLines . Add ( [ ] ) ;
52
52
//如果超过了最大行数,删除最上面的行
53
- if ( _cacheLines . Count > _maxCacheLines )
54
- _cacheLines . RemoveAt ( 0 ) ;
55
- if ( _currentLine != 0 )
53
+ if ( CacheLines . Count > _maxCacheLines )
54
+ CacheLines . RemoveAt ( 0 ) ;
55
+ if ( CurrentLine != 0 )
56
56
{
57
- _currentLine -- ;
57
+ CurrentLine -- ;
58
58
//如果当前行数超过了最大行数,设置为最大行数
59
- if ( _currentLine > _cacheLines . Count - _windowHeight )
60
- _currentLine = _cacheLines . Count - _windowHeight ;
61
- if ( _currentLine < 0 ) _currentLine = 0 ;
59
+ if ( CurrentLine > CacheLines . Count - _windowHeight )
60
+ CurrentLine = CacheLines . Count - _windowHeight ;
61
+ if ( CurrentLine < 0 ) CurrentLine = 0 ;
62
62
}
63
63
}
64
64
65
65
/// <summary>
66
66
/// 基于当前光标,往后追加文本
67
67
/// 文本不得包含不可见字符
68
68
/// </summary>
69
- /// <param name="text ">待添加的文本</param>
69
+ /// <param name="texts ">待添加的文本</param>
70
70
public void AddText ( char [ ] texts ) //TODO)) 保持private
71
71
{
72
72
//防止没有设置窗口大小的时候就添加数据
@@ -77,16 +77,16 @@ public void AddText(char[] texts)//TODO)) 保持private
77
77
while ( chars . Length > 0 )
78
78
{
79
79
//当前光标位置后还有多少个字符的空间
80
- var space = _windowWidth - _positionX ;
80
+ var space = _windowWidth - PositionX ;
81
81
//剩余空间不足,添加新行
82
82
if ( space <= 0 )
83
83
{
84
- _positionX = 0 ;
85
- _positionY ++ ; //超过高度后面再管
84
+ PositionX = 0 ;
85
+ PositionY ++ ; //超过高度后面再管
86
86
space = _windowWidth ;
87
87
}
88
88
//记录一下修改前的X光标位置
89
- var oldX = _positionX ;
89
+ var oldX = PositionX ;
90
90
91
91
//放置文本
92
92
var sb = new StringBuilder ( ) ;
@@ -103,45 +103,45 @@ public void AddText(char[] texts)//TODO)) 保持private
103
103
//去除掉已经添加的字符
104
104
chars = chars [ 1 ..] ;
105
105
//光标位置往后挪动
106
- _positionX += length ;
106
+ PositionX += length ;
107
107
}
108
108
if ( space < 0 )
109
109
{
110
110
//如果剩余空间不足,说明最后一格放不下这个宽字符
111
111
//直接把X位置打到头,交够下一轮来处理
112
- _positionX = _windowWidth ;
112
+ PositionX = _windowWidth ;
113
113
}
114
114
//添加文本
115
115
var text = sb . ToString ( ) ;
116
- var line = _currentState . MakeNew ( text ) ;
116
+ var line = CurrentState . MakeNew ( text ) ;
117
117
118
118
//这一行数据要修改
119
119
List < TerminalBlock > needChangeLine ;
120
120
121
121
//超过了最大高度,说明要新开一行
122
- if ( _positionY >= _windowHeight )
122
+ if ( PositionY >= _windowHeight )
123
123
{
124
- _positionY = _windowHeight - 1 ;
124
+ PositionY = _windowHeight - 1 ;
125
125
AddLine ( ) ;
126
- needChangeLine = _cacheLines [ ^ 1 ] ;
126
+ needChangeLine = CacheLines [ ^ 1 ] ;
127
127
}
128
128
//当前缓存的行数还没有达到显示行高,也开新行
129
- else if ( _cacheLines . Count - 1 < _positionY )
129
+ else if ( CacheLines . Count - 1 < PositionY )
130
130
{
131
- var needLineCount = _positionY - _cacheLines . Count + 1 ;
131
+ var needLineCount = PositionY - CacheLines . Count + 1 ;
132
132
for ( int i = 0 ; i < needLineCount ; i ++ )
133
133
AddLine ( ) ;
134
- needChangeLine = _cacheLines [ ^ 1 ] ;
134
+ needChangeLine = CacheLines [ ^ 1 ] ;
135
135
}
136
136
//不是新行,需要更改当前行的数据
137
137
else
138
138
{
139
139
//计算开始行下标的偏移量
140
- var lineStartOffset = _cacheLines . Count - _windowHeight ;
140
+ var lineStartOffset = CacheLines . Count - _windowHeight ;
141
141
if ( lineStartOffset < 0 )
142
142
lineStartOffset = 0 ;
143
143
//使用当前行
144
- needChangeLine = _cacheLines [ _positionY + lineStartOffset ] ;
144
+ needChangeLine = CacheLines [ PositionY + lineStartOffset ] ;
145
145
}
146
146
147
147
var allLength = needChangeLine . Sum ( l => l . Length ) ;
@@ -259,8 +259,8 @@ public void AddText(char[] texts)//TODO)) 保持private
259
259
//TODO)) 仅用于测试
260
260
public void ChangePosition ( int x , int y )
261
261
{
262
- _positionX = x ;
263
- _positionY = y ;
262
+ PositionX = x ;
263
+ PositionY = y ;
264
264
}
265
265
266
266
/// <summary>
@@ -272,9 +272,9 @@ public List<List<TerminalBlock>> GetShowLines()
272
272
List < List < TerminalBlock > > cacheLines = new ( ) ;
273
273
274
274
//计算出要显示的行数范围
275
- int allLines = _cacheLines . Count ;
275
+ int allLines = CacheLines . Count ;
276
276
//起始行和结束行,闭区间,从0开始,代表CacheLines的项目下标
277
- int startLine = allLines - _windowHeight - _currentLine ;
277
+ int startLine = allLines - _windowHeight - CurrentLine ;
278
278
if ( startLine < 0 )
279
279
startLine = 0 ;
280
280
int endLine = startLine + _windowHeight - 1 ;
@@ -285,7 +285,7 @@ public List<List<TerminalBlock>> GetShowLines()
285
285
for ( int i = startLine ; i <= endLine ; i ++ )
286
286
{
287
287
//添加行
288
- var line = _cacheLines [ i ] ;
288
+ var line = CacheLines [ i ] ;
289
289
cacheLines . Add ( line ) ;
290
290
}
291
291
@@ -296,10 +296,60 @@ public List<List<TerminalBlock>> GetShowLines()
296
296
cacheLines . Add ( [ ] ) ;
297
297
}
298
298
//把当前光标位置背景和前景色反色处理
299
- var posY = _positionY ;
300
- if ( posY < _cacheLines . Count )
299
+ if ( PositionY < cacheLines . Count )
301
300
{
302
- //TODO)) 这里需要处理光标位置
301
+ //这里需要处理光标位置
302
+ //复制一个新的行来替换掉现有的行用来展示
303
+ var tempLine = new List < TerminalBlock > ( ) ;
304
+ foreach ( var block in cacheLines [ PositionY ] )
305
+ {
306
+ tempLine . Add ( ( TerminalBlock ) block . Clone ( ) ) ;
307
+ }
308
+
309
+ var allLength = tempLine . Sum ( l => l . Length ) ;
310
+ //光标没有重叠,说明光标位置在当前行的后面
311
+ if ( allLength <= PositionX )
312
+ {
313
+ //加几个空格,直到光标位置
314
+ if ( allLength < PositionX )
315
+ tempLine . Add ( new TerminalBlock ( new string ( ' ' , allLength - PositionX ) ) ) ;
316
+ tempLine . Add ( new TerminalBlock ( new string ( ' ' , 1 ) , - 1 , - 1 ) ) ;
317
+ }
318
+ else
319
+ {
320
+ var charLine = new List < TerminalBlock > ( ) ;
321
+ var count = 0 ;
322
+ //把这一行按字符拆碎
323
+ foreach ( var block in tempLine )
324
+ {
325
+ //拆碎
326
+ var tempChars = block . Text . ToCharArray ( ) ;
327
+ foreach ( var c in tempChars )
328
+ {
329
+ var start = count ;
330
+ var length = UnicodeCalculator . GetWidth ( c ) ;
331
+ var end = start + length - 1 ;
332
+ //如果posx在当前字符范围内,说明光标在这个字符上
333
+ if ( PositionX >= start && PositionX <= end )
334
+ charLine . Add ( new TerminalBlock ( c . ToString ( ) , - 1 , - 1 ) ) ;
335
+ else
336
+ charLine . Add ( block . MakeNew ( c . ToString ( ) ) ) ;
337
+ count += length ;
338
+ //如果字符宽度超过1,加入空白填位
339
+ length -- ;
340
+ while ( length > 0 )
341
+ {
342
+ charLine . Add ( block . MakeNew ( string . Empty ) ) ;
343
+ length -- ;
344
+ }
345
+ }
346
+ }
347
+ tempLine = charLine ; //替换掉当前行为拆字后的行
348
+ }
349
+ //优化当前这一行数据块
350
+ TerminalBlock . OptimizeBlocks ( tempLine ) ;
351
+ //替换掉当前行
352
+ cacheLines [ PositionY ] = tempLine ;
303
353
}
304
354
305
355
return cacheLines ;
@@ -314,37 +364,37 @@ public void ChangeWindowSize(int width, int height)
314
364
}
315
365
316
366
//当前所在的行数相比较于终端最底部的行数,0表示在最底部,其余数字表示向上挪动的行数
317
- private int _currentLine = 0 ;
367
+ private int CurrentLine { get ; set ; } = 0 ;
318
368
319
369
private double CurrentLine2ScrollValue =>
320
- ( _currentLine == 0 || _cacheLines . Count < _windowHeight )
370
+ ( CurrentLine == 0 || CacheLines . Count < _windowHeight )
321
371
? 100
322
- : 100.0 - ( double ) _currentLine / ( _cacheLines . Count - _windowHeight ) * 100.0 ;
372
+ : 100.0 - ( double ) CurrentLine / ( CacheLines . Count - _windowHeight ) * 100.0 ;
323
373
//向上移动的行数
324
374
public double CurrentLineMoveUp ( int delta )
325
375
{
326
- var lastCurrentLine = _currentLine ;
327
- _currentLine += delta ;
328
- if ( _currentLine > _cacheLines . Count - _windowHeight )
329
- _currentLine = _cacheLines . Count - _windowHeight ;
330
- if ( _currentLine < 0 )
331
- _currentLine = 0 ;
376
+ var lastCurrentLine = CurrentLine ;
377
+ CurrentLine += delta ;
378
+ if ( CurrentLine > CacheLines . Count - _windowHeight )
379
+ CurrentLine = CacheLines . Count - _windowHeight ;
380
+ if ( CurrentLine < 0 )
381
+ CurrentLine = 0 ;
332
382
333
- if ( lastCurrentLine != _currentLine )
383
+ if ( lastCurrentLine != CurrentLine )
334
384
TerminalChanged ( ) ;
335
385
336
386
return CurrentLine2ScrollValue ;
337
387
}
338
388
//滚轮事件
339
389
public void ScrollBarChanged ( double value )
340
390
{
341
- var lastCurrentLine = _currentLine ;
342
- if ( Math . Abs ( value - 100.0 ) < 0.001 || _cacheLines . Count < _windowHeight )
343
- _currentLine = 0 ;
391
+ var lastCurrentLine = CurrentLine ;
392
+ if ( Math . Abs ( value - 100.0 ) < 0.001 || CacheLines . Count < _windowHeight )
393
+ CurrentLine = 0 ;
344
394
else
345
- _currentLine = ( int ) ( _cacheLines . Count - _windowHeight - value * ( _cacheLines . Count - _windowHeight ) / 100.0 ) ;
395
+ CurrentLine = ( int ) ( CacheLines . Count - _windowHeight - value * ( CacheLines . Count - _windowHeight ) / 100.0 ) ;
346
396
347
- if ( lastCurrentLine != _currentLine )
397
+ if ( lastCurrentLine != CurrentLine )
348
398
TerminalChanged ( ) ;
349
399
}
350
400
}
0 commit comments