浏览代码

improves search result drawing (by not interfering with the normal terminal content)

It draws a dim layer on top of the complete terminal content and then paints the background and foreground of each search hit on top of it.
By returning early this doesn't have any impact on the painting when there is no search active
devmil 4 年之前
父节点
当前提交
8ed92ea69a
共有 2 个文件被更改,包括 85 次插入67 次删除
  1. 84 67
      lib/frontend/terminal_painters.dart
  2. 1 0
      lib/frontend/terminal_view.dart

+ 84 - 67
lib/frontend/terminal_painters.dart

@@ -1,3 +1,5 @@
+import 'dart:math';
+
 import 'package:flutter/material.dart';
 import 'package:flutter/widgets.dart';
 import 'package:xterm/buffer/cell_flags.dart';
@@ -28,13 +30,10 @@ class TerminalPainter extends CustomPainter {
   void paint(Canvas canvas, Size size) {
     _paintBackground(canvas);
 
-    // if (oscillator.value) {
-    // }
-
-    _paintUserSearchResult(canvas);
-
     _paintText(canvas);
 
+    _paintUserSearchResult(canvas, size);
+
     _paintSelection(canvas);
   }
 
@@ -44,7 +43,6 @@ class TerminalPainter extends CustomPainter {
     for (var row = 0; row < lines.length; row++) {
       final line = lines[row];
       final offsetY = row * charSize.cellHeight;
-      // final cellCount = math.min(terminal.viewWidth, line.length);
       final cellCount = terminal.terminalWidth;
 
       for (var col = 0; col < cellCount; col++) {
@@ -68,10 +66,6 @@ class TerminalPainter extends CustomPainter {
           continue;
         }
 
-        // final cellFlags = line.cellGetFlags(i);
-        // final cell = line.getCell(i);
-        // final attr = cell.attr;
-
         final offsetX = col * charSize.cellWidth;
         final effectWidth = charSize.cellWidth * cellWidth + 1;
         final effectHeight = charSize.cellHeight + 1;
@@ -89,9 +83,21 @@ class TerminalPainter extends CustomPainter {
     }
   }
 
-  void _paintUserSearchResult(Canvas canvas) {
+  void _paintUserSearchResult(Canvas canvas, Size size) {
     final searchResult = terminal.userSearchResult;
 
+    //when there is no ongoing user search then directly return
+    if (terminal.userSearchPattern == null) {
+      return;
+    }
+
+    //make everything dim so that the search result can be seen better
+    final dimPaint = Paint()
+      ..color = Color(terminal.theme.background).withAlpha(128)
+      ..style = PaintingStyle.fill;
+
+    canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), dimPaint);
+
     for (final hit in searchResult.allHits) {
       _paintSearchHit(canvas, hit);
     }
@@ -136,9 +142,10 @@ class TerminalPainter extends CustomPainter {
             (hit.startLineIndex + 1 - terminal.scrollOffsetFromTop) *
                 charSize.cellHeight;
         final startXMiddleRows = 0.toDouble();
-        final endYMiddleRows =
-            (hit.endLineIndex - terminal.scrollOffsetFromTop) *
-                charSize.cellHeight;
+        final endYMiddleRows = min(
+                hit.endLineIndex - terminal.scrollOffsetFromTop,
+                terminal.terminalHeight) *
+            charSize.cellHeight;
         final endXMiddleRows = terminal.terminalWidth * charSize.cellWidth;
         canvas.drawRect(
             Rect.fromLTRB(startXMiddleRows, startYMiddleRows, endXMiddleRows,
@@ -146,14 +153,51 @@ class TerminalPainter extends CustomPainter {
             paint);
       }
       //draw end row: line start - end
-      final startXEndRow = 0.toDouble();
-      final startYEndRow = (hit.endLineIndex - terminal.scrollOffsetFromTop) *
-          charSize.cellHeight;
-      final endXEndRow = hit.endIndex * charSize.cellWidth;
-      final endYEndRow = startYEndRow + charSize.cellHeight;
-      canvas.drawRect(
-          Rect.fromLTRB(startXEndRow, startYEndRow, endXEndRow, endYEndRow),
-          paint);
+      if (hit.endLineIndex - terminal.scrollOffsetFromTop <
+          terminal.terminalHeight) {
+        final startXEndRow = 0.toDouble();
+        final startYEndRow = (hit.endLineIndex - terminal.scrollOffsetFromTop) *
+            charSize.cellHeight;
+        final endXEndRow = hit.endIndex * charSize.cellWidth;
+        final endYEndRow = startYEndRow + charSize.cellHeight;
+        canvas.drawRect(
+            Rect.fromLTRB(startXEndRow, startYEndRow, endXEndRow, endYEndRow),
+            paint);
+      }
+    }
+
+    final visibleLines = terminal.getVisibleLines();
+
+    //paint text
+    for (var rawRow = hit.startLineIndex;
+        rawRow <= hit.endLineIndex;
+        rawRow++) {
+      final start = rawRow == hit.startLineIndex ? hit.startIndex : 0;
+      final end =
+          rawRow == hit.endLineIndex ? hit.endIndex : terminal.terminalWidth;
+
+      final row = rawRow - terminal.scrollOffsetFromTop;
+
+      final offsetY = row * charSize.cellHeight;
+
+      if (row >= visibleLines.length) {
+        continue;
+      }
+
+      final line = visibleLines[row];
+
+      for (var col = start; col < end; col++) {
+        final offsetX = col * charSize.cellWidth;
+        _paintCell(
+          canvas,
+          line,
+          col,
+          offsetX,
+          offsetY,
+          fgColorOverride: terminal.theme.searchHitForeground,
+          bgColorOverride: terminal.theme.searchHitForeground,
+        );
+      }
     }
   }
 
@@ -195,8 +239,6 @@ class TerminalPainter extends CustomPainter {
 
   void _paintText(Canvas canvas) {
     final lines = terminal.getVisibleLines();
-    final searchResult = terminal.userSearchResult;
-    final userSearchRunning = terminal.userSearchPattern != null;
 
     for (var row = 0; row < lines.length; row++) {
       final line = lines[row];
@@ -207,37 +249,17 @@ class TerminalPainter extends CustomPainter {
       for (var col = 0; col < cellCount; col++) {
         final width = line.cellGetWidth(col);
 
-        final absoluteY = terminal.convertViewLineToRawLine(row) -
-            terminal.scrollOffsetFromBottom;
-        final offsetX = col * charSize.cellWidth;
-        var isInSearchHit = false;
-        if (width != 0) {
-          if (userSearchRunning) {
-            isInSearchHit = searchResult.contains(absoluteY, col);
-          }
-          _paintCell(
-            canvas,
-            line,
-            col,
-            offsetX,
-            offsetY,
-            isInSearchHit,
-          );
+        if (width == 0) {
+          continue;
         }
-
-        // if (userSearchRunning && !isInSearchHit) {
-        //   // Fade out all cells that are not a search hit when a user search is ongoing
-        //   final effectWidth = cellCount * charSize.cellWidth;
-        //   final effectHeight = charSize.cellHeight;
-        //
-        //   final fadePaint = Paint()
-        //     ..color = Color(terminal.theme.background).withAlpha(80);
-        //
-        //   canvas.drawRect(
-        //     Rect.fromLTWH(offsetX, offsetY, effectWidth, effectHeight),
-        //     fadePaint,
-        //   );
-        // }
+        final offsetX = col * charSize.cellWidth;
+        _paintCell(
+          canvas,
+          line,
+          col,
+          offsetX,
+          offsetY,
+        );
       }
     }
   }
@@ -247,12 +269,13 @@ class TerminalPainter extends CustomPainter {
     BufferLine line,
     int cell,
     double offsetX,
-    double offsetY,
-    bool isInSearchResult,
-  ) {
+    double offsetY, {
+    int? fgColorOverride,
+    int? bgColorOverride,
+  }) {
     final codePoint = line.cellGetContent(cell);
-    var fgColor = line.cellGetFgColor(cell);
-    final bgColor = line.cellGetBgColor(cell);
+    final fgColor = fgColorOverride ?? line.cellGetFgColor(cell);
+    final bgColor = bgColorOverride ?? line.cellGetBgColor(cell);
     final flags = line.cellGetFlags(cell);
 
     if (codePoint == 0 || flags.hasFlag(CellFlags.invisible)) {
@@ -263,7 +286,7 @@ class TerminalPainter extends CustomPainter {
     final cellHash = hashValues(codePoint, fgColor, bgColor, flags);
 
     var character = textLayoutCache.getLayoutFromCache(cellHash);
-    if (!isInSearchResult && character != null) {
+    if (character != null) {
       canvas.drawParagraph(character, Offset(offsetX, offsetY));
       return;
     }
@@ -276,10 +299,6 @@ class TerminalPainter extends CustomPainter {
       color = color.withOpacity(0.5);
     }
 
-    if (isInSearchResult) {
-      color = Color(terminal.theme.searchHitForeground);
-    }
-
     final styleToUse = PaintHelper.getStyleToUse(
       style,
       color,
@@ -289,9 +308,7 @@ class TerminalPainter extends CustomPainter {
     );
 
     character = textLayoutCache.performAndCacheLayout(
-        String.fromCharCode(codePoint),
-        styleToUse,
-        isInSearchResult ? null : cellHash);
+        String.fromCharCode(codePoint), styleToUse, cellHash);
 
     canvas.drawParagraph(character, Offset(offsetX, offsetY));
   }

+ 1 - 0
lib/frontend/terminal_view.dart

@@ -306,6 +306,7 @@ class _TerminalViewState extends State<TerminalView> {
                   charSize: _cellSize,
                   textLayoutCache: textLayoutCache,
                 ),
+                child: Container(), //to get the size
               ),
               Positioned(
                 key: _keyCursor,