diff --git a/api/lib/src/models/tool.dart b/api/lib/src/models/tool.dart index 2eb4ba4ca787..b5906b923b09 100644 --- a/api/lib/src/models/tool.dart +++ b/api/lib/src/models/tool.dart @@ -43,6 +43,8 @@ enum SelectMode { rectangle, lasso } enum LaserAnimation { fade, path } +enum ToolCategory { normal, import, surface, action, view } + @Freezed(equal: false) sealed class Tool with _$Tool { Tool._(); @@ -190,10 +192,50 @@ sealed class Tool with _$Tool { @Default(SurfaceTexture.pattern()) SurfaceTexture texture, }) = TextureTool; + factory Tool.ruler({ + @Default('') String name, + @Default('') String displayIcon, + @Default(SRGBColor.black) @ColorJsonConverter() SRGBColor gridColor, + }) = RulerTool; + + factory Tool.grid({ + @Default('') String name, + @Default('') String displayIcon, + @Default(SRGBColor.black) @ColorJsonConverter() SRGBColor color, + @Default(20) double xSize, + @Default(20) double ySize, + }) = GridTool; + factory Tool.eyeDropper({ @Default('') String name, @Default('') String displayIcon, }) = EyeDropperTool; factory Tool.fromJson(Map json) => _$ToolFromJson(json); + + ToolCategory get category => switch (this) { + SelectTool() => ToolCategory.normal, + HandTool() => ToolCategory.normal, + ImportTool() => ToolCategory.import, + UndoTool() => ToolCategory.action, + RedoTool() => ToolCategory.action, + LabelTool() => ToolCategory.normal, + PenTool() => ToolCategory.normal, + EraserTool() => ToolCategory.normal, + PathEraserTool() => ToolCategory.normal, + CollectionTool() => ToolCategory.normal, + AreaTool() => ToolCategory.normal, + LaserTool() => ToolCategory.normal, + ShapeTool() => ToolCategory.surface, + StampTool() => ToolCategory.surface, + PresentationTool() => ToolCategory.normal, + SpacerTool() => ToolCategory.normal, + FullScreenTool() => ToolCategory.action, + AssetTool() => ToolCategory.import, + ExportTool() => ToolCategory.action, + TextureTool() => ToolCategory.surface, + RulerTool() => ToolCategory.view, + GridTool() => ToolCategory.view, + EyeDropperTool() => ToolCategory.action, + }; } diff --git a/api/lib/src/models/tool.freezed.dart b/api/lib/src/models/tool.freezed.dart index f60eba4d63c2..de96650c80d6 100644 --- a/api/lib/src/models/tool.freezed.dart +++ b/api/lib/src/models/tool.freezed.dart @@ -56,6 +56,10 @@ Tool _$ToolFromJson(Map json) { return ExportTool.fromJson(json); case 'texture': return TextureTool.fromJson(json); + case 'ruler': + return RulerTool.fromJson(json); + case 'grid': + return GridTool.fromJson(json); case 'eyeDropper': return EyeDropperTool.fromJson(json); @@ -2785,6 +2789,272 @@ abstract class TextureTool extends Tool { throw _privateConstructorUsedError; } +/// @nodoc +abstract class _$$RulerToolImplCopyWith<$Res> implements $ToolCopyWith<$Res> { + factory _$$RulerToolImplCopyWith( + _$RulerToolImpl value, $Res Function(_$RulerToolImpl) then) = + __$$RulerToolImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {String name, + String displayIcon, + @ColorJsonConverter() SRGBColor gridColor}); +} + +/// @nodoc +class __$$RulerToolImplCopyWithImpl<$Res> + extends _$ToolCopyWithImpl<$Res, _$RulerToolImpl> + implements _$$RulerToolImplCopyWith<$Res> { + __$$RulerToolImplCopyWithImpl( + _$RulerToolImpl _value, $Res Function(_$RulerToolImpl) _then) + : super(_value, _then); + + /// Create a copy of Tool + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? name = null, + Object? displayIcon = null, + Object? gridColor = null, + }) { + return _then(_$RulerToolImpl( + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + displayIcon: null == displayIcon + ? _value.displayIcon + : displayIcon // ignore: cast_nullable_to_non_nullable + as String, + gridColor: null == gridColor + ? _value.gridColor + : gridColor // ignore: cast_nullable_to_non_nullable + as SRGBColor, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$RulerToolImpl extends RulerTool { + _$RulerToolImpl( + {this.name = '', + this.displayIcon = '', + @ColorJsonConverter() this.gridColor = SRGBColor.black, + final String? $type}) + : $type = $type ?? 'ruler', + super._(); + + factory _$RulerToolImpl.fromJson(Map json) => + _$$RulerToolImplFromJson(json); + + @override + @JsonKey() + final String name; + @override + @JsonKey() + final String displayIcon; + @override + @JsonKey() + @ColorJsonConverter() + final SRGBColor gridColor; + + @JsonKey(name: 'type') + final String $type; + + @override + String toString() { + return 'Tool.ruler(name: $name, displayIcon: $displayIcon, gridColor: $gridColor)'; + } + + /// Create a copy of Tool + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$RulerToolImplCopyWith<_$RulerToolImpl> get copyWith => + __$$RulerToolImplCopyWithImpl<_$RulerToolImpl>(this, _$identity); + + @override + Map toJson() { + return _$$RulerToolImplToJson( + this, + ); + } +} + +abstract class RulerTool extends Tool { + factory RulerTool( + {final String name, + final String displayIcon, + @ColorJsonConverter() final SRGBColor gridColor}) = _$RulerToolImpl; + RulerTool._() : super._(); + + factory RulerTool.fromJson(Map json) = + _$RulerToolImpl.fromJson; + + @override + String get name; + @override + String get displayIcon; + @ColorJsonConverter() + SRGBColor get gridColor; + + /// Create a copy of Tool + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$RulerToolImplCopyWith<_$RulerToolImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$GridToolImplCopyWith<$Res> implements $ToolCopyWith<$Res> { + factory _$$GridToolImplCopyWith( + _$GridToolImpl value, $Res Function(_$GridToolImpl) then) = + __$$GridToolImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {String name, + String displayIcon, + @ColorJsonConverter() SRGBColor color, + double xSize, + double ySize}); +} + +/// @nodoc +class __$$GridToolImplCopyWithImpl<$Res> + extends _$ToolCopyWithImpl<$Res, _$GridToolImpl> + implements _$$GridToolImplCopyWith<$Res> { + __$$GridToolImplCopyWithImpl( + _$GridToolImpl _value, $Res Function(_$GridToolImpl) _then) + : super(_value, _then); + + /// Create a copy of Tool + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? name = null, + Object? displayIcon = null, + Object? color = null, + Object? xSize = null, + Object? ySize = null, + }) { + return _then(_$GridToolImpl( + name: null == name + ? _value.name + : name // ignore: cast_nullable_to_non_nullable + as String, + displayIcon: null == displayIcon + ? _value.displayIcon + : displayIcon // ignore: cast_nullable_to_non_nullable + as String, + color: null == color + ? _value.color + : color // ignore: cast_nullable_to_non_nullable + as SRGBColor, + xSize: null == xSize + ? _value.xSize + : xSize // ignore: cast_nullable_to_non_nullable + as double, + ySize: null == ySize + ? _value.ySize + : ySize // ignore: cast_nullable_to_non_nullable + as double, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$GridToolImpl extends GridTool { + _$GridToolImpl( + {this.name = '', + this.displayIcon = '', + @ColorJsonConverter() this.color = SRGBColor.black, + this.xSize = 20, + this.ySize = 20, + final String? $type}) + : $type = $type ?? 'grid', + super._(); + + factory _$GridToolImpl.fromJson(Map json) => + _$$GridToolImplFromJson(json); + + @override + @JsonKey() + final String name; + @override + @JsonKey() + final String displayIcon; + @override + @JsonKey() + @ColorJsonConverter() + final SRGBColor color; + @override + @JsonKey() + final double xSize; + @override + @JsonKey() + final double ySize; + + @JsonKey(name: 'type') + final String $type; + + @override + String toString() { + return 'Tool.grid(name: $name, displayIcon: $displayIcon, color: $color, xSize: $xSize, ySize: $ySize)'; + } + + /// Create a copy of Tool + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$GridToolImplCopyWith<_$GridToolImpl> get copyWith => + __$$GridToolImplCopyWithImpl<_$GridToolImpl>(this, _$identity); + + @override + Map toJson() { + return _$$GridToolImplToJson( + this, + ); + } +} + +abstract class GridTool extends Tool { + factory GridTool( + {final String name, + final String displayIcon, + @ColorJsonConverter() final SRGBColor color, + final double xSize, + final double ySize}) = _$GridToolImpl; + GridTool._() : super._(); + + factory GridTool.fromJson(Map json) = + _$GridToolImpl.fromJson; + + @override + String get name; + @override + String get displayIcon; + @ColorJsonConverter() + SRGBColor get color; + double get xSize; + double get ySize; + + /// Create a copy of Tool + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$GridToolImplCopyWith<_$GridToolImpl> get copyWith => + throw _privateConstructorUsedError; +} + /// @nodoc abstract class _$$EyeDropperToolImplCopyWith<$Res> implements $ToolCopyWith<$Res> { diff --git a/api/lib/src/models/tool.g.dart b/api/lib/src/models/tool.g.dart index b9e66350ce09..460514d1ecf7 100644 --- a/api/lib/src/models/tool.g.dart +++ b/api/lib/src/models/tool.g.dart @@ -424,6 +424,45 @@ Map _$$TextureToolImplToJson(_$TextureToolImpl instance) => 'type': instance.$type, }; +_$RulerToolImpl _$$RulerToolImplFromJson(Map json) => _$RulerToolImpl( + name: json['name'] as String? ?? '', + displayIcon: json['displayIcon'] as String? ?? '', + gridColor: json['gridColor'] == null + ? SRGBColor.black + : const ColorJsonConverter() + .fromJson((json['gridColor'] as num).toInt()), + $type: json['type'] as String?, + ); + +Map _$$RulerToolImplToJson(_$RulerToolImpl instance) => + { + 'name': instance.name, + 'displayIcon': instance.displayIcon, + 'gridColor': const ColorJsonConverter().toJson(instance.gridColor), + 'type': instance.$type, + }; + +_$GridToolImpl _$$GridToolImplFromJson(Map json) => _$GridToolImpl( + name: json['name'] as String? ?? '', + displayIcon: json['displayIcon'] as String? ?? '', + color: json['color'] == null + ? SRGBColor.black + : const ColorJsonConverter().fromJson((json['color'] as num).toInt()), + xSize: (json['xSize'] as num?)?.toDouble() ?? 20, + ySize: (json['ySize'] as num?)?.toDouble() ?? 20, + $type: json['type'] as String?, + ); + +Map _$$GridToolImplToJson(_$GridToolImpl instance) => + { + 'name': instance.name, + 'displayIcon': instance.displayIcon, + 'color': const ColorJsonConverter().toJson(instance.color), + 'xSize': instance.xSize, + 'ySize': instance.ySize, + 'type': instance.$type, + }; + _$EyeDropperToolImpl _$$EyeDropperToolImplFromJson(Map json) => _$EyeDropperToolImpl( name: json['name'] as String? ?? '', diff --git a/api/lib/src/models/utilities.dart b/api/lib/src/models/utilities.dart index 1c69853daca6..20f77ecddea4 100644 --- a/api/lib/src/models/utilities.dart +++ b/api/lib/src/models/utilities.dart @@ -1,6 +1,3 @@ -import 'dart:math'; - -import 'package:butterfly_api/butterfly_api.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'utilities.g.dart'; @@ -13,13 +10,7 @@ sealed class UtilitiesState with _$UtilitiesState { @Default(false) bool lockZoom, @Default(false) bool lockHorizontal, @Default(false) bool lockVertical, - @Default(false) bool rulerEnabled, - @Default(false) bool gridEnabled, @Default(false) bool fullSelection, - @DoublePointJsonConverter() - @Default(Point(0.0, 0.0)) - Point rulerPosition, - @Default(0) double rulerAngle, }) = _UtilitiesState; factory UtilitiesState.fromJson(Map json) => diff --git a/api/lib/src/models/utilities.freezed.dart b/api/lib/src/models/utilities.freezed.dart index f013d77e3d5e..5a80382878a2 100644 --- a/api/lib/src/models/utilities.freezed.dart +++ b/api/lib/src/models/utilities.freezed.dart @@ -24,12 +24,7 @@ mixin _$UtilitiesState { bool get lockZoom => throw _privateConstructorUsedError; bool get lockHorizontal => throw _privateConstructorUsedError; bool get lockVertical => throw _privateConstructorUsedError; - bool get rulerEnabled => throw _privateConstructorUsedError; - bool get gridEnabled => throw _privateConstructorUsedError; bool get fullSelection => throw _privateConstructorUsedError; - @DoublePointJsonConverter() - Point get rulerPosition => throw _privateConstructorUsedError; - double get rulerAngle => throw _privateConstructorUsedError; /// Serializes this UtilitiesState to a JSON map. Map toJson() => throw _privateConstructorUsedError; @@ -52,11 +47,7 @@ abstract class $UtilitiesStateCopyWith<$Res> { bool lockZoom, bool lockHorizontal, bool lockVertical, - bool rulerEnabled, - bool gridEnabled, - bool fullSelection, - @DoublePointJsonConverter() Point rulerPosition, - double rulerAngle}); + bool fullSelection}); } /// @nodoc @@ -78,11 +69,7 @@ class _$UtilitiesStateCopyWithImpl<$Res, $Val extends UtilitiesState> Object? lockZoom = null, Object? lockHorizontal = null, Object? lockVertical = null, - Object? rulerEnabled = null, - Object? gridEnabled = null, Object? fullSelection = null, - Object? rulerPosition = null, - Object? rulerAngle = null, }) { return _then(_value.copyWith( lockCollection: null == lockCollection @@ -101,26 +88,10 @@ class _$UtilitiesStateCopyWithImpl<$Res, $Val extends UtilitiesState> ? _value.lockVertical : lockVertical // ignore: cast_nullable_to_non_nullable as bool, - rulerEnabled: null == rulerEnabled - ? _value.rulerEnabled - : rulerEnabled // ignore: cast_nullable_to_non_nullable - as bool, - gridEnabled: null == gridEnabled - ? _value.gridEnabled - : gridEnabled // ignore: cast_nullable_to_non_nullable - as bool, fullSelection: null == fullSelection ? _value.fullSelection : fullSelection // ignore: cast_nullable_to_non_nullable as bool, - rulerPosition: null == rulerPosition - ? _value.rulerPosition - : rulerPosition // ignore: cast_nullable_to_non_nullable - as Point, - rulerAngle: null == rulerAngle - ? _value.rulerAngle - : rulerAngle // ignore: cast_nullable_to_non_nullable - as double, ) as $Val); } } @@ -138,11 +109,7 @@ abstract class _$$UtilitiesStateImplCopyWith<$Res> bool lockZoom, bool lockHorizontal, bool lockVertical, - bool rulerEnabled, - bool gridEnabled, - bool fullSelection, - @DoublePointJsonConverter() Point rulerPosition, - double rulerAngle}); + bool fullSelection}); } /// @nodoc @@ -162,11 +129,7 @@ class __$$UtilitiesStateImplCopyWithImpl<$Res> Object? lockZoom = null, Object? lockHorizontal = null, Object? lockVertical = null, - Object? rulerEnabled = null, - Object? gridEnabled = null, Object? fullSelection = null, - Object? rulerPosition = null, - Object? rulerAngle = null, }) { return _then(_$UtilitiesStateImpl( lockCollection: null == lockCollection @@ -185,26 +148,10 @@ class __$$UtilitiesStateImplCopyWithImpl<$Res> ? _value.lockVertical : lockVertical // ignore: cast_nullable_to_non_nullable as bool, - rulerEnabled: null == rulerEnabled - ? _value.rulerEnabled - : rulerEnabled // ignore: cast_nullable_to_non_nullable - as bool, - gridEnabled: null == gridEnabled - ? _value.gridEnabled - : gridEnabled // ignore: cast_nullable_to_non_nullable - as bool, fullSelection: null == fullSelection ? _value.fullSelection : fullSelection // ignore: cast_nullable_to_non_nullable as bool, - rulerPosition: null == rulerPosition - ? _value.rulerPosition - : rulerPosition // ignore: cast_nullable_to_non_nullable - as Point, - rulerAngle: null == rulerAngle - ? _value.rulerAngle - : rulerAngle // ignore: cast_nullable_to_non_nullable - as double, )); } } @@ -217,11 +164,7 @@ class _$UtilitiesStateImpl implements _UtilitiesState { this.lockZoom = false, this.lockHorizontal = false, this.lockVertical = false, - this.rulerEnabled = false, - this.gridEnabled = false, - this.fullSelection = false, - @DoublePointJsonConverter() this.rulerPosition = const Point(0.0, 0.0), - this.rulerAngle = 0}); + this.fullSelection = false}); factory _$UtilitiesStateImpl.fromJson(Map json) => _$$UtilitiesStateImplFromJson(json); @@ -240,24 +183,11 @@ class _$UtilitiesStateImpl implements _UtilitiesState { final bool lockVertical; @override @JsonKey() - final bool rulerEnabled; - @override - @JsonKey() - final bool gridEnabled; - @override - @JsonKey() final bool fullSelection; - @override - @JsonKey() - @DoublePointJsonConverter() - final Point rulerPosition; - @override - @JsonKey() - final double rulerAngle; @override String toString() { - return 'UtilitiesState(lockCollection: $lockCollection, lockZoom: $lockZoom, lockHorizontal: $lockHorizontal, lockVertical: $lockVertical, rulerEnabled: $rulerEnabled, gridEnabled: $gridEnabled, fullSelection: $fullSelection, rulerPosition: $rulerPosition, rulerAngle: $rulerAngle)'; + return 'UtilitiesState(lockCollection: $lockCollection, lockZoom: $lockZoom, lockHorizontal: $lockHorizontal, lockVertical: $lockVertical, fullSelection: $fullSelection)'; } @override @@ -273,31 +203,14 @@ class _$UtilitiesStateImpl implements _UtilitiesState { other.lockHorizontal == lockHorizontal) && (identical(other.lockVertical, lockVertical) || other.lockVertical == lockVertical) && - (identical(other.rulerEnabled, rulerEnabled) || - other.rulerEnabled == rulerEnabled) && - (identical(other.gridEnabled, gridEnabled) || - other.gridEnabled == gridEnabled) && (identical(other.fullSelection, fullSelection) || - other.fullSelection == fullSelection) && - (identical(other.rulerPosition, rulerPosition) || - other.rulerPosition == rulerPosition) && - (identical(other.rulerAngle, rulerAngle) || - other.rulerAngle == rulerAngle)); + other.fullSelection == fullSelection)); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => Object.hash( - runtimeType, - lockCollection, - lockZoom, - lockHorizontal, - lockVertical, - rulerEnabled, - gridEnabled, - fullSelection, - rulerPosition, - rulerAngle); + int get hashCode => Object.hash(runtimeType, lockCollection, lockZoom, + lockHorizontal, lockVertical, fullSelection); /// Create a copy of UtilitiesState /// with the given fields replaced by the non-null parameter values. @@ -322,11 +235,7 @@ abstract class _UtilitiesState implements UtilitiesState { final bool lockZoom, final bool lockHorizontal, final bool lockVertical, - final bool rulerEnabled, - final bool gridEnabled, - final bool fullSelection, - @DoublePointJsonConverter() final Point rulerPosition, - final double rulerAngle}) = _$UtilitiesStateImpl; + final bool fullSelection}) = _$UtilitiesStateImpl; factory _UtilitiesState.fromJson(Map json) = _$UtilitiesStateImpl.fromJson; @@ -340,16 +249,7 @@ abstract class _UtilitiesState implements UtilitiesState { @override bool get lockVertical; @override - bool get rulerEnabled; - @override - bool get gridEnabled; - @override bool get fullSelection; - @override - @DoublePointJsonConverter() - Point get rulerPosition; - @override - double get rulerAngle; /// Create a copy of UtilitiesState /// with the given fields replaced by the non-null parameter values. diff --git a/api/lib/src/models/utilities.g.dart b/api/lib/src/models/utilities.g.dart index aab0ef0f57ff..f15c4bfd5692 100644 --- a/api/lib/src/models/utilities.g.dart +++ b/api/lib/src/models/utilities.g.dart @@ -12,14 +12,7 @@ _$UtilitiesStateImpl _$$UtilitiesStateImplFromJson(Map json) => lockZoom: json['lockZoom'] as bool? ?? false, lockHorizontal: json['lockHorizontal'] as bool? ?? false, lockVertical: json['lockVertical'] as bool? ?? false, - rulerEnabled: json['rulerEnabled'] as bool? ?? false, - gridEnabled: json['gridEnabled'] as bool? ?? false, fullSelection: json['fullSelection'] as bool? ?? false, - rulerPosition: json['rulerPosition'] == null - ? const Point(0.0, 0.0) - : const DoublePointJsonConverter() - .fromJson(json['rulerPosition'] as Map), - rulerAngle: (json['rulerAngle'] as num?)?.toDouble() ?? 0, ); Map _$$UtilitiesStateImplToJson( @@ -29,10 +22,5 @@ Map _$$UtilitiesStateImplToJson( 'lockZoom': instance.lockZoom, 'lockHorizontal': instance.lockHorizontal, 'lockVertical': instance.lockVertical, - 'rulerEnabled': instance.rulerEnabled, - 'gridEnabled': instance.gridEnabled, 'fullSelection': instance.fullSelection, - 'rulerPosition': - const DoublePointJsonConverter().toJson(instance.rulerPosition), - 'rulerAngle': instance.rulerAngle, }; diff --git a/api/lib/src/models/view.dart b/api/lib/src/models/view.dart index 856f0f311eb7..9fc6f1cb3edb 100644 --- a/api/lib/src/models/view.dart +++ b/api/lib/src/models/view.dart @@ -1,5 +1,3 @@ -import 'package:butterfly_api/src/converter/color.dart'; -import 'package:dart_leap/dart_leap.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'view.freezed.dart'; @@ -7,11 +5,7 @@ part 'view.g.dart'; @freezed sealed class ViewOption with _$ViewOption { - const factory ViewOption({ - @Default(SRGBColor.black) @ColorJsonConverter() SRGBColor gridColor, - @Default(20) double gridXSize, - @Default(20) double gridYSize, - }) = _ViewOption; + const factory ViewOption() = _ViewOption; factory ViewOption.fromJson(Map json) => _$ViewOptionFromJson(json); diff --git a/api/lib/src/models/view.freezed.dart b/api/lib/src/models/view.freezed.dart index 46e8ee9913b6..294cca6ceb2a 100644 --- a/api/lib/src/models/view.freezed.dart +++ b/api/lib/src/models/view.freezed.dart @@ -20,19 +20,8 @@ ViewOption _$ViewOptionFromJson(Map json) { /// @nodoc mixin _$ViewOption { - @ColorJsonConverter() - SRGBColor get gridColor => throw _privateConstructorUsedError; - double get gridXSize => throw _privateConstructorUsedError; - double get gridYSize => throw _privateConstructorUsedError; - /// Serializes this ViewOption to a JSON map. Map toJson() => throw _privateConstructorUsedError; - - /// Create a copy of ViewOption - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - $ViewOptionCopyWith get copyWith => - throw _privateConstructorUsedError; } /// @nodoc @@ -40,11 +29,6 @@ abstract class $ViewOptionCopyWith<$Res> { factory $ViewOptionCopyWith( ViewOption value, $Res Function(ViewOption) then) = _$ViewOptionCopyWithImpl<$Res, ViewOption>; - @useResult - $Res call( - {@ColorJsonConverter() SRGBColor gridColor, - double gridXSize, - double gridYSize}); } /// @nodoc @@ -59,42 +43,13 @@ class _$ViewOptionCopyWithImpl<$Res, $Val extends ViewOption> /// Create a copy of ViewOption /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? gridColor = null, - Object? gridXSize = null, - Object? gridYSize = null, - }) { - return _then(_value.copyWith( - gridColor: null == gridColor - ? _value.gridColor - : gridColor // ignore: cast_nullable_to_non_nullable - as SRGBColor, - gridXSize: null == gridXSize - ? _value.gridXSize - : gridXSize // ignore: cast_nullable_to_non_nullable - as double, - gridYSize: null == gridYSize - ? _value.gridYSize - : gridYSize // ignore: cast_nullable_to_non_nullable - as double, - ) as $Val); - } } /// @nodoc -abstract class _$$ViewOptionImplCopyWith<$Res> - implements $ViewOptionCopyWith<$Res> { +abstract class _$$ViewOptionImplCopyWith<$Res> { factory _$$ViewOptionImplCopyWith( _$ViewOptionImpl value, $Res Function(_$ViewOptionImpl) then) = __$$ViewOptionImplCopyWithImpl<$Res>; - @override - @useResult - $Res call( - {@ColorJsonConverter() SRGBColor gridColor, - double gridXSize, - double gridYSize}); } /// @nodoc @@ -107,81 +62,30 @@ class __$$ViewOptionImplCopyWithImpl<$Res> /// Create a copy of ViewOption /// with the given fields replaced by the non-null parameter values. - @pragma('vm:prefer-inline') - @override - $Res call({ - Object? gridColor = null, - Object? gridXSize = null, - Object? gridYSize = null, - }) { - return _then(_$ViewOptionImpl( - gridColor: null == gridColor - ? _value.gridColor - : gridColor // ignore: cast_nullable_to_non_nullable - as SRGBColor, - gridXSize: null == gridXSize - ? _value.gridXSize - : gridXSize // ignore: cast_nullable_to_non_nullable - as double, - gridYSize: null == gridYSize - ? _value.gridYSize - : gridYSize // ignore: cast_nullable_to_non_nullable - as double, - )); - } } /// @nodoc @JsonSerializable() class _$ViewOptionImpl implements _ViewOption { - const _$ViewOptionImpl( - {@ColorJsonConverter() this.gridColor = SRGBColor.black, - this.gridXSize = 20, - this.gridYSize = 20}); + const _$ViewOptionImpl(); factory _$ViewOptionImpl.fromJson(Map json) => _$$ViewOptionImplFromJson(json); - @override - @JsonKey() - @ColorJsonConverter() - final SRGBColor gridColor; - @override - @JsonKey() - final double gridXSize; - @override - @JsonKey() - final double gridYSize; - @override String toString() { - return 'ViewOption(gridColor: $gridColor, gridXSize: $gridXSize, gridYSize: $gridYSize)'; + return 'ViewOption()'; } @override bool operator ==(Object other) { return identical(this, other) || - (other.runtimeType == runtimeType && - other is _$ViewOptionImpl && - (identical(other.gridColor, gridColor) || - other.gridColor == gridColor) && - (identical(other.gridXSize, gridXSize) || - other.gridXSize == gridXSize) && - (identical(other.gridYSize, gridYSize) || - other.gridYSize == gridYSize)); + (other.runtimeType == runtimeType && other is _$ViewOptionImpl); } @JsonKey(includeFromJson: false, includeToJson: false) @override - int get hashCode => Object.hash(runtimeType, gridColor, gridXSize, gridYSize); - - /// Create a copy of ViewOption - /// with the given fields replaced by the non-null parameter values. - @JsonKey(includeFromJson: false, includeToJson: false) - @override - @pragma('vm:prefer-inline') - _$$ViewOptionImplCopyWith<_$ViewOptionImpl> get copyWith => - __$$ViewOptionImplCopyWithImpl<_$ViewOptionImpl>(this, _$identity); + int get hashCode => runtimeType.hashCode; @override Map toJson() { @@ -192,26 +96,8 @@ class _$ViewOptionImpl implements _ViewOption { } abstract class _ViewOption implements ViewOption { - const factory _ViewOption( - {@ColorJsonConverter() final SRGBColor gridColor, - final double gridXSize, - final double gridYSize}) = _$ViewOptionImpl; + const factory _ViewOption() = _$ViewOptionImpl; factory _ViewOption.fromJson(Map json) = _$ViewOptionImpl.fromJson; - - @override - @ColorJsonConverter() - SRGBColor get gridColor; - @override - double get gridXSize; - @override - double get gridYSize; - - /// Create a copy of ViewOption - /// with the given fields replaced by the non-null parameter values. - @override - @JsonKey(includeFromJson: false, includeToJson: false) - _$$ViewOptionImplCopyWith<_$ViewOptionImpl> get copyWith => - throw _privateConstructorUsedError; } diff --git a/api/lib/src/models/view.g.dart b/api/lib/src/models/view.g.dart index fd3cea5707eb..72eb0bd27444 100644 --- a/api/lib/src/models/view.g.dart +++ b/api/lib/src/models/view.g.dart @@ -6,18 +6,7 @@ part of 'view.dart'; // JsonSerializableGenerator // ************************************************************************** -_$ViewOptionImpl _$$ViewOptionImplFromJson(Map json) => _$ViewOptionImpl( - gridColor: json['gridColor'] == null - ? SRGBColor.black - : const ColorJsonConverter() - .fromJson((json['gridColor'] as num).toInt()), - gridXSize: (json['gridXSize'] as num?)?.toDouble() ?? 20, - gridYSize: (json['gridYSize'] as num?)?.toDouble() ?? 20, - ); +_$ViewOptionImpl _$$ViewOptionImplFromJson(Map json) => _$ViewOptionImpl(); Map _$$ViewOptionImplToJson(_$ViewOptionImpl instance) => - { - 'gridColor': const ColorJsonConverter().toJson(instance.gridColor), - 'gridXSize': instance.gridXSize, - 'gridYSize': instance.gridYSize, - }; + {}; diff --git a/app/lib/actions/select.dart b/app/lib/actions/select.dart index 4c3214607fa7..4165eb8ec8e8 100644 --- a/app/lib/actions/select.dart +++ b/app/lib/actions/select.dart @@ -25,7 +25,7 @@ class SelectAllAction extends Action { intent.context, SelectTool(), bloc: bloc, - temporaryClicked: true, + temporaryState: TemporaryState.removeAfterClick, ); if (handler is! SelectHandler) return; handler.selectAll(bloc); diff --git a/app/lib/cubits/current_index.dart b/app/lib/cubits/current_index.dart index 45b696be5d44..bd0e9e794261 100644 --- a/app/lib/cubits/current_index.dart +++ b/app/lib/cubits/current_index.dart @@ -37,6 +37,8 @@ enum HideState { visible, keyboard, touch } enum RendererState { visible, temporary, hidden } +enum TemporaryState { allowClick, removeAfterClick, removeAfterRelease } + @Freezed(equal: false) class CurrentIndex with _$CurrentIndex { const CurrentIndex._(); @@ -57,7 +59,7 @@ class CurrentIndex with _$CurrentIndex { @Default({}) Map> toggleableForegrounds, @Default(MouseCursor.defer) MouseCursor cursor, MouseCursor? temporaryCursor, - @Default(false) bool temporaryClicked, + @Default(TemporaryState.allowClick) TemporaryState temporaryState, Offset? lastPosition, @Default([]) List pointers, int? buttons, @@ -501,7 +503,8 @@ class CurrentIndexCubit extends Cubit { } Future changeTemporaryHandlerIndex(BuildContext context, int index, - {DocumentBloc? bloc, bool temporaryClicked = true}) async { + {DocumentBloc? bloc, + TemporaryState temporaryState = TemporaryState.allowClick}) async { bloc ??= context.read(); final blocState = bloc.state; if (blocState is! DocumentLoadSuccess) return null; @@ -513,12 +516,14 @@ class CurrentIndexCubit extends Cubit { context, tool, bloc: bloc, - temporaryClicked: temporaryClicked, + temporaryState: temporaryState, ); } - Future changeTemporaryHandler(BuildContext context, Tool tool, - {DocumentBloc? bloc, bool temporaryClicked = true}) async { + Future?> changeTemporaryHandler( + BuildContext context, T tool, + {DocumentBloc? bloc, + TemporaryState temporaryState = TemporaryState.allowClick}) async { bloc ??= context.read(); final handler = Handler.fromTool(tool); final blocState = bloc.state; @@ -541,7 +546,7 @@ class CurrentIndexCubit extends Cubit { temporaryToolbar: handler.getToolbar(bloc), temporaryCursor: handler.cursor, temporaryRendererStates: handler.rendererStates, - temporaryClicked: temporaryClicked, + temporaryState: temporaryState, )); } return handler; @@ -552,14 +557,22 @@ class CurrentIndexCubit extends Cubit { if (networking) ...state.networkingForegrounds, ]; + void resetReleaseHandler(DocumentBloc bloc) { + if (state.temporaryState == TemporaryState.removeAfterRelease) { + resetTemporaryHandler(bloc, true); + } + } + void resetTemporaryHandler(DocumentBloc bloc, [bool force = false]) { if (state.temporaryHandler == null) { return; } - if (!force && state.temporaryClicked) { - emit(state.copyWith( - temporaryClicked: false, - )); + if (!force && state.temporaryState != TemporaryState.removeAfterClick) { + if (state.temporaryState == TemporaryState.allowClick) { + emit(state.copyWith( + temporaryState: TemporaryState.removeAfterClick, + )); + } return; } state.temporaryHandler?.dispose(bloc); @@ -570,7 +583,6 @@ class CurrentIndexCubit extends Cubit { temporaryToolbar: null, temporaryCursor: null, temporaryRendererStates: null, - temporaryClicked: false, )); } @@ -985,7 +997,6 @@ class CurrentIndexCubit extends Cubit { emit(state.copyWith( temporaryHandler: HandHandler(), temporaryCursor: null, - temporaryClicked: false, )); } diff --git a/app/lib/cubits/current_index.freezed.dart b/app/lib/cubits/current_index.freezed.dart index 854370bbce85..568a03205c24 100644 --- a/app/lib/cubits/current_index.freezed.dart +++ b/app/lib/cubits/current_index.freezed.dart @@ -36,7 +36,7 @@ mixin _$CurrentIndex { throw _privateConstructorUsedError; MouseCursor get cursor => throw _privateConstructorUsedError; MouseCursor? get temporaryCursor => throw _privateConstructorUsedError; - bool get temporaryClicked => throw _privateConstructorUsedError; + TemporaryState get temporaryState => throw _privateConstructorUsedError; ui.Offset? get lastPosition => throw _privateConstructorUsedError; List get pointers => throw _privateConstructorUsedError; int? get buttons => throw _privateConstructorUsedError; @@ -86,7 +86,7 @@ abstract class $CurrentIndexCopyWith<$Res> { Map> toggleableForegrounds, MouseCursor cursor, MouseCursor? temporaryCursor, - bool temporaryClicked, + TemporaryState temporaryState, ui.Offset? lastPosition, List pointers, int? buttons, @@ -137,7 +137,7 @@ class _$CurrentIndexCopyWithImpl<$Res, $Val extends CurrentIndex> Object? toggleableForegrounds = null, Object? cursor = null, Object? temporaryCursor = freezed, - Object? temporaryClicked = null, + Object? temporaryState = null, Object? lastPosition = freezed, Object? pointers = null, Object? buttons = freezed, @@ -219,10 +219,10 @@ class _$CurrentIndexCopyWithImpl<$Res, $Val extends CurrentIndex> ? _value.temporaryCursor : temporaryCursor // ignore: cast_nullable_to_non_nullable as MouseCursor?, - temporaryClicked: null == temporaryClicked - ? _value.temporaryClicked - : temporaryClicked // ignore: cast_nullable_to_non_nullable - as bool, + temporaryState: null == temporaryState + ? _value.temporaryState + : temporaryState // ignore: cast_nullable_to_non_nullable + as TemporaryState, lastPosition: freezed == lastPosition ? _value.lastPosition : lastPosition // ignore: cast_nullable_to_non_nullable @@ -322,7 +322,7 @@ abstract class _$$CurrentIndexImplCopyWith<$Res> Map> toggleableForegrounds, MouseCursor cursor, MouseCursor? temporaryCursor, - bool temporaryClicked, + TemporaryState temporaryState, ui.Offset? lastPosition, List pointers, int? buttons, @@ -372,7 +372,7 @@ class __$$CurrentIndexImplCopyWithImpl<$Res> Object? toggleableForegrounds = null, Object? cursor = null, Object? temporaryCursor = freezed, - Object? temporaryClicked = null, + Object? temporaryState = null, Object? lastPosition = freezed, Object? pointers = null, Object? buttons = freezed, @@ -454,10 +454,10 @@ class __$$CurrentIndexImplCopyWithImpl<$Res> ? _value.temporaryCursor : temporaryCursor // ignore: cast_nullable_to_non_nullable as MouseCursor?, - temporaryClicked: null == temporaryClicked - ? _value.temporaryClicked - : temporaryClicked // ignore: cast_nullable_to_non_nullable - as bool, + temporaryState: null == temporaryState + ? _value.temporaryState + : temporaryState // ignore: cast_nullable_to_non_nullable + as TemporaryState, lastPosition: freezed == lastPosition ? _value.lastPosition : lastPosition // ignore: cast_nullable_to_non_nullable @@ -537,7 +537,7 @@ class _$CurrentIndexImpl extends _CurrentIndex { final Map> toggleableForegrounds = const {}, this.cursor = MouseCursor.defer, this.temporaryCursor, - this.temporaryClicked = false, + this.temporaryState = TemporaryState.allowClick, this.lastPosition, final List pointers = const [], this.buttons, @@ -639,7 +639,7 @@ class _$CurrentIndexImpl extends _CurrentIndex { final MouseCursor? temporaryCursor; @override @JsonKey() - final bool temporaryClicked; + final TemporaryState temporaryState; @override final ui.Offset? lastPosition; final List _pointers; @@ -704,7 +704,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, temporaryClicked: $temporaryClicked, 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, 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 @@ -734,7 +734,7 @@ abstract class _CurrentIndex extends CurrentIndex { final Map> toggleableForegrounds, final MouseCursor cursor, final MouseCursor? temporaryCursor, - final bool temporaryClicked, + final TemporaryState temporaryState, final ui.Offset? lastPosition, final List pointers, final int? buttons, @@ -785,7 +785,7 @@ abstract class _CurrentIndex extends CurrentIndex { @override MouseCursor? get temporaryCursor; @override - bool get temporaryClicked; + TemporaryState get temporaryState; @override ui.Offset? get lastPosition; @override diff --git a/app/lib/dialogs/collections.dart b/app/lib/dialogs/collections.dart index 9b194914fa39..c43fe54a7afe 100644 --- a/app/lib/dialogs/collections.dart +++ b/app/lib/dialogs/collections.dart @@ -1,4 +1,5 @@ import 'package:butterfly/bloc/document_bloc.dart'; +import 'package:butterfly/cubits/current_index.dart'; import 'package:butterfly/dialogs/delete.dart'; import 'package:butterfly/handlers/handler.dart'; import 'package:butterfly_api/butterfly_api.dart'; @@ -97,7 +98,7 @@ class _CollectionsDialogState extends State { context, SelectTool(), bloc: bloc, - temporaryClicked: true, + temporaryState: TemporaryState.removeAfterClick, ); if (handler is! SelectHandler) return; handler.selectAll( diff --git a/app/lib/dialogs/import/add.dart b/app/lib/dialogs/import/add.dart index fe09191b9707..c6ab323a375b 100644 --- a/app/lib/dialogs/import/add.dart +++ b/app/lib/dialogs/import/add.dart @@ -4,7 +4,6 @@ import 'package:butterfly/helpers/color.dart'; import 'package:butterfly/services/import.dart'; import 'package:butterfly/visualizer/element.dart'; import 'package:butterfly/visualizer/tool.dart'; -import 'package:butterfly/visualizer/property.dart'; import 'package:butterfly_api/butterfly_api.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -75,7 +74,10 @@ class _AddDialogState extends State { ), trailing: tool.isAction() ? IconButton( - onPressed: () => handler.onSelected(context), + onPressed: () { + Navigator.of(context).pop(); + handler.onSelected(context, false); + }, icon: const PhosphorIcon(PhosphorIconsLight.playCircle), tooltip: AppLocalizations.of(context).play, ) @@ -157,7 +159,6 @@ class _AddDialogState extends State { () => Tool.select(mode: SelectMode.lasso), () => Tool.select(mode: SelectMode.rectangle), Tool.pen, - Tool.stamp, Tool.laser, Tool.pathEraser, Tool.label, @@ -166,7 +167,6 @@ class _AddDialogState extends State { Tool.presentation, () => Tool.spacer(axis: Axis2D.vertical), () => Tool.spacer(axis: Axis2D.horizontal), - Tool.eyeDropper, ] .map((e) => e()) .where((e) => e @@ -174,13 +174,16 @@ class _AddDialogState extends State { .toLowerCase() .contains(search.toLowerCase())) .toList(); - final shapes = [ - PathShape.circle, - PathShape.rectangle, - PathShape.line, - PathShape.triangle, + final shapes = [ + Tool.stamp(), + ...[ + PathShape.circle, + PathShape.rectangle, + PathShape.line, + PathShape.triangle + ].map((e) => + Tool.shape(property: ShapeProperty(shape: e()))), ] - .map((e) => e()) .where((e) => e .getLocalizedName(context) .toLowerCase() @@ -198,6 +201,7 @@ class _AddDialogState extends State { Tool.redo, Tool.fullScreen, Tool.collection, + Tool.eyeDropper, ] .map((e) => e()) .where((e) => e @@ -278,8 +282,7 @@ class _AddDialogState extends State { ), icon: Icon( e.icon(PhosphorIconsStyle.light)), - onTap: () => addTool(ShapeTool( - property: ShapeProperty(shape: e))), + onTap: () => addTool(e), )), ...textures.map((e) => BoxTile( title: Text( diff --git a/app/lib/handlers/collection.dart b/app/lib/handlers/collection.dart index f9f5d54c283b..43596e13d9fa 100644 --- a/app/lib/handlers/collection.dart +++ b/app/lib/handlers/collection.dart @@ -4,7 +4,7 @@ class CollectionHandler extends Handler { CollectionHandler(super.data); @override - bool onSelected(BuildContext context) { + bool onSelected(BuildContext context, [bool wasAdded = true]) { final bloc = context.read(); showDialog( context: context, diff --git a/app/lib/handlers/export.dart b/app/lib/handlers/export.dart index ee4bb408805d..d14cf11524ee 100644 --- a/app/lib/handlers/export.dart +++ b/app/lib/handlers/export.dart @@ -4,7 +4,7 @@ class ExportHandler extends Handler { ExportHandler(super.data); @override - bool onSelected(BuildContext context) { + bool onSelected(BuildContext context, [bool wasAdded = true]) { final bloc = context.read(); showDialog( context: context, diff --git a/app/lib/handlers/eye_dropper.dart b/app/lib/handlers/eye_dropper.dart index a204cab059c5..08b55243e22f 100644 --- a/app/lib/handlers/eye_dropper.dart +++ b/app/lib/handlers/eye_dropper.dart @@ -3,6 +3,15 @@ part of 'handler.dart'; class EyeDropperHandler extends Handler { EyeDropperHandler(super.data); + @override + bool onSelected(BuildContext context, [bool wasAdded = true]) { + if (!wasAdded) { + context.read().changeTemporaryHandler(context, data, + temporaryState: TemporaryState.removeAfterRelease); + } + return super.onSelected(context); + } + @override void onPointerUp(PointerUpEvent event, EventContext context) async { final globalPos = diff --git a/app/lib/handlers/full_screen.dart b/app/lib/handlers/full_screen.dart index 832c41fb4522..a87ecbd06b2b 100644 --- a/app/lib/handlers/full_screen.dart +++ b/app/lib/handlers/full_screen.dart @@ -4,7 +4,7 @@ class FullScreenHandler extends Handler { FullScreenHandler(super.data); @override - bool onSelected(BuildContext context) { + bool onSelected(BuildContext context, [bool wasAdded = true]) { context.read().toggleFullScreen(); return false; } diff --git a/app/lib/handlers/handler.dart b/app/lib/handlers/handler.dart index 35351a553e8e..7ab3294275f8 100644 --- a/app/lib/handlers/handler.dart +++ b/app/lib/handlers/handler.dart @@ -158,7 +158,7 @@ abstract class Handler { const Handler(this.data); - bool onSelected(BuildContext context) => true; + bool onSelected(BuildContext context, [bool wasAdded = true]) => true; List createForegrounds(CurrentIndexCubit currentIndexCubit, NoteData document, DocumentPage page, DocumentInfo info, @@ -177,7 +177,7 @@ abstract class Handler { void onPointerMove(PointerMoveEvent event, EventContext context) {} - void onPointerUp(PointerUpEvent event, EventContext context) {} + FutureOr onPointerUp(PointerUpEvent event, EventContext context) {} void onPointerHover(PointerHoverEvent event, EventContext context) {} @@ -292,7 +292,7 @@ mixin ColoredHandler on Handler { context, EyeDropperTool(), bloc: bloc, - temporaryClicked: true, + temporaryState: TemporaryState.removeAfterRelease, ); }, ) diff --git a/app/lib/handlers/import.dart b/app/lib/handlers/import.dart index 8c527e8acb95..d36a36aa1d03 100644 --- a/app/lib/handlers/import.dart +++ b/app/lib/handlers/import.dart @@ -61,9 +61,6 @@ class ImportHandler extends Handler { .copyWith(id: createUniqueId())) .nonNulls .toList())); - context - .getCurrentIndexCubit() - .resetTemporaryHandler(context.getDocumentBloc()); context.refresh(); context.bake(); } diff --git a/app/lib/handlers/redo.dart b/app/lib/handlers/redo.dart index 527b7098a638..7c6eb72bb6ba 100644 --- a/app/lib/handlers/redo.dart +++ b/app/lib/handlers/redo.dart @@ -4,7 +4,7 @@ class RedoHandler extends Handler { RedoHandler(super.data); @override - bool onSelected(BuildContext context) { + bool onSelected(BuildContext context, [bool wasAdded = true]) { final bloc = context.read(); bloc.redo(); bloc.load().then((value) => bloc.bake().then((value) => bloc.save())); diff --git a/app/lib/handlers/select.dart b/app/lib/handlers/select.dart index 9ba3230bbd6b..750439adedcc 100644 --- a/app/lib/handlers/select.dart +++ b/app/lib/handlers/select.dart @@ -323,7 +323,7 @@ class SelectHandler extends Handler { event.kind == PointerDeviceKind.mouse && event.buttons != kSecondaryMouseButton; - void _handleRuler(ScaleUpdateDetails details, EventContext context) { + /*void _handleRuler(ScaleUpdateDetails details, EventContext context) { final state = context.getState(); if (state == null) return; final viewport = context.getCameraViewport(); @@ -347,7 +347,7 @@ class SelectHandler extends Handler { _rulerRotation = currentRotation; _rulerPosition = currentPos; context.getCurrentIndexCubit().updateUtilities(utilities: utilitiesState); - } + }*/ @override void onScaleUpdate(ScaleUpdateDetails details, EventContext context) { @@ -355,7 +355,7 @@ class SelectHandler extends Handler { final globalPos = context.getCameraTransform().localToGlobal(details.localFocalPoint); if (_rulerRotation != null && _rulerPosition != null) { - _handleRuler(details, context); + //_handleRuler(details, context); return; } if (_selectionManager.isTransforming) { diff --git a/app/lib/handlers/undo.dart b/app/lib/handlers/undo.dart index 6b04dc61aae2..018b52869cf6 100644 --- a/app/lib/handlers/undo.dart +++ b/app/lib/handlers/undo.dart @@ -4,7 +4,7 @@ class UndoHandler extends Handler { UndoHandler(super.data); @override - bool onSelected(BuildContext context) { + bool onSelected(BuildContext context, [bool wasAdded = true]) { final bloc = context.read(); bloc.undo(); bloc.load().then((value) => bloc.bake().then((value) => bloc.save())); diff --git a/app/lib/l10n/app_en.arb b/app/lib/l10n/app_en.arb index 7b7354fc39e6..0d1390c723c3 100644 --- a/app/lib/l10n/app_en.arb +++ b/app/lib/l10n/app_en.arb @@ -28,7 +28,6 @@ "yes": "Yes", "undo": "Undo", "redo": "Redo", - "project": "Project", "general": "General", "copyTitle": "Copied to clipboard", "loading": "Loading...", diff --git a/app/lib/renderers/utilities.dart b/app/lib/renderers/utilities.dart index ceafaa3db622..49aad6c18a08 100644 --- a/app/lib/renderers/utilities.dart +++ b/app/lib/renderers/utilities.dart @@ -18,7 +18,8 @@ class UtilitiesRenderer extends Renderer { } bool hitRuler(Offset position, Size size) { - if (!element.rulerEnabled) return false; + return false; + /*if (!element.rulerEnabled) return false; final rulerRect = getRulerRect(size).translate( size.width / 2 + element.rulerPosition.x, size.height / 2 + element.rulerPosition.y); @@ -26,14 +27,14 @@ class UtilitiesRenderer extends Renderer { element.rulerPosition .toOffset() .translate(size.width / 2, size.height / 2), - -element.rulerAngle * pi / 180)); + -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.gridEnabled) { + /*if (element.gridEnabled) { if (option.gridXSize > 0) { double x = 0; while (x < size.width) { @@ -145,12 +146,12 @@ class UtilitiesRenderer extends Renderer { x += steps; } canvas.restore(); - } + }*/ } Offset getPointerPosition(Offset position, CurrentIndexCubit cubit) { - if (!element.rulerEnabled) return position; - final size = cubit.state.cameraViewport.toSize(); + /* 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); @@ -173,17 +174,17 @@ class UtilitiesRenderer extends Renderer { } else if (secondHalfHit) { return Offset(rotatedPosition.dx, rulerRect.bottom).rotate(pivot, angle); } - return position; + return position; */ } Offset getGridPosition(Offset position, DocumentPage page, DocumentInfo info, CurrentIndexCubit cubit) { - if (!element.gridEnabled) return position; - final transform = cubit.state.transformCubit.state; + /* 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)); + return transform.localToGlobal(Offset(x, y)); */ } } diff --git a/app/lib/selections/selection.dart b/app/lib/selections/selection.dart index 221fdb56be34..72b4a480518d 100644 --- a/app/lib/selections/selection.dart +++ b/app/lib/selections/selection.dart @@ -2,7 +2,6 @@ import 'package:butterfly/bloc/document_bloc.dart'; import 'package:butterfly/cubits/current_index.dart'; import 'package:butterfly/dialogs/constraints.dart'; import 'package:butterfly/dialogs/texture.dart'; -import 'package:butterfly/helpers/point.dart'; import 'package:butterfly/visualizer/tool.dart'; import 'package:butterfly/visualizer/preset.dart'; import 'package:butterfly/visualizer/property.dart'; diff --git a/app/lib/selections/utilities.dart b/app/lib/selections/utilities.dart index d1174dd4cebd..93f6ddad8175 100644 --- a/app/lib/selections/utilities.dart +++ b/app/lib/selections/utilities.dart @@ -50,11 +50,10 @@ class _UtilitiesViewState extends State<_UtilitiesView> late final TabController _tabController; final TextEditingController _nameController = TextEditingController(), _descriptionController = TextEditingController(); - int _expandedIndex = -1; @override void initState() { - _tabController = TabController(length: 4, vsync: this); + _tabController = TabController(length: 3, vsync: this); _tabController.addListener(_onTabChange); @@ -97,9 +96,8 @@ class _UtilitiesViewState extends State<_UtilitiesView> controller: _tabController, isScrollable: true, tabs: >[ - [PhosphorIconsLight.file, AppLocalizations.of(context).project], + [PhosphorIconsLight.file, AppLocalizations.of(context).file], [PhosphorIconsLight.book, AppLocalizations.of(context).page], - [PhosphorIconsLight.eye, AppLocalizations.of(context).view], [PhosphorIconsLight.camera, AppLocalizations.of(context).camera], ] .map((e) => @@ -348,99 +346,6 @@ class _UtilitiesViewState extends State<_UtilitiesView> child: Text(AppLocalizations.of(context).background), ), ]), - Column(children: [ - ExpansionPanelList( - expansionCallback: (index, isExpanded) { - setState(() { - _expandedIndex = isExpanded ? index : -1; - }); - }, - children: [ - ExpansionPanel( - canTapOnHeader: true, - isExpanded: _expandedIndex == 0, - headerBuilder: (context, isExpanded) => ListTile( - leading: Checkbox( - value: widget.state.gridEnabled, - onChanged: (value) => widget.onStateChanged( - widget.state - .copyWith(gridEnabled: value ?? false), - ), - ), - title: Text(AppLocalizations.of(context).grid), - ), - body: Column(children: [ - OffsetPropertyView( - value: Offset(widget.option.gridXSize, - widget.option.gridYSize), - title: Text(AppLocalizations.of(context).size), - onChanged: (value) => widget.onToolChanged( - widget.option.copyWith( - gridXSize: value.dx, gridYSize: value.dy), - ), - ), - const SizedBox(height: 8), - ColorField( - title: Text(LeapLocalizations.of(context).color), - value: widget.option.gridColor.withValues(a: 255), - onChanged: (value) => widget.onToolChanged( - widget.option.copyWith( - gridColor: value.withValues( - a: widget.option.gridColor.a)), - ), - ), - const SizedBox(height: 8), - ExactSlider( - header: Text(AppLocalizations.of(context).alpha), - value: widget.option.gridColor.a.toDouble(), - defaultValue: 255, - min: 0, - max: 255, - fractionDigits: 0, - onChangeEnd: (value) => widget.onToolChanged( - widget.option.copyWith( - gridColor: widget.option.gridColor - .withValues(a: value.toInt()), - ), - ), - ), - ]), - ), - ExpansionPanel( - canTapOnHeader: true, - isExpanded: _expandedIndex == 1, - headerBuilder: (context, isExpanded) => ListTile( - leading: Checkbox( - value: widget.state.rulerEnabled, - onChanged: (value) => widget.onStateChanged(widget - .state - .copyWith(rulerEnabled: value ?? false)), - ), - title: Text(AppLocalizations.of(context).ruler), - ), - body: Column(children: [ - OffsetPropertyView( - title: - Text(AppLocalizations.of(context).position), - onChanged: (value) => widget.onStateChanged(widget - .state - .copyWith(rulerPosition: value.toPoint())), - value: widget.state.rulerPosition.toOffset(), - ), - const SizedBox(height: 8), - ExactSlider( - header: Text(AppLocalizations.of(context).angle), - value: widget.state.rulerAngle, - defaultValue: 0, - min: 0, - max: 360, - onChangeEnd: (value) => widget.onStateChanged( - widget.state.copyWith(rulerAngle: value)), - ), - ]), - ), - ]), - ]), Column( children: [ OffsetPropertyView( diff --git a/app/lib/services/import.dart b/app/lib/services/import.dart index 2eb954b26c8e..b8c1d404438a 100644 --- a/app/lib/services/import.dart +++ b/app/lib/services/import.dart @@ -743,7 +743,7 @@ class ImportService { context, ImportTool(elements: elements, areas: areas), bloc: bloc!, - temporaryClicked: true, + temporaryState: TemporaryState.removeAfterRelease, ); } else { bloc diff --git a/app/lib/views/edit.dart b/app/lib/views/edit.dart index ea95380670d2..00ef540de263 100644 --- a/app/lib/views/edit.dart +++ b/app/lib/views/edit.dart @@ -266,8 +266,7 @@ class _EditToolbarState extends State { final selected = i == currentIndex.index; final tool = handler.data; final highlighted = currentIndex.selection?.selected.any( - (element) => - element.hashCode == handler.hashCode) ?? + (element) => element.hashCode == tool.hashCode) ?? false; String tooltip = tool.name.trim(); if (tooltip.isEmpty) { diff --git a/app/lib/views/view.dart b/app/lib/views/view.dart index c521959d9f08..0f0af8af9c87 100644 --- a/app/lib/views/view.dart +++ b/app/lib/views/view.dart @@ -119,12 +119,13 @@ class _MainViewViewportState extends State }); } + final bloc = context.read(); + Future changeTemporaryTool( PointerDeviceKind kind, int buttons) async { int? nextPointerIndex; final config = context.read().state.inputConfiguration; final cubit = context.read(); - final bloc = context.read(); // Mapped to the priority of the buttons switch (kind) { case PointerDeviceKind.touch: @@ -157,7 +158,6 @@ class _MainViewViewportState extends State await cubit.changeTemporaryHandlerIndex( context, nextPointerIndex, - temporaryClicked: false, ); } } @@ -341,11 +341,12 @@ class _MainViewViewportState extends State onPointerUp: (PointerUpEvent event) async { cubit.updateLastPosition(event.localPosition); if (_isScalingDisabled ?? true) { - getHandler() + await getHandler() .onPointerUp(event, getEventContext()); } cubit.removePointer(event.pointer); cubit.removeButtons(); + cubit.resetReleaseHandler(bloc); }, behavior: HitTestBehavior.translucent, onPointerHover: (event) { diff --git a/app/lib/visualizer/tool.dart b/app/lib/visualizer/tool.dart index 2b95d0604e72..ea4fb1ec7cfe 100644 --- a/app/lib/visualizer/tool.dart +++ b/app/lib/visualizer/tool.dart @@ -14,6 +14,16 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:material_leap/material_leap.dart'; import 'package:phosphor_flutter/phosphor_flutter.dart'; +extension ToolCategoryVisualizer on ToolCategory { + IconGetter get icon => switch (this) { + ToolCategory.normal => PhosphorIcons.paintBrush, + ToolCategory.import => PhosphorIcons.arrowSquareIn, + ToolCategory.surface => PhosphorIcons.monitor, + ToolCategory.action => PhosphorIcons.arrowClockwise, + ToolCategory.view => PhosphorIcons.eye, + }; +} + extension ToolVisualizer on Tool { String getDisplay(BuildContext context) { if (name.trim().isEmpty) return getLocalizedName(context); @@ -44,6 +54,8 @@ extension ToolVisualizer on Tool { AssetTool e => e.importType.getLocalizedName(context), EyeDropperTool() => loc.eyeDropper, ExportTool() => loc.export, + GridTool() => loc.grid, + RulerTool() => loc.ruler, }; } @@ -89,6 +101,8 @@ extension ToolVisualizer on Tool { AssetTool tool => tool.importType.icon, EyeDropperTool() => PhosphorIcons.eyedropper, ExportTool() => PhosphorIcons.export, + GridTool() => PhosphorIcons.gridFour, + RulerTool() => PhosphorIcons.ruler, }; List get help { @@ -114,6 +128,8 @@ extension ToolVisualizer on Tool { AssetTool() => null, ExportTool() => null, EyeDropperTool() => 'eye_dropper', + GridTool() => 'grid', + RulerTool() => 'ruler', }; if (page == null) return []; return ['tools', page]; @@ -127,6 +143,7 @@ extension ToolVisualizer on Tool { FullScreenTool() => true, ExportTool() => true, CollectionTool() => true, + EyeDropperTool() => true, _ => false, }; } diff --git a/app/lib/widgets/option_button.dart b/app/lib/widgets/option_button.dart index 3218be5fa6fb..7719801568f9 100644 --- a/app/lib/widgets/option_button.dart +++ b/app/lib/widgets/option_button.dart @@ -3,7 +3,7 @@ import 'package:phosphor_flutter/phosphor_flutter.dart'; class OptionButton extends StatefulWidget { final Widget icon; - final Widget? selectedIcon, bottomIcon; + final Widget? selectedIcon, bottomIcon, leadingIcon; final VoidCallback? onPressed, onSecondaryPressed, onLongPressed; final bool selected, highlighted, focussed, alwaysShowBottom; final String tooltip; @@ -14,6 +14,7 @@ class OptionButton extends StatefulWidget { required this.icon, this.selectedIcon, this.bottomIcon, + this.leadingIcon, this.onPressed, this.onSecondaryPressed, this.onLongPressed, @@ -139,9 +140,18 @@ class _OptionButtonState extends State child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - widget.selected - ? (widget.selectedIcon ?? widget.icon) - : widget.icon, + Stack( + children: [ + if (widget.leadingIcon != null) + Align( + alignment: Alignment.topLeft, + child: widget.leadingIcon!, + ), + widget.selected + ? (widget.selectedIcon ?? widget.icon) + : widget.icon + ], + ), SizeTransition( axisAlignment: -1, axis: Axis.vertical,