Skip to content

Commit 22035f0

Browse files
authored
PAINTROID-764 add more shapes and styles (#121)
* PAINTROID-764 add more shapes and styles * PAINTROID-764 adapted new bounding box * PAINTROID-764 remove comment * PAINTROID-764 fix minor issues * resolve conflicts
1 parent 2de1192 commit 22035f0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2310
-536
lines changed

lib/core/commands/command_factory/command_factory.dart

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ import 'package:paintroid/core/commands/command_implementation/graphic/text_comm
33
import 'package:paintroid/core/commands/command_implementation/graphic/line_command.dart';
44
import 'package:paintroid/core/commands/command_implementation/graphic/path_command.dart';
55
import 'package:paintroid/core/commands/command_implementation/graphic/shape/ellipse_shape_command.dart';
6+
import 'package:paintroid/core/commands/command_implementation/graphic/shape/heart_shape_command.dart';
67
import 'package:paintroid/core/commands/command_implementation/graphic/shape/square_shape_command.dart';
8+
import 'package:paintroid/core/commands/command_implementation/graphic/shape/star_shape_command.dart';
79
import 'package:paintroid/core/commands/command_implementation/graphic/spray_command.dart';
810
import 'package:paintroid/core/commands/path_with_action_history.dart';
11+
import 'package:paintroid/core/enums/shape_style.dart';
912

1013
class CommandFactory {
1114
const CommandFactory();
@@ -30,22 +33,26 @@ class CommandFactory {
3033
Offset topRight,
3134
Offset bottomLeft,
3235
Offset bottomRight,
36+
ShapeStyle style,
3337
) =>
34-
SquareShapeCommand(paint, topLeft, topRight, bottomLeft, bottomRight);
38+
SquareShapeCommand(
39+
paint, topLeft, topRight, bottomLeft, bottomRight, style);
3540

3641
EllipseShapeCommand createEllipseShapeCommand(
3742
Paint paint,
3843
double radiusX,
3944
double radiusY,
4045
Offset center,
46+
ShapeStyle style,
4147
double angle,
4248
) =>
4349
EllipseShapeCommand(
4450
paint,
4551
radiusX,
4652
radiusY,
4753
center,
48-
angle: angle,
54+
style,
55+
angle,
4956
);
5057

5158
TextCommand createTextCommand(
@@ -69,6 +76,35 @@ class CommandFactory {
6976
scaleY: scaleY,
7077
);
7178

79+
StarShapeCommand createStarShapeCommand(
80+
Paint paint,
81+
int numPoints,
82+
double angle,
83+
Offset center,
84+
ShapeStyle style,
85+
double radiusX,
86+
double radiusY,
87+
) =>
88+
StarShapeCommand(
89+
paint,
90+
numPoints,
91+
angle,
92+
center,
93+
style,
94+
radiusX,
95+
radiusY,
96+
);
97+
98+
HeartShapeCommand createHeartShapeCommand(
99+
Paint paint,
100+
double width,
101+
double height,
102+
double angle,
103+
Offset center,
104+
ShapeStyle style,
105+
) =>
106+
HeartShapeCommand(paint, width, height, angle, center, style);
107+
72108
SprayCommand createSprayCommand(List<Offset> points, Paint paint) {
73109
return SprayCommand(points, paint);
74110
}

lib/core/commands/command_implementation/command.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import 'package:paintroid/core/commands/command_implementation/graphic/path_comm
44
import 'package:paintroid/core/commands/command_implementation/graphic/shape/ellipse_shape_command.dart';
55
import 'package:paintroid/core/commands/command_implementation/graphic/shape/square_shape_command.dart';
66
import 'package:paintroid/core/commands/command_implementation/graphic/text_command.dart';
7+
import 'package:paintroid/core/commands/command_implementation/graphic/shape/heart_shape_command.dart';
8+
import 'package:paintroid/core/commands/command_implementation/graphic/shape/star_shape_command.dart';
79
import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart';
810

911
abstract class Command with EquatableMixin {
@@ -24,6 +26,10 @@ abstract class Command with EquatableMixin {
2426
return EllipseShapeCommand.fromJson(json);
2527
case SerializerType.TEXT_COMMAND:
2628
return TextCommand.fromJson(json);
29+
case SerializerType.HEART_SHAPE_COMMAND:
30+
return HeartShapeCommand.fromJson(json);
31+
case SerializerType.STAR_SHAPE_COMMAND:
32+
return StarShapeCommand.fromJson(json);
2733
default:
2834
return PathCommand.fromJson(json);
2935
}

lib/core/commands/command_implementation/graphic/shape/ellipse_shape_command.dart

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
// ignore_for_file: must_be_immutable
22

3-
import 'dart:ui';
3+
import 'package:flutter/material.dart';
44

55
import 'package:freezed_annotation/freezed_annotation.dart';
66
import 'package:paintroid/core/commands/command_implementation/graphic/shape/shape_command.dart';
7+
import 'package:paintroid/core/enums/shape_style.dart';
78
import 'package:paintroid/core/json_serialization/converter/offset_converter.dart';
89
import 'package:paintroid/core/json_serialization/converter/paint_converter.dart';
910
import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart';
1011
import 'package:paintroid/core/json_serialization/versioning/version_strategy.dart';
12+
import 'package:paintroid/ui/utils/shape_drawing_utils.dart';
1113

1214
part 'ellipse_shape_command.g.dart';
1315

@@ -18,50 +20,67 @@ class EllipseShapeCommand extends ShapeCommand {
1820
@OffsetConverter()
1921
Offset center;
2022
final double angle;
23+
24+
final ShapeStyle style;
2125
final int version;
2226
final String type;
2327

2428
EllipseShapeCommand(
2529
super.paint,
2630
this.radiusX,
2731
this.radiusY,
28-
this.center, {
29-
this.angle = 0.0,
32+
this.center,
33+
this.style,
34+
this.angle, {
3035
int? version,
3136
this.type = SerializerType.ELLIPSE_SHAPE_COMMAND,
3237
}) : version = version ??
3338
VersionStrategyManager.strategy.getEllipseShapeCommandVersion();
3439

40+
Path get path {
41+
Path ovalPathAtOrigin = Path()
42+
..addOval(Rect.fromCenter(
43+
center: Offset.zero,
44+
width: radiusX,
45+
height: radiusY,
46+
));
47+
48+
Path rotatedOvalPath = ovalPathAtOrigin;
49+
if (angle != 0.0) {
50+
final rotationMatrix = Matrix4.identity()..rotateZ(angle);
51+
rotatedOvalPath = ovalPathAtOrigin.transform(rotationMatrix.storage);
52+
}
53+
54+
return rotatedOvalPath.shift(center);
55+
}
56+
3557
@override
3658
void call(Canvas canvas) {
37-
canvas.save();
38-
canvas.translate(center.dx, center.dy);
39-
canvas.rotate(angle);
40-
41-
final Rect ovalRect = Rect.fromCenter(
42-
center: Offset.zero,
43-
width: radiusX * 2,
44-
height: radiusY * 2,
59+
ShapeDrawingUtils.drawPathWithStyle(
60+
canvas: canvas,
61+
path: path,
62+
basePaint: paint,
63+
style: style,
4564
);
46-
canvas.drawOval(ovalRect, paint);
47-
canvas.restore();
4865
}
4966

5067
@override
5168
List<Object?> get props =>
52-
[paint, radiusX, radiusY, center, angle, version, type];
69+
[paint, radiusX, radiusY, center, style, angle];
5370

5471
@override
55-
Map<String, dynamic> toJson() => _$EllipseShapeCommandToJson(this);
72+
Map<String, dynamic> toJson() => _$EllipseShapeCommandToJson(
73+
this);
5674

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

6079
switch (version) {
6180
case Version.v1:
6281
return _$EllipseShapeCommandFromJson(json);
6382
case Version.v2:
64-
// For different versions of SquareShapeCommand the deserialization
83+
// For different versions of EllipseShapeCommand the deserialization
6584
// has to be implemented manually.
6685
// Autogenerated code can only be used for one version
6786
default:

lib/core/commands/command_implementation/graphic/shape/ellipse_shape_command.g.dart

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// ignore_for_file: must_be_immutable
2+
3+
import 'package:flutter/widgets.dart';
4+
import 'package:freezed_annotation/freezed_annotation.dart';
5+
import 'package:paintroid/core/commands/command_implementation/graphic/shape/shape_command.dart';
6+
import 'package:paintroid/core/enums/shape_style.dart';
7+
import 'package:paintroid/core/json_serialization/converter/offset_converter.dart';
8+
import 'package:paintroid/core/json_serialization/converter/paint_converter.dart';
9+
import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart';
10+
import 'package:paintroid/core/json_serialization/versioning/version_strategy.dart';
11+
import 'package:paintroid/ui/utils/shape_drawing_utils.dart';
12+
import 'package:paintroid/ui/utils/shape_path_generator.dart';
13+
14+
part 'heart_shape_command.g.dart';
15+
16+
@JsonSerializable()
17+
class HeartShapeCommand extends ShapeCommand {
18+
final double width;
19+
final double height;
20+
final double angle;
21+
@OffsetConverter()
22+
final Offset center;
23+
24+
final ShapeStyle style;
25+
final int version;
26+
final String type;
27+
28+
HeartShapeCommand(
29+
super.paint,
30+
this.width,
31+
this.height,
32+
this.angle,
33+
this.center,
34+
this.style, {
35+
int? version,
36+
this.type = SerializerType.HEART_SHAPE_COMMAND,
37+
}) : version = version ??
38+
VersionStrategyManager.strategy.getHeartShapeCommandVersion();
39+
40+
Path get path {
41+
return ShapePathUtils.generateHeartPath(
42+
width: width, height: height, angle: angle, center: center);
43+
}
44+
45+
@override
46+
void call(Canvas canvas) {
47+
ShapeDrawingUtils.drawPathWithStyle(
48+
canvas: canvas,
49+
path: path,
50+
basePaint: paint,
51+
style: style,
52+
);
53+
}
54+
55+
@override
56+
List<Object?> get props => [paint, width, height, center, style];
57+
58+
@override
59+
Map<String, dynamic> toJson() => _$HeartShapeCommandToJson(this);
60+
61+
factory HeartShapeCommand.fromJson(Map<String, dynamic> json) {
62+
int version = json['version'] as int;
63+
64+
switch (version) {
65+
case Version.v1:
66+
return _$HeartShapeCommandFromJson(json);
67+
case Version.v2:
68+
// For different versions of HeartShapeCommand the deserialization
69+
// has to be implemented manually.
70+
// Autogenerated code can only be used for one version
71+
default:
72+
return _$HeartShapeCommandFromJson(json);
73+
}
74+
}
75+
}

lib/core/commands/command_implementation/graphic/shape/heart_shape_command.g.dart

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)