Skip to content

Commit

Permalink
Unfocused cursor hack
Browse files Browse the repository at this point in the history
  • Loading branch information
jpnurmi authored and CarlosNihelton committed Dec 27, 2024
1 parent 324d215 commit ff42190
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 20 deletions.
58 changes: 44 additions & 14 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class Home extends StatefulWidget {
}

class _HomeState extends State<Home> {
final focusNode = FocusNode();

final terminal = Terminal(
maxLines: 10000,
);
Expand Down Expand Up @@ -94,21 +96,49 @@ class _HomeState extends State<Home> {
child: TerminalView(
terminal,
controller: terminalController,
autofocus: true,
backgroundOpacity: 0.7,
//autofocus: true,
focusNode: focusNode,
theme: TerminalTheme(
//cursor: Color(0XAAAEAFAD),
//cursor: Colors.yellow,
//selection: Color(0XFFFFFF40),
//selection: Colors.red,
foreground: Color(0XFFCCCCCC),
background: Color(0XFF1E1E1E),
black: Colors.black,
red: Colors.red,
green: Colors.green,
yellow: Colors.yellow,
blue: Colors.blue,
magenta: Colors.purple,
cyan: Colors.cyan,
white: Colors.white,
brightBlack: Colors.black,
brightRed: Colors.red[300]!,
brightGreen: Colors.green[300]!,
brightYellow: Colors.yellow[300]!,
brightBlue: Colors.blue[300]!,
brightMagenta: Colors.purple[300]!,
brightCyan: Colors.cyan[300]!,
brightWhite: Colors.white,
searchHitBackground: Color(0XFFFFFF2B),
searchHitBackgroundCurrent: Color(0XFF31FF26),
searchHitForeground: Color(0XFF000000),
),
onSecondaryTapDown: (details, offset) async {
final selection = terminalController.selection;
if (selection != null) {
final text = terminal.buffer.getText(selection);
terminalController.clearSelection();
await Clipboard.setData(ClipboardData(text: text));
} else {
final data = await Clipboard.getData('text/plain');
final text = data?.text;
if (text != null) {
terminal.paste(text);
}
}
focusNode.unfocus();
// final selection = terminalController.selection;
// if (selection != null) {
// final text = terminal.buffer.getText(selection);
// terminalController.clearSelection();
// await Clipboard.setData(ClipboardData(text: text));
// } else {
// final data = await Clipboard.getData('text/plain');
// final text = data?.text;
// if (text != null) {
// terminal.paste(text);
// }
// }
},
),
),
Expand Down
96 changes: 90 additions & 6 deletions lib/src/ui/render.dart
Original file line number Diff line number Diff line change
Expand Up @@ -428,12 +428,7 @@ class RenderTerminal extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
}

if (_shouldShowCursor) {
_painter.paintCursor(
canvas,
offset + cursorOffset,
cursorType: _cursorType,
hasFocus: _focusNode.hasFocus,
);
_paintCursor(canvas, cursorOffset);
}
}

Expand All @@ -454,6 +449,51 @@ class RenderTerminal extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
}
}

/// Paints the cursor based on the current cursor type.
void _paintCursor(Canvas canvas, Offset offset) {
var color = _theme.cursor;
if (color == null) {
final x = _terminal.buffer.cursorX;
final y = _terminal.buffer.absoluteCursorY;
if (_controller.selection?.contains(CellOffset(x, y)) == true) {
color = _theme.background;
} else {
color = _theme.foreground;
}
}

final paint = Paint()
..color = color
..strokeWidth = 1;

if (!_focusNode.hasFocus) {
paint.style = PaintingStyle.stroke;
canvas.drawRect(offset & _charSize, paint);
return;
}

if (_theme.cursor != null) {
switch (_cursorType) {
case TerminalCursorType.block:
paint.style = PaintingStyle.fill;
canvas.drawRect(offset & _charSize, paint);
return;
case TerminalCursorType.underline:
return canvas.drawLine(
Offset(offset.dx, _charSize.height - 1),
Offset(offset.dx + _charSize.width, _charSize.height - 1),
paint,
);
case TerminalCursorType.verticalBar:
return canvas.drawLine(
Offset(offset.dx, 0),
Offset(offset.dx, _charSize.height),
paint,
);
}
}
}

/// Paints the text that is currently being composed in IME to [canvas] at
/// [offset]. [offset] is usually the cursor position.
void _paintComposingText(Canvas canvas, Offset offset) {
Expand Down Expand Up @@ -485,6 +525,50 @@ class RenderTerminal extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
canvas.drawParagraph(paragraph, Offset(0, offset.dy));
}

void _toggleInverse(CellData cellData) {
if (cellData.flags & CellFlags.inverse == 0) {
cellData.flags |= CellFlags.inverse;
} else {
cellData.flags &= ~CellFlags.inverse;
}
}

/// Paints [line] to [canvas] at [offset]. The x offset of [offset] is usually
/// 0, and the y offset is the top of the line.
void _paintLine(Canvas canvas, int y, Offset offset) {
final line = _terminal.buffer.lines[y];
final cellData = CellData.empty();
final cellWidth = _charSize.width;

final visibleCells = size.width ~/ cellWidth + 1;
final effectCells = min(visibleCells, line.length);

for (var x = 0; x < effectCells; x++) {
line.getCellData(x, cellData);

if (_theme.selection == null &&
_controller.selection?.contains(CellOffset(x, y)) == true) {
_toggleInverse(cellData);
}
if (_theme.cursor == null &&
_focusNode.hasFocus &&
_terminal.buffer.absoluteCursorY == y &&
_terminal.buffer.cursorX == x) {
_toggleInverse(cellData);
}

final charWidth = cellData.content >> CellContent.widthShift;
final cellOffset = offset.translate(x * cellWidth, 0);

_paintCellBackground(canvas, cellOffset, cellData);
_paintCellForeground(canvas, cellOffset, cellData);

if (charWidth == 2) {
x++;
}
}
}

void _paintSelection(
Canvas canvas,
BufferRange selection,
Expand Down

0 comments on commit ff42190

Please sign in to comment.