Skip to content

Commit 385cf61

Browse files
committed
Add KeyboardActions & TextCursorAnimation.
1 parent 484f69c commit 385cf61

File tree

5 files changed

+102
-41
lines changed

5 files changed

+102
-41
lines changed

patterns/state/manipulator_state/states/_/paint_style.dart

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,18 @@ class PaintStyle {
7474
TextShape selectedShape,
7575
Canvas canvas,
7676
) {
77-
canvas.drawRect(
78-
Rect.fromLTWH(
79-
cursor.xCoordinate,
80-
selectedShape.y + (selectedShape.height - selectedShape.userHeight),
81-
1.5,
82-
selectedShape.userHeight),
83-
Paint()..color = Colors.white,
77+
canvas.drawLine(
78+
Offset(
79+
cursor.xCoordinate,
80+
selectedShape.y + (selectedShape.height - selectedShape.userHeight) + 2,
81+
),
82+
Offset(
83+
cursor.xCoordinate,
84+
selectedShape.y + (selectedShape.height) - 2,
85+
),
86+
Paint()
87+
..strokeWidth = 2.2
88+
..color = Colors.white,
8489
);
8590
}
8691

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import 'package:flutter/services.dart';
2+
3+
class KeyboardActions {
4+
final Map<PhysicalKeyboardKey, void Function()> actions;
5+
final void Function(String) inputCharAction;
6+
7+
KeyboardActions({
8+
required this.actions,
9+
required this.inputCharAction,
10+
});
11+
12+
void keyDown(KeyEvent keyEvent) {
13+
final isNotKeyDown =
14+
!(keyEvent is KeyDownEvent || keyEvent is KeyRepeatEvent);
15+
16+
if (isNotKeyDown) {
17+
return;
18+
}
19+
20+
final foundEvent = actions[keyEvent.physicalKey];
21+
22+
if (foundEvent != null) {
23+
foundEvent.call();
24+
return;
25+
}
26+
27+
if (keyEvent.character != null) {
28+
inputCharAction.call(keyEvent.character!);
29+
}
30+
}
31+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ class TextCursor {
1111
x = x - _shape.x;
1212

1313
final pos = _shape.paragraph.getPositionForOffset(Offset(x, _shape.y));
14+
1415
_charIndex = pos.offset;
16+
_xPosition = _shape.x;
1517

1618
final range = _shape.paragraph.getBoxesForRange(
1719
pos.offset - 1,
1820
pos.offset,
1921
);
2022

21-
_xPosition = _shape.x;
22-
2323
if (range.isNotEmpty) {
2424
_xPosition += range.first.right;
2525
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import 'dart:async';
2+
3+
class TextCursorAnimation {
4+
final Duration speed;
5+
final void Function() onBlink;
6+
7+
TextCursorAnimation({
8+
required this.speed,
9+
required this.onBlink,
10+
}) {
11+
_timer = Timer.periodic(speed, (_) {
12+
_isShowCursor = !_isShowCursor;
13+
onBlink.call();
14+
});
15+
}
16+
17+
bool get isVisible => _isShowCursor;
18+
19+
void touch() {
20+
_isShowCursor = true;
21+
onBlink.call();
22+
}
23+
24+
void dispose() {
25+
_timer.cancel();
26+
}
27+
28+
bool _isShowCursor = true;
29+
late Timer _timer;
30+
}
Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,64 @@
1-
import 'dart:async';
2-
31
import 'package:flutter/material.dart';
42
import 'package:flutter/services.dart';
53

64
import '../../shapes/text_shape.dart';
75
import 'selection_state.dart';
6+
import 'text/keyboard_actions.dart';
87
import 'text/text_cursor.dart';
8+
import 'text/text_cursor_animation.dart';
99

1010
class TextChangeState extends SelectionState<TextShape> {
1111
TextChangeState({
1212
required Offset startPointer,
1313
required super.selectedShape,
14-
}) : _startPointer = startPointer,
15-
_textCursor = TextCursor(selectedShape);
14+
}) : _startPointer = startPointer;
1615

1716
@override
1817
void init() {
19-
_textCursor.changePosition(_startPointer.dx);
20-
context.cursor = SystemMouseCursors.text;
21-
22-
_cursorAnimateTimer = Timer.periodic(Duration(milliseconds: 500), (_) {
23-
_isShowCursor = !_isShowCursor;
24-
context.update();
25-
});
18+
_textCursor = TextCursor(selectedShape)..changePosition(_startPointer.dx);
19+
20+
_keyboardActions = KeyboardActions(
21+
actions: {
22+
PhysicalKeyboardKey.backspace: _textCursor.backspace,
23+
PhysicalKeyboardKey.arrowLeft: _textCursor.moveLeft,
24+
PhysicalKeyboardKey.arrowRight: _textCursor.moveRight,
25+
},
26+
inputCharAction: _textCursor.inputText,
27+
);
28+
29+
_animationCursor = TextCursorAnimation(
30+
speed: Duration(milliseconds: 400),
31+
onBlink: context.update,
32+
);
2633

34+
context.cursor = SystemMouseCursors.text;
2735
context.update();
2836
}
2937

3038
@override
3139
void mouseDown(double x, double y) {
3240
if (selectedShape.rect.contains(Offset(x, y))) {
3341
_textCursor.changePosition(x);
34-
_isShowCursor = true;
35-
context.update();
42+
_animationCursor.touch();
3643
return;
3744
}
3845

39-
_cursorAnimateTimer.cancel();
46+
_animationCursor.dispose();
4047
super.mouseDown(x, y);
4148
}
4249

4350
@override
4451
void keyDown(KeyEvent keyEvent) {
45-
if (keyEvent is KeyDownEvent || keyEvent is KeyRepeatEvent) {
46-
if (keyEvent.physicalKey == PhysicalKeyboardKey.backspace) {
47-
_textCursor.backspace();
48-
} else if (keyEvent.physicalKey == PhysicalKeyboardKey.arrowLeft) {
49-
_textCursor.moveLeft();
50-
} else if (keyEvent.physicalKey == PhysicalKeyboardKey.arrowRight) {
51-
_textCursor.moveRight();
52-
} else if (keyEvent.character != null) {
53-
_textCursor.inputText(keyEvent.character!);
54-
}
55-
56-
_isShowCursor = true;
57-
context.update();
58-
}
52+
_keyboardActions.keyDown(keyEvent);
53+
_animationCursor.touch();
5954
}
6055

6156
@override
6257
void paint(Canvas canvas) {
6358
context.paintStyle.paintSelectedText(selectedShape, canvas);
6459
super.paint(canvas);
6560

66-
if (_isShowCursor) {
61+
if (_animationCursor.isVisible) {
6762
context.paintStyle.paintTextCursor(_textCursor, selectedShape, canvas);
6863
}
6964
}
@@ -86,7 +81,7 @@ class TextChangeState extends SelectionState<TextShape> {
8681
}
8782

8883
final Offset _startPointer;
89-
final TextCursor _textCursor;
90-
bool _isShowCursor = true;
91-
late Timer _cursorAnimateTimer;
84+
late final TextCursor _textCursor;
85+
late final KeyboardActions _keyboardActions;
86+
late final TextCursorAnimation _animationCursor;
9287
}

0 commit comments

Comments
 (0)