Skip to content
Merged
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
40 changes: 38 additions & 2 deletions lib/core/commands/command_factory/command_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import 'package:paintroid/core/commands/command_implementation/graphic/text_comm
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';
import 'package:paintroid/core/commands/command_implementation/graphic/shape/heart_shape_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/shape/square_shape_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/shape/star_shape_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/spray_command.dart';
import 'package:paintroid/core/commands/path_with_action_history.dart';
import 'package:paintroid/core/enums/shape_style.dart';

class CommandFactory {
const CommandFactory();
Expand All @@ -30,22 +33,26 @@ class CommandFactory {
Offset topRight,
Offset bottomLeft,
Offset bottomRight,
ShapeStyle style,
) =>
SquareShapeCommand(paint, topLeft, topRight, bottomLeft, bottomRight);
SquareShapeCommand(
paint, topLeft, topRight, bottomLeft, bottomRight, style);

EllipseShapeCommand createEllipseShapeCommand(
Paint paint,
double radiusX,
double radiusY,
Offset center,
ShapeStyle style,
double angle,
) =>
EllipseShapeCommand(
paint,
radiusX,
radiusY,
center,
angle: angle,
style,
angle,
);

TextCommand createTextCommand(
Expand All @@ -69,6 +76,35 @@ class CommandFactory {
scaleY: scaleY,
);

StarShapeCommand createStarShapeCommand(
Paint paint,
int numPoints,
double angle,
Offset center,
ShapeStyle style,
double radiusX,
double radiusY,
) =>
StarShapeCommand(
paint,
numPoints,
angle,
center,
style,
radiusX,
radiusY,
);

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);
}
Expand Down
6 changes: 6 additions & 0 deletions lib/core/commands/command_implementation/command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import 'package:paintroid/core/commands/command_implementation/graphic/path_comm
import 'package:paintroid/core/commands/command_implementation/graphic/shape/ellipse_shape_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/shape/square_shape_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/text_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/shape/heart_shape_command.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/shape/star_shape_command.dart';
import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart';

abstract class Command with EquatableMixin {
Expand All @@ -24,6 +26,10 @@ abstract class Command with EquatableMixin {
return EllipseShapeCommand.fromJson(json);
case SerializerType.TEXT_COMMAND:
return TextCommand.fromJson(json);
case SerializerType.HEART_SHAPE_COMMAND:
return HeartShapeCommand.fromJson(json);
case SerializerType.STAR_SHAPE_COMMAND:
return StarShapeCommand.fromJson(json);
default:
return PathCommand.fromJson(json);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
// ignore_for_file: must_be_immutable

import 'dart:ui';
import 'package:flutter/material.dart';

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/shape/shape_command.dart';
import 'package:paintroid/core/enums/shape_style.dart';
import 'package:paintroid/core/json_serialization/converter/offset_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:paintroid/ui/utils/shape_drawing_utils.dart';

part 'ellipse_shape_command.g.dart';

Expand All @@ -18,50 +20,67 @@ class EllipseShapeCommand extends ShapeCommand {
@OffsetConverter()
Offset center;
final double angle;

final ShapeStyle style;
final int version;
final String type;

EllipseShapeCommand(
super.paint,
this.radiusX,
this.radiusY,
this.center, {
this.angle = 0.0,
this.center,
this.style,
this.angle, {
int? version,
this.type = SerializerType.ELLIPSE_SHAPE_COMMAND,
}) : version = version ??
VersionStrategyManager.strategy.getEllipseShapeCommandVersion();

Path get path {
Path ovalPathAtOrigin = Path()
..addOval(Rect.fromCenter(
center: Offset.zero,
width: radiusX,
height: radiusY,
));

Path rotatedOvalPath = ovalPathAtOrigin;
if (angle != 0.0) {
final rotationMatrix = Matrix4.identity()..rotateZ(angle);
rotatedOvalPath = ovalPathAtOrigin.transform(rotationMatrix.storage);
}

return rotatedOvalPath.shift(center);
}

@override
void call(Canvas canvas) {
canvas.save();
canvas.translate(center.dx, center.dy);
canvas.rotate(angle);

final Rect ovalRect = Rect.fromCenter(
center: Offset.zero,
width: radiusX * 2,
height: radiusY * 2,
ShapeDrawingUtils.drawPathWithStyle(
canvas: canvas,
path: path,
basePaint: paint,
style: style,
);
canvas.drawOval(ovalRect, paint);
canvas.restore();
}

@override
List<Object?> get props =>
[paint, radiusX, radiusY, center, angle, version, type];
[paint, radiusX, radiusY, center, style, angle];

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

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

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

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,75 @@
// ignore_for_file: must_be_immutable

import 'package:flutter/widgets.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:paintroid/core/commands/command_implementation/graphic/shape/shape_command.dart';
import 'package:paintroid/core/enums/shape_style.dart';
import 'package:paintroid/core/json_serialization/converter/offset_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:paintroid/ui/utils/shape_drawing_utils.dart';
import 'package:paintroid/ui/utils/shape_path_generator.dart';

part 'heart_shape_command.g.dart';

@JsonSerializable()
class HeartShapeCommand extends ShapeCommand {
final double width;
final double height;
final double angle;
@OffsetConverter()
final Offset center;

final ShapeStyle style;
final int version;
final String type;

HeartShapeCommand(
super.paint,
this.width,
this.height,
this.angle,
this.center,
this.style, {
int? version,
this.type = SerializerType.HEART_SHAPE_COMMAND,
}) : version = version ??
VersionStrategyManager.strategy.getHeartShapeCommandVersion();

Path get path {
return ShapePathUtils.generateHeartPath(
width: width, height: height, angle: angle, center: center);
}

@override
void call(Canvas canvas) {
ShapeDrawingUtils.drawPathWithStyle(
canvas: canvas,
path: path,
basePaint: paint,
style: style,
);
}

@override
List<Object?> get props => [paint, width, height, center, style];

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

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

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

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

Loading