outline active eraser pen when erasing
info text when no note is available
This commit is contained in:
parent
6d3d74ebc7
commit
ce1d081e16
@ -80,6 +80,20 @@ class MyPainter extends CustomPainter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// active eraser outline
|
||||||
|
if (activePen == Pen.eraser) {
|
||||||
|
final pointerpos = controller.getPointerPosition();
|
||||||
|
if (pointerpos != null) {
|
||||||
|
final translatedPointerpos = _translatept(pointerpos, size);
|
||||||
|
canvas.drawCircle(
|
||||||
|
translatedPointerpos,
|
||||||
|
calcPageDependentScale(zoom, a4Page, canvasSize) * 2.0,
|
||||||
|
paint
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..color = Colors.grey);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -12,45 +12,24 @@ import 'my_painter.dart';
|
|||||||
enum Pen { eraser, pen, highlighter, selector }
|
enum Pen { eraser, pen, highlighter, selector }
|
||||||
|
|
||||||
class PaintController extends ChangeNotifier {
|
class PaintController extends ChangeNotifier {
|
||||||
|
final bool _allowDrawWithFinger = false;
|
||||||
|
final NoteFile file;
|
||||||
|
|
||||||
|
Offset? _currentPointerPosition;
|
||||||
Pen activePen = Pen.pen;
|
Pen activePen = Pen.pen;
|
||||||
List<Stroke> strokes = [];
|
List<Stroke> strokes = [];
|
||||||
final bool _allowDrawWithFinger = false;
|
|
||||||
|
|
||||||
PaintController(this.file);
|
PaintController(this.file);
|
||||||
|
|
||||||
final NoteFile file;
|
|
||||||
|
|
||||||
void changePen(Pen pen) {
|
void changePen(Pen pen) {
|
||||||
activePen = pen;
|
activePen = pen;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
double _calcTiltedWidth(double baseWidth, double tilt) {
|
/// return current position of pointer
|
||||||
if (tilt == .0) return baseWidth;
|
/// null if nowhere hovering or painting
|
||||||
return baseWidth * tilt;
|
Offset? getPointerPosition() {
|
||||||
}
|
return _currentPointerPosition;
|
||||||
|
|
||||||
double _calcAngleDependentWidth(Point pt1, Point pt2, double basetickness) {
|
|
||||||
final delta = pt2.point - pt1.point;
|
|
||||||
final normalizedDelta =
|
|
||||||
delta / sqrt(delta.dx * delta.dx + delta.dy * delta.dy);
|
|
||||||
|
|
||||||
double alpha = asin(normalizedDelta.dy);
|
|
||||||
// range [-pi,pi]
|
|
||||||
alpha += (3 * pi / 4);
|
|
||||||
// range [0,inf]
|
|
||||||
alpha = alpha % (2 * pi);
|
|
||||||
// range [0,2pi]
|
|
||||||
alpha -= pi;
|
|
||||||
// range [-pi,pi]
|
|
||||||
alpha = alpha.abs();
|
|
||||||
// range [0,pi]
|
|
||||||
alpha /= pi;
|
|
||||||
// range [0,1]
|
|
||||||
alpha += .5;
|
|
||||||
// range [.5,1.5]
|
|
||||||
|
|
||||||
return basetickness * alpha;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pointDownEvent(Offset offset, PointerDownEvent e) async {
|
void pointDownEvent(Offset offset, PointerDownEvent e) async {
|
||||||
@ -73,6 +52,9 @@ class PaintController extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pointUpEvent(PointerUpEvent e) {
|
void pointUpEvent(PointerUpEvent e) {
|
||||||
|
_currentPointerPosition = null;
|
||||||
|
notifyListeners();
|
||||||
|
|
||||||
if (activePen == Pen.eraser) return;
|
if (activePen == Pen.eraser) return;
|
||||||
|
|
||||||
// pointerupevent doesn't deliver correct event button
|
// pointerupevent doesn't deliver correct event button
|
||||||
@ -90,14 +72,9 @@ class PaintController extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// check if pointer event is allowed to draw points
|
|
||||||
bool _allowedToDraw(PointerDeviceKind kind, int button) {
|
|
||||||
return (_allowDrawWithFinger && kind == PointerDeviceKind.touch) ||
|
|
||||||
kind == PointerDeviceKind.stylus ||
|
|
||||||
(kind == PointerDeviceKind.mouse && button == kPrimaryMouseButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pointMoveEvent(Offset offset, PointerMoveEvent event) {
|
void pointMoveEvent(Offset offset, PointerMoveEvent event) {
|
||||||
|
_currentPointerPosition = offset;
|
||||||
|
|
||||||
if (!a4Page.contains(offset)) {
|
if (!a4Page.contains(offset)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -106,10 +83,10 @@ class PaintController extends ChangeNotifier {
|
|||||||
switch (activePen) {
|
switch (activePen) {
|
||||||
case Pen.eraser:
|
case Pen.eraser:
|
||||||
// todo dynamic eraser size
|
// todo dynamic eraser size
|
||||||
final eraserrect = Rect.fromCircle(center: offset, radius: 3);
|
final eraserrect = Rect.fromCircle(center: offset, radius: 2.0);
|
||||||
for (final stroke in strokes) {
|
for (final stroke in strokes) {
|
||||||
// check if delete action was within bounding rect of stroke
|
// check if delete action was within bounding rect of stroke
|
||||||
if (stroke.getBoundingRect().contains(offset)) {
|
if (stroke.getBoundingRect().overlaps(eraserrect)) {
|
||||||
// check if eraser hit an point within its range
|
// check if eraser hit an point within its range
|
||||||
for (final pt in stroke.points) {
|
for (final pt in stroke.points) {
|
||||||
if (eraserrect.contains(pt.point)) {
|
if (eraserrect.contains(pt.point)) {
|
||||||
@ -155,4 +132,39 @@ class PaintController extends ChangeNotifier {
|
|||||||
debugPrint('finished loading strokes from file');
|
debugPrint('finished loading strokes from file');
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// check if pointer event is allowed to draw points
|
||||||
|
bool _allowedToDraw(PointerDeviceKind kind, int button) {
|
||||||
|
return (_allowDrawWithFinger && kind == PointerDeviceKind.touch) ||
|
||||||
|
kind == PointerDeviceKind.stylus ||
|
||||||
|
(kind == PointerDeviceKind.mouse && button == kPrimaryMouseButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
double _calcAngleDependentWidth(Point pt1, Point pt2, double basetickness) {
|
||||||
|
final delta = pt2.point - pt1.point;
|
||||||
|
final normalizedDelta =
|
||||||
|
delta / sqrt(delta.dx * delta.dx + delta.dy * delta.dy);
|
||||||
|
|
||||||
|
double alpha = asin(normalizedDelta.dy);
|
||||||
|
// range [-pi,pi]
|
||||||
|
alpha += (3 * pi / 4);
|
||||||
|
// range [0,inf]
|
||||||
|
alpha = alpha % (2 * pi);
|
||||||
|
// range [0,2pi]
|
||||||
|
alpha -= pi;
|
||||||
|
// range [-pi,pi]
|
||||||
|
alpha = alpha.abs();
|
||||||
|
// range [0,pi]
|
||||||
|
alpha /= pi;
|
||||||
|
// range [0,1]
|
||||||
|
alpha += .5;
|
||||||
|
// range [.5,1.5]
|
||||||
|
|
||||||
|
return basetickness * alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
double _calcTiltedWidth(double baseWidth, double tilt) {
|
||||||
|
if (tilt == .0) return baseWidth;
|
||||||
|
return baseWidth * tilt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,48 +209,75 @@ class _AllNotesPageState extends State<AllNotesPage> {
|
|||||||
Widget _buildNoteTiles() {
|
Widget _buildNoteTiles() {
|
||||||
return Consumer<FileChangeNotifier>(
|
return Consumer<FileChangeNotifier>(
|
||||||
builder: (BuildContext context, value, Widget? child) {
|
builder: (BuildContext context, value, Widget? child) {
|
||||||
return Expanded(
|
if (value.tiledata.isEmpty) {
|
||||||
child: GridView.builder(
|
return _buildNoNotesText();
|
||||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
} else {
|
||||||
crossAxisCount: 6, childAspectRatio: 0.7),
|
return Expanded(
|
||||||
physics: const ScrollPhysics(),
|
child: GridView.builder(
|
||||||
padding: const EdgeInsets.all(2),
|
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
itemBuilder: (BuildContext context, int idx) => NoteTile(
|
crossAxisCount: 6, childAspectRatio: 0.7),
|
||||||
data: value.tiledata[idx],
|
physics: const ScrollPhysics(),
|
||||||
selectionMode: selectionMode,
|
padding: const EdgeInsets.all(2),
|
||||||
selected: selectionIdx.contains(idx),
|
itemBuilder: (BuildContext context, int idx) => NoteTile(
|
||||||
onSelectionChange: (selection) {
|
data: value.tiledata[idx],
|
||||||
if (selection) {
|
selectionMode: selectionMode,
|
||||||
if (!selectionMode) {
|
selected: selectionIdx.contains(idx),
|
||||||
setState(() {
|
onSelectionChange: (selection) {
|
||||||
selectionMode = true;
|
if (selection) {
|
||||||
});
|
if (!selectionMode) {
|
||||||
}
|
setState(() {
|
||||||
if (!selectionIdx.contains(idx)) {
|
selectionMode = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!selectionIdx.contains(idx)) {
|
||||||
|
final sel = selectionIdx;
|
||||||
|
sel.add(idx);
|
||||||
|
setState(() {
|
||||||
|
selectionIdx = sel;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
final sel = selectionIdx;
|
final sel = selectionIdx;
|
||||||
sel.add(idx);
|
sel.remove(idx);
|
||||||
|
if (sel.isEmpty) {
|
||||||
|
setState(() {
|
||||||
|
selectionMode = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
selectionIdx = sel;
|
selectionIdx = sel;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
final sel = selectionIdx;
|
),
|
||||||
sel.remove(idx);
|
itemCount: value.tiledata.length,
|
||||||
if (sel.isEmpty) {
|
|
||||||
setState(() {
|
|
||||||
selectionMode = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
setState(() {
|
|
||||||
selectionIdx = sel;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
itemCount: value.tiledata.length,
|
);
|
||||||
),
|
}
|
||||||
);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildNoNotesText() {
|
||||||
|
return Expanded(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: const [
|
||||||
|
Text(
|
||||||
|
'No notes',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color.fromRGBO(255, 255, 255, .75), fontSize: 14),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'Tap the Add Button to create a note.',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color.fromRGBO(255, 255, 255, .65), fontSize: 12),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user