diff --git a/app/lib/handlers/ruler.dart b/app/lib/handlers/ruler.dart index 4f08fb06c58d..745f88a92c05 100644 --- a/app/lib/handlers/ruler.dart +++ b/app/lib/handlers/ruler.dart @@ -14,7 +14,7 @@ Rect _getRulerRect(Size size, Offset position, class RulerHandler extends Handler with PointerManipulationHandler { Offset _position = Offset.zero; - double _rotation = 0; + double _rotation = 20; Offset get position => _position; double get rotation => _rotation; @@ -26,7 +26,7 @@ class RulerHandler extends Handler with PointerManipulationHandler { NoteData document, DocumentPage page, DocumentInfo info, [Area? currentArea]) => [ - RulerRenderer(data, position: _position, rotation: _rotation), + RulerRenderer(data, position: _position, rulerRotation: _rotation), ]; @override @@ -48,8 +48,13 @@ class RulerHandler extends Handler with PointerManipulationHandler { context.refresh(); } + Rect getRect(Size size, + [CameraTransform transform = const CameraTransform()]) { + return _getRulerRect(size, _position, transform); + } + bool isPointerInside(Offset position, Size viewportSize) { - final rect = _getRulerRect(viewportSize, _position); + final rect = getRect(viewportSize); // Check if the position is inside the ruler rect, consider rotation final rotatedPosition = position.rotate(rect.center, -_rotation * pi / 180); return rect.contains(rotatedPosition); @@ -60,7 +65,7 @@ class RulerHandler extends Handler with PointerManipulationHandler { if (!isPointerInside(position, viewportSize)) { return position; } - final rulerRect = _getRulerRect(viewportSize, _position); + final rulerRect = getRect(viewportSize); final pivot = rulerRect.center; final angle = _rotation * pi / 180; @@ -91,58 +96,54 @@ class RulerHandler extends Handler with PointerManipulationHandler { class RulerRenderer extends Renderer { final Offset position; - @override - final double rotation; + final double rulerRotation; RulerRenderer( super.element, { this.position = Offset.zero, - this.rotation = 0, + this.rulerRotation = 0, }); @override void build(Canvas canvas, Size size, NoteData document, DocumentPage page, DocumentInfo info, CameraTransform transform, [ColorScheme? colorScheme, bool foreground = false]) { + canvas.save(); + canvas.translate(transform.position.dx, transform.position.dy); + canvas.scale(1 / transform.size, 1 / transform.size); + var rulerRect = _getRulerRect(size, position); + final rulerCenter = rulerRect.center; + canvas.translate(rulerCenter.dx, rulerCenter.dy); + canvas.rotate(rulerRotation * pi / 180); + rulerRect = rulerRect.translate(-rulerCenter.dx, -rulerCenter.dy); final rulerColor = colorScheme?.primary ?? Colors.grey; final rulerBackgroundColor = element.color?.toColor() ?? (colorScheme?.primaryContainer ?? Colors.grey).withAlpha(200); final rulerForegroundColor = colorScheme?.onPrimary ?? Colors.white; final rulerPaint = Paint() ..color = rulerColor - ..strokeWidth = 1 / transform.size + ..strokeWidth = 1 ..style = PaintingStyle.stroke ..strokeJoin = StrokeJoin.round; final rulerBackgroundPaint = Paint() ..color = rulerBackgroundColor ..style = PaintingStyle.fill; final rulerForegroundPaint = Paint()..color = rulerForegroundColor; - final rulerRect = _getRulerRect(size, position, transform); // Calculate steps based on zoom level var steps = 50; // Paint ruler background canvas.drawRect(rulerRect, rulerBackgroundPaint); - canvas.drawLine( - Offset(rulerRect.left, rulerRect.top), - Offset(rulerRect.right, rulerRect.top), - rulerPaint, - ); - canvas.drawLine( - Offset(rulerRect.left, rulerRect.bottom), - Offset(rulerRect.right, rulerRect.bottom), - rulerPaint, - ); + canvas.drawRect(rulerRect, rulerPaint); // Paint ruler lines int x = steps; var even = (transform.position.dx ~/ (steps / transform.size)) % 2 == 0; - while (x <= size.width) { + while (x <= size.width * transform.size) { final posX = x / transform.size - - (transform.position.dx % (steps / transform.size)) + - transform.position.dx + - position.dx / transform.size; + (transform.position.dx % (steps / transform.size)) - + size.width / 2; canvas.drawLine( Offset(posX, rulerRect.top), Offset( @@ -154,5 +155,11 @@ class RulerRenderer extends Renderer { even = !even; x += steps; } + + canvas.rotate(-rulerRotation * pi / 180); + canvas.translate(-rulerCenter.dx, -rulerCenter.dy); + canvas.scale(transform.size, transform.size); + canvas.translate(-transform.position.dx, -transform.position.dy); + canvas.restore(); } } diff --git a/app/lib/handlers/select.dart b/app/lib/handlers/select.dart index b6ad33936629..e536a351d290 100644 --- a/app/lib/handlers/select.dart +++ b/app/lib/handlers/select.dart @@ -290,7 +290,8 @@ class SelectHandler extends Handler { final currentIndex = context.getCurrentIndex(); _ruler = RulerHandler.getFirstRuler(context.getCurrentIndex(), details.localFocalPoint, context.viewportSize); - if (_ruler == null) return true; + _rulerRotationStart = details.localFocalPoint; + if (_ruler != null) return true; if (currentIndex.buttons == kSecondaryMouseButton && currentIndex.temporaryHandler == null) { return false; @@ -317,32 +318,43 @@ class SelectHandler extends Handler { event.buttons != kSecondaryMouseButton; RulerHandler? _ruler; + Offset? _rulerRotationStart; bool _handleRuler(ScaleUpdateDetails details, EventContext context) { final state = context.getState(); if (state == null) return false; final ruler = _ruler; if (ruler == null) return false; - //final currentRotation = ruler.rotation * 180 / pi * details.scale; - final delta = details.rotation; - var angle = ruler.rotation + delta; + final rightClick = + (context.getCurrentIndex().buttons ?? 0) & kSecondaryMouseButton != 0; + var angle = details.rotation * 180 / pi; + var currentPos = Offset.zero; + if (details.rotation == 0 && rightClick) { + final rulerCenter = ruler.getRect(context.viewportSize).center; + var start = _rulerRotationStart ?? rulerCenter; + final startDelta = (start - rulerCenter).direction; + final currentDelta = (details.localFocalPoint - rulerCenter).direction; + angle = (currentDelta - startDelta) * 180 / pi - ruler.rotation; + } else { + currentPos = details.focalPointDelta; + } while (angle < 0) { angle += 360; } angle %= 360; - final currentPos = details.focalPointDelta; ruler.transform(context, position: currentPos, rotation: angle); return true; } @override void onScaleUpdate(ScaleUpdateDetails details, EventContext context) { - if (details.pointerCount > 1) return; + print("onScaleUpdate"); final globalPos = context.getCameraTransform().localToGlobal(details.localFocalPoint); if (_handleRuler(details, context)) { return; } + if (details.pointerCount > 1) return; if (_selectionManager.isTransforming) { _selectionManager.updateCurrentPosition(globalPos); context.refresh();