Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add s-pen button erasing #783

Merged
merged 2 commits into from
Jul 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion lib/components/canvas/canvas_gesture_detector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class CanvasGestureDetector extends StatefulWidget {
required this.onDrawUpdate,
required this.onDrawEnd,
required this.onPressureChanged,
required this.onStylusButtonChanged,

required this.undo,
required this.redo,
Expand All @@ -45,6 +46,7 @@ class CanvasGestureDetector extends StatefulWidget {
/// Called when the pressure of the stylus changes,
/// pressure is negative if stylus button is pressed
final ValueChanged<double?> onPressureChanged;
final ValueChanged<bool> onStylusButtonChanged;

final VoidCallback undo;
final VoidCallback redo;
Expand Down Expand Up @@ -202,15 +204,26 @@ class _CanvasGestureDetectorState extends State<CanvasGestureDetector> {

void _listenerPointerEvent(PointerEvent event) {
double? pressure;
bool stylusButtonPressed = false;

if (event.kind == PointerDeviceKind.stylus) {
pressure = event.pressure;
stylusButtonPressed = event.buttons == kPrimaryStylusButton;
} else if (event.kind == PointerDeviceKind.invertedStylus) {
pressure = -event.pressure;
pressure = event.pressure;
stylusButtonPressed = true; // treat eraser as stylus button
} else if (Platform.isLinux && event.pressureMin != event.pressureMax) {
// if min == max, then the device isn't pressure sensitive
pressure = event.pressure;
}

widget.onPressureChanged(pressure);
widget.onStylusButtonChanged(stylusButtonPressed);
}

void _listenerPointerUpEvent(PointerEvent event) {
widget.onPressureChanged(null);
widget.onStylusButtonChanged(false);
}

@override
Expand All @@ -222,6 +235,7 @@ class _CanvasGestureDetectorState extends State<CanvasGestureDetector> {
Listener(
onPointerDown: _listenerPointerEvent,
onPointerMove: _listenerPointerEvent,
onPointerUp: _listenerPointerUpEvent,
child: GestureDetector(
onSecondaryTapUp: (TapUpDetails details) => widget.undo(),
onTertiaryTapUp: (TapUpDetails details) => widget.redo(),
Expand Down
6 changes: 1 addition & 5 deletions lib/components/toolbar/toolbar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,7 @@ class _ToolbarState extends State<Toolbar> {

void toggleEraser() {
toolOptionsType = ToolOptions.hide;
if (widget.currentTool is Eraser) {
widget.setTool(Pen.currentPen);
} else {
widget.setTool(Eraser());
}
widget.setTool(Eraser()); // this toggles eraser
}
void toggleColorOptions() {
setState(() {
Expand Down
49 changes: 37 additions & 12 deletions lib/pages/editor/editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ class EditorState extends State<Editor> {
/// Whether the platform can rasterize a pdf
bool canRasterPdf = true;

/// The tool that was used before switching to the eraser.
Tool? tmpTool;
/// If the stylus button is pressed.
bool stylusButtonPressed = false;

@override
void initState() {
DynamicMaterialApp.addFullscreenListener(_setState);
Expand Down Expand Up @@ -466,8 +471,6 @@ class EditorState extends State<Editor> {

int? dragPageIndex;
double? currentPressure;
/// if [pressureWasNegative], switch back to pen when pressure becomes positive again
bool pressureWasNegative = false;
bool isDrawGesture(ScaleStartDetails details) {
if (coreInfo.readOnly) return false;

Expand Down Expand Up @@ -626,11 +629,6 @@ class EditorState extends State<Editor> {
}
});
autosaveAfterDelay();

if (pressureWasNegative) {
pressureWasNegative = false;
currentTool = Pen.currentPen;
}
}
void onInteractionEnd(ScaleEndDetails details) {
// reset after 1ms to keep track of the same gesture only
Expand All @@ -639,13 +637,27 @@ class EditorState extends State<Editor> {
lastSeenPointerCount = 0;
});
}
void onPressureChanged(double? pressure) {
currentPressure = pressure == 0.0 ? null : pressure;
if (currentPressure == null) return;

if (currentPressure! < 0) {
pressureWasNegative = true;
void onPressureChanged(double? pressure) {
currentPressure = pressure == 0 ? null : pressure;
}
void onStylusButtonChanged(bool buttonPressed) {
stylusButtonPressed = buttonPressed;

if (buttonPressed) {
if (currentTool is Eraser) return;
tmpTool = currentTool;
if (currentTool is Pen && dragPageIndex != null) {
// if the pen is currently drawing, end the stroke
(currentTool as Pen).onDragEnd();
}
currentTool = Eraser();
setState(() {});
} else {
if (tmpTool == null) return;
currentTool = tmpTool!;
tmpTool = null;
setState(() {});
}
}

Expand Down Expand Up @@ -1107,6 +1119,7 @@ class EditorState extends State<Editor> {
onDrawStart: onDrawStart,
onDrawUpdate: onDrawUpdate,
onDrawEnd: onDrawEnd,
onStylusButtonChanged: onStylusButtonChanged,
onPressureChanged: onPressureChanged,

undo: undo,
Expand Down Expand Up @@ -1189,6 +1202,18 @@ class EditorState extends State<Editor> {

setTool: (tool) {
setState(() {
if (tool is Eraser) {
// setTool(Eraser) is called to toggle eraser
if (currentTool is Eraser && tmpTool != null) {
// switch to previous tool
tool = tmpTool!;
tmpTool = null;
} else {
// store previous tool to restore it later
tmpTool = currentTool;
}
}

currentTool = tool;

if (currentTool is Highlighter) {
Expand Down