diff --git a/app/lib/bloc/document_bloc.dart b/app/lib/bloc/document_bloc.dart index 65c03f0be731..49bdfe3abe35 100644 --- a/app/lib/bloc/document_bloc.dart +++ b/app/lib/bloc/document_bloc.dart @@ -1079,13 +1079,7 @@ class DocumentBloc extends ReplayBloc { final current = state; if (current is! DocumentLoaded) return; final cubit = current.currentIndexCubit; - final document = current.data; - final page = current.page; - final assetService = current.assetService; cubit.setSaveState(saved: SaveState.saved); - final tool = UtilitiesRenderer(cubit.state.utilitiesState); - await tool.setup(document, assetService, page); - cubit.unbake(tool: tool); cubit.loadElements(current); cubit.init(this); } @@ -1158,7 +1152,7 @@ class DocumentBloc extends ReplayBloc { if (state is! DocumentLoadSuccess) return {}; transform ??= state.currentIndexCubit.state.transformCubit.state; final renderers = state.cameraViewport.visibleElements; - full ??= state.cameraViewport.utilities.element.fullSelection; + full ??= state.currentIndexCubit.state.utilities.fullSelection; return compute( _executeRayCast, _RayCastParams( @@ -1182,7 +1176,7 @@ class DocumentBloc extends ReplayBloc { if (state is! DocumentLoadSuccess) return {}; final renderers = state.cameraViewport.visibleElements; transform ??= state.currentIndexCubit.state.transformCubit.state; - full ??= state.cameraViewport.utilities.element.fullSelection; + full ??= state.currentIndexCubit.state.utilities.fullSelection; return compute( _executeRayCastPolygon, _RayCastPolygonParams( diff --git a/app/lib/cubits/current_index.dart b/app/lib/cubits/current_index.dart index 9f4791a8b6e3..4471588c6931 100644 --- a/app/lib/cubits/current_index.dart +++ b/app/lib/cubits/current_index.dart @@ -49,6 +49,7 @@ class CurrentIndex with _$CurrentIndex { SettingsCubit settingsCubit, TransformCubit transformCubit, NetworkingService networkingService, { + @Default(UtilitiesState()) UtilitiesState utilities, Handler? temporaryHandler, @Default([]) List foregrounds, Selection? selection, @@ -84,8 +85,6 @@ class CurrentIndex with _$CurrentIndex { MouseCursor get currentCursor => temporaryCursor ?? cursor; - UtilitiesState get utilitiesState => cameraViewport.utilities.element; - Map get allRendererStates => { ...rendererStates, ...?temporaryRendererStates, @@ -123,12 +122,6 @@ class CurrentIndexCubit extends Cubit { } } - Offset getGridPosition( - Offset position, DocumentPage page, DocumentInfo info) { - return state.cameraViewport.utilities - .getGridPosition(position, page, info, this); - } - Future changeTool( DocumentBloc bloc, { int? index, @@ -529,7 +522,7 @@ class CurrentIndexCubit extends Cubit { temporaryForegrounds: null, temporaryCursor: null, temporaryRendererStates: null, - cameraViewport: CameraViewport.unbaked(UtilitiesRenderer()), + cameraViewport: CameraViewport.unbaked(), )); } @@ -864,13 +857,10 @@ class CurrentIndexCubit extends Cubit { void unbake( {List>? backgrounds, - UtilitiesRenderer? tool, List>? unbakedElements}) { emit(state.copyWith( cameraViewport: state.cameraViewport.unbake( - unbakedElements: unbakedElements, - utilities: tool, - backgrounds: backgrounds))); + unbakedElements: unbakedElements, backgrounds: backgrounds))); } Future loadElements(DocumentState docState) async { @@ -893,17 +883,10 @@ class CurrentIndexCubit extends Cubit { final backgrounds = page.backgrounds.map(Renderer.fromInstance).toList(); await Future.wait(backgrounds .map((e) async => await e.setup(document, assetService, page))); - final utilities = UtilitiesRenderer(state.settingsCubit.state.utilities); - await utilities.setup( - docState.data, - docState.assetService, - docState.page, - ); emit(state.copyWith( cameraViewport: state.cameraViewport.unbake( unbakedElements: renderers, backgrounds: backgrounds, - utilities: utilities, ))); } @@ -1048,24 +1031,10 @@ class CurrentIndexCubit extends Cubit { Future updateUtilities( {UtilitiesState? utilities, ViewOption? view}) async { var state = this.state; - final renderer = UtilitiesRenderer( - utilities ?? state.utilitiesState, view ?? state.viewOption); - if (utilities != null) { - var newSelection = - state.selection?.remove(state.cameraViewport.utilities.element); - if (newSelection == null && state.selection != null) { - newSelection = Selection.from(utilities); - } else if (newSelection != state.selection) { - newSelection = newSelection?.insert(renderer); - } - state = state.copyWith(selection: newSelection); - } state = state.copyWith( - cameraViewport: state.cameraViewport.withUtilities(renderer), + utilities: utilities ?? state.utilities, + viewOption: view ?? state.viewOption, ); - if (view != null) { - state = state.copyWith(viewOption: view); - } emit(state); if (utilities != null) { return state.settingsCubit.changeUtilities(utilities); @@ -1075,7 +1044,7 @@ class CurrentIndexCubit extends Cubit { void togglePin() => emit(state.copyWith(pinned: !state.pinned)); void move(Offset delta, [bool force = false]) { - final utilitiesState = state.utilitiesState; + final utilitiesState = state.utilities; if (utilitiesState.lockHorizontal && !force) { delta = Offset(0, delta.dy); } @@ -1089,7 +1058,7 @@ class CurrentIndexCubit extends Cubit { } void zoom(double delta, [Offset cursor = Offset.zero, bool force = false]) { - final utilitiesState = state.utilitiesState; + final utilitiesState = state.utilities; if (utilitiesState.lockZoom && !force) { delta = 1; } diff --git a/app/lib/cubits/current_index.freezed.dart b/app/lib/cubits/current_index.freezed.dart index 568a03205c24..8f4bc578a183 100644 --- a/app/lib/cubits/current_index.freezed.dart +++ b/app/lib/cubits/current_index.freezed.dart @@ -22,6 +22,7 @@ mixin _$CurrentIndex { SettingsCubit get settingsCubit => throw _privateConstructorUsedError; TransformCubit get transformCubit => throw _privateConstructorUsedError; NetworkingService get networkingService => throw _privateConstructorUsedError; + UtilitiesState get utilities => throw _privateConstructorUsedError; Handler? get temporaryHandler => throw _privateConstructorUsedError; List get foregrounds => throw _privateConstructorUsedError; Selection? get selection => throw _privateConstructorUsedError; @@ -76,6 +77,7 @@ abstract class $CurrentIndexCopyWith<$Res> { SettingsCubit settingsCubit, TransformCubit transformCubit, NetworkingService networkingService, + UtilitiesState utilities, Handler? temporaryHandler, List foregrounds, Selection? selection, @@ -103,6 +105,7 @@ abstract class $CurrentIndexCopyWith<$Res> { bool areaNavigatorExact, bool areaNavigatorAsk}); + $UtilitiesStateCopyWith<$Res> get utilities; $ViewOptionCopyWith<$Res> get viewOption; } @@ -127,6 +130,7 @@ class _$CurrentIndexCopyWithImpl<$Res, $Val extends CurrentIndex> Object? settingsCubit = null, Object? transformCubit = null, Object? networkingService = null, + Object? utilities = null, Object? temporaryHandler = freezed, Object? foregrounds = null, Object? selection = freezed, @@ -179,6 +183,10 @@ class _$CurrentIndexCopyWithImpl<$Res, $Val extends CurrentIndex> ? _value.networkingService : networkingService // ignore: cast_nullable_to_non_nullable as NetworkingService, + utilities: null == utilities + ? _value.utilities + : utilities // ignore: cast_nullable_to_non_nullable + as UtilitiesState, temporaryHandler: freezed == temporaryHandler ? _value.temporaryHandler : temporaryHandler // ignore: cast_nullable_to_non_nullable @@ -286,6 +294,16 @@ class _$CurrentIndexCopyWithImpl<$Res, $Val extends CurrentIndex> ) as $Val); } + /// Create a copy of CurrentIndex + /// with the given fields replaced by the non-null parameter values. + @override + @pragma('vm:prefer-inline') + $UtilitiesStateCopyWith<$Res> get utilities { + return $UtilitiesStateCopyWith<$Res>(_value.utilities, (value) { + return _then(_value.copyWith(utilities: value) as $Val); + }); + } + /// Create a copy of CurrentIndex /// with the given fields replaced by the non-null parameter values. @override @@ -312,6 +330,7 @@ abstract class _$$CurrentIndexImplCopyWith<$Res> SettingsCubit settingsCubit, TransformCubit transformCubit, NetworkingService networkingService, + UtilitiesState utilities, Handler? temporaryHandler, List foregrounds, Selection? selection, @@ -339,6 +358,8 @@ abstract class _$$CurrentIndexImplCopyWith<$Res> bool areaNavigatorExact, bool areaNavigatorAsk}); + @override + $UtilitiesStateCopyWith<$Res> get utilities; @override $ViewOptionCopyWith<$Res> get viewOption; } @@ -362,6 +383,7 @@ class __$$CurrentIndexImplCopyWithImpl<$Res> Object? settingsCubit = null, Object? transformCubit = null, Object? networkingService = null, + Object? utilities = null, Object? temporaryHandler = freezed, Object? foregrounds = null, Object? selection = freezed, @@ -414,6 +436,10 @@ class __$$CurrentIndexImplCopyWithImpl<$Res> ? _value.networkingService : networkingService // ignore: cast_nullable_to_non_nullable as NetworkingService, + utilities: null == utilities + ? _value.utilities + : utilities // ignore: cast_nullable_to_non_nullable + as UtilitiesState, temporaryHandler: freezed == temporaryHandler ? _value.temporaryHandler : temporaryHandler // ignore: cast_nullable_to_non_nullable @@ -527,7 +553,8 @@ class __$$CurrentIndexImplCopyWithImpl<$Res> class _$CurrentIndexImpl extends _CurrentIndex { const _$CurrentIndexImpl(this.index, this.handler, this.cameraViewport, this.settingsCubit, this.transformCubit, this.networkingService, - {this.temporaryHandler, + {this.utilities = const UtilitiesState(), + this.temporaryHandler, final List foregrounds = const [], this.selection, this.pinned = false, @@ -576,6 +603,9 @@ class _$CurrentIndexImpl extends _CurrentIndex { @override final NetworkingService networkingService; @override + @JsonKey() + final UtilitiesState utilities; + @override final Handler? temporaryHandler; final List _foregrounds; @override @@ -704,7 +734,7 @@ class _$CurrentIndexImpl extends _CurrentIndex { @override String toString() { - return 'CurrentIndex(index: $index, handler: $handler, cameraViewport: $cameraViewport, settingsCubit: $settingsCubit, transformCubit: $transformCubit, networkingService: $networkingService, temporaryHandler: $temporaryHandler, foregrounds: $foregrounds, selection: $selection, pinned: $pinned, temporaryForegrounds: $temporaryForegrounds, toggleableHandlers: $toggleableHandlers, networkingForegrounds: $networkingForegrounds, toggleableForegrounds: $toggleableForegrounds, cursor: $cursor, temporaryCursor: $temporaryCursor, temporaryState: $temporaryState, lastPosition: $lastPosition, pointers: $pointers, buttons: $buttons, location: $location, embedding: $embedding, saved: $saved, toolbar: $toolbar, temporaryToolbar: $temporaryToolbar, rendererStates: $rendererStates, temporaryRendererStates: $temporaryRendererStates, viewOption: $viewOption, hideUi: $hideUi, areaNavigatorCreate: $areaNavigatorCreate, areaNavigatorExact: $areaNavigatorExact, areaNavigatorAsk: $areaNavigatorAsk)'; + return 'CurrentIndex(index: $index, handler: $handler, cameraViewport: $cameraViewport, settingsCubit: $settingsCubit, transformCubit: $transformCubit, networkingService: $networkingService, utilities: $utilities, temporaryHandler: $temporaryHandler, foregrounds: $foregrounds, selection: $selection, pinned: $pinned, temporaryForegrounds: $temporaryForegrounds, toggleableHandlers: $toggleableHandlers, networkingForegrounds: $networkingForegrounds, toggleableForegrounds: $toggleableForegrounds, cursor: $cursor, temporaryCursor: $temporaryCursor, temporaryState: $temporaryState, lastPosition: $lastPosition, pointers: $pointers, buttons: $buttons, location: $location, embedding: $embedding, saved: $saved, toolbar: $toolbar, temporaryToolbar: $temporaryToolbar, rendererStates: $rendererStates, temporaryRendererStates: $temporaryRendererStates, viewOption: $viewOption, hideUi: $hideUi, areaNavigatorCreate: $areaNavigatorCreate, areaNavigatorExact: $areaNavigatorExact, areaNavigatorAsk: $areaNavigatorAsk)'; } /// Create a copy of CurrentIndex @@ -724,7 +754,8 @@ abstract class _CurrentIndex extends CurrentIndex { final SettingsCubit settingsCubit, final TransformCubit transformCubit, final NetworkingService networkingService, - {final Handler? temporaryHandler, + {final UtilitiesState utilities, + final Handler? temporaryHandler, final List foregrounds, final Selection? selection, final bool pinned, @@ -765,6 +796,8 @@ abstract class _CurrentIndex extends CurrentIndex { @override NetworkingService get networkingService; @override + UtilitiesState get utilities; + @override Handler? get temporaryHandler; @override List get foregrounds; diff --git a/app/lib/handlers/eraser.dart b/app/lib/handlers/eraser.dart index 4aa2617df7bc..983a47427fe9 100644 --- a/app/lib/handlers/eraser.dart +++ b/app/lib/handlers/eraser.dart @@ -38,7 +38,7 @@ class EraserHandler extends Handler { Future _changeElement(Offset position, EventContext context) async { final currentIndex = context.getCurrentIndex(); final transform = currentIndex.transformCubit.state; - final utilities = currentIndex.utilitiesState; + final utilities = currentIndex.utilities; final globalPos = transform.localToGlobal(position); final size = data.strokeWidth; final shouldErase = diff --git a/app/lib/handlers/grid.dart b/app/lib/handlers/grid.dart index 54076e8e424b..e0a4e5b028eb 100644 --- a/app/lib/handlers/grid.dart +++ b/app/lib/handlers/grid.dart @@ -1,6 +1,6 @@ part of 'handler.dart'; -class GridHandler extends Handler { +class GridHandler extends Handler with PointerManipulationHandler { GridHandler(super.data); @override @@ -13,6 +13,14 @@ class GridHandler extends Handler { SelectState onSelected(BuildContext context, [bool wasAdded = true]) { return SelectState.toggle; } + + @override + Offset getPointerPosition(Offset position, Size viewportSize) { + return Offset( + (position.dx / data.xSize).round() * data.xSize, + (position.dy / data.ySize).round() * data.ySize, + ); + } } class GridRenderer extends Renderer { diff --git a/app/lib/handlers/handler.dart b/app/lib/handlers/handler.dart index 6e14674fd7ba..c815d6cc5452 100644 --- a/app/lib/handlers/handler.dart +++ b/app/lib/handlers/handler.dart @@ -474,3 +474,19 @@ abstract class PastingHandler extends Handler { bool get currentlyPasting => _firstPos != null && _secondPos != null; } + +mixin PointerManipulationHandler on Handler { + Offset getPointerPosition(Offset position, Size viewportSize) { + return position; + } + + static Offset calculatePointerPosition( + CurrentIndex index, Offset position, Size viewportSize) { + return index.toggleableHandlers.values + .whereType() + .map((e) => e.getPointerPosition(position, viewportSize)) + .where((e) => e != position) + .firstOrNull ?? + position; + } +} diff --git a/app/lib/handlers/laser.dart b/app/lib/handlers/laser.dart index 3df076427f7e..8dca78ea04ab 100644 --- a/app/lib/handlers/laser.dart +++ b/app/lib/handlers/laser.dart @@ -111,8 +111,8 @@ class LaserHandler extends Handler with ColoredHandler { final state = bloc.state as DocumentLoadSuccess; final settings = context.read().state; final penOnlyInput = settings.penOnlyInput; - localPosition = - viewport.utilities.getPointerPosition(localPosition, currentIndexCubit); + localPosition = PointerManipulationHandler.calculatePointerPosition( + currentIndexCubit.state, localPosition, viewport.toSize()); if (penOnlyInput && kind != PointerDeviceKind.stylus) { return; } diff --git a/app/lib/handlers/path_eraser.dart b/app/lib/handlers/path_eraser.dart index 9c4682781f49..0089a017860f 100644 --- a/app/lib/handlers/path_eraser.dart +++ b/app/lib/handlers/path_eraser.dart @@ -43,7 +43,7 @@ class PathEraserHandler extends Handler { _currentPos = event.localPosition; final currentIndex = context.getCurrentIndex(); final transform = currentIndex.transformCubit.state; - final utilities = currentIndex.utilitiesState; + final utilities = currentIndex.utilities; final state = context.getState(); final globalPos = transform.localToGlobal(event.localPosition); final size = data.strokeWidth; diff --git a/app/lib/handlers/pen.dart b/app/lib/handlers/pen.dart index 85b401c0915e..78b9774f5dcd 100644 --- a/app/lib/handlers/pen.dart +++ b/app/lib/handlers/pen.dart @@ -81,8 +81,8 @@ class PenHandler extends Handler with ColoredHandler { final currentIndexCubit = context.read(); final viewport = currentIndexCubit.state.cameraViewport; final transform = context.read().state; - localPos = - viewport.utilities.getPointerPosition(localPos, currentIndexCubit); + localPos = PointerManipulationHandler.calculatePointerPosition( + currentIndexCubit.state, localPos, viewport.toSize()); final globalPos = transform.localToGlobal(localPos); if (!bloc.isInBounds(globalPos)) return; final state = bloc.state as DocumentLoadSuccess; diff --git a/app/lib/handlers/ruler.dart b/app/lib/handlers/ruler.dart index 58ca7c378d7a..8eceaee52f4d 100644 --- a/app/lib/handlers/ruler.dart +++ b/app/lib/handlers/ruler.dart @@ -1,9 +1,23 @@ part of 'handler.dart'; -class RulerHandler extends Handler { +Rect _getRulerRect(Size size, + [CameraTransform transform = const CameraTransform()]) { + const rulerSize = 100.0; + return Rect.fromLTWH( + transform.position.dx, + transform.position.dy + (size.height / 2 + -rulerSize / 2) / transform.size, + size.width / transform.size, + rulerSize / transform.size, + ); +} + +class RulerHandler extends Handler with PointerManipulationHandler { Offset _position = Offset.zero; double _rotation = 0; + Offset get position => _position; + double get rotation => _rotation; + RulerHandler(super.data); @override @@ -19,14 +33,44 @@ class RulerHandler extends Handler { return SelectState.toggle; } - void move(Offset offset, EventContext context) { - _position = offset; + void transform( + EventContext context, { + Offset? position, + double? rotation, + }) { + if (position != null) { + _position = position; + } + if (rotation != null) { + _rotation = rotation; + } context.refresh(); } - void rotate(double rotation, EventContext context) { - _rotation = rotation; - context.refresh(); + bool isPointerInside(Offset position, Size viewportSize) { + final rect = _getRulerRect(viewportSize); + // Check if the position is inside the ruler rect, consider rotation + final rotatedPosition = position.rotate(rect.center, -_rotation); + return rect.contains(rotatedPosition); + } + + @override + Offset getPointerPosition(Offset position, Size viewportSize) { + if (!isPointerInside(position, viewportSize)) { + return _position; + } + final rotatedPosition = position.rotate(_position, _rotation); + return Offset( + _position.dx + (rotatedPosition.dx - _position.dx).roundToDouble(), + _position.dy + (rotatedPosition.dy - _position.dy).roundToDouble(), + ); + } + + static RulerHandler? getFirstRuler( + CurrentIndex index, Offset position, Size viewportSize) { + return index.toggleableHandlers.values + .whereType() + .firstWhereOrNull((e) => e.isPointerInside(position, viewportSize)); } } @@ -41,17 +85,6 @@ class RulerRenderer extends Renderer { this.rotation = 0, }); - Rect getRulerRect(Size size, CameraTransform transform) { - const rulerSize = 100.0; - return Rect.fromLTWH( - transform.position.dx, - transform.position.dy + - (size.height / 2 + -rulerSize / 2) / transform.size, - size.width / transform.size, - rulerSize / transform.size, - ); - } - @override void build(Canvas canvas, Size size, NoteData document, DocumentPage page, DocumentInfo info, CameraTransform transform, @@ -69,7 +102,7 @@ class RulerRenderer extends Renderer { ..color = rulerBackgroundColor ..style = PaintingStyle.fill; final rulerForegroundPaint = Paint()..color = rulerForegroundColor; - final rulerRect = getRulerRect(size, transform); + final rulerRect = _getRulerRect(size, transform); // Calculate steps based on zoom level var steps = 50; diff --git a/app/lib/handlers/select.dart b/app/lib/handlers/select.dart index ceb2ea4395d0..d6ee6d5b0465 100644 --- a/app/lib/handlers/select.dart +++ b/app/lib/handlers/select.dart @@ -182,7 +182,7 @@ class SelectHandler extends Handler { if (_selectionManager.isTransforming) { return; } - final utilities = context.getCurrentIndex().utilitiesState; + final utilities = context.getCurrentIndex().utilities; final transform = context.getCameraTransform(); final globalPos = transform.localToGlobal(localPosition); final selectionRect = getSelectionRect(); @@ -285,19 +285,10 @@ class SelectHandler extends Handler { context.refresh(); } - double? _rulerRotation; - Offset? _rulerPosition; - @override bool onScaleStart(ScaleStartDetails details, EventContext context) { - final viewport = context.getCameraViewport(); - if (viewport.utilities - .hitRuler(details.localFocalPoint, viewport.toSize())) { - _rulerRotation = 0; - _rulerPosition = details.localFocalPoint; - return true; - } final currentIndex = context.getCurrentIndex(); + _ruler = false; if (currentIndex.buttons == kSecondaryMouseButton && currentIndex.temporaryHandler == null) { return false; @@ -323,39 +314,33 @@ class SelectHandler extends Handler { event.kind == PointerDeviceKind.mouse && event.buttons != kSecondaryMouseButton; - /*void _handleRuler(ScaleUpdateDetails details, EventContext context) { + bool _ruler = false; + + bool _handleRuler(ScaleUpdateDetails details, EventContext context) { + _ruler = true; final state = context.getState(); - if (state == null) return; - final viewport = context.getCameraViewport(); - var utilitiesState = viewport.utilities.element; - final currentRotation = details.rotation * 180 / pi * details.scale; - final delta = currentRotation - _rulerRotation!; - var angle = utilitiesState.rulerAngle + delta; + if (state == null) return false; + final ruler = RulerHandler.getFirstRuler(context.getCurrentIndex(), + details.localFocalPoint, context.viewportSize); + if (ruler == null) return false; + //final currentRotation = ruler.rotation * 180 / pi * details.scale; + final delta = details.rotation; + var angle = ruler.rotation + delta; while (angle < 0) { angle += 360; } angle %= 360; final currentPos = details.localFocalPoint; - utilitiesState = utilitiesState.copyWith( - rulerPosition: utilitiesState.rulerPosition + - Point( - currentPos.dx - _rulerPosition!.dx, - currentPos.dy - _rulerPosition!.dy, - ), - rulerAngle: angle, - ); - _rulerRotation = currentRotation; - _rulerPosition = currentPos; - context.getCurrentIndexCubit().updateUtilities(utilities: utilitiesState); - }*/ + ruler.transform(context, position: currentPos, rotation: angle); + return true; + } @override void onScaleUpdate(ScaleUpdateDetails details, EventContext context) { if (details.pointerCount > 1) return; final globalPos = context.getCameraTransform().localToGlobal(details.localFocalPoint); - if (_rulerRotation != null && _rulerPosition != null) { - //_handleRuler(details, context); + if (_handleRuler(details, context)) { return; } if (_selectionManager.isTransforming) { @@ -381,11 +366,10 @@ class SelectHandler extends Handler { @override void onScaleEnd(ScaleEndDetails details, EventContext context) async { - final utilities = context.getCurrentIndex().utilitiesState; + final utilities = context.getCurrentIndex().utilities; final rectangleSelection = _rectangleFreeSelection?.normalized(); final lassoSelection = _lassoFreeSelection; - if (_rulerRotation != null) { - _rulerRotation = null; + if (_ruler) { return; } final transformed = _submitTransform(context.getDocumentBloc()); diff --git a/app/lib/models/viewport.dart b/app/lib/models/viewport.dart index 06ab26f6bccd..801756fd6d33 100644 --- a/app/lib/models/viewport.dart +++ b/app/lib/models/viewport.dart @@ -10,7 +10,6 @@ import 'package:flutter/material.dart'; class CameraViewport extends Equatable { final ui.Image? image, belowLayerImage, aboveLayerImage; final List> backgrounds; - final UtilitiesRenderer utilities; final List> bakedElements, unbakedElements, visibleElements; @@ -19,7 +18,7 @@ class CameraViewport extends Equatable { final double scale; final double x, y; - const CameraViewport.unbaked(this.utilities, + const CameraViewport.unbaked( [this.backgrounds = const [], this.unbakedElements = const [], List>? visibleElements]) @@ -35,7 +34,7 @@ class CameraViewport extends Equatable { y = 0, visibleElements = visibleElements ?? unbakedElements; - const CameraViewport.baked(this.utilities, + const CameraViewport.baked( {this.backgrounds = const [], required this.image, this.belowLayerImage, @@ -80,7 +79,6 @@ class CameraViewport extends Equatable { CameraViewport withUnbaked(List> unbakedElements, [List>? backgrounds]) => CameraViewport.baked( - utilities, backgrounds: backgrounds ?? this.backgrounds, image: image, width: width, @@ -99,12 +97,10 @@ class CameraViewport extends Equatable { CameraViewport unbake({ List>? backgrounds, - UtilitiesRenderer? utilities, List>? unbakedElements, List>? visibleElements, }) => CameraViewport.unbaked( - utilities ?? this.utilities, backgrounds ?? this.backgrounds, unbakedElements ?? (List>.from(this.unbakedElements) @@ -129,7 +125,6 @@ class CameraViewport extends Equatable { double y = 0, }) => CameraViewport.baked( - utilities, backgrounds: backgrounds, image: image, width: width, @@ -146,7 +141,6 @@ class CameraViewport extends Equatable { ); CameraViewport withoutLayers() => CameraViewport.baked( - utilities, backgrounds: backgrounds, image: image, width: width, @@ -164,25 +158,6 @@ class CameraViewport extends Equatable { CameraViewport withBackgrounds(List> backgrounds) => CameraViewport.baked( - utilities, - backgrounds: backgrounds, - pixelRatio: pixelRatio, - image: image, - width: width, - height: height, - scale: scale, - bakedElements: bakedElements, - unbakedElements: unbakedElements, - x: x, - y: y, - visibleElements: visibleElements, - aboveLayerImage: aboveLayerImage, - belowLayerImage: belowLayerImage, - ); - - CameraViewport withUtilities(UtilitiesRenderer utilities) => - CameraViewport.baked( - utilities, backgrounds: backgrounds, pixelRatio: pixelRatio, image: image, @@ -211,7 +186,6 @@ class CameraViewport extends Equatable { y, pixelRatio, visibleElements, - utilities, aboveLayerImage, belowLayerImage, ]; diff --git a/app/lib/renderers/renderer.dart b/app/lib/renderers/renderer.dart index 4be18c784e7c..b85b0b69286d 100644 --- a/app/lib/renderers/renderer.dart +++ b/app/lib/renderers/renderer.dart @@ -22,7 +22,6 @@ import 'package:perfect_freehand/perfect_freehand.dart' as freehand; import 'package:phosphor_flutter/phosphor_flutter.dart'; import 'package:xml/xml.dart'; -import '../cubits/current_index.dart'; import '../cubits/transform.dart'; import '../helpers/xml.dart'; import '../models/label.dart'; @@ -40,7 +39,6 @@ part 'elements/path.dart'; part 'elements/pen.dart'; part 'elements/shape.dart'; part 'elements/svg.dart'; -part 'utilities.dart'; class DefaultHitCalculator extends HitCalculator { final Rect? rect; @@ -160,10 +158,6 @@ abstract class Renderer { } as Renderer; } - if (element is UtilitiesState) { - return UtilitiesRenderer(element) as Renderer; - } - throw Exception('Invalid instance type'); } diff --git a/app/lib/renderers/utilities.dart b/app/lib/renderers/utilities.dart deleted file mode 100644 index 45e71f241f7f..000000000000 --- a/app/lib/renderers/utilities.dart +++ /dev/null @@ -1,159 +0,0 @@ -part of 'renderer.dart'; - -class UtilitiesRenderer extends Renderer { - final ViewOption option; - - UtilitiesRenderer( - [super.element = const UtilitiesState(), - this.option = const ViewOption()]); - - Rect getRulerRect(Size size) { - const rulerSize = 100.0; - return Rect.fromLTWH( - -size.width, - -rulerSize / 2, - size.width * 2, - rulerSize, - ); - } - - bool hitRuler(Offset position, Size size) { - return false; - /*if (!element.rulerEnabled) return false; - final rulerRect = getRulerRect(size).translate( - size.width / 2 + element.rulerPosition.x, - size.height / 2 + element.rulerPosition.y); - return rulerRect.contains(position.rotate( - element.rulerPosition - .toOffset() - .translate(size.width / 2, size.height / 2), - -element.rulerAngle * pi / 180));*/ - } - - @override - void build(Canvas canvas, Size size, NoteData document, DocumentPage page, - DocumentInfo info, CameraTransform transform, - [ColorScheme? colorScheme, bool foreground = false]) { - /* - if (element.rulerEnabled) { - final rulerColor = colorScheme?.primary ?? Colors.grey; - final rulerBackgroundColor = - (colorScheme?.primaryContainer ?? Colors.grey).withAlpha(200); - final rulerForegroundColor = colorScheme?.onPrimary ?? Colors.white; - final rulerPaint = Paint() - ..color = rulerColor - ..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); - - // Calculate steps based on zoom level - var steps = 10; - - // Paint ruler background - canvas.save(); - canvas.translate(transform.position.dx, transform.position.dy); - canvas.scale(1 / transform.size, 1 / transform.size); - canvas.translate(size.width / 2 + element.rulerPosition.x, - size.height / 2 + element.rulerPosition.y); - canvas.rotate(element.rulerAngle * pi / 180); - 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, - ); - - // Paint ruler lines - int x = 0; - var placeTextBottom = false; - while (x < size.width * 2) { - // Disable text for now - //final realX = x - (size.width / 2 ~/ steps) * steps; - final posX = - x + (transform.position.dx * transform.size) % steps - size.width; - canvas.drawLine( - Offset(posX, rulerRect.top), - Offset( - posX, - rulerRect.top + - (placeTextBottom - ? rulerRect.height / 8 - : rulerRect.height / 4)), - rulerForegroundPaint, - ); - /*if (realX >= 0 && realX < size.width) { - final textPainter = TextPainter( - textDirection: TextDirection.ltr, - textAlign: TextAlign.center, - text: TextSpan( - text: realX.toString(), - style: TextStyle(color: colorScheme?.onPrimary ?? Colors.white), - ), - ); - textPainter.layout(); - textPainter.paint( - canvas, - Offset( - posX - textPainter.width / 2, - rulerRect.top + - 10 + - (placeTextBottom - ? rulerRect.height / 8 - : rulerRect.height / 4))); - }*/ - placeTextBottom = !placeTextBottom; - x += steps; - } - canvas.restore(); - }*/ - } - - Offset getPointerPosition(Offset position, CurrentIndexCubit cubit) { - /* if (!element.rulerEnabled) */ return position; - /* final size = cubit.state.cameraViewport.toSize(); - final rulerRect = getRulerRect(size).translate( - size.width / 2 + element.rulerPosition.x, - size.height / 2 + element.rulerPosition.y); - final pivot = element.rulerPosition - .toOffset() - .translate(size.width / 2, size.height / 2); - final angle = element.rulerAngle * 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; */ - } - - Offset getGridPosition(Offset position, DocumentPage page, DocumentInfo info, - CurrentIndexCubit cubit) { - /* if (!element.gridEnabled) */ return position; - /* final transform = cubit.state.transformCubit.state; - final localPosition = transform.globalToLocal(position); - final option = info.view; - final x = (localPosition.dx ~/ option.gridXSize) * option.gridXSize; - final y = (localPosition.dy ~/ option.gridYSize) * option.gridYSize; - return transform.localToGlobal(Offset(x, y)); */ - } -} diff --git a/app/lib/selections/utilities.dart b/app/lib/selections/file.dart similarity index 99% rename from app/lib/selections/utilities.dart rename to app/lib/selections/file.dart index 93f6ddad8175..c22fa438f6ed 100644 --- a/app/lib/selections/utilities.dart +++ b/app/lib/selections/file.dart @@ -1,7 +1,7 @@ part of 'selection.dart'; -class UtilitiesSelection extends Selection { - UtilitiesSelection(super.selected); +class FileSelection extends Selection { + FileSelection() : super([null]); @override IconGetter get icon => PhosphorIcons.wrench; @@ -20,7 +20,7 @@ class UtilitiesSelection extends Selection { return [ ...super.buildProperties(context), _UtilitiesView( - state: selected.first, + state: currentIndex.utilities, option: currentIndex.viewOption, onStateChanged: (state) => cubit.updateUtilities(utilities: state), onToolChanged: (option) => cubit.updateUtilities(view: option), diff --git a/app/lib/selections/selection.dart b/app/lib/selections/selection.dart index 0abf448a3bf3..562d4ad5650d 100644 --- a/app/lib/selections/selection.dart +++ b/app/lib/selections/selection.dart @@ -46,7 +46,7 @@ part 'properties/path.dart'; part 'properties/pen.dart'; part 'area.dart'; -part 'utilities.dart'; +part 'file.dart'; abstract class Selection { List _selected; @@ -65,8 +65,8 @@ abstract class Selection { if (selected is Area) { return AreaSelection([selected]) as Selection; } - if (selected is UtilitiesState) { - return UtilitiesSelection([selected]) as Selection; + if (selected == null) { + return FileSelection() as Selection; } throw UnsupportedError('Unsupported selection type: $T'); } diff --git a/app/lib/view_painter.dart b/app/lib/view_painter.dart index 119962f41875..eea11f3948e2 100644 --- a/app/lib/view_painter.dart +++ b/app/lib/view_painter.dart @@ -19,11 +19,10 @@ class ForegroundPainter extends CustomPainter { final List renderers; final CameraTransform transform; final Selection? selection; - final Renderer? tool; ForegroundPainter( this.renderers, this.document, this.page, this.info, this.colorScheme, - [this.transform = const CameraTransform(), this.selection, this.tool]); + [this.transform = const CameraTransform(), this.selection]); @override void paint(Canvas canvas, Size size) { @@ -60,10 +59,6 @@ class ForegroundPainter extends CustomPainter { */ _drawSelection(canvas, selection); } - if (tool != null) { - tool!.build( - canvas, size, document, page, info, transform, colorScheme, true); - } } void _drawSelection(Canvas canvas, ElementSelection selection) { @@ -83,7 +78,6 @@ class ForegroundPainter extends CustomPainter { oldDelegate.renderers != renderers || oldDelegate.transform != transform || oldDelegate.selection != selection || - oldDelegate.tool != tool || oldDelegate.colorScheme != colorScheme; } diff --git a/app/lib/views/edit.dart b/app/lib/views/edit.dart index c4d4d382ce76..5b37119c7c03 100644 --- a/app/lib/views/edit.dart +++ b/app/lib/views/edit.dart @@ -381,8 +381,7 @@ class _EditToolbarState extends State { false, onPressed: () { final cubit = context.read(); - final state = cubit.state.cameraViewport.utilities.element; - cubit.changeSelection(state); + cubit.changeSelection(null); }, ), if (windowState.fullScreen && @@ -396,7 +395,7 @@ class _EditToolbarState extends State { ), BlocBuilder( builder: (context, currentIndex) { - final utilitiesState = currentIndex.utilitiesState; + final utilitiesState = currentIndex.utilities; Widget buildButton( bool selected, UtilitiesState Function() update, diff --git a/app/lib/views/main.dart b/app/lib/views/main.dart index ba7fdd802e17..23a54188c2b6 100644 --- a/app/lib/views/main.dart +++ b/app/lib/views/main.dart @@ -152,7 +152,7 @@ class _ProjectPageState extends State { setState(() { _transformCubit = TransformCubit(); _currentIndexCubit = CurrentIndexCubit(settingsCubit, _transformCubit!, - CameraViewport.unbaked(UtilitiesRenderer()), embedding); + CameraViewport.unbaked(), embedding); _bloc = DocumentBloc( fileSystem, _currentIndexCubit!, @@ -264,7 +264,7 @@ class _ProjectPageState extends State { _currentIndexCubit = CurrentIndexCubit( settingsCubit, _transformCubit!, - CameraViewport.unbaked(UtilitiesRenderer(), backgrounds), + CameraViewport.unbaked(backgrounds), null, networkingService, ); @@ -283,7 +283,7 @@ class _ProjectPageState extends State { _currentIndexCubit = CurrentIndexCubit( settingsCubit, _transformCubit!, - CameraViewport.unbaked(UtilitiesRenderer()), + CameraViewport.unbaked(), null, networkingService, ); diff --git a/app/lib/views/view.dart b/app/lib/views/view.dart index e44e650f8965..145471afdeac 100644 --- a/app/lib/views/view.dart +++ b/app/lib/views/view.dart @@ -449,7 +449,6 @@ class _MainViewViewportState extends State Theme.of(context).colorScheme, frictionTransform, cubit.state.selection, - currentIndex.cameraViewport.utilities, ), painter: ViewPainter( state.data,