Skip to content

Commit 484f69c

Browse files
committed
Add keyboard cursor moving: left, right.
1 parent 9507a28 commit 484f69c

File tree

2 files changed

+65
-29
lines changed

2 files changed

+65
-29
lines changed

patterns/state/manipulator_state/states/selections/text/text_cursor.dart

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ class TextCursor {
77

88
double get xCoordinate => _xPosition;
99

10-
void changePosition(double x, double y) {
10+
void changePosition(double x) {
1111
x = x - _shape.x;
12-
y = y - _shape.y;
1312

14-
final pos = _shape.paragraph.getPositionForOffset(Offset(x, y));
13+
final pos = _shape.paragraph.getPositionForOffset(Offset(x, _shape.y));
1514
_charIndex = pos.offset;
1615

1716
final range = _shape.paragraph.getBoxesForRange(
@@ -26,41 +25,59 @@ class TextCursor {
2625
}
2726
}
2827

29-
String inputText(String char) {
30-
final start = _shape.text.substring(0, _charIndex);
31-
final end = _shape.text.substring(_charIndex);
32-
_shape.text = '$start$char$end';
33-
final range = _shape.paragraph.getBoxesForRange(_charIndex, ++_charIndex);
34-
_xPosition = _shape.x;
28+
void inputText(String char) {
29+
_changeText(char: char);
30+
moveRight();
31+
}
3532

36-
if (range.isNotEmpty) {
37-
_xPosition += range.first.right;
33+
void backspace() {
34+
if (_charIndex <= 0) {
35+
return;
3836
}
3937

40-
return '$start$char$end';
38+
_changeText(removeChars: -1);
39+
moveLeft();
4140
}
4241

43-
void backspace() {
42+
void moveLeft() {
43+
_charIndex--;
44+
_xPosition = _shape.x;
45+
4446
if (_charIndex <= 0) {
47+
_charIndex = 0;
4548
return;
4649
}
4750

48-
final start = _shape.text.substring(0, _charIndex - 1);
49-
final end = _shape.text.length > start.length
50-
? _shape.text.substring(_charIndex)
51-
: '';
51+
final range = _shape.paragraph.getBoxesForRange(_charIndex - 1, _charIndex);
52+
53+
if (range.isNotEmpty) {
54+
_xPosition += range.first.right;
55+
}
56+
}
5257

53-
_shape.text = '$start$end';
58+
void moveRight() {
59+
_charIndex++;
60+
_xPosition = _shape.x;
61+
62+
if (_charIndex >= _shape.text.length) {
63+
_charIndex = _shape.text.length;
64+
_xPosition += _shape.width;
65+
return;
66+
}
5467

5568
final range = _shape.paragraph.getBoxesForRange(_charIndex - 1, _charIndex);
56-
_xPosition = _shape.x;
5769

5870
if (range.isNotEmpty) {
59-
_xPosition += range.first.left;
60-
} else {
61-
_xPosition += _shape.width;
71+
_xPosition += range.first.right;
6272
}
63-
_charIndex--;
73+
}
74+
75+
void _changeText({String char = '', int removeChars = 0}) {
76+
final start = _shape.text.substring(0, _charIndex + removeChars);
77+
final end = _shape.text.length > start.length
78+
? _shape.text.substring(_charIndex)
79+
: '';
80+
_shape.text = '$start$char$end';
6481
}
6582

6683
final TextShape _shape;

patterns/state/manipulator_state/states/selections/text_change_state.dart

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:async';
2+
13
import 'package:flutter/material.dart';
24
import 'package:flutter/services.dart';
35

@@ -14,19 +16,27 @@ class TextChangeState extends SelectionState<TextShape> {
1416

1517
@override
1618
void init() {
17-
_textCursor.changePosition(_startPointer.dx, _startPointer.dy);
19+
_textCursor.changePosition(_startPointer.dx);
1820
context.cursor = SystemMouseCursors.text;
21+
22+
_cursorAnimateTimer = Timer.periodic(Duration(milliseconds: 500), (_) {
23+
_isShowCursor = !_isShowCursor;
24+
context.update();
25+
});
26+
1927
context.update();
2028
}
2129

2230
@override
2331
void mouseDown(double x, double y) {
2432
if (selectedShape.rect.contains(Offset(x, y))) {
25-
_textCursor.changePosition(x, y);
33+
_textCursor.changePosition(x);
34+
_isShowCursor = true;
2635
context.update();
2736
return;
2837
}
2938

39+
_cursorAnimateTimer.cancel();
3040
super.mouseDown(x, y);
3141
}
3242

@@ -35,19 +45,27 @@ class TextChangeState extends SelectionState<TextShape> {
3545
if (keyEvent is KeyDownEvent || keyEvent is KeyRepeatEvent) {
3646
if (keyEvent.physicalKey == PhysicalKeyboardKey.backspace) {
3747
_textCursor.backspace();
38-
context.update();
48+
} else if (keyEvent.physicalKey == PhysicalKeyboardKey.arrowLeft) {
49+
_textCursor.moveLeft();
50+
} else if (keyEvent.physicalKey == PhysicalKeyboardKey.arrowRight) {
51+
_textCursor.moveRight();
3952
} else if (keyEvent.character != null) {
4053
_textCursor.inputText(keyEvent.character!);
41-
context.update();
4254
}
55+
56+
_isShowCursor = true;
57+
context.update();
4358
}
4459
}
4560

4661
@override
4762
void paint(Canvas canvas) {
4863
context.paintStyle.paintSelectedText(selectedShape, canvas);
4964
super.paint(canvas);
50-
context.paintStyle.paintTextCursor(_textCursor, selectedShape, canvas);
65+
66+
if (_isShowCursor) {
67+
context.paintStyle.paintTextCursor(_textCursor, selectedShape, canvas);
68+
}
5169
}
5270

5371
@override
@@ -62,12 +80,13 @@ class TextChangeState extends SelectionState<TextShape> {
6280
context.cursor = SystemMouseCursors.basic;
6381
}
6482

65-
6683
@override
6784
String toString() {
6885
return '${super.toString()} + Text Change State';
6986
}
7087

7188
final Offset _startPointer;
7289
final TextCursor _textCursor;
90+
bool _isShowCursor = true;
91+
late Timer _cursorAnimateTimer;
7392
}

0 commit comments

Comments
 (0)