فهرست منبع

Search Hit style can now be configured via Theme

devmil 4 سال پیش
والد
کامیت
293556bc17

+ 43 - 9
lib/frontend/terminal_painters.dart

@@ -104,10 +104,10 @@ class TerminalPainter extends CustomPainter {
         hit.endLineIndex < terminal.scrollOffsetFromTop) {
       return;
     }
+
     final paint = Paint()
-      ..color = Colors.yellowAccent.withOpacity(0.8)
-      ..style = PaintingStyle.stroke
-      ..strokeWidth = 3;
+      ..color = Color(terminal.theme.searchHitBackground)
+      ..style = PaintingStyle.fill;
 
     if (hit.startLineIndex == hit.endLineIndex) {
       final double y =
@@ -195,6 +195,8 @@ 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];
@@ -205,12 +207,37 @@ class TerminalPainter extends CustomPainter {
       for (var col = 0; col < cellCount; col++) {
         final width = line.cellGetWidth(col);
 
-        if (width == 0) {
-          continue;
+        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,
+          );
         }
 
-        final offsetX = col * charSize.cellWidth;
-        _paintCell(canvas, line, col, offsetX, offsetY);
+        // 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,
+        //   );
+        // }
       }
     }
   }
@@ -221,6 +248,7 @@ class TerminalPainter extends CustomPainter {
     int cell,
     double offsetX,
     double offsetY,
+    bool isInSearchResult,
   ) {
     final codePoint = line.cellGetContent(cell);
     var fgColor = line.cellGetFgColor(cell);
@@ -235,7 +263,7 @@ class TerminalPainter extends CustomPainter {
     final cellHash = hashValues(codePoint, fgColor, bgColor, flags);
 
     var character = textLayoutCache.getLayoutFromCache(cellHash);
-    if (character != null) {
+    if (!isInSearchResult && character != null) {
       canvas.drawParagraph(character, Offset(offsetX, offsetY));
       return;
     }
@@ -248,6 +276,10 @@ class TerminalPainter extends CustomPainter {
       color = color.withOpacity(0.5);
     }
 
+    if (isInSearchResult) {
+      color = Color(terminal.theme.searchHitForeground);
+    }
+
     final styleToUse = PaintHelper.getStyleToUse(
       style,
       color,
@@ -257,7 +289,9 @@ class TerminalPainter extends CustomPainter {
     );
 
     character = textLayoutCache.performAndCacheLayout(
-        String.fromCharCode(codePoint), styleToUse, cellHash);
+        String.fromCharCode(codePoint),
+        styleToUse,
+        isInSearchResult ? null : cellHash);
 
     canvas.drawParagraph(character, Offset(offsetX, offsetY));
   }

+ 5 - 0
lib/terminal/terminal.dart

@@ -194,6 +194,7 @@ class Terminal with Observable implements TerminalUiInteraction {
   MouseMode _mouseMode = MouseMode.none;
   MouseMode get mouseMode => _mouseMode;
 
+  @override
   final TerminalTheme theme;
 
   // final cellAttr = CellAttrTemplate();
@@ -741,5 +742,9 @@ class Terminal with Observable implements TerminalUiInteraction {
     refresh();
   }
 
+  @override
   TerminalSearchResult get userSearchResult => _userSearchTask.searchResult;
+
+  @override
+  String? get userSearchPattern => _userSearchTask.pattern;
 }

+ 27 - 19
lib/terminal/terminal_isolate.dart

@@ -129,25 +129,27 @@ void terminalMain(SendPort port) async {
         }
         if (_terminal.dirty) {
           final newState = TerminalState(
-              _terminal.scrollOffsetFromBottom,
-              _terminal.scrollOffsetFromTop,
-              _terminal.buffer.height,
-              _terminal.invisibleHeight,
-              _terminal.viewHeight,
-              _terminal.viewWidth,
-              _terminal.selection!,
-              _terminal.getSelectedText(),
-              _terminal.theme.background,
-              _terminal.cursorX,
-              _terminal.cursorY,
-              _terminal.showCursor,
-              _terminal.theme.cursor,
-              _terminal
-                  .getVisibleLines()
-                  .map((bl) => BufferLine.withDataFrom(bl))
-                  .toList(growable: false),
-              _terminal.composingString,
-              _terminal.userSearchResult);
+            _terminal.scrollOffsetFromBottom,
+            _terminal.scrollOffsetFromTop,
+            _terminal.buffer.height,
+            _terminal.invisibleHeight,
+            _terminal.viewHeight,
+            _terminal.viewWidth,
+            _terminal.selection!,
+            _terminal.getSelectedText(),
+            _terminal.theme.background,
+            _terminal.cursorX,
+            _terminal.cursorY,
+            _terminal.showCursor,
+            _terminal.theme.cursor,
+            _terminal
+                .getVisibleLines()
+                .map((bl) => BufferLine.withDataFrom(bl))
+                .toList(growable: false),
+            _terminal.composingString,
+            _terminal.userSearchResult,
+            _terminal.userSearchPattern,
+          );
           port.send([_IsolateEvent.newState, newState]);
           _needNotify = true;
         }
@@ -207,6 +209,7 @@ class TerminalState {
   String composingString;
 
   TerminalSearchResult searchResult;
+  String? userSearchPattern;
 
   TerminalState(
     this.scrollOffsetFromBottom,
@@ -225,6 +228,7 @@ class TerminalState {
     this.visibleLines,
     this.composingString,
     this.searchResult,
+    this.userSearchPattern,
   );
 }
 
@@ -261,6 +265,7 @@ class TerminalIsolate with Observable implements TerminalUiInteraction {
   final IconChangeHandler onIconChange;
   final PlatformBehavior _platform;
 
+  @override
   final TerminalTheme theme;
   final int maxLines;
 
@@ -537,4 +542,7 @@ class TerminalIsolate with Observable implements TerminalUiInteraction {
   @override
   TerminalSearchResult get userSearchResult =>
       _lastState?.searchResult ?? TerminalSearchResult.empty();
+
+  @override
+  String? get userSearchPattern => _lastState?.userSearchPattern;
 }

+ 7 - 0
lib/terminal/terminal_ui_interaction.dart

@@ -4,10 +4,14 @@ import 'package:xterm/mouse/position.dart';
 import 'package:xterm/mouse/selection.dart';
 import 'package:xterm/terminal/platform.dart';
 import 'package:xterm/terminal/terminal_search.dart';
+import 'package:xterm/theme/terminal_theme.dart';
 import 'package:xterm/util/observable.dart';
 
 /// this interface describes what a Terminal UI needs from a Terminal
 abstract class TerminalUiInteraction with Observable {
+  /// The theme associated with this Terminal
+  TerminalTheme get theme;
+
   /// the ViewPort scroll offset from the bottom
   int get scrollOffsetFromBottom;
 
@@ -133,4 +137,7 @@ abstract class TerminalUiInteraction with Observable {
 
   /// returns the list of search hits
   TerminalSearchResult get userSearchResult;
+
+  /// the search pattern of a currently active search or [null]
+  String? get userSearchPattern;
 }

+ 26 - 22
lib/theme/terminal_theme.dart

@@ -1,26 +1,27 @@
 class TerminalTheme {
-  const TerminalTheme({
-    required this.cursor,
-    required this.selection,
-    required this.foreground,
-    required this.background,
-    required this.black,
-    required this.white,
-    required this.red,
-    required this.green,
-    required this.yellow,
-    required this.blue,
-    required this.magenta,
-    required this.cyan,
-    required this.brightBlack,
-    required this.brightRed,
-    required this.brightGreen,
-    required this.brightYellow,
-    required this.brightBlue,
-    required this.brightMagenta,
-    required this.brightCyan,
-    required this.brightWhite,
-  });
+  const TerminalTheme(
+      {required this.cursor,
+      required this.selection,
+      required this.foreground,
+      required this.background,
+      required this.black,
+      required this.white,
+      required this.red,
+      required this.green,
+      required this.yellow,
+      required this.blue,
+      required this.magenta,
+      required this.cyan,
+      required this.brightBlack,
+      required this.brightRed,
+      required this.brightGreen,
+      required this.brightYellow,
+      required this.brightBlue,
+      required this.brightMagenta,
+      required this.brightCyan,
+      required this.brightWhite,
+      required this.searchHitBackground,
+      required this.searchHitForeground});
 
   final int cursor;
   final int selection;
@@ -44,4 +45,7 @@ class TerminalTheme {
   final int brightMagenta;
   final int brightCyan;
   final int brightWhite;
+
+  final int searchHitBackground;
+  final int searchHitForeground;
 }

+ 4 - 0
lib/theme/terminal_themes.dart

@@ -22,6 +22,8 @@ class TerminalThemes {
     brightMagenta: 0XFFD670D6,
     brightCyan: 0XFF29B8DB,
     brightWhite: 0XFFFFFFFF,
+    searchHitBackground: 0XFFFFFF2B,
+    searchHitForeground: 0XFF000000,
   );
 
   static const whiteOnBlack = TerminalTheme(
@@ -45,5 +47,7 @@ class TerminalThemes {
     brightMagenta: 0XFFD670D6,
     brightCyan: 0XFF29B8DB,
     brightWhite: 0XFFFFFFFF,
+    searchHitBackground: 0XFFFFFF2B,
+    searchHitForeground: 0XFF000000,
   );
 }