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 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 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 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 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(); } }