From f9f46d279ddb8b00facfe105e6cb2744a4ccddb6 Mon Sep 17 00:00:00 2001 From: CodeDoctorDE Date: Mon, 30 Dec 2024 01:07:16 +0100 Subject: [PATCH] Fix ruler --- app/lib/handlers/laser.dart | 11 ++++---- app/lib/handlers/pen.dart | 11 ++++---- app/lib/handlers/ruler.dart | 54 +++++++++++++++++++++++------------- app/lib/handlers/select.dart | 14 +++++----- app/pubspec.lock | 16 +++++------ 5 files changed, 60 insertions(+), 46 deletions(-) diff --git a/app/lib/handlers/laser.dart b/app/lib/handlers/laser.dart index 8dca78ea04ab..494174bd07c8 100644 --- a/app/lib/handlers/laser.dart +++ b/app/lib/handlers/laser.dart @@ -97,22 +97,21 @@ class LaserHandler extends Handler with ColoredHandler { @override void onPointerUp(PointerUpEvent event, EventContext context) { addPoint(context.buildContext, event.pointer, event.localPosition, - event.pressure, event.kind); + context.viewportSize, event.pressure, event.kind); _submit(context.getDocumentBloc(), [event.pointer]); } void addPoint(BuildContext context, int pointer, Offset localPosition, - double pressure, PointerDeviceKind kind, + Size viewportSize, double pressure, PointerDeviceKind kind, {bool forceCreate = false}) { final bloc = context.read(); final currentIndexCubit = context.read(); - final viewport = currentIndexCubit.state.cameraViewport; final transform = context.read().state; final state = bloc.state as DocumentLoadSuccess; final settings = context.read().state; final penOnlyInput = settings.penOnlyInput; localPosition = PointerManipulationHandler.calculatePointerPosition( - currentIndexCubit.state, localPosition, viewport.toSize()); + currentIndexCubit.state, localPosition, viewportSize); if (penOnlyInput && kind != PointerDeviceKind.stylus) { return; } @@ -146,7 +145,7 @@ class LaserHandler extends Handler with ColoredHandler { return; } addPoint(context.buildContext, event.pointer, event.localPosition, - event.pressure, event.kind, + context.viewportSize, event.pressure, event.kind, forceCreate: true); } @@ -154,7 +153,7 @@ class LaserHandler extends Handler with ColoredHandler { Future onPointerMove( PointerMoveEvent event, EventContext context) async { addPoint(context.buildContext, event.pointer, event.localPosition, - event.pressure, event.kind); + context.viewportSize, event.pressure, event.kind); } @override diff --git a/app/lib/handlers/pen.dart b/app/lib/handlers/pen.dart index 78b9774f5dcd..3298f5ff6f0d 100644 --- a/app/lib/handlers/pen.dart +++ b/app/lib/handlers/pen.dart @@ -50,7 +50,7 @@ class PenHandler extends Handler with ColoredHandler { _positionCheckTimer?.cancel(); _positionCheckTimer = null; addPoint(context.buildContext, event.pointer, event.localPosition, - _getPressure(event), event.kind, + context.viewportSize, _getPressure(event), event.kind, refresh: false); submitElements(context.getDocumentBloc(), [event.pointer]); points.clear(); @@ -75,14 +75,13 @@ class PenHandler extends Handler with ColoredHandler { // Add a point to the element. void addPoint(BuildContext context, int pointer, Offset localPos, - double pressure, PointerDeviceKind kind, + Size viewportSize, double pressure, PointerDeviceKind kind, {bool refresh = true, bool shouldCreate = false}) { final bloc = context.read(); final currentIndexCubit = context.read(); - final viewport = currentIndexCubit.state.cameraViewport; final transform = context.read().state; localPos = PointerManipulationHandler.calculatePointerPosition( - currentIndexCubit.state, localPos, viewport.toSize()); + currentIndexCubit.state, localPos, viewportSize); final globalPos = transform.localToGlobal(localPos); if (!bloc.isInBounds(globalPos)) return; final state = bloc.state as DocumentLoadSuccess; @@ -125,7 +124,7 @@ class PenHandler extends Handler with ColoredHandler { } elements.remove(event.pointer); addPoint(context.buildContext, event.pointer, event.localPosition, - _getPressure(event), event.kind, + context.viewportSize, _getPressure(event), event.kind, shouldCreate: true); } @@ -152,7 +151,7 @@ class PenHandler extends Handler with ColoredHandler { }); // Call the addPoint function to add a point to the current brush stroke. addPoint(context.buildContext, event.pointer, event.localPosition, - _getPressure(event), event.kind); + context.viewportSize, _getPressure(event), event.kind); points.add(event.localPosition); } diff --git a/app/lib/handlers/ruler.dart b/app/lib/handlers/ruler.dart index 8eceaee52f4d..4f08fb06c58d 100644 --- a/app/lib/handlers/ruler.dart +++ b/app/lib/handlers/ruler.dart @@ -1,11 +1,12 @@ part of 'handler.dart'; -Rect _getRulerRect(Size size, +Rect _getRulerRect(Size size, Offset position, [CameraTransform transform = const CameraTransform()]) { const rulerSize = 100.0; return Rect.fromLTWH( - transform.position.dx, - transform.position.dy + (size.height / 2 + -rulerSize / 2) / transform.size, + transform.position.dx + position.dx / transform.size, + transform.position.dy + + (size.height / 2 + -rulerSize / 2 + position.dy) / transform.size, size.width / transform.size, rulerSize / transform.size, ); @@ -39,31 +40,45 @@ class RulerHandler extends Handler with PointerManipulationHandler { double? rotation, }) { if (position != null) { - _position = position; + _position += position; } if (rotation != null) { - _rotation = rotation; + _rotation += rotation; } context.refresh(); } bool isPointerInside(Offset position, Size viewportSize) { - final rect = _getRulerRect(viewportSize); + final rect = _getRulerRect(viewportSize, _position); // Check if the position is inside the ruler rect, consider rotation - final rotatedPosition = position.rotate(rect.center, -_rotation); + final rotatedPosition = position.rotate(rect.center, -_rotation * pi / 180); return rect.contains(rotatedPosition); } @override Offset getPointerPosition(Offset position, Size viewportSize) { if (!isPointerInside(position, viewportSize)) { - return _position; + return position; } - final rotatedPosition = position.rotate(_position, _rotation); - return Offset( - _position.dx + (rotatedPosition.dx - _position.dx).roundToDouble(), - _position.dy + (rotatedPosition.dy - _position.dy).roundToDouble(), - ); + final rulerRect = _getRulerRect(viewportSize, _position); + final pivot = rulerRect.center; + final angle = _rotation * pi / 180; + + final rotatedPosition = position.rotate(pivot, -angle); + final firstHalf = + rulerRect.topLeft & Size(rulerRect.width, rulerRect.height / 2); + final secondHalf = firstHalf.translate(0, rulerRect.height / 2); + final firstHalfHit = firstHalf.contains(rotatedPosition); + final secondHalfHit = secondHalf.contains(rotatedPosition); + // If the pointer is in the first half of the ruler, set the y to the top + // If the pointer is in the second half of the ruler, set the y to the bottom + + if (firstHalfHit) { + return Offset(rotatedPosition.dx, rulerRect.top).rotate(pivot, angle); + } else if (secondHalfHit) { + return Offset(rotatedPosition.dx, rulerRect.bottom).rotate(pivot, angle); + } + return position; } static RulerHandler? getFirstRuler( @@ -102,7 +117,7 @@ class RulerRenderer extends Renderer { ..color = rulerBackgroundColor ..style = PaintingStyle.fill; final rulerForegroundPaint = Paint()..color = rulerForegroundColor; - final rulerRect = _getRulerRect(size, transform); + final rulerRect = _getRulerRect(size, position, transform); // Calculate steps based on zoom level var steps = 50; @@ -121,12 +136,13 @@ class RulerRenderer extends Renderer { ); // Paint ruler lines - double x = 0; + int x = steps; var even = (transform.position.dx ~/ (steps / transform.size)) % 2 == 0; - while (x <= size.width / transform.size) { - final posX = x - + while (x <= size.width) { + final posX = x / transform.size - (transform.position.dx % (steps / transform.size)) + - transform.position.dx; + transform.position.dx + + position.dx / transform.size; canvas.drawLine( Offset(posX, rulerRect.top), Offset( @@ -136,7 +152,7 @@ class RulerRenderer extends Renderer { rulerForegroundPaint, ); even = !even; - x += steps / transform.size; + x += steps; } } } diff --git a/app/lib/handlers/select.dart b/app/lib/handlers/select.dart index d6ee6d5b0465..b6ad33936629 100644 --- a/app/lib/handlers/select.dart +++ b/app/lib/handlers/select.dart @@ -288,7 +288,9 @@ class SelectHandler extends Handler { @override bool onScaleStart(ScaleStartDetails details, EventContext context) { final currentIndex = context.getCurrentIndex(); - _ruler = false; + _ruler = RulerHandler.getFirstRuler(context.getCurrentIndex(), + details.localFocalPoint, context.viewportSize); + if (_ruler == null) return true; if (currentIndex.buttons == kSecondaryMouseButton && currentIndex.temporaryHandler == null) { return false; @@ -314,14 +316,12 @@ class SelectHandler extends Handler { event.kind == PointerDeviceKind.mouse && event.buttons != kSecondaryMouseButton; - bool _ruler = false; + RulerHandler? _ruler; bool _handleRuler(ScaleUpdateDetails details, EventContext context) { - _ruler = true; final state = context.getState(); if (state == null) return false; - final ruler = RulerHandler.getFirstRuler(context.getCurrentIndex(), - details.localFocalPoint, context.viewportSize); + final ruler = _ruler; if (ruler == null) return false; //final currentRotation = ruler.rotation * 180 / pi * details.scale; final delta = details.rotation; @@ -330,7 +330,7 @@ class SelectHandler extends Handler { angle += 360; } angle %= 360; - final currentPos = details.localFocalPoint; + final currentPos = details.focalPointDelta; ruler.transform(context, position: currentPos, rotation: angle); return true; } @@ -369,7 +369,7 @@ class SelectHandler extends Handler { final utilities = context.getCurrentIndex().utilities; final rectangleSelection = _rectangleFreeSelection?.normalized(); final lassoSelection = _lassoFreeSelection; - if (_ruler) { + if (_ruler != null) { return; } final transformed = _submitTransform(context.getDocumentBloc()); diff --git a/app/pubspec.lock b/app/pubspec.lock index 35e274ab270b..9b1d7d09cb92 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -458,18 +458,18 @@ packages: dependency: "direct main" description: name: flex_color_scheme - sha256: "90f4fe67b9561ae8a4af117df65a8ce9988624025667c54e6d304e65cff77d52" + sha256: "09bea5d776f694c5a67f2229f2aa500cc7cce369322dc6500ab01cf9ad1b4e1a" url: "https://pub.dev" source: hosted - version: "8.0.2" + version: "8.1.0" flex_seed_scheme: dependency: transitive description: name: flex_seed_scheme - sha256: "7639d2c86268eff84a909026eb169f008064af0fb3696a651b24b0fa24a40334" + sha256: d3ba3c5c92d2d79d45e94b4c6c71d01fac3c15017da1545880c53864da5dfeb0 url: "https://pub.dev" source: hosted - version: "3.4.1" + version: "3.5.0" flutter: dependency: "direct main" description: flutter @@ -1366,18 +1366,18 @@ packages: dependency: "direct main" description: name: super_clipboard - sha256: "687ef5d4ceb2cb1e0e36a4af37683936609f424f0767b46fee5fc312b0aeb595" + sha256: "5203c881d24033c3e6154c2ae01afd94e7f0a3201280373f28e540f1defa3f40" url: "https://pub.dev" source: hosted - version: "0.9.0-dev.5" + version: "0.9.0-dev.6" super_native_extensions: dependency: transitive description: name: super_native_extensions - sha256: "1cb6baecf529300ae7f59974bdc33a53b947ecc4ce374c00126df064c10e4e51" + sha256: "09ccc40c475e6f91770eaeb2553bf4803812d7beadc3759aa57d643370619c86" url: "https://pub.dev" source: hosted - version: "0.9.0-dev.5" + version: "0.9.0-dev.6" sync_http: dependency: transitive description: