Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 64 additions & 63 deletions lib/core/commands/command_factory/command_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import 'package:flutter/material.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/clipboard_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/delete_region_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/text_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/clip_area_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/clip_path_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/line_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/path_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/shape/ellipse_shape_command.dart';
Expand All @@ -18,39 +20,43 @@ import 'package:paintroid/core/enums/shape_style.dart';
class CommandFactory {
const CommandFactory();

PathCommand createPathCommand(
PathWithActionHistory path,
Paint paint,
) =>
PathCommand createPathCommand(PathWithActionHistory path,
Paint paint,) =>
PathCommand(path, paint);

LineCommand createLineCommand(
PathWithActionHistory path,
Paint paint,
Offset startPoint,
Offset endPoint,
) =>
ClipPathCommand createClipPathCommand(PathWithActionHistory path,
Paint paint, {
Offset? startPoint,
Offset? endPoint,
}) =>
ClipPathCommand(
path,
paint,
startPoint: startPoint,
endPoint: endPoint,
);

LineCommand createLineCommand(PathWithActionHistory path,
Paint paint,
Offset startPoint,
Offset endPoint,) =>
LineCommand(path, paint, startPoint, endPoint);

SquareShapeCommand createSquareShapeCommand(
Paint paint,
Offset topLeft,
Offset topRight,
Offset bottomLeft,
Offset bottomRight,
ShapeStyle style,
) =>
SquareShapeCommand createSquareShapeCommand(Paint paint,
Offset topLeft,
Offset topRight,
Offset bottomLeft,
Offset bottomRight,
ShapeStyle style,) =>
SquareShapeCommand(
paint, topLeft, topRight, bottomLeft, bottomRight, style);

EllipseShapeCommand createEllipseShapeCommand(
Paint paint,
double radiusX,
double radiusY,
Offset center,
ShapeStyle style,
double angle,
) =>
EllipseShapeCommand createEllipseShapeCommand(Paint paint,
double radiusX,
double radiusY,
Offset center,
ShapeStyle style,
double angle,) =>
EllipseShapeCommand(
paint,
radiusX,
Expand All @@ -60,13 +66,11 @@ class CommandFactory {
angle,
);

ClipboardCommand createClipboardCommand(
Paint paint,
Uint8List imageData,
ui.Offset offset,
double scale,
double rotation,
) =>
ClipboardCommand createClipboardCommand(Paint paint,
Uint8List imageData,
ui.Offset offset,
double scale,
double rotation,) =>
ClipboardCommand(
paint,
imageData,
Expand All @@ -75,16 +79,15 @@ class CommandFactory {
rotation,
);

TextCommand createTextCommand(
Offset point,
String text,
TextStyle style,
double fontSize,
Paint paint,
double rotationAngle, {
double scaleX = 1.0,
double scaleY = 1.0,
}) =>
TextCommand createTextCommand(Offset point,
String text,
TextStyle style,
double fontSize,
Paint paint,
double rotationAngle, {
double scaleX = 1.0,
double scaleY = 1.0,
}) =>
TextCommand(
point,
text,
Expand All @@ -96,15 +99,13 @@ class CommandFactory {
scaleY: scaleY,
);

StarShapeCommand createStarShapeCommand(
Paint paint,
int numPoints,
double angle,
Offset center,
ShapeStyle style,
double radiusX,
double radiusY,
) =>
StarShapeCommand createStarShapeCommand(Paint paint,
int numPoints,
double angle,
Offset center,
ShapeStyle style,
double radiusX,
double radiusY,) =>
StarShapeCommand(
paint,
numPoints,
Expand All @@ -115,23 +116,23 @@ class CommandFactory {
radiusY,
);

HeartShapeCommand createHeartShapeCommand(
Paint paint,
double width,
double height,
double angle,
Offset center,
ShapeStyle style,
) =>
HeartShapeCommand createHeartShapeCommand(Paint paint,
double width,
double height,
double angle,
Offset center,
ShapeStyle style,) =>
HeartShapeCommand(paint, width, height, angle, center, style);

SprayCommand createSprayCommand(List<Offset> points, Paint paint) {
return SprayCommand(points, paint);
}

DeleteRegionCommand createDeleteRegionCommand(
ui.Rect region,
) =>
ClipAreaCommand createClipAreaCommand(PathWithActionHistory path,
Paint paint,) =>
ClipAreaCommand(path, paint);

DeleteRegionCommand createDeleteRegionCommand(ui.Rect region,) =>
DeleteRegionCommand(
Paint(),
region,
Expand Down
7 changes: 7 additions & 0 deletions lib/core/commands/command_implementation/command.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import 'package:equatable/equatable.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/clip_area_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/clip_path_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/clipboard_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/delete_region_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/line_command.dart';
Expand Down Expand Up @@ -38,6 +40,11 @@ abstract class Command with EquatableMixin {
return HeartShapeCommand.fromJson(json);
case SerializerType.STAR_SHAPE_COMMAND:
return StarShapeCommand.fromJson(json);
case SerializerType.CLIP_PATH_COMMAND:
return ClipPathCommand.fromJson(json);
case SerializerType.CLIP_AREA_COMMAND:
return ClipAreaCommand.fromJson(json);

default:
return PathCommand.fromJson(json);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import 'dart:ui';

import 'package:json_annotation/json_annotation.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/graphic_command.dart';
import 'package:paintroid/core/commands/path_with_action_history.dart';
import 'package:paintroid/core/json_serialization/converter/paint_converter.dart';
import 'package:paintroid/core/json_serialization/converter/path_with_action_history_converter.dart';
import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart';
import 'package:paintroid/core/json_serialization/versioning/version_strategy.dart';

part 'clip_area_command.g.dart';

@JsonSerializable()
class ClipAreaCommand extends GraphicCommand {
@JsonKey(includeToJson: true, includeFromJson: true)
final String type;
@JsonKey(includeToJson: true, includeFromJson: true)
final int version;

@PathWithActionHistoryConverter()
final PathWithActionHistory clipPathData;

ClipAreaCommand(
this.clipPathData,
Paint paint, {
this.type = SerializerType.CLIP_AREA_COMMAND,
int? version,
}) : version = version ??
VersionStrategyManager.strategy.getClipAreaCommandVersion(),
super(paint);

@override
void call(Canvas canvas) {
final Rect canvasBounds = canvas.getLocalClipBounds();

Path areaToClear = Path.combine(
PathOperation.difference,
Path()..addRect(canvasBounds),
clipPathData.path,
);

canvas.drawPath(
areaToClear,
Paint()
..blendMode = BlendMode.clear
..style = PaintingStyle.fill);
}

@override
List<Object?> get props => [paint, clipPathData, type, version];

factory ClipAreaCommand.fromJson(Map<String, dynamic> json) {
int version = json['version'] as int;

switch (version) {
case Version.v1:
return _$ClipAreaCommandFromJson(json);
case Version.v2:
// For different versions of ClipAreaCommand the deserialization
// has to be implemented manually.
// Autogenerated code can only be used for one version
default:
return _$ClipAreaCommandFromJson(json);
}
}

@override
Map<String, dynamic> toJson() => _$ClipAreaCommandToJson(this);
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import 'dart:ui';

import 'package:flutter/widgets.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/graphic_command.dart';
import 'package:paintroid/core/commands/path_with_action_history.dart';
import 'package:paintroid/core/json_serialization/converter/offset_converter.dart';
import 'package:paintroid/core/json_serialization/converter/path_with_action_history_converter.dart';
import 'package:paintroid/core/json_serialization/converter/paint_converter.dart';
import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart';
import 'package:paintroid/core/json_serialization/versioning/version_strategy.dart';
import 'package:path_drawing/path_drawing.dart';

part 'clip_path_command.g.dart';

@JsonSerializable()
class ClipPathCommand extends GraphicCommand {
@JsonKey(includeToJson: true, includeFromJson: true)
final String type;
@JsonKey(includeToJson: true, includeFromJson: true)
final int version;

@PathWithActionHistoryConverter()
final PathWithActionHistory path;

@OffsetConverter()
final Offset? startPoint;
@OffsetConverter()
final Offset? endPoint;

ClipPathCommand(
this.path,
super.paint, {
this.startPoint,
this.endPoint,
this.type = SerializerType.CLIP_PATH_COMMAND,
int? version,
}) : version = version ??
VersionStrategyManager.strategy.getClipPathCommandVersion();

@override
void call(Canvas canvas) {
final dashLength = paint.strokeWidth * 4;
final dashGap = paint.strokeWidth * 2;

final dashedPath = dashPath(
path.path,
dashArray: CircularIntervalList<double>([dashLength, dashGap]),
);
canvas.drawPath(dashedPath, paint);

if (startPoint != null &&
endPoint != null &&
(startPoint!.dx != endPoint!.dx || startPoint!.dy != endPoint!.dy)) {
final solidPaint = Paint()
..color = paint.color
..style = PaintingStyle.stroke
..strokeWidth = paint.strokeWidth
..isAntiAlias = true;

final solidPath = Path()
..moveTo(startPoint!.dx, startPoint!.dy)
..lineTo(endPoint!.dx, endPoint!.dy);

canvas.drawPath(solidPath, solidPaint);
}
}

@override
List<Object?> get props => [paint, path, startPoint, endPoint, type, version];

factory ClipPathCommand.fromJson(Map<String, dynamic> json) {
int version = json['version'] as int;

switch (version) {
case Version.v1:
return _$ClipPathCommandFromJson(json);
case Version.v2:
// For different versions of ClipPathCommand the deserialization
// has to be implemented manually.
// Autogenerated code can only be used for one version
default:
return _$ClipPathCommandFromJson(json);
}
}

@override
Map<String, dynamic> toJson() => _$ClipPathCommandToJson(this);
}
Loading