subwrite/lib/cursor_provider.dart

123 lines
3.3 KiB
Dart

import 'package:flutter/material.dart';
import 'cursor.dart';
import 'line_info.dart';
class CursorProvider extends ChangeNotifier {
Cursor cursor = Cursor(line: 1, column: 0);
bool inMouseSelection = false;
int get line => cursor.line;
int get column => cursor.column;
void publishCursor(List<LineInfo> elements) {
var ncursor = cursor.normalized();
elements.forEach((element) {
element.setCursor(ncursor);
});
}
void moveCursorToDocStart() {
clearSelection();
cursor.line = 0;
cursor.column = 0;
cursor = cursor.normalized();
notifyListeners();
}
void moveCursorToLineStart() {
cursor.column = 0;
notifyListeners();
}
void clearSelection() {
inMouseSelection = false;
cursor.anchorLine = cursor.line;
cursor.anchorColumn = cursor.column;
notifyListeners();
}
void moveCursorToLineEnd(int lineLength) {
cursor.column = lineLength;
notifyListeners();
}
void moveCursor(int dx, int dy, List<LineInfo> backingLines, {bool keepAnchor = false}) {
//print(cursor.line.toString() + " " + cursor.column.toString() + " " + dx.toString() + " " + dy.toString() + " " + backingLines[cursor.line - 1].text.length.toString());
if (dx != 0) {
if (cursor.column + dx < 0) {
moveCursor(0, -1, backingLines, keepAnchor: keepAnchor);
if (cursor.line > 1) {
moveCursorToLineEnd(backingLines[cursor.line - 1].text.length);
}
} else if (cursor.column + dx > backingLines[cursor.line - 1].text.length) {
moveCursor(0, 1, backingLines, keepAnchor: keepAnchor);
moveCursorToLineStart();
} else {
cursor.column += dx;
}
}
if (dy != 0) {
// Only allow the cursor line to change if in bounds
if (cursor.line + dy > 0 && cursor.line + dy <= backingLines.length) {
cursor.line += dy;
// Change cursor to line end
if (cursor.column > backingLines[cursor.line - 1].text.length) {
moveCursorToLineEnd(backingLines[cursor.line - 1].text.length);
}
}
}
if (!keepAnchor) {
clearSelection();
}
notifyListeners();
}
void mouseDownEnd() {
inMouseSelection = false;
}
void mouseDownMoveUpdate(int col, List<LineInfo> backingLines) {
if (cursor.column != col) {
var lineLength = backingLines[cursor.line - 1].text.length;
cursor.column = col.clamp(0, lineLength);
if (inMouseSelection == false) {
clearSelection();
}
publishCursor(backingLines);
} else if (inMouseSelection == false) {
clearSelection();
publishCursor(backingLines);
}
inMouseSelection = true;
}
void mouseDownUpdate(int line, int col, List<LineInfo> backingLines) {
if (cursor.line != line || cursor.column != col) {
cursor.line = line;
var lineLength = backingLines[cursor.line - 1].text.length;
cursor.column = col.clamp(0, lineLength);
if (inMouseSelection == false) {
clearSelection();
}
publishCursor(backingLines);
} else if (inMouseSelection == false) {
clearSelection();
publishCursor(backingLines);
}
inMouseSelection = true;
}
bool hasSelection() {
return cursor.hasSelection();
}
Cursor normalized() {
return cursor.normalized();
}
}