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
|
||||
|
@ -12,45 +12,24 @@ import 'my_painter.dart';
|
||||
enum Pen { eraser, pen, highlighter, selector }
|
||||
|
||||
class PaintController extends ChangeNotifier {
|
||||
final bool _allowDrawWithFinger = false;
|
||||
final NoteFile file;
|
||||
|
||||
Offset? _currentPointerPosition;
|
||||
Pen activePen = Pen.pen;
|
||||
List<Stroke> strokes = [];
|
||||
final bool _allowDrawWithFinger = false;
|
||||
|
||||
PaintController(this.file);
|
||||
|
||||
final NoteFile file;
|
||||
|
||||
void changePen(Pen pen) {
|
||||
activePen = pen;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
double _calcTiltedWidth(double baseWidth, double tilt) {
|
||||
if (tilt == .0) return baseWidth;
|
||||
return baseWidth * tilt;
|
||||
}
|
||||
|
||||
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;
|
||||
/// return current position of pointer
|
||||
/// null if nowhere hovering or painting
|
||||
Offset? getPointerPosition() {
|
||||
return _currentPointerPosition;
|
||||
}
|
||||
|
||||
void pointDownEvent(Offset offset, PointerDownEvent e) async {
|
||||
@ -73,6 +52,9 @@ class PaintController extends ChangeNotifier {
|
||||
}
|
||||
|
||||
void pointUpEvent(PointerUpEvent e) {
|
||||
_currentPointerPosition = null;
|
||||
notifyListeners();
|
||||
|
||||
if (activePen == Pen.eraser) return;
|
||||
|
||||
// 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) {
|
||||
_currentPointerPosition = offset;
|
||||
|
||||
if (!a4Page.contains(offset)) {
|
||||
return;
|
||||
}
|
||||
@ -106,10 +83,10 @@ class PaintController extends ChangeNotifier {
|
||||
switch (activePen) {
|
||||
case Pen.eraser:
|
||||
// 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) {
|
||||
// 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
|
||||
for (final pt in stroke.points) {
|
||||
if (eraserrect.contains(pt.point)) {
|
||||
@ -155,4 +132,39 @@ class PaintController extends ChangeNotifier {
|
||||
debugPrint('finished loading strokes from file');
|
||||
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() {
|
||||
return Consumer<FileChangeNotifier>(
|
||||
builder: (BuildContext context, value, Widget? child) {
|
||||
return Expanded(
|
||||
child: GridView.builder(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 6, childAspectRatio: 0.7),
|
||||
physics: const ScrollPhysics(),
|
||||
padding: const EdgeInsets.all(2),
|
||||
itemBuilder: (BuildContext context, int idx) => NoteTile(
|
||||
data: value.tiledata[idx],
|
||||
selectionMode: selectionMode,
|
||||
selected: selectionIdx.contains(idx),
|
||||
onSelectionChange: (selection) {
|
||||
if (selection) {
|
||||
if (!selectionMode) {
|
||||
setState(() {
|
||||
selectionMode = true;
|
||||
});
|
||||
}
|
||||
if (!selectionIdx.contains(idx)) {
|
||||
if (value.tiledata.isEmpty) {
|
||||
return _buildNoNotesText();
|
||||
} else {
|
||||
return Expanded(
|
||||
child: GridView.builder(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 6, childAspectRatio: 0.7),
|
||||
physics: const ScrollPhysics(),
|
||||
padding: const EdgeInsets.all(2),
|
||||
itemBuilder: (BuildContext context, int idx) => NoteTile(
|
||||
data: value.tiledata[idx],
|
||||
selectionMode: selectionMode,
|
||||
selected: selectionIdx.contains(idx),
|
||||
onSelectionChange: (selection) {
|
||||
if (selection) {
|
||||
if (!selectionMode) {
|
||||
setState(() {
|
||||
selectionMode = true;
|
||||
});
|
||||
}
|
||||
if (!selectionIdx.contains(idx)) {
|
||||
final sel = selectionIdx;
|
||||
sel.add(idx);
|
||||
setState(() {
|
||||
selectionIdx = sel;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
final sel = selectionIdx;
|
||||
sel.add(idx);
|
||||
sel.remove(idx);
|
||||
if (sel.isEmpty) {
|
||||
setState(() {
|
||||
selectionMode = false;
|
||||
});
|
||||
}
|
||||
setState(() {
|
||||
selectionIdx = sel;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
final sel = selectionIdx;
|
||||
sel.remove(idx);
|
||||
if (sel.isEmpty) {
|
||||
setState(() {
|
||||
selectionMode = false;
|
||||
});
|
||||
}
|
||||
setState(() {
|
||||
selectionIdx = sel;
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
),
|
||||
itemCount: value.tiledata.length,
|
||||
),
|
||||
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