Skip to content

Commit d5c2cfc

Browse files
committed
Impl project "Tool Panel".
1 parent 30c49b3 commit d5c2cfc

27 files changed

+947
-1
lines changed

bin/main.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:flutter/material.dart';
2+
import '../patterns/abstract_factory/tool_panel_factory/main.dart';
23
import '../patterns/observer/subscriber_flutter_widget/main.dart';
34
import '../patterns/adapter/flutter_adapter/main.dart';
45
import '../patterns/memento/memento_editor/main.dart';
@@ -13,11 +14,12 @@ class MyApp extends StatelessWidget {
1314
return MaterialApp(
1415
title: 'Refactoring Guru: Flutter launcher',
1516
theme: ThemeData(primarySwatch: Colors.pink),
16-
initialRoute: '/memento/flutter_memento_editor',
17+
initialRoute: '/abstract_factory/tool_panel',
1718
routes: {
1819
'/observer/subscriber_flutter_widget': (_) => SubscriberFlutterApp(),
1920
'/adapter/flutter_adapter': (_) => FlutterAdapterApp(),
2021
'/memento/flutter_memento_editor': (_) => FlutterMementoEditorApp(),
22+
'/abstract_factory/tool_panel': (_) => WToolPanelApp(),
2123
},
2224
);
2325
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import '../app/tools.dart';
2+
import 'shapes.dart';
3+
4+
class App {
5+
final Tools tools;
6+
final Shapes shapes;
7+
8+
App({
9+
required this.tools,
10+
required this.shapes,
11+
});
12+
13+
void addShape(double x, double y) {
14+
final activeColor = tools.activeColor.value;
15+
final activeFactory = tools.activeFactory.value!;
16+
17+
final newShape = activeFactory.createShape(x, y, activeColor);
18+
newShape.centerToFit();
19+
shapes.add(newShape);
20+
}
21+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import 'dart:collection';
2+
3+
import 'package:flutter/foundation.dart';
4+
5+
import '../pattern/shape.dart';
6+
7+
class Shapes with IterableMixin<Shape> {
8+
final List<Shape> _shapes;
9+
10+
Shapes(this._shapes);
11+
12+
void add(Shape shape) {
13+
_shapes.add(shape);
14+
onAddShapeEvent._emit();
15+
}
16+
17+
@override
18+
Iterator<Shape> get iterator => _shapes.iterator;
19+
20+
final onAddShapeEvent = Event();
21+
}
22+
23+
class Event extends ChangeNotifier {
24+
void _emit() => notifyListeners();
25+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import 'dart:async';
2+
import 'dart:ui';
3+
4+
import 'package:flutter/foundation.dart';
5+
6+
import '../mixin/icon_box_mixin.dart';
7+
import '../pattern/tool_factory.dart';
8+
9+
class Tools {
10+
final List<FactoryTool> factories;
11+
final List<Color> colors;
12+
13+
final activeFactory = ValueNotifier<FactoryTool?>(null);
14+
15+
final activeColor = ValueNotifier(Color(0x0FFFFFFFF));
16+
17+
Future<bool> get iconsReady => _iconsInitCompleter.future;
18+
19+
Tools({required this.factories, required this.colors}) {
20+
_initIconsFromShapes();
21+
22+
if (factories.isNotEmpty) {
23+
activeFactory.value = factories.first;
24+
}
25+
26+
if (colors.isNotEmpty) {
27+
activeColor.value = colors.first;
28+
}
29+
}
30+
31+
final _iconsInitCompleter = Completer<bool>();
32+
33+
void _initIconsFromShapes() async {
34+
await Future.wait([
35+
for (final factory in factories)
36+
(factory as IconBoxMixin).updateIcon(activeColor.value),
37+
]);
38+
_iconsInitCompleter.complete(Future.value(true));
39+
}
40+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'dart:ui';
2+
3+
import '../mixin/icon_box_mixin.dart';
4+
import '../pattern/tool_factory.dart';
5+
import '../shapes/circle_shape.dart';
6+
import '../pattern/shape.dart';
7+
8+
class CircleFactory extends FactoryTool with IconBoxMixin {
9+
@override
10+
Shape createShape(double x, double y, Color color) {
11+
return CircleShape(
12+
radius: 50,
13+
x: x,
14+
y: y,
15+
color: color,
16+
);
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'dart:ui';
2+
3+
import '../mixin/icon_box_mixin.dart';
4+
import '../pattern/tool_factory.dart';
5+
import '../pattern/shape.dart';
6+
import '../shapes/line_shape.dart';
7+
8+
class LineFactory extends FactoryTool with IconBoxMixin {
9+
@override
10+
Shape createShape(double x, double y, Color color) {
11+
return LineShape(
12+
length: 100,
13+
x: x,
14+
y: y,
15+
color: color,
16+
);
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'dart:ui';
2+
3+
import '../mixin/icon_box_mixin.dart';
4+
import '../pattern/tool_factory.dart';
5+
import '../pattern/shape.dart';
6+
import '../shapes/star_shape.dart';
7+
8+
class StarFactory extends FactoryTool with IconBoxMixin {
9+
@override
10+
Shape createShape(double x, double y, Color color) {
11+
return StarShape(
12+
radius: 80,
13+
x: x,
14+
y: y,
15+
color: color,
16+
);
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'dart:ui';
2+
3+
import '../mixin/icon_box_mixin.dart';
4+
import '../pattern/tool_factory.dart';
5+
import '../pattern/shape.dart';
6+
import '../shapes/triangle_shape.dart';
7+
8+
class TriangleFactory extends FactoryTool with IconBoxMixin {
9+
@override
10+
Shape createShape(double x, double y, Color color) {
11+
return TriangleShape(
12+
sideLength: 120,
13+
x: x,
14+
y: y,
15+
color: color,
16+
);
17+
}
18+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import 'dart:ui';
2+
3+
import '../mixin/icon_box_mixin.dart';
4+
import '../pattern/tool_factory.dart';
5+
import '../shapes/txt_shape.dart';
6+
import '../pattern/shape.dart';
7+
8+
class TxtFactory extends FactoryTool with IconBoxMixin {
9+
@override
10+
Shape createShape(double x, double y, Color color) {
11+
return Txt(
12+
text: 'Text',
13+
fontSize: 100,
14+
x: x,
15+
y: y,
16+
color: color,
17+
);
18+
}
19+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import 'package:flutter/material.dart';
2+
3+
import 'app/app.dart';
4+
import 'app/shapes.dart';
5+
import 'app/tools.dart';
6+
import 'factories/circle_factory.dart';
7+
import 'factories/line_factory.dart';
8+
import 'factories/star_factory.dart';
9+
import 'factories/triangle_factory.dart';
10+
import 'factories/txt_factory.dart';
11+
import 'widgets/drawing_board.dart';
12+
import 'widgets/tool_panel.dart';
13+
14+
class WToolPanelApp extends StatefulWidget {
15+
const WToolPanelApp({Key? key}) : super(key: key);
16+
17+
@override
18+
_WToolPanelAppState createState() => _WToolPanelAppState();
19+
}
20+
21+
class _WToolPanelAppState extends State<WToolPanelApp> {
22+
final app = App(
23+
shapes: Shapes([]),
24+
tools: Tools(
25+
factories: [
26+
TxtFactory(),
27+
LineFactory(),
28+
CircleFactory(),
29+
TriangleFactory(),
30+
StarFactory(),
31+
],
32+
colors: [
33+
Colors.white,
34+
Colors.green,
35+
Colors.blue,
36+
Colors.yellow,
37+
],
38+
),
39+
);
40+
41+
@override
42+
Widget build(BuildContext context) {
43+
return Stack(
44+
children: [
45+
DrawingBoard(
46+
shapes: app.shapes,
47+
onClick: app.addShape,
48+
),
49+
ToolPanel(
50+
tools: app.tools,
51+
),
52+
],
53+
);
54+
}
55+
}

0 commit comments

Comments
 (0)