From da5297f054586789411268ff5a170febe056b456 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Thu, 28 Dec 2023 14:27:59 +0530 Subject: [PATCH 01/39] Add Color Picker --- lib/ui/drawing_space/bottom_nav_bar.dart | 47 +++++++++++-- lib/ui/drawing_space/color_box.dart | 22 ++++++ lib/ui/drawing_space/color_picker_dialog.dart | 52 ++++++++++++++ pubspec.lock | 68 +++++++++++++------ pubspec.yaml | 1 + 5 files changed, 164 insertions(+), 26 deletions(-) create mode 100644 lib/ui/drawing_space/color_box.dart create mode 100644 lib/ui/drawing_space/color_picker_dialog.dart diff --git a/lib/ui/drawing_space/bottom_nav_bar.dart b/lib/ui/drawing_space/bottom_nav_bar.dart index 12b1e4e4..ca442f23 100644 --- a/lib/ui/drawing_space/bottom_nav_bar.dart +++ b/lib/ui/drawing_space/bottom_nav_bar.dart @@ -2,15 +2,24 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:paintroid/core/app_localizations.dart'; import 'package:paintroid/tool/tool.dart'; +import 'package:paintroid/ui/drawing_space/color_picker_dialog.dart'; import 'package:paintroid/ui/drawing_space/tools_bottom_sheet.dart'; import 'package:paintroid/ui/shared/bottom_nav_bar_icon.dart'; import 'package:paintroid/ui/styles.dart'; -class BottomNavBar extends StatelessWidget { +Color selectedColor = Colors.black; +final selectedColorProvider = StateProvider((ref) => Colors.black); + +class BottomNavBar extends StatefulWidget { static const height = 64.0; const BottomNavBar({Key? key}) : super(key: key); + @override + State createState() => _BottomNavBarState(); +} + +class _BottomNavBarState extends State { void _onNavigationItemSelected(int index, BuildContext context) { if (index == 0) { showModalBottomSheet( @@ -21,6 +30,36 @@ class BottomNavBar extends StatelessWidget { ), ); } + if (index == 2) { + _showColorPicker(context); + } + } + + void _showColorPicker(BuildContext context) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + contentPadding: const EdgeInsets.all(20), + content: ColorPickerDialog( + selectedColor: Colors.red, // Set your initial color here + onColorChanged: (Color color) { + setState(() { + selectedColor = color; + }); + }, + ), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Text('Done'), + ), + ], + ); + }, + ); } @override @@ -29,7 +68,7 @@ class BottomNavBar extends StatelessWidget { return NavigationBarTheme( data: WidgetThemes.bottomNavBarThemeData, child: NavigationBar( - height: height, + height: BottomNavBar.height, onDestinationSelected: (index) => _onNavigationItemSelected(index, context), destinations: [ @@ -57,9 +96,9 @@ class BottomNavBar extends StatelessWidget { NavigationDestination( label: localizations.color, icon: Icon( - Icons.check_box_outline_blank, + Icons.square, size: 24, - color: Theme.of(context).colorScheme.onSurface, + color: selectedColor, ), ), NavigationDestination( diff --git a/lib/ui/drawing_space/color_box.dart b/lib/ui/drawing_space/color_box.dart new file mode 100644 index 00000000..61614eef --- /dev/null +++ b/lib/ui/drawing_space/color_box.dart @@ -0,0 +1,22 @@ +import 'package:flutter/material.dart'; + +class ColorBox extends StatelessWidget { + const ColorBox({ + required this.color, + super.key, + }); + + final Color color; + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: color, + ), + height: 40, + width: 40, + ); + } +} diff --git a/lib/ui/drawing_space/color_picker_dialog.dart b/lib/ui/drawing_space/color_picker_dialog.dart new file mode 100644 index 00000000..0b033a6a --- /dev/null +++ b/lib/ui/drawing_space/color_picker_dialog.dart @@ -0,0 +1,52 @@ +import 'package:flex_color_picker/flex_color_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:paintroid/ui/drawing_space/color_box.dart'; + +class ColorPickerDialog extends StatelessWidget { + const ColorPickerDialog({ + required this.selectedColor, + required this.onColorChanged, + super.key, + }); + + final Color selectedColor; + final Function(Color) onColorChanged; + + @override + Widget build(BuildContext context) { + return IntrinsicHeight( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ColorBox(color: Colors.black), + ColorBox(color: Colors.green), + ColorBox(color: Colors.red), + ColorBox(color: Colors.blue), + ], + ), + const SizedBox(height: 16), + ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: Colors.white, + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 20), + ), + onPressed: () { + ColorPicker( + color: selectedColor, + onColorChanged: onColorChanged, + ) + .showPickerDialog( + context, + ) + .then((value) => Navigator.pop(context)); + }, + child: const Text('Open Color Picker'), + ), + ], + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 9811a1c3..5f88f5a3 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -181,10 +181,10 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.17.2" convert: dependency: transitive description: @@ -313,6 +313,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + flex_color_picker: + dependency: "direct main" + description: + name: flex_color_picker + sha256: f37476ab3e80dcaca94e428e159944d465dd16312fda9ff41e07e86f04bfa51c + url: "https://pub.dev" + source: hosted + version: "3.3.0" + flex_seed_scheme: + dependency: transitive + description: + name: flex_seed_scheme + sha256: "29c12aba221eb8a368a119685371381f8035011d18de5ba277ad11d7dfb8657f" + url: "https://pub.dev" + source: hosted + version: "1.4.0" floor: dependency: "direct main" description: @@ -388,10 +404,10 @@ packages: dependency: "direct main" description: name: flutter_riverpod - sha256: b83ac5827baadefd331ea1d85110f34645827ea234ccabf53a655f41901a9bf4 + sha256: da9591d1f8d5881628ccd5c25c40e74fc3eef50ba45e40c3905a06e1712412d5 url: "https://pub.dev" source: hosted - version: "2.3.6" + version: "2.4.9" flutter_svg: dependency: "direct main" description: @@ -544,10 +560,10 @@ packages: dependency: "direct main" description: name: intl - sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" url: "https://pub.dev" source: hosted - version: "0.18.0" + version: "0.18.1" io: dependency: transitive description: @@ -608,18 +624,18 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.5.0" meta: dependency: transitive description: @@ -640,10 +656,10 @@ packages: dependency: "direct dev" description: name: mockito - sha256: dd61809f04da1838a680926de50a9e87385c1de91c6579629c3d1723946e8059 + sha256: "8b46d7eb40abdda92d62edd01546051f0c27365e65608c284de336dccfef88cc" url: "https://pub.dev" source: hosted - version: "5.4.0" + version: "5.4.1" oxidized: dependency: "direct main" description: @@ -856,10 +872,10 @@ packages: dependency: "direct dev" description: name: riverpod - sha256: "80e48bebc83010d5e67a11c9514af6b44bbac1ec77b4333c8ea65dbc79e2d8ef" + sha256: "942999ee48b899f8a46a860f1e13cee36f2f77609eb54c5b7a669bb20d550b11" url: "https://pub.dev" source: hosted - version: "2.3.6" + version: "2.4.9" riverpod_analyzer_utils: dependency: transitive description: @@ -997,10 +1013,10 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" sqflite: dependency: "direct main" description: @@ -1117,10 +1133,10 @@ packages: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.6.0" timing: dependency: transitive description: @@ -1237,10 +1253,10 @@ packages: dependency: transitive description: name: vm_service - sha256: f6deed8ed625c52864792459709183da231ebf66ff0cf09e69b573227c377efe + sha256: c620a6f783fa22436da68e42db7ebbf18b8c44b9a46ab911f666ff09ffd9153f url: "https://pub.dev" source: hosted - version: "11.3.0" + version: "11.7.1" watcher: dependency: transitive description: @@ -1249,6 +1265,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.2" + web: + dependency: transitive + description: + name: web + sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + url: "https://pub.dev" + source: hosted + version: "0.1.4-beta" web_socket_channel: dependency: transitive description: @@ -1306,5 +1330,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.0.0-0 <4.0.0" - flutter: ">=3.3.0" + dart: ">=3.1.0-185.0.dev <4.0.0" + flutter: ">=3.10.0" diff --git a/pubspec.yaml b/pubspec.yaml index a5e01859..22a46660 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,6 +37,7 @@ dependencies: launch_review: ^3.0.1 smooth_page_indicator: ^1.0.0+2 shared_preferences: ^2.0.15 + flex_color_picker: ^3.3.0 dev_dependencies: flutter_test: From a6cafb02779633b9c9f94696042f0c4efeb9b455 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Tue, 16 Jan 2024 20:32:50 +0530 Subject: [PATCH 02/39] Implement color picker --- colorpicker/.gitignore | 29 ++++ colorpicker/.metadata | 10 ++ colorpicker/CHANGELOG.md | 3 + colorpicker/LICENSE | 1 + colorpicker/README.md | 39 +++++ colorpicker/analysis_options.yaml | 4 + colorpicker/assets/img/checkerboard.png | Bin 0 -> 103386 bytes colorpicker/lib/colorpicker.dart | 116 +++++++++++++ colorpicker/lib/constants/colors.dart | 25 +++ colorpicker/lib/widgets/color_compare.dart | 69 ++++++++ colorpicker/lib/widgets/slider.dart | 81 ++++++++++ colorpicker/lib/widgets/slider_indicator.dart | 20 +++ colorpicker/pubspec.yaml | 52 ++++++ colorpicker/test/colorpicker_test.dart | 7 + lib/core/path_with_action_history.dart | 153 +++++++++++++++++- lib/ui/drawing_space/bottom_nav_bar.dart | 46 +++--- lib/ui/drawing_space/color_picker_dialog.dart | 52 ------ pubspec.lock | 25 +-- pubspec.yaml | 3 +- 19 files changed, 633 insertions(+), 102 deletions(-) create mode 100644 colorpicker/.gitignore create mode 100644 colorpicker/.metadata create mode 100644 colorpicker/CHANGELOG.md create mode 100644 colorpicker/LICENSE create mode 100644 colorpicker/README.md create mode 100644 colorpicker/analysis_options.yaml create mode 100644 colorpicker/assets/img/checkerboard.png create mode 100644 colorpicker/lib/colorpicker.dart create mode 100644 colorpicker/lib/constants/colors.dart create mode 100644 colorpicker/lib/widgets/color_compare.dart create mode 100644 colorpicker/lib/widgets/slider.dart create mode 100644 colorpicker/lib/widgets/slider_indicator.dart create mode 100644 colorpicker/pubspec.yaml create mode 100644 colorpicker/test/colorpicker_test.dart delete mode 100644 lib/ui/drawing_space/color_picker_dialog.dart diff --git a/colorpicker/.gitignore b/colorpicker/.gitignore new file mode 100644 index 00000000..ac5aa989 --- /dev/null +++ b/colorpicker/.gitignore @@ -0,0 +1,29 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +build/ diff --git a/colorpicker/.metadata b/colorpicker/.metadata new file mode 100644 index 00000000..6ceac0ff --- /dev/null +++ b/colorpicker/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "9e1c857886f07d342cf106f2cd588bcd5e031bb2" + channel: "stable" + +project_type: package diff --git a/colorpicker/CHANGELOG.md b/colorpicker/CHANGELOG.md new file mode 100644 index 00000000..41cc7d81 --- /dev/null +++ b/colorpicker/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/colorpicker/LICENSE b/colorpicker/LICENSE new file mode 100644 index 00000000..ba75c69f --- /dev/null +++ b/colorpicker/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/colorpicker/README.md b/colorpicker/README.md new file mode 100644 index 00000000..02fe8eca --- /dev/null +++ b/colorpicker/README.md @@ -0,0 +1,39 @@ + + +TODO: Put a short description of the package here that helps potential users +know whether this package might be useful for them. + +## Features + +TODO: List what your package can do. Maybe include images, gifs, or videos. + +## Getting started + +TODO: List prerequisites and provide or point to information on how to +start using the package. + +## Usage + +TODO: Include short and useful examples for package users. Add longer examples +to `/example` folder. + +```dart +const like = 'sample'; +``` + +## Additional information + +TODO: Tell users more about the package: where to find more information, how to +contribute to the package, how to file issues, what response they can expect +from the package authors, and more. diff --git a/colorpicker/analysis_options.yaml b/colorpicker/analysis_options.yaml new file mode 100644 index 00000000..a5744c1c --- /dev/null +++ b/colorpicker/analysis_options.yaml @@ -0,0 +1,4 @@ +include: package:flutter_lints/flutter.yaml + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/colorpicker/assets/img/checkerboard.png b/colorpicker/assets/img/checkerboard.png new file mode 100644 index 0000000000000000000000000000000000000000..ecc4202152720c6c84ef5dfe5314bad3f1e885a9 GIT binary patch literal 103386 zcmeHQe{56b8t&;LL@8~#9kFETKlPa9?_A0a;#(=DhWfe{4Lg~OXFq(Y z<&mj5yc|S>SB)me~1PN~gd zjJhYeyw#B^-jgkzrS8ZoJKFdE*Qgyt3Vj-SICp5T^wynZ_hh3+)Uh*_Z7cca*cs{=u|d=Hko$dgUllu}!ow@o?^u+aZISPg z)899!7l*5euP$4sef^?kZNb{Movc^8{-?OB4)n>(540z$)UP^8pWLQHnVN~ckw?`X z(%W1TF1_*(+#1{(L=B>b#RH9gXkxCxTq7Y3K!%144aqZ-XJxrZFCDP1!IG1V0W3Lz z1^}p0AQS*Kz|bgk5AY`7O(4%eo>3G)y$1Cfl+s9n6;)1DIZ=QvK#@>@1~&k-4bV2g zr~%mt7#etJHc$jX5d?b^?9Dvo7sOg{p22wr4-Gst@X)|R0}l;6G#jK(ETm7(P^CdI z2*DsV2B77HmJ>2tD4?N$Cfa;O%lVfD>zZbI0RT@!4*@M(Ko5ax2Xvk2yn)UeXo`ZS zC~6xY=sM9#=&CUQT_<#%&~-xBiQZ@&IB95GhmL|AIBCGpfT00H%lB^uCk>o5aMHj@ z11AlfG;q=!;H2^3q@jsDn%L800Gu>%(tZ^uZGY|dOQ)aMzM!b1I{nc>=K<>pr+L7* zVNE<$yyK|07@ccv3sx-;`t6E~hv+}dl;_&W)hk2Tw^uRbD4H8DHp``5H6<4^>%ZfNdO6#`Qn|K% z52G1?3`AI8;$33np==iPO1j6z(agg9O0sr;FzYJw#&~t-p3T(9!n>u!nBGCkEKk{A z%b^e%`*fyziRxY<`dNP2(=#3=Lg-vN{%=0$SC87q(;GQ^*uZGpmsf^r=O_nDRDNEcnVYbKOp~_OYZaM=`qdpY>z*I<=L4hu(DC(SGZrRc?v1=r ziD$?(9igZP%usvJ70nSvx$rHT8B2*R_IBP7#o3+G9ZUw6dK`)9#@wwpyGy!iEk$eHwb%gBGDyFTPIq(9$P zV{*>xd@eiiqnhbAQkTsC!~F5x_II>F5qqBHk{S0m#p-0nps!IIobi4$82Edd+pIm@+sMy?9|`Q~Rmwylk+ z(iXMD772cRcs3@O;T?}Zqm8JDyny;z(L?3aJ1(GW*p2om~l9yYDm=-G#9B_ z&cD%$H4fG|SmOX3061`MBnsdFP&J@xK-GY%0geV74LJHbtmEAOS+8xT7XT^Ep{7Hs zmq^=?wjpgp+J>|ZX&cfuq;1z>+J;oETBTDWRYR(VR1K*bQZ=M%NY#+4AyorY8cbiqh@S&?*Y8qR?ZFv~r~b0hAk1Za}#KgW7Tr1Lp1hk%On9)>c5mNQ&YK0czX|3ORwsHp#ga&V*qHtt`F3#ilv_!K%P;r0fvSpCzhO8a;iwVt#$KNU>%m6SaM>? zi6tjWY0VB6$uqrr0NDuzXjD1%W(kE@Jt%^xaw2&~@{Hse$up8?B+mi|r2xoIViaU2 zqbA~!psz7a54nLn19{#Xc~mXI(8LAM(II_;U=Sh>&^CJQUm|&iQh;wp^89-fr~k`T z^WID^0L|Ne7C33(q=AzLP8v9AKn8#e02xr)_|Uir1RW4`K+sVV_d(F18Tz5DhO!!v zf!`Z405m{ra|DttNVXu^f@BMxz&OwVpaDPwY@$EKqp@&dn_RSa02%-^KjsG~al(Lv_{>j|fMz_?*eJXO5os9<0e zuD`V{ShYOpw=4E)qW>^co_F7{idANJIB+tNUazRc2#lLuaCtV_gus77fz`;Oe8Q)g zQBCETu`%+Mbc+vXd0-zog1RGN-(KzD@nW-F+Er6>A+!EFeyCS5c#~`E_b}?2RS!g1 zU*cWDFH|-QdL_M0@6pV{yc0<6{$SQs=8f^{&OMu{kA-(ji80;r!z@qPUt6q!ml^wX zrh7@w{Dh@VR6^&{KkvOVM>$xsvh@q)Vvz6hJY!#*)mxX-_A~4tJSgEo2@lE})q@hg zlW|_P;)3rad?%Tq_MR)6Mi9P}@STM3Bzz}tG~dahQ?9Rbz6_>%- z0%vPu3W0;balILxI;LC($1s(5wD$bqU81HVL>dN(0VD>H7*HAuNDLq`fW!b2gRiCL zL-U{WB}!R^JD8?f>F)6GXi&9bA(~{iji`_{jWz-YfrG$7;Gq8iv^fy9fhis5z?248 z4a@-)KvBm591S=caI~gnw=`3Fk*-C~a!vY9KzbTXXnxjXLmkI1wjgj2I0&3Rt)X+6 z0wO&_rs)Xfgn&8@>NxZaB5ZM-Lf{~9)bwJREcEC-V3$X_=SQSUt>w-cfqrtJ0E#*e z>Nu$5ppJ9h)N#T$O{NWon>N(ft!Pj>c7yN<-kQ!j08lWu8m)1Wwjpgp+IFL*ZJ8f0 zp5{8tTt{QJ>BtLw*DZ~b$+cP>DT^2PrG)5_yK|MJY(e|eYiiOjwkBJr0P20vt@pv*e(0>wjint<|OSVQs9%qB{S}CiZuh3YmJSju0^>Tt&c5z Z^4%{Q{=Rh883XyR{^3=1{SSFM{s$oSe3k$J literal 0 HcmV?d00001 diff --git a/colorpicker/lib/colorpicker.dart b/colorpicker/lib/colorpicker.dart new file mode 100644 index 00000000..09a335b3 --- /dev/null +++ b/colorpicker/lib/colorpicker.dart @@ -0,0 +1,116 @@ +library colorpicker; + +import 'package:colorpicker/constants/colors.dart'; +import 'package:colorpicker/widgets/color_compare.dart'; +import 'package:colorpicker/widgets/slider.dart'; +import 'package:flutter/material.dart'; + +class ColorPicker extends StatefulWidget { + const ColorPicker({ + super.key, + required this.currentColor, + required this.onColorChanged, + }); + + final Color currentColor; + final void Function(Color) onColorChanged; + + @override + State createState() => _ColorPickerState(); +} + +class _ColorPickerState extends State { + final colors = DisplayColors.colors; + Color newColor = Colors.black; + double opacity = 1.0; + + void callback(Color color, double op) { + setState(() { + opacity = op; + }); + } + + @override + void initState() { + super.initState(); + newColor = widget.currentColor; + } + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.all(26), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16), + ), + child: Column( + children: [ + ColorCompare( + currentColor: widget.currentColor, + newColor: newColor.withOpacity(opacity), + ), + const SizedBox( + height: 10, + ), + GridView.count( + childAspectRatio: 1.4, + crossAxisCount: 4, + crossAxisSpacing: 2.0, + mainAxisSpacing: 2.0, + shrinkWrap: true, + children: List.generate( + colors.length + 1, + (index) { + if (index == colors.length) { + return Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/img/checkerboard.png'), + fit: BoxFit.contain, + repeat: ImageRepeat.repeat, + ), + ), + ); + } + return GestureDetector( + onTap: () { + setState(() { + newColor = colors[index]; + }); + }, + child: Container( + decoration: BoxDecoration( + color: colors[index], + ), + ), + ); + }, + ), + ), + const SizedBox( + height: 30, + ), + OpacitySlider( + gradientColor: newColor, + callback: callback, + ), + const Spacer(), + Row( + children: [ + const Spacer(), + TextButton(onPressed: (){ + Navigator.pop(context); + }, child: const Text('CANCEL')), + const SizedBox(width: 10,), + TextButton(onPressed: (){ + widget.onColorChanged(newColor.withOpacity(opacity)); + Navigator.pop(context); + }, child: const Text('APPLY')), + ], + ) + ], + ), + ); + } +} diff --git a/colorpicker/lib/constants/colors.dart b/colorpicker/lib/constants/colors.dart new file mode 100644 index 00000000..72598514 --- /dev/null +++ b/colorpicker/lib/constants/colors.dart @@ -0,0 +1,25 @@ +import 'dart:ui'; + +class DisplayColors { + static const colors = [ + Color(0xff0073cc), + Color(0xff00b4f1), + Color(0xff068708), + Color(0xff8EC430), + Color(0xff61290e), + Color(0xffa84818), + Color(0xffdeae66), + Color(0xfff0e4a8), + Color(0xff7d1378), + Color(0xffa643d1), + Color(0xffca0086), + Color(0xffeb90d3), + Color(0xffc5060e), + Color(0xffeb4618), + Color(0xfff9921c), + Color(0xfff2d606), + Color(0xff000000), + Color(0xffa3a3a3), + Color(0xffffffff), + ]; +} diff --git a/colorpicker/lib/widgets/color_compare.dart b/colorpicker/lib/widgets/color_compare.dart new file mode 100644 index 00000000..a7c6c8a0 --- /dev/null +++ b/colorpicker/lib/widgets/color_compare.dart @@ -0,0 +1,69 @@ +import 'package:flutter/material.dart'; + +class ColorCompare extends StatefulWidget { + const ColorCompare({ + super.key, + required this.currentColor, + required this.newColor, + }); + + final Color currentColor; + final Color newColor; + + @override + State createState() => _ColorCompareState(); +} + +class _ColorCompareState extends State { + @override + Widget build(BuildContext context) { + return Container( + width: 130, + height: 70, + child: Row( + children: [ + Expanded( + child: ColorDesc( + color: widget.currentColor, + desc: 'current', + ), + ), + Expanded( + child: ColorDesc( + color: widget.newColor, + desc: 'new', + ), + ), + ], + ), + ); + } +} + +class ColorDesc extends StatelessWidget { + const ColorDesc({ + super.key, + required this.color, + required this.desc, + }); + + final Color color; + final String desc; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + Expanded( + child: Container( + color: color, + ), + ), + const SizedBox(width: 8), + Text(desc, style: const TextStyle( + color: Color.fromARGB(255, 149, 149, 149) + ),), + ], + ); + } +} \ No newline at end of file diff --git a/colorpicker/lib/widgets/slider.dart b/colorpicker/lib/widgets/slider.dart new file mode 100644 index 00000000..39db2e2a --- /dev/null +++ b/colorpicker/lib/widgets/slider.dart @@ -0,0 +1,81 @@ +import 'package:colorpicker/widgets/slider_indicator.dart'; +import 'package:flutter/material.dart'; + +class OpacitySlider extends StatefulWidget { + const OpacitySlider({ + super.key, + required this.gradientColor, + required this.callback, + }); + + final Color gradientColor; + final Function(Color, double) callback; + + @override + State createState() => _OpacitySliderState(); +} + +class _OpacitySliderState extends State { + double _sliderPosition = 0; + double _positionFraction = 0; + + void _handleColorChange(double position, double widgetWidth) { + if (position < 0) { + position = 0; + } + if (position > widgetWidth) { + position = widgetWidth; + } + setState(() { + _sliderPosition = position; + _positionFraction = _sliderPosition / widgetWidth; + widget.callback( + widget.gradientColor, + 1 - _positionFraction, + ); + }); + } + + @override + Widget build(BuildContext context) { + double widgetWidth = MediaQuery.of(context).size.width - 52; + return Container( + height: 25, + width: widgetWidth, + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage('assets/img/checkerboard.png'), + fit: BoxFit.fitHeight, + repeat: ImageRepeat.repeat, + ), + ), + child: GestureDetector( + onHorizontalDragStart: (DragStartDetails details) {}, + onHorizontalDragUpdate: (DragUpdateDetails details) { + double position = details.localPosition.dx; + _handleColorChange(position, widgetWidth); + }, + onHorizontalDragEnd: (DragEndDetails details) {}, + onTapDown: (TapDownDetails details) { + double position = details.localPosition.dx; + _handleColorChange(position, widgetWidth); + }, + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + widget.gradientColor, + widget.gradientColor.withOpacity(0), + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + child: CustomPaint( + painter: SliderIndicatorPainter(_sliderPosition), + ), + ), + ), + ); + } +} diff --git a/colorpicker/lib/widgets/slider_indicator.dart b/colorpicker/lib/widgets/slider_indicator.dart new file mode 100644 index 00000000..35826baa --- /dev/null +++ b/colorpicker/lib/widgets/slider_indicator.dart @@ -0,0 +1,20 @@ +import 'package:flutter/material.dart'; + +class SliderIndicatorPainter extends CustomPainter { + final double position; + SliderIndicatorPainter(this.position); + @override + void paint(Canvas canvas, Size size) { + canvas.drawRect( + Offset(position, -1) & Size(6, size.height + 2), + Paint() + ..color = const Color.fromARGB(255, 62, 62, 62) + ..style = PaintingStyle.stroke + ..strokeWidth = 2); + } + + @override + bool shouldRepaint(SliderIndicatorPainter oldDelegate) { + return true; + } +} diff --git a/colorpicker/pubspec.yaml b/colorpicker/pubspec.yaml new file mode 100644 index 00000000..bf1da0a0 --- /dev/null +++ b/colorpicker/pubspec.yaml @@ -0,0 +1,52 @@ +name: colorpicker +description: "A new Flutter package project." +version: 0.0.1 +homepage: + +environment: + sdk: ">=2.17.0 <3.0.0" + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^2.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + + assets: + - assets/img/ + # + # For details regarding assets in packages, see + # https://flutter.dev/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware + + # To add custom fonts to your package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/custom-fonts/#from-packages diff --git a/colorpicker/test/colorpicker_test.dart b/colorpicker/test/colorpicker_test.dart new file mode 100644 index 00000000..72bdd0b2 --- /dev/null +++ b/colorpicker/test/colorpicker_test.dart @@ -0,0 +1,7 @@ +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('test colorpicker', () { + + }); +} diff --git a/lib/core/path_with_action_history.dart b/lib/core/path_with_action_history.dart index 75bffb9b..78a411ce 100644 --- a/lib/core/path_with_action_history.dart +++ b/lib/core/path_with_action_history.dart @@ -1,24 +1,169 @@ +import 'dart:typed_data'; import 'dart:ui'; -class PathWithActionHistory extends Path { +class PathWithActionHistory implements Path { final actions = []; + final _path = Path(); + @override void moveTo(double x, double y) { actions.add(MoveToAction(x, y)); - super.moveTo(x, y); + _path.moveTo(x, y); } @override void lineTo(double x, double y) { actions.add(LineToAction(x, y)); - super.lineTo(x, y); + _path.lineTo(x, y); } @override void close() { actions.add(const CloseAction()); - super.close(); + _path.close(); + } + + @override + PathFillType get fillType => _path.fillType; + + @override + void set fillType(PathFillType value) => _path.fillType = value; + + @override + void addArc(Rect oval, double startAngle, double sweepAngle) { + // TODO: implement addArc + } + + @override + void addOval(Rect oval) { + // TODO: implement addOval + } + + @override + void addPath(Path path, Offset offset, {Float64List? matrix4}) { + // TODO: implement addPath + } + + @override + void addPolygon(List points, bool close) { + // TODO: implement addPolygon + } + + @override + void addRRect(RRect rrect) { + // TODO: implement addRRect + } + + @override + void addRect(Rect rect) { + // TODO: implement addRect + } + + @override + void arcTo( + Rect rect, double startAngle, double sweepAngle, bool forceMoveTo) { + // TODO: implement arcTo + } + + @override + void arcToPoint(Offset arcEnd, + {Radius radius = Radius.zero, + double rotation = 0.0, + bool largeArc = false, + bool clockwise = true}) { + // TODO: implement arcToPoint + } + + @override + PathMetrics computeMetrics({bool forceClosed = false}) { + // TODO: implement computeMetrics + throw UnimplementedError(); + } + + @override + void conicTo(double x1, double y1, double x2, double y2, double w) { + // TODO: implement conicTo + } + + @override + bool contains(Offset point) { + // TODO: implement contains + throw UnimplementedError(); + } + + @override + void cubicTo( + double x1, double y1, double x2, double y2, double x3, double y3) { + // TODO: implement cubicTo + } + + @override + void extendWithPath(Path path, Offset offset, {Float64List? matrix4}) { + // TODO: implement extendWithPath + } + + @override + Rect getBounds() { + // TODO: implement getBounds + throw UnimplementedError(); + } + + @override + void quadraticBezierTo(double x1, double y1, double x2, double y2) { + // TODO: implement quadraticBezierTo + } + + @override + void relativeArcToPoint(Offset arcEndDelta, + {Radius radius = Radius.zero, + double rotation = 0.0, + bool largeArc = false, + bool clockwise = true}) { + // TODO: implement relativeArcToPoint + } + + @override + void relativeConicTo(double x1, double y1, double x2, double y2, double w) { + // TODO: implement relativeConicTo + } + + @override + void relativeCubicTo( + double x1, double y1, double x2, double y2, double x3, double y3) { + // TODO: implement relativeCubicTo + } + + @override + void relativeLineTo(double dx, double dy) { + // TODO: implement relativeLineTo + } + + @override + void relativeMoveTo(double dx, double dy) { + // TODO: implement relativeMoveTo + } + + @override + void relativeQuadraticBezierTo(double x1, double y1, double x2, double y2) { + // TODO: implement relativeQuadraticBezierTo + } + + @override + void reset() { + // TODO: implement reset + } + + @override + Path shift(Offset offset) { + // TODO: implement shift + throw UnimplementedError(); + } + + @override + Path transform(Float64List matrix4) { + // TODO: implement transform + throw UnimplementedError(); } } diff --git a/lib/ui/drawing_space/bottom_nav_bar.dart b/lib/ui/drawing_space/bottom_nav_bar.dart index ca442f23..772ad00c 100644 --- a/lib/ui/drawing_space/bottom_nav_bar.dart +++ b/lib/ui/drawing_space/bottom_nav_bar.dart @@ -1,8 +1,8 @@ +import 'package:colorpicker/colorpicker.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:paintroid/core/app_localizations.dart'; import 'package:paintroid/tool/tool.dart'; -import 'package:paintroid/ui/drawing_space/color_picker_dialog.dart'; import 'package:paintroid/ui/drawing_space/tools_bottom_sheet.dart'; import 'package:paintroid/ui/shared/bottom_nav_bar_icon.dart'; import 'package:paintroid/ui/styles.dart'; @@ -31,36 +31,26 @@ class _BottomNavBarState extends State { ); } if (index == 2) { - _showColorPicker(context); + showModalBottomSheet( + context: context, + isScrollControlled: true, + builder: (BuildContext context) => Container( + height: MediaQuery.of(context).size.height * 0.7, + alignment: Alignment.center, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + ), + child: ColorPicker( + currentColor: Colors.black, + onColorChanged: (color) {}, + ), + ), + ); } } - void _showColorPicker(BuildContext context) { - showDialog( - context: context, - builder: (BuildContext context) { - return AlertDialog( - contentPadding: const EdgeInsets.all(20), - content: ColorPickerDialog( - selectedColor: Colors.red, // Set your initial color here - onColorChanged: (Color color) { - setState(() { - selectedColor = color; - }); - }, - ), - actions: [ - TextButton( - onPressed: () { - Navigator.pop(context); - }, - child: const Text('Done'), - ), - ], - ); - }, - ); - } + @override Widget build(BuildContext context) { diff --git a/lib/ui/drawing_space/color_picker_dialog.dart b/lib/ui/drawing_space/color_picker_dialog.dart deleted file mode 100644 index 0b033a6a..00000000 --- a/lib/ui/drawing_space/color_picker_dialog.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flex_color_picker/flex_color_picker.dart'; -import 'package:flutter/material.dart'; -import 'package:paintroid/ui/drawing_space/color_box.dart'; - -class ColorPickerDialog extends StatelessWidget { - const ColorPickerDialog({ - required this.selectedColor, - required this.onColorChanged, - super.key, - }); - - final Color selectedColor; - final Function(Color) onColorChanged; - - @override - Widget build(BuildContext context) { - return IntrinsicHeight( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - ColorBox(color: Colors.black), - ColorBox(color: Colors.green), - ColorBox(color: Colors.red), - ColorBox(color: Colors.blue), - ], - ), - const SizedBox(height: 16), - ElevatedButton( - style: ElevatedButton.styleFrom( - backgroundColor: Colors.white, - padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 20), - ), - onPressed: () { - ColorPicker( - color: selectedColor, - onColorChanged: onColorChanged, - ) - .showPickerDialog( - context, - ) - .then((value) => Navigator.pop(context)); - }, - child: const Text('Open Color Picker'), - ), - ], - ), - ); - } -} diff --git a/pubspec.lock b/pubspec.lock index 5f88f5a3..c745224f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -185,6 +185,13 @@ packages: url: "https://pub.dev" source: hosted version: "1.17.2" + colorpicker: + dependency: "direct main" + description: + path: colorpicker + relative: true + source: path + version: "0.0.1" convert: dependency: transitive description: @@ -313,22 +320,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" - flex_color_picker: - dependency: "direct main" - description: - name: flex_color_picker - sha256: f37476ab3e80dcaca94e428e159944d465dd16312fda9ff41e07e86f04bfa51c - url: "https://pub.dev" - source: hosted - version: "3.3.0" - flex_seed_scheme: - dependency: transitive - description: - name: flex_seed_scheme - sha256: "29c12aba221eb8a368a119685371381f8035011d18de5ba277ad11d7dfb8657f" - url: "https://pub.dev" - source: hosted - version: "1.4.0" floor: dependency: "direct main" description: @@ -1331,4 +1322,4 @@ packages: version: "3.1.2" sdks: dart: ">=3.1.0-185.0.dev <4.0.0" - flutter: ">=3.10.0" + flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index 22a46660..dbdc8a32 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,7 +37,8 @@ dependencies: launch_review: ^3.0.1 smooth_page_indicator: ^1.0.0+2 shared_preferences: ^2.0.15 - flex_color_picker: ^3.3.0 + colorpicker: + path: ./colorpicker dev_dependencies: flutter_test: From 29f018761303fec007fd8c9d5366a4fdd33ceba3 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Tue, 16 Jan 2024 20:45:53 +0530 Subject: [PATCH 03/39] Fix issues --- colorpicker/lib/widgets/color_compare.dart | 2 +- lib/core/path_with_action_history.dart | 153 +-------------------- 2 files changed, 5 insertions(+), 150 deletions(-) diff --git a/colorpicker/lib/widgets/color_compare.dart b/colorpicker/lib/widgets/color_compare.dart index a7c6c8a0..c1b5bce2 100644 --- a/colorpicker/lib/widgets/color_compare.dart +++ b/colorpicker/lib/widgets/color_compare.dart @@ -17,7 +17,7 @@ class ColorCompare extends StatefulWidget { class _ColorCompareState extends State { @override Widget build(BuildContext context) { - return Container( + return SizedBox( width: 130, height: 70, child: Row( diff --git a/lib/core/path_with_action_history.dart b/lib/core/path_with_action_history.dart index 78a411ce..75bffb9b 100644 --- a/lib/core/path_with_action_history.dart +++ b/lib/core/path_with_action_history.dart @@ -1,169 +1,24 @@ -import 'dart:typed_data'; import 'dart:ui'; -class PathWithActionHistory implements Path { +class PathWithActionHistory extends Path { final actions = []; - final _path = Path(); - @override void moveTo(double x, double y) { actions.add(MoveToAction(x, y)); - _path.moveTo(x, y); + super.moveTo(x, y); } @override void lineTo(double x, double y) { actions.add(LineToAction(x, y)); - _path.lineTo(x, y); + super.lineTo(x, y); } @override void close() { actions.add(const CloseAction()); - _path.close(); - } - - @override - PathFillType get fillType => _path.fillType; - - @override - void set fillType(PathFillType value) => _path.fillType = value; - - @override - void addArc(Rect oval, double startAngle, double sweepAngle) { - // TODO: implement addArc - } - - @override - void addOval(Rect oval) { - // TODO: implement addOval - } - - @override - void addPath(Path path, Offset offset, {Float64List? matrix4}) { - // TODO: implement addPath - } - - @override - void addPolygon(List points, bool close) { - // TODO: implement addPolygon - } - - @override - void addRRect(RRect rrect) { - // TODO: implement addRRect - } - - @override - void addRect(Rect rect) { - // TODO: implement addRect - } - - @override - void arcTo( - Rect rect, double startAngle, double sweepAngle, bool forceMoveTo) { - // TODO: implement arcTo - } - - @override - void arcToPoint(Offset arcEnd, - {Radius radius = Radius.zero, - double rotation = 0.0, - bool largeArc = false, - bool clockwise = true}) { - // TODO: implement arcToPoint - } - - @override - PathMetrics computeMetrics({bool forceClosed = false}) { - // TODO: implement computeMetrics - throw UnimplementedError(); - } - - @override - void conicTo(double x1, double y1, double x2, double y2, double w) { - // TODO: implement conicTo - } - - @override - bool contains(Offset point) { - // TODO: implement contains - throw UnimplementedError(); - } - - @override - void cubicTo( - double x1, double y1, double x2, double y2, double x3, double y3) { - // TODO: implement cubicTo - } - - @override - void extendWithPath(Path path, Offset offset, {Float64List? matrix4}) { - // TODO: implement extendWithPath - } - - @override - Rect getBounds() { - // TODO: implement getBounds - throw UnimplementedError(); - } - - @override - void quadraticBezierTo(double x1, double y1, double x2, double y2) { - // TODO: implement quadraticBezierTo - } - - @override - void relativeArcToPoint(Offset arcEndDelta, - {Radius radius = Radius.zero, - double rotation = 0.0, - bool largeArc = false, - bool clockwise = true}) { - // TODO: implement relativeArcToPoint - } - - @override - void relativeConicTo(double x1, double y1, double x2, double y2, double w) { - // TODO: implement relativeConicTo - } - - @override - void relativeCubicTo( - double x1, double y1, double x2, double y2, double x3, double y3) { - // TODO: implement relativeCubicTo - } - - @override - void relativeLineTo(double dx, double dy) { - // TODO: implement relativeLineTo - } - - @override - void relativeMoveTo(double dx, double dy) { - // TODO: implement relativeMoveTo - } - - @override - void relativeQuadraticBezierTo(double x1, double y1, double x2, double y2) { - // TODO: implement relativeQuadraticBezierTo - } - - @override - void reset() { - // TODO: implement reset - } - - @override - Path shift(Offset offset) { - // TODO: implement shift - throw UnimplementedError(); - } - - @override - Path transform(Float64List matrix4) { - // TODO: implement transform - throw UnimplementedError(); + super.close(); } } From 432fbf87ba3de0e9370270ad57d4fa1170a00141 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Tue, 23 Jan 2024 03:09:36 +0530 Subject: [PATCH 04/39] Merge with develop --- .fvm/fvm_config.json | 4 + .gitignore | 22 +- Makefile | 60 +- README.md | 108 +- analysis_options.yaml | 5 +- generate_files.sh | 1 - generate_protos.sh | 4 +- ios/Flutter/AppFrameworkInfo.plist | 2 +- ios/Podfile | 2 +- ios/Podfile.lock | 76 +- ios/Runner.xcodeproj/project.pbxproj | 11 +- ios/Runner/Info.plist | 2 + l10n.yaml | 3 - lib/core/app_localizations.dart | 10 - lib/core/path_with_action_history.dart | 45 - lib/io/io.dart | 18 - lib/main.dart | 62 +- lib/pocket_paint_app.dart | 66 + lib/ui/drawing_space/color_box.dart | 22 - lib/workspace/workspace.dart | 4 - melos.yaml | 97 ++ .../colorpicker}/.gitignore | 0 .../colorpicker}/.metadata | 0 .../colorpicker}/CHANGELOG.md | 0 {colorpicker => packages/colorpicker}/LICENSE | 0 .../colorpicker}/README.md | 0 .../colorpicker}/analysis_options.yaml | 0 .../colorpicker/assets}/img/checkerboard.png | Bin .../colorpicker}/lib/colorpicker.dart | 0 .../colorpicker}/lib/constants/colors.dart | 0 .../lib/widgets/color_compare.dart | 0 .../colorpicker}/lib/widgets/slider.dart | 0 .../lib/widgets/slider_indicator.dart | 0 .../colorpicker}/pubspec.yaml | 7 +- .../colorpicker}/test/colorpicker_test.dart | 0 packages/command/.metadata | 10 + packages/command/analysis_options.yaml | 23 + .../command/lib}/command.dart | 9 +- packages/command/lib/command_providers.dart | 4 + .../command/lib}/src/command.dart | 0 .../command/lib}/src/command_factory.dart | 4 +- .../lib}/src/command_factory_provider.dart | 2 +- .../lib/src/command_factory_provider.g.dart | 25 + .../command/lib}/src/command_manager.dart | 3 +- .../lib}/src/command_manager_provider.dart | 3 +- .../lib/src/command_manager_provider.g.dart | 25 + .../lib/src}/graphic/draw_path_command.dart | 5 +- .../command/lib}/src/graphic_command.dart | 2 +- .../src}/manager/sync_command_manager.dart | 4 +- packages/command/pubspec.yaml | 36 + .../test/unit}/command_factory_test.dart | 4 +- .../test/unit}/draw_path_command_test.dart | 4 +- .../unit/draw_path_command_test.mocks.dart | 616 ++++++++++ packages/component_library/.metadata | 10 + .../component_library/analysis_options.yaml | 23 + .../assets/img/checkerboard.png | Bin .../img}/pocketpaint_intro_landscape.png | Bin .../img}/pocketpaint_intro_portrait.png | Bin .../assets/img}/pocketpaint_logo_small.png | Bin .../assets}/svg/ic_brush.svg | 0 .../assets}/svg/ic_clipboard.svg | 0 .../assets}/svg/ic_clipping.svg | 0 .../assets}/svg/ic_cursor.svg | 0 .../assets}/svg/ic_edit_circle.svg | 0 .../assets}/svg/ic_eraser.svg | 0 .../component_library/assets}/svg/ic_fill.svg | 0 .../component_library/assets}/svg/ic_hand.svg | 0 .../assets}/svg/ic_import.svg | 0 .../assets}/svg/ic_layers.svg | 0 .../component_library/assets}/svg/ic_line.svg | 0 .../assets}/svg/ic_pipette.svg | 0 .../assets}/svg/ic_shapes.svg | 0 .../assets}/svg/ic_smudge.svg | 0 .../assets}/svg/ic_spray_can.svg | 0 .../assets}/svg/ic_stamp.svg | 0 .../component_library/assets}/svg/ic_text.svg | 0 .../assets}/svg/ic_tools.svg | 0 .../assets}/svg/ic_transform.svg | 0 .../assets}/svg/ic_watercolor.svg | 0 .../lib/component_library.dart | 20 + .../src/components}/bottom_nav_bar_icon.dart | 9 +- .../src/components}/custom_action_chip.dart | 0 .../components}/icon_button_with_label.dart | 0 .../lib/src/components/icon_svg.dart | 27 + .../lib/src/components/imgs.dart | 59 + .../lib/src/components}/loading_overlay.dart | 0 .../lib/src/components}/pop_menu_button.dart | 0 .../lib/src}/graphic_factory_provider.dart | 2 +- .../lib/src/graphic_factory_provider.g.dart | 25 + .../lib/src/models}/graphic_factory.dart | 2 +- .../src/models/path_with_action_history.dart | 179 +++ .../lib/src/theme}/color_schemes.dart | 0 .../lib/src/theme}/styles.dart | 2 +- .../lib/src/utils/open_url.dart | 0 .../lib/src/utils}/toast_utils.dart | 0 packages/component_library/pubspec.yaml | 41 + packages/database/.metadata | 10 + packages/database/analysis_options.yaml | 24 + packages/database/lib/database.dart | 8 + .../database/lib/src/models}/project.dart | 0 .../database/lib/src}/project_dao.dart | 2 +- .../database/lib/src}/project_database.dart | 7 +- .../database/lib/src/project_database.g.dart | 204 ++++ .../lib/src/utils}/date_time_converter.dart | 0 packages/database/pubspec.yaml | 35 + .../test/unit}/project_database_test.dart | 4 +- .../features/landing_page_screen/.metadata | 10 + .../landing_page_screen/analysis_options.yaml | 23 + .../lib/landing_page_screen.dart | 9 + .../src/components}/custom_action_button.dart | 0 .../lib/src/components}/image_preview.dart | 6 +- .../src/components}/main_overflow_menu.dart | 6 +- .../src/components}/project_list_tile.dart | 7 +- .../components}/project_overflow_menu.dart | 8 +- .../lib/src}/landing_page.dart | 27 +- .../features/landing_page_screen/pubspec.yaml | 55 + .../test}/fixture/image/test.jpg | Bin .../test}/fixture/image/test.png | Bin .../test/fixture/image/test1.png | Bin 0 -> 1272 bytes .../test/widget}/landing_page_test.dart | 17 +- .../test/widget/landing_page_test.mocks.dart | 412 +++++++ packages/features/onboarding_screen/.metadata | 10 + .../onboarding_screen/analysis_options.yaml | 23 + .../lib/onboarding_screen.dart | 13 + .../components}/bottom_nav_bar_container.dart | 4 +- .../components}/onboarding_page_app_bar.dart | 0 .../onboarding_page_bottom_nav_bar.dart | 2 +- .../lib/src/onboarding_screen.dart | 9 +- .../lib/src/screens}/screen1.dart | 2 +- .../lib/src/screens}/screen2.dart | 7 +- .../lib/src/screens}/screen3.dart | 15 +- .../lib/src/screens}/screen4.dart | 9 +- .../lib/src/screens}/screen5.dart | 7 +- .../features/onboarding_screen/pubspec.yaml | 46 + .../test/widget/onboarding_screen_test.dart | 8 +- packages/features/workspace_screen/.metadata | 10 + .../workspace_screen/analysis_options.yaml | 23 + .../bottom_brush_tool_options.dart | 4 +- .../lib/src/components}/bottom_nav_bar.dart | 28 +- .../lib/src/components}/canvas_painter.dart | 7 +- .../src/components}/checkerboard_pattern.dart | 11 +- .../lib/src/components}/command_painter.dart | 2 +- .../lib/src/components}/drawing_canvas.dart | 9 +- .../components}/exit_fullscreen_button.dart | 4 +- .../lib/src/components}/overflow_menu.dart | 16 +- .../lib/src/components}/tool_button.dart | 13 +- .../lib/src/components}/tool_options.dart | 3 +- .../src/components}/tools_bottom_sheet.dart | 4 +- .../lib/src/components}/top_app_bar.dart | 2 +- .../components}/top_brush_tool_options.dart | 4 +- .../src/models}/image_with_pixel_info.dart | 0 .../lib/src}/service/device_service.dart | 0 .../lib/src/states}/canvas_dirty_state.dart | 0 .../lib/src/states}/canvas_state_data.dart | 4 +- .../src/states/canvas_state_data.freezed.dart | 221 ++++ .../src/states}/canvas_state_provider.dart | 11 +- .../src/states/canvas_state_provider.g.dart | 25 + .../lib/src/states}/workspace_state.dart | 0 .../src/states}/workspace_state_notifier.dart | 4 +- .../src/usecase/render_image_for_export.dart | 9 +- .../lib/src/workspace_screen.dart | 18 +- .../lib/workspace_screen.dart | 28 + .../features/workspace_screen/pubspec.yaml | 57 + .../unit}/render_image_for_export_test.dart | 12 +- .../render_image_for_export_test.mocks.dart | 684 +++++++++++ .../bottom_control_navigation_bar_test.dart | 14 +- .../widget}/bottom_nav_bar_interactions.dart | 5 +- .../test/widget}/canvas_interactions.dart | 2 +- .../test/widget}/eraser_tool_test.dart | 16 +- .../test/widget}/hand_tool_test.dart | 17 +- .../interactive_viewer_interactions.dart | 0 .../test/widget/workspace_screen_test.dart | 21 +- packages/io_library/.metadata | 10 + packages/io_library/analysis_options.yaml | 23 + packages/io_library/lib/io_library.dart | 43 + .../io_library/lib}/serialization.dart | 0 .../lib/src/enums}/image_format.dart | 2 - .../lib/src/enums}/image_location.dart | 0 .../lib}/src/failure/load_image_failure.dart | 2 +- .../lib}/src/failure/save_image_failure.dart | 2 +- .../io_library/lib/src}/io_handler.dart | 12 +- .../lib/src/models}/catrobat_image.dart | 2 +- .../io_library/lib/src/models}/failure.dart | 0 .../lib/src/models}/image_from_file.dart | 2 +- .../lib/src/models}/image_meta_data.dart | 2 +- .../lib/src/models}/loggable_mixin.dart | 0 .../proto/output/catrobat_image.pb.dart | 161 +++ .../proto/output/catrobat_image.pbenum.dart | 10 + .../proto/output/catrobat_image.pbjson.dart | 42 + .../proto/output/catrobat_image.pbserver.dart | 13 + .../command/graphic/draw_path_command.pb.dart | 108 ++ .../graphic/draw_path_command.pbenum.dart | 10 + .../graphic/draw_path_command.pbjson.dart | 43 + .../graphic/draw_path_command.pbserver.dart | 13 + .../proto/output/google/protobuf/any.pb.dart | 224 ++++ .../output/google/protobuf/any.pbenum.dart | 10 + .../output/google/protobuf/any.pbjson.dart | 27 + .../output/google/protobuf/any.pbserver.dart | 13 + .../proto/output/graphic/paint.pb.dart | 187 +++ .../proto/output/graphic/paint.pbenum.dart | 115 ++ .../proto/output/graphic/paint.pbjson.dart | 113 ++ .../proto/output/graphic/paint.pbserver.dart | 13 + .../proto/output/graphic/path.pb.dart | 420 +++++++ .../proto/output/graphic/path.pbenum.dart | 35 + .../proto/output/graphic/path.pbjson.dart | 125 ++ .../proto/output/graphic/path.pbserver.dart | 13 + .../lib}/src/serialization/proto/protos.dart | 0 .../proto/schema/catrobat_image.proto | 0 .../command/graphic/draw_path_command.proto | 0 .../proto/schema/graphic/paint.proto | 0 .../proto/schema/graphic/path.proto | 0 .../proto_serializer_with_versioning.dart | 2 +- .../serializer/catrobat_image_serializer.dart | 6 +- .../graphic/draw_path_command_serializer.dart | 7 +- .../serializer/graphic/paint_serializer.dart | 15 +- .../serializer/graphic/path_serializer.dart | 7 +- .../src/serialization/version_serializer.dart | 0 .../lib}/src/service/file_service.dart | 5 +- .../lib}/src/service/image_service.dart | 5 +- .../lib}/src/service/permission_service.dart | 6 +- .../src/service/photo_library_service.dart | 5 +- .../io_library/lib}/src/ui/about_dialog.dart | 6 +- .../lib}/src/ui/delete_project_dialog.dart | 2 +- .../lib}/src/ui/discard_changes_dialog.dart | 2 +- .../lib}/src/ui/generic_dialog.dart | 0 .../lib}/src/ui/image_format_info.dart | 3 +- .../lib}/src/ui/load_image_dialog.dart | 3 +- .../lib}/src/ui/overwrite_dialog.dart | 2 +- .../lib}/src/ui/project_details_dialog.dart | 8 +- .../lib}/src/ui/save_image_dialog.dart | 7 +- .../usecase/load_image_from_file_manager.dart | 4 +- .../load_image_from_photo_library.dart | 6 +- .../src/usecase/save_as_catrobat_image.dart | 11 +- .../src/usecase/save_as_raster_image.dart | 3 +- packages/io_library/pubspec.yaml | 56 + .../io_library/test/fixture/image/test.jpg | Bin 0 -> 1731 bytes .../io_library/test/fixture/image/test.png | Bin 0 -> 1272 bytes .../io_library/test/fixture/image/test1.png | Bin 0 -> 1272 bytes .../serialization/paint_serializer_test.dart | 4 +- .../test/unit}/service/file_service_test.dart | 2 +- .../unit}/service/image_service_test.dart | 2 +- .../service/photo_library_service_test.dart | 15 +- .../photo_library_service_test.mocks.dart | 480 ++++++++ .../load_image_from_photo_library_test.dart | 3 +- ...d_image_from_photo_library_test.mocks.dart | 211 ++++ .../usecase/save_as_raster_image_test.dart | 9 +- .../save_as_raster_image_test.mocks.dart | 333 +++++ packages/l10n/.metadata | 10 + packages/l10n/analysis_options.yaml | 25 + packages/l10n/l10n.yaml | 6 + packages/l10n/lib/l10n.dart | 4 + .../l10n/lib/src/l10n/app_localizations.dart | 178 +++ .../lib/src/l10n/app_localizations_en.dart | 33 + .../l10n/lib/src/l10n/app_translations_en.arb | 0 packages/l10n/pubspec.yaml | 26 + packages/tools/.metadata | 10 + packages/tools/analysis_options.yaml | 23 + .../tools/lib}/src/brush_tool/brush_tool.dart | 9 +- .../src/brush_tool/brush_tool_provider.dart | 9 +- .../src/brush_tool/brush_tool_provider.g.dart | 24 + .../src/brush_tool/brush_tool_state_data.dart | 0 .../brush_tool_state_data.freezed.dart | 134 ++ .../brush_tool/brush_tool_state_provider.dart | 4 +- .../brush_tool_state_provider.g.dart | 26 + .../tools/lib/src/enums}/tool_types.dart | 0 .../src/eraser_tool/eraser_tool_provider.dart | 9 +- .../eraser_tool/eraser_tool_provider.g.dart | 24 + .../tools/lib}/src/hand_tool/hand_tool.dart | 8 +- .../src/hand_tool/hand_tool_provider.dart | 7 +- .../src/hand_tool/hand_tool_provider.g.dart | 24 + .../tool => packages/tools/lib}/src/tool.dart | 4 +- .../tools/lib}/src/tool_data.dart | 2 +- .../lib}/src/toolbox/toolbox_state_data.dart | 2 +- .../toolbox/toolbox_state_data.freezed.dart | 173 +++ .../src/toolbox/toolbox_state_provider.dart | 3 +- .../src/toolbox/toolbox_state_provider.g.dart | 25 + .../tools/lib/tools.dart | 15 +- packages/tools/pubspec.yaml | 45 + .../test/unit}/brush_tool_state_test.dart | 6 +- .../tools/test/unit}/brush_tool_test.dart | 7 +- .../test/unit/brush_tool_test.mocks.dart | 1079 +++++++++++++++++ .../tools/test/unit}/hand_tool_test.dart | 6 +- .../tools/test/unit/hand_tool_test.mocks.dart | 341 ++++++ pubspec.lock | 581 ++++++--- pubspec.yaml | 56 +- setup_melos.sh | 14 + setup_sdk.sh | 72 ++ test/widget/utils/utils.dart | 2 - 288 files changed, 9304 insertions(+), 873 deletions(-) create mode 100644 .fvm/fvm_config.json delete mode 100755 generate_files.sh delete mode 100644 l10n.yaml delete mode 100644 lib/core/app_localizations.dart delete mode 100644 lib/core/path_with_action_history.dart delete mode 100644 lib/io/io.dart create mode 100644 lib/pocket_paint_app.dart delete mode 100644 lib/ui/drawing_space/color_box.dart delete mode 100644 lib/workspace/workspace.dart create mode 100644 melos.yaml rename {colorpicker => packages/colorpicker}/.gitignore (100%) rename {colorpicker => packages/colorpicker}/.metadata (100%) rename {colorpicker => packages/colorpicker}/CHANGELOG.md (100%) rename {colorpicker => packages/colorpicker}/LICENSE (100%) rename {colorpicker => packages/colorpicker}/README.md (100%) rename {colorpicker => packages/colorpicker}/analysis_options.yaml (100%) rename {assets => packages/colorpicker/assets}/img/checkerboard.png (100%) rename {colorpicker => packages/colorpicker}/lib/colorpicker.dart (100%) rename {colorpicker => packages/colorpicker}/lib/constants/colors.dart (100%) rename {colorpicker => packages/colorpicker}/lib/widgets/color_compare.dart (100%) rename {colorpicker => packages/colorpicker}/lib/widgets/slider.dart (100%) rename {colorpicker => packages/colorpicker}/lib/widgets/slider_indicator.dart (100%) rename {colorpicker => packages/colorpicker}/pubspec.yaml (87%) rename {colorpicker => packages/colorpicker}/test/colorpicker_test.dart (100%) create mode 100644 packages/command/.metadata create mode 100644 packages/command/analysis_options.yaml rename {lib/command => packages/command/lib}/command.dart (50%) create mode 100644 packages/command/lib/command_providers.dart rename {lib/command => packages/command/lib}/src/command.dart (100%) rename {lib/command => packages/command/lib}/src/command_factory.dart (56%) rename {lib/command => packages/command/lib}/src/command_factory_provider.dart (78%) create mode 100644 packages/command/lib/src/command_factory_provider.g.dart rename {lib/command => packages/command/lib}/src/command_manager.dart (74%) rename {lib/command => packages/command/lib}/src/command_manager_provider.dart (60%) create mode 100644 packages/command/lib/src/command_manager_provider.g.dart rename {lib/command/src/implementation/command => packages/command/lib/src}/graphic/draw_path_command.dart (72%) rename {lib/command => packages/command/lib}/src/graphic_command.dart (74%) rename {lib/command/src/implementation => packages/command/lib/src}/manager/sync_command_manager.dart (85%) create mode 100644 packages/command/pubspec.yaml rename {test/unit/command => packages/command/test/unit}/command_factory_test.dart (83%) rename {test/unit/command => packages/command/test/unit}/draw_path_command_test.dart (87%) create mode 100644 packages/command/test/unit/draw_path_command_test.mocks.dart create mode 100644 packages/component_library/.metadata create mode 100644 packages/component_library/analysis_options.yaml rename {colorpicker => packages/component_library}/assets/img/checkerboard.png (100%) rename {assets/icon => packages/component_library/assets/img}/pocketpaint_intro_landscape.png (100%) rename {assets/icon => packages/component_library/assets/img}/pocketpaint_intro_portrait.png (100%) rename {assets/icon => packages/component_library/assets/img}/pocketpaint_logo_small.png (100%) rename {assets => packages/component_library/assets}/svg/ic_brush.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_clipboard.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_clipping.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_cursor.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_edit_circle.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_eraser.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_fill.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_hand.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_import.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_layers.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_line.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_pipette.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_shapes.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_smudge.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_spray_can.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_stamp.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_text.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_tools.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_transform.svg (100%) rename {assets => packages/component_library/assets}/svg/ic_watercolor.svg (100%) create mode 100644 packages/component_library/lib/component_library.dart rename {lib/ui/shared => packages/component_library/lib/src/components}/bottom_nav_bar_icon.dart (68%) rename {lib/ui/shared => packages/component_library/lib/src/components}/custom_action_chip.dart (100%) rename {lib/ui/shared => packages/component_library/lib/src/components}/icon_button_with_label.dart (100%) create mode 100644 packages/component_library/lib/src/components/icon_svg.dart create mode 100644 packages/component_library/lib/src/components/imgs.dart rename {lib/ui/shared => packages/component_library/lib/src/components}/loading_overlay.dart (100%) rename {lib/ui => packages/component_library/lib/src/components}/pop_menu_button.dart (100%) rename {lib/core => packages/component_library/lib/src}/graphic_factory_provider.dart (79%) create mode 100644 packages/component_library/lib/src/graphic_factory_provider.g.dart rename {lib/core => packages/component_library/lib/src/models}/graphic_factory.dart (93%) create mode 100644 packages/component_library/lib/src/models/path_with_action_history.dart rename {lib/ui => packages/component_library/lib/src/theme}/color_schemes.dart (100%) rename {lib/ui => packages/component_library/lib/src/theme}/styles.dart (92%) rename lib/ui/util.dart => packages/component_library/lib/src/utils/open_url.dart (100%) rename {lib/core => packages/component_library/lib/src/utils}/toast_utils.dart (100%) create mode 100644 packages/component_library/pubspec.yaml create mode 100644 packages/database/.metadata create mode 100644 packages/database/analysis_options.yaml create mode 100644 packages/database/lib/database.dart rename {lib/data/model => packages/database/lib/src/models}/project.dart (100%) rename {lib/data => packages/database/lib/src}/project_dao.dart (92%) rename {lib/data => packages/database/lib/src}/project_database.dart (73%) create mode 100644 packages/database/lib/src/project_database.g.dart rename {lib/data/typeconverters => packages/database/lib/src/utils}/date_time_converter.dart (100%) create mode 100644 packages/database/pubspec.yaml rename {test/unit/data => packages/database/test/unit}/project_database_test.dart (95%) create mode 100644 packages/features/landing_page_screen/.metadata create mode 100644 packages/features/landing_page_screen/analysis_options.yaml create mode 100644 packages/features/landing_page_screen/lib/landing_page_screen.dart rename {lib/ui/landing_page => packages/features/landing_page_screen/lib/src/components}/custom_action_button.dart (100%) rename {lib/ui/landing_page => packages/features/landing_page_screen/lib/src/components}/image_preview.dart (89%) rename {lib/ui/landing_page => packages/features/landing_page_screen/lib/src/components}/main_overflow_menu.dart (91%) rename {lib/ui/landing_page => packages/features/landing_page_screen/lib/src/components}/project_list_tile.dart (84%) rename {lib/ui/landing_page => packages/features/landing_page_screen/lib/src/components}/project_overflow_menu.dart (89%) rename {lib/ui/landing_page => packages/features/landing_page_screen/lib/src}/landing_page.dart (87%) create mode 100644 packages/features/landing_page_screen/pubspec.yaml rename {test => packages/features/landing_page_screen/test}/fixture/image/test.jpg (100%) rename {test => packages/features/landing_page_screen/test}/fixture/image/test.png (100%) create mode 100644 packages/features/landing_page_screen/test/fixture/image/test1.png rename {test/widget/ui => packages/features/landing_page_screen/test/widget}/landing_page_test.dart (95%) create mode 100644 packages/features/landing_page_screen/test/widget/landing_page_test.mocks.dart create mode 100644 packages/features/onboarding_screen/.metadata create mode 100644 packages/features/onboarding_screen/analysis_options.yaml create mode 100644 packages/features/onboarding_screen/lib/onboarding_screen.dart rename {lib/ui/onboarding => packages/features/onboarding_screen/lib/src/components}/bottom_nav_bar_container.dart (83%) rename {lib/ui/onboarding => packages/features/onboarding_screen/lib/src/components}/onboarding_page_app_bar.dart (100%) rename {lib/ui/onboarding => packages/features/onboarding_screen/lib/src/components}/onboarding_page_bottom_nav_bar.dart (94%) rename lib/ui/onboarding/onboarding_page.dart => packages/features/onboarding_screen/lib/src/onboarding_screen.dart (90%) rename {lib/ui/onboarding/onboarding_screens => packages/features/onboarding_screen/lib/src/screens}/screen1.dart (94%) rename {lib/ui/onboarding/onboarding_screens => packages/features/onboarding_screen/lib/src/screens}/screen2.dart (93%) rename {lib/ui/onboarding/onboarding_screens => packages/features/onboarding_screen/lib/src/screens}/screen3.dart (94%) rename {lib/ui/onboarding/onboarding_screens => packages/features/onboarding_screen/lib/src/screens}/screen4.dart (86%) rename {lib/ui/onboarding/onboarding_screens => packages/features/onboarding_screen/lib/src/screens}/screen5.dart (88%) create mode 100644 packages/features/onboarding_screen/pubspec.yaml rename test/widget/ui/onboarding_page_test.dart => packages/features/onboarding_screen/test/widget/onboarding_screen_test.dart (97%) create mode 100644 packages/features/workspace_screen/.metadata create mode 100644 packages/features/workspace_screen/analysis_options.yaml rename {lib/ui/drawing_space => packages/features/workspace_screen/lib/src/components}/bottom_brush_tool_options.dart (95%) rename {lib/ui/drawing_space => packages/features/workspace_screen/lib/src/components}/bottom_nav_bar.dart (79%) rename {lib/workspace/src/ui => packages/features/workspace_screen/lib/src/components}/canvas_painter.dart (83%) rename {lib/workspace/src/ui => packages/features/workspace_screen/lib/src/components}/checkerboard_pattern.dart (57%) rename {lib/workspace/src/ui => packages/features/workspace_screen/lib/src/components}/command_painter.dart (89%) rename {lib/workspace/src/ui => packages/features/workspace_screen/lib/src/components}/drawing_canvas.dart (90%) rename {lib/ui/drawing_space => packages/features/workspace_screen/lib/src/components}/exit_fullscreen_button.dart (88%) rename {lib/ui/shared => packages/features/workspace_screen/lib/src/components}/overflow_menu.dart (89%) rename {lib/ui/shared => packages/features/workspace_screen/lib/src/components}/tool_button.dart (70%) rename {lib/ui/drawing_space => packages/features/workspace_screen/lib/src/components}/tool_options.dart (72%) rename {lib/ui/drawing_space => packages/features/workspace_screen/lib/src/components}/tools_bottom_sheet.dart (83%) rename {lib/ui/shared => packages/features/workspace_screen/lib/src/components}/top_app_bar.dart (82%) rename {lib/ui/drawing_space => packages/features/workspace_screen/lib/src/components}/top_brush_tool_options.dart (95%) rename {lib/core => packages/features/workspace_screen/lib/src/models}/image_with_pixel_info.dart (100%) rename {lib => packages/features/workspace_screen/lib/src}/service/device_service.dart (100%) rename {lib/workspace/src/state => packages/features/workspace_screen/lib/src/states}/canvas_dirty_state.dart (100%) rename {lib/workspace/src/state/canvas => packages/features/workspace_screen/lib/src/states}/canvas_state_data.dart (80%) create mode 100644 packages/features/workspace_screen/lib/src/states/canvas_state_data.freezed.dart rename {lib/workspace/src/state/canvas => packages/features/workspace_screen/lib/src/states}/canvas_state_provider.dart (89%) create mode 100644 packages/features/workspace_screen/lib/src/states/canvas_state_provider.g.dart rename {lib/workspace/src/state => packages/features/workspace_screen/lib/src/states}/workspace_state.dart (100%) rename {lib/workspace/src/state => packages/features/workspace_screen/lib/src/states}/workspace_state_notifier.dart (88%) rename {lib/workspace => packages/features/workspace_screen/lib}/src/usecase/render_image_for_export.dart (88%) rename lib/ui/pocket_paint.dart => packages/features/workspace_screen/lib/src/workspace_screen.dart (77%) create mode 100644 packages/features/workspace_screen/lib/workspace_screen.dart create mode 100644 packages/features/workspace_screen/pubspec.yaml rename {test/unit/workspace/usecase => packages/features/workspace_screen/test/unit}/render_image_for_export_test.dart (93%) create mode 100644 packages/features/workspace_screen/test/unit/render_image_for_export_test.mocks.dart rename {test/widget/ui => packages/features/workspace_screen/test/widget}/bottom_control_navigation_bar_test.dart (70%) rename {test/widget/utils/interactions => packages/features/workspace_screen/test/widget}/bottom_nav_bar_interactions.dart (91%) rename {test/widget/utils/interactions => packages/features/workspace_screen/test/widget}/canvas_interactions.dart (96%) rename {test/widget/tool => packages/features/workspace_screen/test/widget}/eraser_tool_test.dart (75%) rename {test/widget/tool => packages/features/workspace_screen/test/widget}/hand_tool_test.dart (83%) rename {test/widget/utils/interactions => packages/features/workspace_screen/test/widget}/interactive_viewer_interactions.dart (100%) rename test/widget/ui/pocket_paint_test.dart => packages/features/workspace_screen/test/widget/workspace_screen_test.dart (83%) create mode 100644 packages/io_library/.metadata create mode 100644 packages/io_library/analysis_options.yaml create mode 100644 packages/io_library/lib/io_library.dart rename {lib/io => packages/io_library/lib}/serialization.dart (100%) rename {lib/io/src/entity => packages/io_library/lib/src/enums}/image_format.dart (81%) rename {lib/io/src/entity => packages/io_library/lib/src/enums}/image_location.dart (100%) rename {lib/io => packages/io_library/lib}/src/failure/load_image_failure.dart (90%) rename {lib/io => packages/io_library/lib}/src/failure/save_image_failure.dart (90%) rename {lib/ui => packages/io_library/lib/src}/io_handler.dart (95%) rename {lib/io/src/entity => packages/io_library/lib/src/models}/catrobat_image.dart (86%) rename {lib/core => packages/io_library/lib/src/models}/failure.dart (100%) rename {lib/io/src/entity => packages/io_library/lib/src/models}/image_from_file.dart (89%) rename {lib/io/src/entity => packages/io_library/lib/src/models}/image_meta_data.dart (94%) rename {lib/core => packages/io_library/lib/src/models}/loggable_mixin.dart (100%) create mode 100644 packages/io_library/lib/src/serialization/proto/output/catrobat_image.pb.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbenum.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbjson.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbserver.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pb.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbenum.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbjson.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbserver.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pb.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbenum.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbjson.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbserver.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/paint.pb.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbenum.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbjson.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbserver.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/path.pb.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/path.pbenum.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/path.pbjson.dart create mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/path.pbserver.dart rename {lib/io => packages/io_library/lib}/src/serialization/proto/protos.dart (100%) rename {lib/io => packages/io_library/lib}/src/serialization/proto/schema/catrobat_image.proto (100%) rename {lib/io => packages/io_library/lib}/src/serialization/proto/schema/command/graphic/draw_path_command.proto (100%) rename {lib/io => packages/io_library/lib}/src/serialization/proto/schema/graphic/paint.proto (100%) rename {lib/io => packages/io_library/lib}/src/serialization/proto/schema/graphic/path.proto (100%) rename {lib/io => packages/io_library/lib}/src/serialization/proto_serializer_with_versioning.dart (90%) rename {lib/io => packages/io_library/lib}/src/serialization/serializer/catrobat_image_serializer.dart (92%) rename {lib/io => packages/io_library/lib}/src/serialization/serializer/command/graphic/draw_path_command_serializer.dart (87%) rename {lib/io => packages/io_library/lib}/src/serialization/serializer/graphic/paint_serializer.dart (86%) rename {lib/io => packages/io_library/lib}/src/serialization/serializer/graphic/path_serializer.dart (90%) rename {lib/io => packages/io_library/lib}/src/serialization/version_serializer.dart (100%) rename {lib/io => packages/io_library/lib}/src/service/file_service.dart (96%) rename {lib/io => packages/io_library/lib}/src/service/image_service.dart (91%) rename {lib/io => packages/io_library/lib}/src/service/permission_service.dart (94%) rename {lib/io => packages/io_library/lib}/src/service/photo_library_service.dart (88%) rename {lib/io => packages/io_library/lib}/src/ui/about_dialog.dart (94%) rename {lib/io => packages/io_library/lib}/src/ui/delete_project_dialog.dart (93%) rename {lib/io => packages/io_library/lib}/src/ui/discard_changes_dialog.dart (94%) rename {lib/io => packages/io_library/lib}/src/ui/generic_dialog.dart (100%) rename {lib/io => packages/io_library/lib}/src/ui/image_format_info.dart (93%) rename {lib/io => packages/io_library/lib}/src/ui/load_image_dialog.dart (88%) rename {lib/io => packages/io_library/lib}/src/ui/overwrite_dialog.dart (92%) rename {lib/io => packages/io_library/lib}/src/ui/project_details_dialog.dart (93%) rename {lib/io => packages/io_library/lib}/src/ui/save_image_dialog.dart (97%) rename {lib/io => packages/io_library/lib}/src/usecase/load_image_from_file_manager.dart (94%) rename {lib/io => packages/io_library/lib}/src/usecase/load_image_from_photo_library.dart (77%) rename {lib/io => packages/io_library/lib}/src/usecase/save_as_catrobat_image.dart (81%) rename {lib/io => packages/io_library/lib}/src/usecase/save_as_raster_image.dart (93%) create mode 100644 packages/io_library/pubspec.yaml create mode 100644 packages/io_library/test/fixture/image/test.jpg create mode 100644 packages/io_library/test/fixture/image/test.png create mode 100644 packages/io_library/test/fixture/image/test1.png rename {test/unit/io => packages/io_library/test/unit}/serialization/paint_serializer_test.dart (94%) rename {test/unit/io => packages/io_library/test/unit}/service/file_service_test.dart (97%) rename {test/unit/io => packages/io_library/test/unit}/service/image_service_test.dart (97%) rename {test/unit/io => packages/io_library/test/unit}/service/photo_library_service_test.dart (93%) create mode 100644 packages/io_library/test/unit/service/photo_library_service_test.mocks.dart rename {test/unit/io => packages/io_library/test/unit}/usecase/load_image_from_photo_library_test.dart (97%) create mode 100644 packages/io_library/test/unit/usecase/load_image_from_photo_library_test.mocks.dart rename {test/unit/io => packages/io_library/test/unit}/usecase/save_as_raster_image_test.dart (97%) create mode 100644 packages/io_library/test/unit/usecase/save_as_raster_image_test.mocks.dart create mode 100644 packages/l10n/.metadata create mode 100644 packages/l10n/analysis_options.yaml create mode 100644 packages/l10n/l10n.yaml create mode 100644 packages/l10n/lib/l10n.dart create mode 100644 packages/l10n/lib/src/l10n/app_localizations.dart create mode 100644 packages/l10n/lib/src/l10n/app_localizations_en.dart rename assets/l10n/en.arb => packages/l10n/lib/src/l10n/app_translations_en.arb (100%) create mode 100644 packages/l10n/pubspec.yaml create mode 100644 packages/tools/.metadata create mode 100644 packages/tools/analysis_options.yaml rename {lib/tool => packages/tools/lib}/src/brush_tool/brush_tool.dart (82%) rename {lib/tool => packages/tools/lib}/src/brush_tool/brush_tool_provider.dart (52%) create mode 100644 packages/tools/lib/src/brush_tool/brush_tool_provider.g.dart rename {lib/tool => packages/tools/lib}/src/brush_tool/brush_tool_state_data.dart (100%) create mode 100644 packages/tools/lib/src/brush_tool/brush_tool_state_data.freezed.dart rename {lib/tool => packages/tools/lib}/src/brush_tool/brush_tool_state_provider.dart (89%) create mode 100644 packages/tools/lib/src/brush_tool/brush_tool_state_provider.g.dart rename {lib/tool/src => packages/tools/lib/src/enums}/tool_types.dart (100%) rename {lib/tool => packages/tools/lib}/src/eraser_tool/eraser_tool_provider.dart (52%) create mode 100644 packages/tools/lib/src/eraser_tool/eraser_tool_provider.g.dart rename {lib/tool => packages/tools/lib}/src/hand_tool/hand_tool.dart (76%) rename {lib/tool => packages/tools/lib}/src/hand_tool/hand_tool_provider.dart (53%) create mode 100644 packages/tools/lib/src/hand_tool/hand_tool_provider.g.dart rename {lib/tool => packages/tools/lib}/src/tool.dart (80%) rename {lib/tool => packages/tools/lib}/src/tool_data.dart (97%) rename {lib/tool => packages/tools/lib}/src/toolbox/toolbox_state_data.dart (88%) create mode 100644 packages/tools/lib/src/toolbox/toolbox_state_data.freezed.dart rename {lib/tool => packages/tools/lib}/src/toolbox/toolbox_state_provider.dart (94%) create mode 100644 packages/tools/lib/src/toolbox/toolbox_state_provider.g.dart rename lib/tool/tool.dart => packages/tools/lib/tools.dart (73%) create mode 100644 packages/tools/pubspec.yaml rename {test/unit/tool => packages/tools/test/unit}/brush_tool_state_test.dart (91%) rename {test/unit/tool => packages/tools/test/unit}/brush_tool_test.dart (95%) create mode 100644 packages/tools/test/unit/brush_tool_test.mocks.dart rename {test/unit/tool => packages/tools/test/unit}/hand_tool_test.dart (88%) create mode 100644 packages/tools/test/unit/hand_tool_test.mocks.dart create mode 100755 setup_melos.sh create mode 100755 setup_sdk.sh delete mode 100644 test/widget/utils/utils.dart diff --git a/.fvm/fvm_config.json b/.fvm/fvm_config.json new file mode 100644 index 00000000..23e73971 --- /dev/null +++ b/.fvm/fvm_config.json @@ -0,0 +1,4 @@ +{ + "flutterSdkVersion": "3.10.5", + "flavors": {} +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index ec3a832c..ac8927d7 100644 --- a/.gitignore +++ b/.gitignore @@ -30,10 +30,12 @@ migrate_working_dir/ .pub/ /build/ coverage -*.mocks.dart -*.pb*.dart -*.g.dart -*.freezed.dart + +# Commented out to push generated code: +# *.mocks.dart +# *.pb*.dart +# *.g.dart +# *.freezed.dart # Web related lib/generated_plugin_registrant.dart @@ -48,3 +50,15 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + +.fvm/flutter_sdk + +# Melos +pubspec_overrides.yaml + +# Packages +packages/*/pubspec.lock +packages/*/build + +packages/features/*/pubspec.lock +packages/features/*/build diff --git a/Makefile b/Makefile index ea6c04f4..528b93e2 100644 --- a/Makefile +++ b/Makefile @@ -1,30 +1,56 @@ -.PHONY: pubget build watch clean test analyze test-unit test-widget test-all all +.PHONY: run pods-clean get clean build languages lint format test watch -clean: - flutter clean +FLUTTER := flutter +DART := dart + +run: + $(FLUTTER) run + +pods-clean: + rm -Rf ios/Pods ; \ + rm -Rf ios/.symlinks ; \ + rm -Rf ios/Flutter/Flutter.framework ; \ + rm -Rf ios/Flutter/Flutter.podspec ; \ + rm ios/Podfile ; \ + rm ios/Podfile.lock ; \ + +get: + chmod +x ./setup_sdk.sh + ./setup_sdk.sh + chmod +x ./setup_melos.sh + ./setup_melos.sh + melos bootstrap -pubget: - flutter pub get +clean: + melos clean build: - dart run build_runner build --delete-conflicting-outputs + melos run build:all -run: - flutter run +languages: + @cd packages/l10n ; \ + $(FLUTTER) gen-l10n + @echo "-> Generated l10n" -all: clean pubget build run +lint: + $(FLUTTER) analyze + melos run lint:all -watch: - dart run build_runner watch --delete-conflicting-outputs +format: + $(DART) format --set-exit-if-changed . -analyze: - flutter analyze +test: + melos run test:all test-unit: - flutter test test/unit + melos run test:unit test-widget: - flutter test test/widget + melos run test:widget + +watch: + $(DART) run build_runner watch --delete-conflicting-outputs -test-all: - flutter test +melos: + $(DART) pub global activate melos + \ No newline at end of file diff --git a/README.md b/README.md index 89672c2b..d3a25760 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,80 @@ -Paintroid -========= +# Paintroid -Paintroid, also known as **Pocket Paint**, is associated -to [Catroid](https://github.com/Catrobat/Catroid). It is a graphical paint editor application for -the Android platform that, among others, allows setting parts of pictures to transparent. +Paintroid, also known as **Pocket Paint**, is associated to [Catroid](https://github.com/Catrobat/Catroid). It is a graphical paint editor application for the Android platform that, among others, allows setting parts of pictures to transparent. -Since Pocket Paint is now available in **Google Play store** you can also download Paintroid (Pocket -Paint) from [here](https://play.google.com/store/apps/details?id=org.catrobat.paintroid). -Alternatively, you can find it on ** -F-Droid** [here](https://f-droid.org/packages/org.catrobat.paintroid/). +Since Pocket Paint is now available in **Google Play store** you can also download Paintroid (Pocket Paint) from [here](https://play.google.com/store/apps/details?id=org.catrobat.paintroid). Alternatively, you can find it on **F-Droid** [here](https://f-droid.org/packages/org.catrobat.paintroid/). -For more information oriented towards developers please visit -our [developers page](http://developer.catrobat.org/). +For more information oriented towards developers please visit our [developers page](http://developer.catrobat.org/). > **Note** This repository is the Flutter version of [Paintroid](https://github.com/Catrobat/Paintroid) ## Getting Started -1. Install [Flutter](https://docs.flutter.dev/get-started/install) - - check the currently used version in file ".github/workflows/main.yml" -2. Set up the [Protocol Buffer](https://grpc.io/docs/languages/dart/quickstart/) compiler - - `protoc` for Dart -4. Get dependencies - `flutter pub get` -5. Build supporting files - `./generate_files.sh` -6. Build protobuf files - `./generate_protos.sh` -7. Run app - `flutter run lib/main.dart` +1. Install [Flutter](https://docs.flutter.dev/get-started/install): + - Currently used version specified in _.github/workflows/main.yml_ + - **Recommended**: Use [fvm](https://fvm.app/) for managing Flutter versions +2. Get dependencies: `make get` +3. Run app: `make run` + +> In case `make` does not work for you, `melos` can be used for most of the commands. Check them out in _Makefile_ or in _melos.yaml_. + +What `make get` does: + +- Runs `./setup-sdk.sh`, if _fvm_ is not installed: + - changes "FLUTTER" (= `fvm flutter`) to `flutter` in _Makefile_ + - changes "DART" (= `fvm dart`) to `dart` in _Makefile_ if _fvm_ + - changes "sdkPath" (= `.fvm/flutter_sdk`) to `auto` in _melos.yaml_ +- Runs `./setup-melos.sh`: activates _melos_ if not activated. + +## Building generated files + +- For **protoc**: + - Set up the [Protocol Buffer](https://grpc.io/docs/languages/dart/quickstart/) compiler + - Run `./generate_protos.sh` +- For **build-runner**: run `make build` +- For **localizations**: run `make languages` ## Tests -1. For unit tests, run `flutter test` at the project root -2. For integration tests - - - Make sure you have an iOS/Android device online by running `flutter devices` - - Run `flutter test integration_test -d ` - > **Note** Replace `` with the ID of the device from previous command +- Run tests for **all** packages: + - all: `make test` + - unit: `make test-unit` + - widget: `make test-widget` +- Run tests for a **specific** package: + - all: `melos test` + - unit: `melos test-unit` + - widget: `melos test-widget` + +**For integration tests:** + +1. Make sure you have an iOS/Android device online by running `flutter devices` +2. `cd` into the package where the test is located +3. Run `flutter test -d ` + - Replace `` with the ID of the device from `flutter devices` + - Replace `` with the actual path to the test (_test/..._) -# Issues # +## Issues -**Please report all bugs on -our [Jira Bugtracker](https://jira.catrob.at/secure/CreateIssue.jspa?pid=10401&issuetype=1)** +**Please report all bugs on our [Jira Bugtracker](https://jira.catrob.at/secure/CreateIssue.jspa?pid=10401&issuetype=1)** -# Contributing # +## Contributing -If you want to contribute we suggest that you start -with [forking](https://help.github.com/articles/fork-a-repo/) our repository and browse the code. -Then you can look at our [Issue-Tracker](https://jira.catrob.at/secure/RapidBoard.jspa?rapidView=60) -and start with fixing one ticket. We strictly -use [Test-Driven Development](http://c2.com/cgi/wiki?TestDrivenDevelopment) -and [Clean Code](http://www.planetgeek.ch/wp-content/uploads/2013/06/Clean-Code-V2.2.pdf), so first -read everything you can about these development methods. Code developed in a different style will -not be accepted. After you've created a pull request we will review your code and do a full testrun -on your branch. +If you want to contribute we suggest that you start with [forking](https://help.github.com/articles/fork-a-repo/) our repository and browse the code. Then you can look at our [Issue-Tracker](https://jira.catrob.at/secure/RapidBoard.jspa?rapidView=60) and start with fixing one ticket. We strictly use [Test-Driven Development](http://c2.com/cgi/wiki?TestDrivenDevelopment) and [Clean Code](http://www.planetgeek.ch/wp-content/uploads/2013/06/Clean-Code-V2.2.pdf), so first read everything you can about these development methods. Code developed in a different style will not be accepted. After you've created a pull request we will review your code and do a full testrun on your branch. -If you want to implement a new feature, please ask about the details in JIRA or our IRC channel ( -#catrobat or #catrobatdev) first. +If you want to implement a new feature, please ask about the details in JIRA or our IRC channel (#catrobat or #catrobatdev) first. -Let's start to set up the working environment using the instructions in -our [Wiki](https://github.com/Catrobat/Catroid/wiki/Setup-working-environment)! +Let's start to set up the working environment using the instructions in our [Wiki](https://github.com/Catrobat/Catroid/wiki/Setup-working-environment)! -# Resources and links # +## Resources and links -* [Google Play Store Download](https://play.google.com/store/apps/details?id=org.catrobat.paintroid) -* [F-Droid Download](https://f-droid.org/packages/org.catrobat.paintroid/) -* [Frequently Asked Questions](https://github.com/Catrobat/Catroid/wiki/Frequently-Asked-Questions) -* [Credits](http://developer.catrobat.org/credits) -* [Statistics on OpenHub](https://www.openhub.net/p/catrobat/) -* [Twitter](http://twitter.com/Catroid) -* [Our Google group](https://groups.google.com/forum/?fromgroups#!forum/catrobat) +- [Google Play Store Download](https://play.google.com/store/apps/details?id=org.catrobat.paintroid) +- [F-Droid Download](https://f-droid.org/packages/org.catrobat.paintroid/) +- [Frequently Asked Questions](https://github.com/Catrobat/Catroid/wiki/Frequently-Asked-Questions) +- [Credits](http://developer.catrobat.org/credits) +- [Statistics on OpenHub](https://www.openhub.net/p/catrobat/) +- [Twitter](http://twitter.com/Catroid) +- [Our Google group](https://groups.google.com/forum/?fromgroups#!forum/catrobat) -# License # +## License [License](http://developer.catrobat.org/licenses) of our project (mainly AGPL v3). diff --git a/analysis_options.yaml b/analysis_options.yaml index f26de79a..1ee68bd9 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -9,7 +9,6 @@ linter: constant_identifier_names: false analyzer: - errors: missing_enum_constant_in_switch: error exhaustive_cases: error @@ -20,5 +19,5 @@ analyzer: unused_import: error exclude: - - lib/**.pb*.dart - - lib/data/*.g.dart + - lib/src/**.pb*.dart + - lib/src/data/*.g.dart diff --git a/generate_files.sh b/generate_files.sh deleted file mode 100755 index acb214db..00000000 --- a/generate_files.sh +++ /dev/null @@ -1 +0,0 @@ -flutter pub run build_runner build --delete-conflicting-outputs \ No newline at end of file diff --git a/generate_protos.sh b/generate_protos.sh index a0183514..bcdcea6a 100755 --- a/generate_protos.sh +++ b/generate_protos.sh @@ -1,3 +1,3 @@ -cd lib/io/src/serialization/proto || exit +cd packages/io_library/lib/src/serialization/proto || exit mkdir -p output -protoc --dart_out=output --proto_path=schema $(find schema -iname "*.proto") google/protobuf/any.proto \ No newline at end of file +protoc --dart_out=output --proto_path=schema $(find schema -iname "*.proto") google/protobuf/any.proto diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index 8d4492f9..9625e105 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 9.0 + 11.0 diff --git a/ios/Podfile b/ios/Podfile index 96a322b8..3854b694 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '9.0' +platform :ios, '11.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 72cf21bc..62cb12ec 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,4 +1,6 @@ PODS: + - device_info_plus (0.0.1): + - Flutter - DKImagePickerController/Core (4.3.4): - DKImagePickerController/ImageDataManager - DKImagePickerController/Resource @@ -34,60 +36,108 @@ PODS: - DKImagePickerController/PhotoGallery - Flutter - Flutter (1.0.0) + - flutter_localization (0.0.1): + - Flutter + - FMDB (2.7.5): + - FMDB/standard (= 2.7.5) + - FMDB/standard (2.7.5) - image_picker_ios (0.0.1): - Flutter - integration_test (0.0.1): - Flutter - - path_provider_ios (0.0.1): + - launch_review (0.0.1): + - Flutter + - package_info_plus (0.4.5): + - Flutter + - path_provider_foundation (0.0.1): - Flutter - - permission_handler_apple (9.0.4): + - FlutterMacOS + - permission_handler_apple (9.1.1): - Flutter - SDWebImage (5.13.1): - SDWebImage/Core (= 5.13.1) - SDWebImage/Core (5.13.1) + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - sqflite (0.0.3): + - Flutter + - FMDB (>= 2.7.5) - SwiftyGif (5.4.3) + - url_launcher_ios (0.0.1): + - Flutter DEPENDENCIES: + - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`) - Flutter (from `Flutter`) + - flutter_localization (from `.symlinks/plugins/flutter_localization/ios`) - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) - integration_test (from `.symlinks/plugins/integration_test/ios`) - - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) + - launch_review (from `.symlinks/plugins/launch_review/ios`) + - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + - sqflite (from `.symlinks/plugins/sqflite/ios`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) SPEC REPOS: trunk: - DKImagePickerController - DKPhotoGallery + - FMDB - SDWebImage - SwiftyGif EXTERNAL SOURCES: + device_info_plus: + :path: ".symlinks/plugins/device_info_plus/ios" file_picker: :path: ".symlinks/plugins/file_picker/ios" Flutter: :path: Flutter + flutter_localization: + :path: ".symlinks/plugins/flutter_localization/ios" image_picker_ios: :path: ".symlinks/plugins/image_picker_ios/ios" integration_test: :path: ".symlinks/plugins/integration_test/ios" - path_provider_ios: - :path: ".symlinks/plugins/path_provider_ios/ios" + launch_review: + :path: ".symlinks/plugins/launch_review/ios" + package_info_plus: + :path: ".symlinks/plugins/package_info_plus/ios" + path_provider_foundation: + :path: ".symlinks/plugins/path_provider_foundation/darwin" permission_handler_apple: :path: ".symlinks/plugins/permission_handler_apple/ios" + shared_preferences_foundation: + :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + sqflite: + :path: ".symlinks/plugins/sqflite/ios" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" SPEC CHECKSUMS: + device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6 DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 - file_picker: 817ab1d8cd2da9d2da412a417162deee3500fc95 - Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a - image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb - integration_test: a1e7d09bd98eca2fc37aefd79d4f41ad37bdbbe5 - path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 - permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce + file_picker: ce3938a0df3cc1ef404671531facef740d03f920 + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + flutter_localization: f43b18844a2b3d2c71fd64f04ffd6b1e64dd54d4 + FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a + image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5 + integration_test: 13825b8a9334a850581300559b8839134b124670 + launch_review: 75d5a956ba8eaa493e9c9d4bf4c05e505e8d5ed0 + package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85 + path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 + permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 SDWebImage: fb26a455eeda4c7a55e4dcb6172dbb258af7a4ca + shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 + sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780 + url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b -PODFILE CHECKSUM: 0bb9cd0668dcd7eee7f213e7cfebebde242de503 +PODFILE CHECKSUM: a62623f56f2d1d0e85a4a3c73509cd2832d5c86f -COCOAPODS: 1.11.3 +COCOAPODS: 1.14.3 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 2db987e8..a7efac41 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -200,10 +200,12 @@ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( @@ -236,6 +238,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -340,7 +343,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -418,7 +421,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -467,7 +470,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index ea55f3eb..83a9271b 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -118,5 +118,7 @@ CADisableMinimumFrameDurationOnPhone + UIApplicationSupportsIndirectInputEvents + diff --git a/l10n.yaml b/l10n.yaml deleted file mode 100644 index fc80cd87..00000000 --- a/l10n.yaml +++ /dev/null @@ -1,3 +0,0 @@ -arb-dir: assets/l10n -template-arb-file: en.arb -output-localization-file: app_localizations.dart \ No newline at end of file diff --git a/lib/core/app_localizations.dart b/lib/core/app_localizations.dart deleted file mode 100644 index 304170cb..00000000 --- a/lib/core/app_localizations.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart' as generated; -import 'package:flutter_gen/gen_l10n/app_localizations_en.dart'; - -class AppLocalizations { - AppLocalizations._(); - - static generated.AppLocalizations of(BuildContext context) => - generated.AppLocalizations.of(context) ?? AppLocalizationsEn(); -} diff --git a/lib/core/path_with_action_history.dart b/lib/core/path_with_action_history.dart deleted file mode 100644 index 75bffb9b..00000000 --- a/lib/core/path_with_action_history.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'dart:ui'; - -class PathWithActionHistory extends Path { - final actions = []; - - @override - void moveTo(double x, double y) { - actions.add(MoveToAction(x, y)); - super.moveTo(x, y); - } - - @override - void lineTo(double x, double y) { - actions.add(LineToAction(x, y)); - super.lineTo(x, y); - } - - @override - void close() { - actions.add(const CloseAction()); - super.close(); - } -} - -abstract class PathAction { - const PathAction(); -} - -class MoveToAction extends PathAction { - final double x; - final double y; - - const MoveToAction(this.x, this.y); -} - -class LineToAction extends PathAction { - final double x; - final double y; - - const LineToAction(this.x, this.y); -} - -class CloseAction extends PathAction { - const CloseAction(); -} diff --git a/lib/io/io.dart b/lib/io/io.dart deleted file mode 100644 index 51858f85..00000000 --- a/lib/io/io.dart +++ /dev/null @@ -1,18 +0,0 @@ -export 'src/entity/catrobat_image.dart'; -export 'src/entity/image_from_file.dart'; -export 'src/entity/image_location.dart'; -export 'src/entity/image_meta_data.dart'; -export 'src/failure/load_image_failure.dart'; -export 'src/failure/save_image_failure.dart'; -export 'src/serialization/serializer/catrobat_image_serializer.dart'; -export 'src/service/file_service.dart'; -export 'src/service/image_service.dart'; -export 'src/service/permission_service.dart'; -export 'src/service/photo_library_service.dart'; -export 'src/ui/discard_changes_dialog.dart'; -export 'src/ui/load_image_dialog.dart'; -export 'src/ui/save_image_dialog.dart'; -export 'src/usecase/load_image_from_file_manager.dart'; -export 'src/usecase/load_image_from_photo_library.dart'; -export 'src/usecase/save_as_catrobat_image.dart'; -export 'src/usecase/save_as_raster_image.dart'; diff --git a/lib/main.dart b/lib/main.dart index 2a7cf6cd..27182e3a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,15 +1,10 @@ import 'dart:developer'; import 'package:flutter/material.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:logging/logging.dart'; -import 'package:paintroid/ui/color_schemes.dart'; -import 'package:paintroid/ui/landing_page/landing_page.dart'; -import 'package:paintroid/ui/onboarding/onboarding_page.dart'; -import 'package:paintroid/ui/pocket_paint.dart'; -import 'package:paintroid/ui/shared/loading_overlay.dart'; -import 'package:paintroid/workspace/workspace.dart'; +import 'package:paintroid/pocket_paint_app.dart'; + import 'package:shared_preferences/shared_preferences.dart'; void main() async { @@ -36,56 +31,3 @@ void main() async { ), ); } - -class PocketPaintApp extends StatelessWidget { - final bool showOnboardingPage; - - const PocketPaintApp({Key? key, required this.showOnboardingPage}) - : super(key: key); - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Pocket Paint', - localizationsDelegates: AppLocalizations.localizationsDelegates, - supportedLocales: AppLocalizations.supportedLocales, - theme: ThemeData.from( - useMaterial3: true, - colorScheme: lightColorScheme, - ), - initialRoute: '/', - onGenerateRoute: (settings) { - switch (settings.name) { - case '/': - return MaterialPageRoute( - builder: (context) => showOnboardingPage - ? const OnboardingPage( - navigateTo: LandingPage(title: 'Pocket Paint'), - ) - : const LandingPage(title: 'Pocket Paint'), - ); - case '/PocketPaint': - return MaterialPageRoute( - builder: (context) => const PocketPaint(), - ); - case '/OnboardingPage': - return MaterialPageRoute( - builder: (context) => const OnboardingPage(), - ); - } - return null; - }, - home: Consumer( - builder: (BuildContext context, WidgetRef ref, Widget? child) { - return LoadingOverlay( - isLoading: ref.watch( - WorkspaceState.provider - .select((state) => state.isPerformingIOTask), - ), - child: child); - }, - child: const LandingPage(title: 'Pocket Paint'), - ), - ); - } -} diff --git a/lib/pocket_paint_app.dart b/lib/pocket_paint_app.dart new file mode 100644 index 00000000..3d617c6a --- /dev/null +++ b/lib/pocket_paint_app.dart @@ -0,0 +1,66 @@ +import 'package:component_library/component_library.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:l10n/l10n.dart'; +import 'package:landing_page_screen/landing_page_screen.dart'; +import 'package:onboarding_screen/onboarding_screen.dart'; +import 'package:workspace_screen/workspace_screen.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; + +class PocketPaintApp extends StatelessWidget { + final bool showOnboardingPage; + + const PocketPaintApp({Key? key, required this.showOnboardingPage}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Pocket Paint', + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: AppLocalizations.supportedLocales, + theme: ThemeData.from( + useMaterial3: true, + colorScheme: lightColorScheme, + ), + initialRoute: '/', + onGenerateRoute: (settings) { + switch (settings.name) { + case '/': + return MaterialPageRoute( + builder: (context) => showOnboardingPage + ? const OnboardingPage( + navigateTo: LandingPage(title: 'Pocket Paint'), + ) + : const LandingPage(title: 'Pocket Paint'), + ); + case '/PocketPaint': + return MaterialPageRoute( + builder: (context) => const WorkspaceScreen(), + ); + case '/OnboardingPage': + return MaterialPageRoute( + builder: (context) => const OnboardingPage(), + ); + } + return null; + }, + home: Consumer( + builder: (BuildContext context, WidgetRef ref, Widget? child) { + return LoadingOverlay( + isLoading: ref.watch( + WorkspaceState.provider + .select((state) => state.isPerformingIOTask), + ), + child: child); + }, + child: const LandingPage(title: 'Pocket Paint'), + ), + ); + } +} diff --git a/lib/ui/drawing_space/color_box.dart b/lib/ui/drawing_space/color_box.dart deleted file mode 100644 index 61614eef..00000000 --- a/lib/ui/drawing_space/color_box.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; - -class ColorBox extends StatelessWidget { - const ColorBox({ - required this.color, - super.key, - }); - - final Color color; - - @override - Widget build(BuildContext context) { - return Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - color: color, - ), - height: 40, - width: 40, - ); - } -} diff --git a/lib/workspace/workspace.dart b/lib/workspace/workspace.dart deleted file mode 100644 index 0933385b..00000000 --- a/lib/workspace/workspace.dart +++ /dev/null @@ -1,4 +0,0 @@ -export 'src/state/workspace_state_notifier.dart'; -export 'src/ui/canvas_painter.dart'; -export 'src/ui/drawing_canvas.dart'; -export 'src/usecase/render_image_for_export.dart'; diff --git a/melos.yaml b/melos.yaml new file mode 100644 index 00000000..eb95a60a --- /dev/null +++ b/melos.yaml @@ -0,0 +1,97 @@ +name: Paintroid-Flutter +repository: https://github.com/Catrobat/Paintroid-Flutter +sdkPath: auto + +packages: + - packages/* + - packages/features/* + +command: + bootstrap: + runPubGetInParallel: true + usePubspecOverrides: true + +scripts: + lint:all: + run: melos run analyze + description: Run all static analysis checks. + + analyze: + # We are setting the concurrency to 1 because a higher concurrency can crash + # the analysis server on low performance machines (like GitHub Actions). + run: | + melos exec -c 1 -- \ + dart analyze . --fatal-infos + description: | + Run `dart analyze` in all packages. + - Note: you can also rely on your IDEs Dart Analysis / Issues window. + + test:all: + run: | + melos run test --no-select + description: | + Run all tests available. + + test: + run: | + melos exec -c 6 --fail-fast -- \ + "flutter test" + description: Run `flutter test` for a specific package. + packageFilters: + dirExists: + - test + ignore: + - "*web*" + - "*odm*" + - "*example*" + + test:unit: + run: | + melos run test-unit --no-select + description: | + Run all tests available. + + test-unit: + run: | + melos exec -c 6 --fail-fast -- \ + "flutter test test/unit" + description: Run `flutter test test/unit` for a specific package. + packageFilters: + dirExists: + - test/unit + ignore: + - "*web*" + - "*odm*" + - "*example*" + + test:widget: + run: | + melos run test-widget --no-select + description: | + Run all tests available. + + test-widget: + run: | + melos exec -c 6 --fail-fast -- \ + "flutter test test/widget" + description: Run `flutter test test/widget` for a specific package. + packageFilters: + dirExists: + - test/widget + ignore: + - "*web*" + - "*odm*" + - "*example*" + + build:all: + run: | + melos run build --no-select + description: | + Run all build_runners available. + + build: + # We are setting the concurrency to 1 because a higher concurrency creates dependencies problems. + run: | + melos exec -c 1 --fail-fast -- \ + "flutter pub run build_runner build --delete-conflicting-outputs" + description: Run `flutter pub run build_runner build --delete-conflicting-outputs` for a specific package. diff --git a/colorpicker/.gitignore b/packages/colorpicker/.gitignore similarity index 100% rename from colorpicker/.gitignore rename to packages/colorpicker/.gitignore diff --git a/colorpicker/.metadata b/packages/colorpicker/.metadata similarity index 100% rename from colorpicker/.metadata rename to packages/colorpicker/.metadata diff --git a/colorpicker/CHANGELOG.md b/packages/colorpicker/CHANGELOG.md similarity index 100% rename from colorpicker/CHANGELOG.md rename to packages/colorpicker/CHANGELOG.md diff --git a/colorpicker/LICENSE b/packages/colorpicker/LICENSE similarity index 100% rename from colorpicker/LICENSE rename to packages/colorpicker/LICENSE diff --git a/colorpicker/README.md b/packages/colorpicker/README.md similarity index 100% rename from colorpicker/README.md rename to packages/colorpicker/README.md diff --git a/colorpicker/analysis_options.yaml b/packages/colorpicker/analysis_options.yaml similarity index 100% rename from colorpicker/analysis_options.yaml rename to packages/colorpicker/analysis_options.yaml diff --git a/assets/img/checkerboard.png b/packages/colorpicker/assets/img/checkerboard.png similarity index 100% rename from assets/img/checkerboard.png rename to packages/colorpicker/assets/img/checkerboard.png diff --git a/colorpicker/lib/colorpicker.dart b/packages/colorpicker/lib/colorpicker.dart similarity index 100% rename from colorpicker/lib/colorpicker.dart rename to packages/colorpicker/lib/colorpicker.dart diff --git a/colorpicker/lib/constants/colors.dart b/packages/colorpicker/lib/constants/colors.dart similarity index 100% rename from colorpicker/lib/constants/colors.dart rename to packages/colorpicker/lib/constants/colors.dart diff --git a/colorpicker/lib/widgets/color_compare.dart b/packages/colorpicker/lib/widgets/color_compare.dart similarity index 100% rename from colorpicker/lib/widgets/color_compare.dart rename to packages/colorpicker/lib/widgets/color_compare.dart diff --git a/colorpicker/lib/widgets/slider.dart b/packages/colorpicker/lib/widgets/slider.dart similarity index 100% rename from colorpicker/lib/widgets/slider.dart rename to packages/colorpicker/lib/widgets/slider.dart diff --git a/colorpicker/lib/widgets/slider_indicator.dart b/packages/colorpicker/lib/widgets/slider_indicator.dart similarity index 100% rename from colorpicker/lib/widgets/slider_indicator.dart rename to packages/colorpicker/lib/widgets/slider_indicator.dart diff --git a/colorpicker/pubspec.yaml b/packages/colorpicker/pubspec.yaml similarity index 87% rename from colorpicker/pubspec.yaml rename to packages/colorpicker/pubspec.yaml index bf1da0a0..f15352f0 100644 --- a/colorpicker/pubspec.yaml +++ b/packages/colorpicker/pubspec.yaml @@ -15,13 +15,10 @@ dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^2.0.0 + build_runner: ^2.2.0 -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter packages. flutter: - + uses-material-design: true assets: - assets/img/ # diff --git a/colorpicker/test/colorpicker_test.dart b/packages/colorpicker/test/colorpicker_test.dart similarity index 100% rename from colorpicker/test/colorpicker_test.dart rename to packages/colorpicker/test/colorpicker_test.dart diff --git a/packages/command/.metadata b/packages/command/.metadata new file mode 100644 index 00000000..9596faee --- /dev/null +++ b/packages/command/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 796c8ef79279f9c774545b3771238c3098dbefab + channel: stable + +project_type: package diff --git a/packages/command/analysis_options.yaml b/packages/command/analysis_options.yaml new file mode 100644 index 00000000..1ee68bd9 --- /dev/null +++ b/packages/command/analysis_options.yaml @@ -0,0 +1,23 @@ +include: package:flutter_lints/flutter.yaml +linter: + rules: + always_use_package_imports: true + avoid_relative_lib_imports: true + prefer_relative_imports: false + prefer_single_quotes: true + avoid_void_async: true + constant_identifier_names: false + +analyzer: + errors: + missing_enum_constant_in_switch: error + exhaustive_cases: error + unused_element: error + type_annotate_public_apis: error + missing_required_param: error + invalid_use_of_protected_member: error + unused_import: error + + exclude: + - lib/src/**.pb*.dart + - lib/src/data/*.g.dart diff --git a/lib/command/command.dart b/packages/command/lib/command.dart similarity index 50% rename from lib/command/command.dart rename to packages/command/lib/command.dart index 041aef1a..e6dc05e4 100644 --- a/lib/command/command.dart +++ b/packages/command/lib/command.dart @@ -1,6 +1,9 @@ -export 'src/command.dart'; +library command; + +export 'src/graphic/draw_path_command.dart'; +export 'src/manager/sync_command_manager.dart'; + export 'src/command_factory.dart'; export 'src/command_manager.dart'; +export 'src/command.dart'; export 'src/graphic_command.dart'; -export 'src/implementation/command/graphic/draw_path_command.dart'; -export 'src/implementation/manager/sync_command_manager.dart'; diff --git a/packages/command/lib/command_providers.dart b/packages/command/lib/command_providers.dart new file mode 100644 index 00000000..f94e8ec9 --- /dev/null +++ b/packages/command/lib/command_providers.dart @@ -0,0 +1,4 @@ +library command; + +export 'src/command_factory_provider.dart'; +export 'src/command_manager_provider.dart'; diff --git a/lib/command/src/command.dart b/packages/command/lib/src/command.dart similarity index 100% rename from lib/command/src/command.dart rename to packages/command/lib/src/command.dart diff --git a/lib/command/src/command_factory.dart b/packages/command/lib/src/command_factory.dart similarity index 56% rename from lib/command/src/command_factory.dart rename to packages/command/lib/src/command_factory.dart index 7068d45e..2953b28c 100644 --- a/lib/command/src/command_factory.dart +++ b/packages/command/lib/src/command_factory.dart @@ -1,7 +1,7 @@ import 'dart:ui'; -import 'package:paintroid/command/src/implementation/command/graphic/draw_path_command.dart'; -import 'package:paintroid/core/path_with_action_history.dart'; +import 'package:command/command.dart'; +import 'package:component_library/component_library.dart'; class CommandFactory { const CommandFactory(); diff --git a/lib/command/src/command_factory_provider.dart b/packages/command/lib/src/command_factory_provider.dart similarity index 78% rename from lib/command/src/command_factory_provider.dart rename to packages/command/lib/src/command_factory_provider.dart index d0141c74..2145599c 100644 --- a/lib/command/src/command_factory_provider.dart +++ b/packages/command/lib/src/command_factory_provider.dart @@ -1,4 +1,4 @@ -import 'package:paintroid/command/src/command_factory.dart'; +import 'package:command/command.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'command_factory_provider.g.dart'; diff --git a/packages/command/lib/src/command_factory_provider.g.dart b/packages/command/lib/src/command_factory_provider.g.dart new file mode 100644 index 00000000..c851d50b --- /dev/null +++ b/packages/command/lib/src/command_factory_provider.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'command_factory_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$commandFactoryHash() => r'9274f1b9adb5d973abccec2e14a55c11b299f52c'; + +/// See also [commandFactory]. +@ProviderFor(commandFactory) +final commandFactoryProvider = Provider.internal( + commandFactory, + name: r'commandFactoryProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$commandFactoryHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef CommandFactoryRef = ProviderRef; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/lib/command/src/command_manager.dart b/packages/command/lib/src/command_manager.dart similarity index 74% rename from lib/command/src/command_manager.dart rename to packages/command/lib/src/command_manager.dart index c12856cc..e854432b 100644 --- a/lib/command/src/command_manager.dart +++ b/packages/command/lib/src/command_manager.dart @@ -1,7 +1,6 @@ import 'dart:ui'; -import 'package:paintroid/command/src/command.dart'; -import 'package:paintroid/command/src/graphic_command.dart'; +import 'package:command/command.dart'; abstract class CommandManager { Iterable get history; diff --git a/lib/command/src/command_manager_provider.dart b/packages/command/lib/src/command_manager_provider.dart similarity index 60% rename from lib/command/src/command_manager_provider.dart rename to packages/command/lib/src/command_manager_provider.dart index 66a96499..f9b73082 100644 --- a/lib/command/src/command_manager_provider.dart +++ b/packages/command/lib/src/command_manager_provider.dart @@ -1,5 +1,4 @@ -import 'package:paintroid/command/src/command_manager.dart'; -import 'package:paintroid/command/src/implementation/manager/sync_command_manager.dart'; +import 'package:command/command.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'command_manager_provider.g.dart'; diff --git a/packages/command/lib/src/command_manager_provider.g.dart b/packages/command/lib/src/command_manager_provider.g.dart new file mode 100644 index 00000000..528fd2be --- /dev/null +++ b/packages/command/lib/src/command_manager_provider.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'command_manager_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$commandManagerHash() => r'cd76374b9414ebebac1eead0d28106cb9fcd4eea'; + +/// See also [commandManager]. +@ProviderFor(commandManager) +final commandManagerProvider = Provider.internal( + commandManager, + name: r'commandManagerProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$commandManagerHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef CommandManagerRef = ProviderRef; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/lib/command/src/implementation/command/graphic/draw_path_command.dart b/packages/command/lib/src/graphic/draw_path_command.dart similarity index 72% rename from lib/command/src/implementation/command/graphic/draw_path_command.dart rename to packages/command/lib/src/graphic/draw_path_command.dart index 1b4993ba..45cfd96b 100644 --- a/lib/command/src/implementation/command/graphic/draw_path_command.dart +++ b/packages/command/lib/src/graphic/draw_path_command.dart @@ -1,8 +1,7 @@ import 'dart:ui'; - +import 'package:command/command.dart'; +import 'package:component_library/component_library.dart'; import 'package:flutter/widgets.dart'; -import 'package:paintroid/command/src/graphic_command.dart'; -import 'package:paintroid/core/path_with_action_history.dart'; class DrawPathCommand extends GraphicCommand { const DrawPathCommand(this.path, super.paint); diff --git a/lib/command/src/graphic_command.dart b/packages/command/lib/src/graphic_command.dart similarity index 74% rename from lib/command/src/graphic_command.dart rename to packages/command/lib/src/graphic_command.dart index ded772e0..7f251477 100644 --- a/lib/command/src/graphic_command.dart +++ b/packages/command/lib/src/graphic_command.dart @@ -1,6 +1,6 @@ import 'dart:ui'; -import 'package:paintroid/command/src/command.dart'; +import 'package:command/command.dart'; abstract class GraphicCommand extends Command { const GraphicCommand(this.paint); diff --git a/lib/command/src/implementation/manager/sync_command_manager.dart b/packages/command/lib/src/manager/sync_command_manager.dart similarity index 85% rename from lib/command/src/implementation/manager/sync_command_manager.dart rename to packages/command/lib/src/manager/sync_command_manager.dart index 963ce240..9c060087 100644 --- a/lib/command/src/implementation/manager/sync_command_manager.dart +++ b/packages/command/lib/src/manager/sync_command_manager.dart @@ -1,8 +1,6 @@ import 'dart:ui'; -import 'package:paintroid/command/src/command.dart'; -import 'package:paintroid/command/src/command_manager.dart'; -import 'package:paintroid/command/src/graphic_command.dart'; +import 'package:command/command.dart'; class SyncCommandManager implements CommandManager { SyncCommandManager({required List commands}) : _history = commands; diff --git a/packages/command/pubspec.yaml b/packages/command/pubspec.yaml new file mode 100644 index 00000000..bc3e81f7 --- /dev/null +++ b/packages/command/pubspec.yaml @@ -0,0 +1,36 @@ +name: command +description: Internal package for commands. +version: 0.0.1 +publish_to: "none" + +environment: + sdk: ">=3.0.5 <4.0.0" + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + + flutter_riverpod: ^2.3.6 + riverpod_annotation: ^2.1.1 + equatable: ^2.0.3 + + # Internal packages + component_library: + path: ../component_library + +dev_dependencies: + flutter_test: + sdk: flutter + + mockito: ^5.2.0 + flutter_launcher_icons: ^0.9.3 + flutter_lints: ^2.0.1 + floor_generator: ^1.2.0 + riverpod_generator: ^2.2.3 + riverpod_lint: ^1.3.2 + build_runner: ^2.2.0 + freezed: ^2.4.1 + +flutter: + uses-material-design: true diff --git a/test/unit/command/command_factory_test.dart b/packages/command/test/unit/command_factory_test.dart similarity index 83% rename from test/unit/command/command_factory_test.dart rename to packages/command/test/unit/command_factory_test.dart index 64173bbd..dd97df80 100644 --- a/test/unit/command/command_factory_test.dart +++ b/packages/command/test/unit/command_factory_test.dart @@ -1,8 +1,8 @@ import 'dart:ui'; import 'package:flutter_test/flutter_test.dart'; -import 'package:paintroid/command/command.dart'; -import 'package:paintroid/core/path_with_action_history.dart'; +import 'package:command/command.dart'; +import 'package:component_library/component_library.dart'; void main() { late PathWithActionHistory testPath; diff --git a/test/unit/command/draw_path_command_test.dart b/packages/command/test/unit/draw_path_command_test.dart similarity index 87% rename from test/unit/command/draw_path_command_test.dart rename to packages/command/test/unit/draw_path_command_test.dart index 0e15859d..bfe43a4d 100644 --- a/test/unit/command/draw_path_command_test.dart +++ b/packages/command/test/unit/draw_path_command_test.dart @@ -1,10 +1,10 @@ import 'dart:ui'; +import 'package:command/command.dart'; +import 'package:component_library/component_library.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; -import 'package:paintroid/command/command.dart'; -import 'package:paintroid/core/path_with_action_history.dart'; import 'draw_path_command_test.mocks.dart'; diff --git a/packages/command/test/unit/draw_path_command_test.mocks.dart b/packages/command/test/unit/draw_path_command_test.mocks.dart new file mode 100644 index 00000000..28d796c0 --- /dev/null +++ b/packages/command/test/unit/draw_path_command_test.mocks.dart @@ -0,0 +1,616 @@ +// Mocks generated by Mockito 5.4.2 from annotations +// in command/test/unit/draw_path_command_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:typed_data' as _i3; +import 'dart:ui' as _i2; + +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeRect_0 extends _i1.SmartFake implements _i2.Rect { + _FakeRect_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [Canvas]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCanvas extends _i1.Mock implements _i2.Canvas { + MockCanvas() { + _i1.throwOnMissingStub(this); + } + + @override + void save() => super.noSuchMethod( + Invocation.method( + #save, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void saveLayer( + _i2.Rect? bounds, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #saveLayer, + [ + bounds, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void restore() => super.noSuchMethod( + Invocation.method( + #restore, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void restoreToCount(int? count) => super.noSuchMethod( + Invocation.method( + #restoreToCount, + [count], + ), + returnValueForMissingStub: null, + ); + + @override + int getSaveCount() => (super.noSuchMethod( + Invocation.method( + #getSaveCount, + [], + ), + returnValue: 0, + ) as int); + + @override + void translate( + double? dx, + double? dy, + ) => + super.noSuchMethod( + Invocation.method( + #translate, + [ + dx, + dy, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void scale( + double? sx, [ + double? sy, + ]) => + super.noSuchMethod( + Invocation.method( + #scale, + [ + sx, + sy, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void rotate(double? radians) => super.noSuchMethod( + Invocation.method( + #rotate, + [radians], + ), + returnValueForMissingStub: null, + ); + + @override + void skew( + double? sx, + double? sy, + ) => + super.noSuchMethod( + Invocation.method( + #skew, + [ + sx, + sy, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void transform(_i3.Float64List? matrix4) => super.noSuchMethod( + Invocation.method( + #transform, + [matrix4], + ), + returnValueForMissingStub: null, + ); + + @override + _i3.Float64List getTransform() => (super.noSuchMethod( + Invocation.method( + #getTransform, + [], + ), + returnValue: _i3.Float64List(0), + ) as _i3.Float64List); + + @override + void clipRect( + _i2.Rect? rect, { + _i2.ClipOp? clipOp = _i2.ClipOp.intersect, + bool? doAntiAlias = true, + }) => + super.noSuchMethod( + Invocation.method( + #clipRect, + [rect], + { + #clipOp: clipOp, + #doAntiAlias: doAntiAlias, + }, + ), + returnValueForMissingStub: null, + ); + + @override + void clipRRect( + _i2.RRect? rrect, { + bool? doAntiAlias = true, + }) => + super.noSuchMethod( + Invocation.method( + #clipRRect, + [rrect], + {#doAntiAlias: doAntiAlias}, + ), + returnValueForMissingStub: null, + ); + + @override + void clipPath( + _i2.Path? path, { + bool? doAntiAlias = true, + }) => + super.noSuchMethod( + Invocation.method( + #clipPath, + [path], + {#doAntiAlias: doAntiAlias}, + ), + returnValueForMissingStub: null, + ); + + @override + _i2.Rect getLocalClipBounds() => (super.noSuchMethod( + Invocation.method( + #getLocalClipBounds, + [], + ), + returnValue: _FakeRect_0( + this, + Invocation.method( + #getLocalClipBounds, + [], + ), + ), + ) as _i2.Rect); + + @override + _i2.Rect getDestinationClipBounds() => (super.noSuchMethod( + Invocation.method( + #getDestinationClipBounds, + [], + ), + returnValue: _FakeRect_0( + this, + Invocation.method( + #getDestinationClipBounds, + [], + ), + ), + ) as _i2.Rect); + + @override + void drawColor( + _i2.Color? color, + _i2.BlendMode? blendMode, + ) => + super.noSuchMethod( + Invocation.method( + #drawColor, + [ + color, + blendMode, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawLine( + _i2.Offset? p1, + _i2.Offset? p2, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawLine, + [ + p1, + p2, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawPaint(_i2.Paint? paint) => super.noSuchMethod( + Invocation.method( + #drawPaint, + [paint], + ), + returnValueForMissingStub: null, + ); + + @override + void drawRect( + _i2.Rect? rect, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawRect, + [ + rect, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawRRect( + _i2.RRect? rrect, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawRRect, + [ + rrect, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawDRRect( + _i2.RRect? outer, + _i2.RRect? inner, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawDRRect, + [ + outer, + inner, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawOval( + _i2.Rect? rect, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawOval, + [ + rect, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawCircle( + _i2.Offset? c, + double? radius, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawCircle, + [ + c, + radius, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawArc( + _i2.Rect? rect, + double? startAngle, + double? sweepAngle, + bool? useCenter, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawArc, + [ + rect, + startAngle, + sweepAngle, + useCenter, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawPath( + _i2.Path? path, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawPath, + [ + path, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawImage( + _i2.Image? image, + _i2.Offset? offset, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawImage, + [ + image, + offset, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawImageRect( + _i2.Image? image, + _i2.Rect? src, + _i2.Rect? dst, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawImageRect, + [ + image, + src, + dst, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawImageNine( + _i2.Image? image, + _i2.Rect? center, + _i2.Rect? dst, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawImageNine, + [ + image, + center, + dst, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawPicture(_i2.Picture? picture) => super.noSuchMethod( + Invocation.method( + #drawPicture, + [picture], + ), + returnValueForMissingStub: null, + ); + + @override + void drawParagraph( + _i2.Paragraph? paragraph, + _i2.Offset? offset, + ) => + super.noSuchMethod( + Invocation.method( + #drawParagraph, + [ + paragraph, + offset, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawPoints( + _i2.PointMode? pointMode, + List<_i2.Offset>? points, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawPoints, + [ + pointMode, + points, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawRawPoints( + _i2.PointMode? pointMode, + _i3.Float32List? points, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawRawPoints, + [ + pointMode, + points, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawVertices( + _i2.Vertices? vertices, + _i2.BlendMode? blendMode, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawVertices, + [ + vertices, + blendMode, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawAtlas( + _i2.Image? atlas, + List<_i2.RSTransform>? transforms, + List<_i2.Rect>? rects, + List<_i2.Color>? colors, + _i2.BlendMode? blendMode, + _i2.Rect? cullRect, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawAtlas, + [ + atlas, + transforms, + rects, + colors, + blendMode, + cullRect, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawRawAtlas( + _i2.Image? atlas, + _i3.Float32List? rstTransforms, + _i3.Float32List? rects, + _i3.Int32List? colors, + _i2.BlendMode? blendMode, + _i2.Rect? cullRect, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawRawAtlas, + [ + atlas, + rstTransforms, + rects, + colors, + blendMode, + cullRect, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawShadow( + _i2.Path? path, + _i2.Color? color, + double? elevation, + bool? transparentOccluder, + ) => + super.noSuchMethod( + Invocation.method( + #drawShadow, + [ + path, + color, + elevation, + transparentOccluder, + ], + ), + returnValueForMissingStub: null, + ); +} diff --git a/packages/component_library/.metadata b/packages/component_library/.metadata new file mode 100644 index 00000000..9596faee --- /dev/null +++ b/packages/component_library/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 796c8ef79279f9c774545b3771238c3098dbefab + channel: stable + +project_type: package diff --git a/packages/component_library/analysis_options.yaml b/packages/component_library/analysis_options.yaml new file mode 100644 index 00000000..1ee68bd9 --- /dev/null +++ b/packages/component_library/analysis_options.yaml @@ -0,0 +1,23 @@ +include: package:flutter_lints/flutter.yaml +linter: + rules: + always_use_package_imports: true + avoid_relative_lib_imports: true + prefer_relative_imports: false + prefer_single_quotes: true + avoid_void_async: true + constant_identifier_names: false + +analyzer: + errors: + missing_enum_constant_in_switch: error + exhaustive_cases: error + unused_element: error + type_annotate_public_apis: error + missing_required_param: error + invalid_use_of_protected_member: error + unused_import: error + + exclude: + - lib/src/**.pb*.dart + - lib/src/data/*.g.dart diff --git a/colorpicker/assets/img/checkerboard.png b/packages/component_library/assets/img/checkerboard.png similarity index 100% rename from colorpicker/assets/img/checkerboard.png rename to packages/component_library/assets/img/checkerboard.png diff --git a/assets/icon/pocketpaint_intro_landscape.png b/packages/component_library/assets/img/pocketpaint_intro_landscape.png similarity index 100% rename from assets/icon/pocketpaint_intro_landscape.png rename to packages/component_library/assets/img/pocketpaint_intro_landscape.png diff --git a/assets/icon/pocketpaint_intro_portrait.png b/packages/component_library/assets/img/pocketpaint_intro_portrait.png similarity index 100% rename from assets/icon/pocketpaint_intro_portrait.png rename to packages/component_library/assets/img/pocketpaint_intro_portrait.png diff --git a/assets/icon/pocketpaint_logo_small.png b/packages/component_library/assets/img/pocketpaint_logo_small.png similarity index 100% rename from assets/icon/pocketpaint_logo_small.png rename to packages/component_library/assets/img/pocketpaint_logo_small.png diff --git a/assets/svg/ic_brush.svg b/packages/component_library/assets/svg/ic_brush.svg similarity index 100% rename from assets/svg/ic_brush.svg rename to packages/component_library/assets/svg/ic_brush.svg diff --git a/assets/svg/ic_clipboard.svg b/packages/component_library/assets/svg/ic_clipboard.svg similarity index 100% rename from assets/svg/ic_clipboard.svg rename to packages/component_library/assets/svg/ic_clipboard.svg diff --git a/assets/svg/ic_clipping.svg b/packages/component_library/assets/svg/ic_clipping.svg similarity index 100% rename from assets/svg/ic_clipping.svg rename to packages/component_library/assets/svg/ic_clipping.svg diff --git a/assets/svg/ic_cursor.svg b/packages/component_library/assets/svg/ic_cursor.svg similarity index 100% rename from assets/svg/ic_cursor.svg rename to packages/component_library/assets/svg/ic_cursor.svg diff --git a/assets/svg/ic_edit_circle.svg b/packages/component_library/assets/svg/ic_edit_circle.svg similarity index 100% rename from assets/svg/ic_edit_circle.svg rename to packages/component_library/assets/svg/ic_edit_circle.svg diff --git a/assets/svg/ic_eraser.svg b/packages/component_library/assets/svg/ic_eraser.svg similarity index 100% rename from assets/svg/ic_eraser.svg rename to packages/component_library/assets/svg/ic_eraser.svg diff --git a/assets/svg/ic_fill.svg b/packages/component_library/assets/svg/ic_fill.svg similarity index 100% rename from assets/svg/ic_fill.svg rename to packages/component_library/assets/svg/ic_fill.svg diff --git a/assets/svg/ic_hand.svg b/packages/component_library/assets/svg/ic_hand.svg similarity index 100% rename from assets/svg/ic_hand.svg rename to packages/component_library/assets/svg/ic_hand.svg diff --git a/assets/svg/ic_import.svg b/packages/component_library/assets/svg/ic_import.svg similarity index 100% rename from assets/svg/ic_import.svg rename to packages/component_library/assets/svg/ic_import.svg diff --git a/assets/svg/ic_layers.svg b/packages/component_library/assets/svg/ic_layers.svg similarity index 100% rename from assets/svg/ic_layers.svg rename to packages/component_library/assets/svg/ic_layers.svg diff --git a/assets/svg/ic_line.svg b/packages/component_library/assets/svg/ic_line.svg similarity index 100% rename from assets/svg/ic_line.svg rename to packages/component_library/assets/svg/ic_line.svg diff --git a/assets/svg/ic_pipette.svg b/packages/component_library/assets/svg/ic_pipette.svg similarity index 100% rename from assets/svg/ic_pipette.svg rename to packages/component_library/assets/svg/ic_pipette.svg diff --git a/assets/svg/ic_shapes.svg b/packages/component_library/assets/svg/ic_shapes.svg similarity index 100% rename from assets/svg/ic_shapes.svg rename to packages/component_library/assets/svg/ic_shapes.svg diff --git a/assets/svg/ic_smudge.svg b/packages/component_library/assets/svg/ic_smudge.svg similarity index 100% rename from assets/svg/ic_smudge.svg rename to packages/component_library/assets/svg/ic_smudge.svg diff --git a/assets/svg/ic_spray_can.svg b/packages/component_library/assets/svg/ic_spray_can.svg similarity index 100% rename from assets/svg/ic_spray_can.svg rename to packages/component_library/assets/svg/ic_spray_can.svg diff --git a/assets/svg/ic_stamp.svg b/packages/component_library/assets/svg/ic_stamp.svg similarity index 100% rename from assets/svg/ic_stamp.svg rename to packages/component_library/assets/svg/ic_stamp.svg diff --git a/assets/svg/ic_text.svg b/packages/component_library/assets/svg/ic_text.svg similarity index 100% rename from assets/svg/ic_text.svg rename to packages/component_library/assets/svg/ic_text.svg diff --git a/assets/svg/ic_tools.svg b/packages/component_library/assets/svg/ic_tools.svg similarity index 100% rename from assets/svg/ic_tools.svg rename to packages/component_library/assets/svg/ic_tools.svg diff --git a/assets/svg/ic_transform.svg b/packages/component_library/assets/svg/ic_transform.svg similarity index 100% rename from assets/svg/ic_transform.svg rename to packages/component_library/assets/svg/ic_transform.svg diff --git a/assets/svg/ic_watercolor.svg b/packages/component_library/assets/svg/ic_watercolor.svg similarity index 100% rename from assets/svg/ic_watercolor.svg rename to packages/component_library/assets/svg/ic_watercolor.svg diff --git a/packages/component_library/lib/component_library.dart b/packages/component_library/lib/component_library.dart new file mode 100644 index 00000000..ee32f582 --- /dev/null +++ b/packages/component_library/lib/component_library.dart @@ -0,0 +1,20 @@ +library component_library; + +export 'src/components/imgs.dart'; +export 'src/components/icon_svg.dart'; +export 'src/components/bottom_nav_bar_icon.dart'; +export 'src/components/custom_action_chip.dart'; +export 'src/components/icon_button_with_label.dart'; +export 'src/components/loading_overlay.dart'; +export 'src/components/pop_menu_button.dart'; + +export 'src/models/graphic_factory.dart'; +export 'src/models/path_with_action_history.dart'; + +export 'src/theme/color_schemes.dart'; +export 'src/theme/styles.dart'; + +export 'src/utils/open_url.dart'; +export 'src/utils/toast_utils.dart'; + +export 'src/graphic_factory_provider.dart'; diff --git a/lib/ui/shared/bottom_nav_bar_icon.dart b/packages/component_library/lib/src/components/bottom_nav_bar_icon.dart similarity index 68% rename from lib/ui/shared/bottom_nav_bar_icon.dart rename to packages/component_library/lib/src/components/bottom_nav_bar_icon.dart index 9568549d..e35205f1 100644 --- a/lib/ui/shared/bottom_nav_bar_icon.dart +++ b/packages/component_library/lib/src/components/bottom_nav_bar_icon.dart @@ -1,5 +1,5 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; class BottomBarIcon extends StatelessWidget { final String asset; @@ -8,9 +8,10 @@ class BottomBarIcon extends StatelessWidget { @override Widget build(BuildContext context) { - return SvgPicture.asset( - asset, - height: 24, + return IconSvg( + path: asset, + height: 24.0, + width: 24.0, color: Theme.of(context).colorScheme.onSurface, ); } diff --git a/lib/ui/shared/custom_action_chip.dart b/packages/component_library/lib/src/components/custom_action_chip.dart similarity index 100% rename from lib/ui/shared/custom_action_chip.dart rename to packages/component_library/lib/src/components/custom_action_chip.dart diff --git a/lib/ui/shared/icon_button_with_label.dart b/packages/component_library/lib/src/components/icon_button_with_label.dart similarity index 100% rename from lib/ui/shared/icon_button_with_label.dart rename to packages/component_library/lib/src/components/icon_button_with_label.dart diff --git a/packages/component_library/lib/src/components/icon_svg.dart b/packages/component_library/lib/src/components/icon_svg.dart new file mode 100644 index 00000000..80e6648d --- /dev/null +++ b/packages/component_library/lib/src/components/icon_svg.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +class IconSvg extends StatelessWidget { + final String path; + final double height; + final double width; + final Color? color; + + const IconSvg({ + Key? key, + required this.path, + required this.height, + required this.width, + this.color, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return SvgPicture.asset( + 'packages/component_library/$path', + height: height, + width: width, + color: color, + ); + } +} diff --git a/packages/component_library/lib/src/components/imgs.dart b/packages/component_library/lib/src/components/imgs.dart new file mode 100644 index 00000000..16421d92 --- /dev/null +++ b/packages/component_library/lib/src/components/imgs.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; + +class CheckerboardImg extends StatelessWidget { + const CheckerboardImg({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + child: Image.asset( + 'packages/component_library/assets/img/checkerboard.png', + repeat: ImageRepeat.repeat, + cacheWidth: 50, + cacheHeight: 50, + filterQuality: FilterQuality.none, + ), + ); + } +} + +class PocketPaintIntroLandscape extends StatelessWidget { + const PocketPaintIntroLandscape({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + child: Image.asset( + 'packages/component_library/assets/img/pocketpaint_intro_landscape.png', + fit: BoxFit.contain, + ), + ); + } +} + +class PocketPaintIntroPortrait extends StatelessWidget { + const PocketPaintIntroPortrait({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + child: Image.asset( + 'packages/component_library/assets/img/pocketpaint_intro_portrait.png', + fit: BoxFit.fitHeight, + ), + ); + } +} + +class PocketPaintLogoSmall extends StatelessWidget { + const PocketPaintLogoSmall({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + child: Image.asset( + 'packages/component_library/assets/img/pocketpaint_logo_small.png', + ), + ); + } +} diff --git a/lib/ui/shared/loading_overlay.dart b/packages/component_library/lib/src/components/loading_overlay.dart similarity index 100% rename from lib/ui/shared/loading_overlay.dart rename to packages/component_library/lib/src/components/loading_overlay.dart diff --git a/lib/ui/pop_menu_button.dart b/packages/component_library/lib/src/components/pop_menu_button.dart similarity index 100% rename from lib/ui/pop_menu_button.dart rename to packages/component_library/lib/src/components/pop_menu_button.dart diff --git a/lib/core/graphic_factory_provider.dart b/packages/component_library/lib/src/graphic_factory_provider.dart similarity index 79% rename from lib/core/graphic_factory_provider.dart rename to packages/component_library/lib/src/graphic_factory_provider.dart index ee32cac7..1d56fee7 100644 --- a/lib/core/graphic_factory_provider.dart +++ b/packages/component_library/lib/src/graphic_factory_provider.dart @@ -1,4 +1,4 @@ -import 'package:paintroid/core/graphic_factory.dart'; +import 'package:component_library/component_library.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'graphic_factory_provider.g.dart'; diff --git a/packages/component_library/lib/src/graphic_factory_provider.g.dart b/packages/component_library/lib/src/graphic_factory_provider.g.dart new file mode 100644 index 00000000..af0d0b89 --- /dev/null +++ b/packages/component_library/lib/src/graphic_factory_provider.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'graphic_factory_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$graphicFactoryHash() => r'a32ae8670aee6a5741031a48a68bac61b3aa411a'; + +/// See also [graphicFactory]. +@ProviderFor(graphicFactory) +final graphicFactoryProvider = Provider.internal( + graphicFactory, + name: r'graphicFactoryProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$graphicFactoryHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef GraphicFactoryRef = ProviderRef; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/lib/core/graphic_factory.dart b/packages/component_library/lib/src/models/graphic_factory.dart similarity index 93% rename from lib/core/graphic_factory.dart rename to packages/component_library/lib/src/models/graphic_factory.dart index 7be04c52..8c421094 100644 --- a/lib/core/graphic_factory.dart +++ b/packages/component_library/lib/src/models/graphic_factory.dart @@ -1,6 +1,6 @@ import 'dart:ui'; -import 'package:paintroid/core/path_with_action_history.dart'; +import 'package:component_library/component_library.dart'; class GraphicFactory { const GraphicFactory(); diff --git a/packages/component_library/lib/src/models/path_with_action_history.dart b/packages/component_library/lib/src/models/path_with_action_history.dart new file mode 100644 index 00000000..596c07b7 --- /dev/null +++ b/packages/component_library/lib/src/models/path_with_action_history.dart @@ -0,0 +1,179 @@ +import 'dart:typed_data'; +import 'dart:ui'; + +class PathWithActionHistory implements Path { + final actions = []; + + final Path _path = Path(); + + @override + void moveTo(double x, double y) { + actions.add(MoveToAction(x, y)); + _path.moveTo(x, y); + } + + @override + void lineTo(double x, double y) { + actions.add(LineToAction(x, y)); + _path.lineTo(x, y); + } + + @override + void close() { + actions.add(const CloseAction()); + _path.close(); + } + + @override + PathFillType get fillType => _path.fillType; + + @override + set fillType(PathFillType value) => _path.fillType = value; + + @override + void addArc(Rect oval, double startAngle, double sweepAngle) { + // TODO: implement addArc + } + + @override + void addOval(Rect oval) { + // TODO: implement addOval + } + + @override + void addPath(Path path, Offset offset, {Float64List? matrix4}) { + // TODO: implement addPath + } + + @override + void addPolygon(List points, bool close) { + // TODO: implement addPolygon + } + + @override + void addRRect(RRect rrect) { + // TODO: implement addRRect + } + + @override + void addRect(Rect rect) { + // TODO: implement addRect + } + + @override + void arcTo(Rect rect, double startAngle, double sweepAngle, bool forceMoveTo) { + // TODO: implement arcTo + } + + @override + void arcToPoint(Offset arcEnd, {Radius radius = Radius.zero, double rotation = 0.0, bool largeArc = false, bool clockwise = true}) { + // TODO: implement arcToPoint + } + + @override + PathMetrics computeMetrics({bool forceClosed = false}) { + // TODO: implement computeMetrics + throw UnimplementedError(); + } + + @override + void conicTo(double x1, double y1, double x2, double y2, double w) { + // TODO: implement conicTo + } + + @override + bool contains(Offset point) { + // TODO: implement contains + throw UnimplementedError(); + } + + @override + void cubicTo(double x1, double y1, double x2, double y2, double x3, double y3) { + // TODO: implement cubicTo + } + + @override + void extendWithPath(Path path, Offset offset, {Float64List? matrix4}) { + // TODO: implement extendWithPath + } + + @override + Rect getBounds() { + // TODO: implement getBounds + throw UnimplementedError(); + } + + @override + void quadraticBezierTo(double x1, double y1, double x2, double y2) { + // TODO: implement quadraticBezierTo + } + + @override + void relativeArcToPoint(Offset arcEndDelta, {Radius radius = Radius.zero, double rotation = 0.0, bool largeArc = false, bool clockwise = true}) { + // TODO: implement relativeArcToPoint + } + + @override + void relativeConicTo(double x1, double y1, double x2, double y2, double w) { + // TODO: implement relativeConicTo + } + + @override + void relativeCubicTo(double x1, double y1, double x2, double y2, double x3, double y3) { + // TODO: implement relativeCubicTo + } + + @override + void relativeLineTo(double dx, double dy) { + // TODO: implement relativeLineTo + } + + @override + void relativeMoveTo(double dx, double dy) { + // TODO: implement relativeMoveTo + } + + @override + void relativeQuadraticBezierTo(double x1, double y1, double x2, double y2) { + // TODO: implement relativeQuadraticBezierTo + } + + @override + void reset() { + // TODO: implement reset + } + + @override + Path shift(Offset offset) { + // TODO: implement shift + throw UnimplementedError(); + } + + @override + Path transform(Float64List matrix4) { + // TODO: implement transform + throw UnimplementedError(); + } +} + +abstract class PathAction { + const PathAction(); +} + +class MoveToAction extends PathAction { + final double x; + final double y; + + const MoveToAction(this.x, this.y); +} + +class LineToAction extends PathAction { + final double x; + final double y; + + const LineToAction(this.x, this.y); +} + +class CloseAction extends PathAction { + const CloseAction(); +} diff --git a/lib/ui/color_schemes.dart b/packages/component_library/lib/src/theme/color_schemes.dart similarity index 100% rename from lib/ui/color_schemes.dart rename to packages/component_library/lib/src/theme/color_schemes.dart diff --git a/lib/ui/styles.dart b/packages/component_library/lib/src/theme/styles.dart similarity index 92% rename from lib/ui/styles.dart rename to packages/component_library/lib/src/theme/styles.dart index 94a76673..2e822183 100644 --- a/lib/ui/styles.dart +++ b/packages/component_library/lib/src/theme/styles.dart @@ -1,5 +1,5 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; -import 'package:paintroid/ui/color_schemes.dart'; abstract class TextThemes { static TextStyle menuItem = TextStyle( diff --git a/lib/ui/util.dart b/packages/component_library/lib/src/utils/open_url.dart similarity index 100% rename from lib/ui/util.dart rename to packages/component_library/lib/src/utils/open_url.dart diff --git a/lib/core/toast_utils.dart b/packages/component_library/lib/src/utils/toast_utils.dart similarity index 100% rename from lib/core/toast_utils.dart rename to packages/component_library/lib/src/utils/toast_utils.dart diff --git a/packages/component_library/pubspec.yaml b/packages/component_library/pubspec.yaml new file mode 100644 index 00000000..6889f556 --- /dev/null +++ b/packages/component_library/pubspec.yaml @@ -0,0 +1,41 @@ +name: component_library +description: Internal package for shared coponents. +version: 0.0.1 +publish_to: "none" + +environment: + sdk: ">=3.0.5 <4.0.0" + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + + flutter_riverpod: ^2.3.6 + riverpod_annotation: ^2.1.1 + freezed_annotation: ^2.4.1 + + flutter_svg: ^1.1.0 + url_launcher: ^6.1.5 + toast: ^0.3.0 + logging: ^1.0.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + mockito: ^5.2.0 + flutter_launcher_icons: ^0.9.3 + flutter_lints: ^2.0.1 + floor_generator: ^1.2.0 + riverpod_generator: ^2.2.3 + riverpod_lint: ^1.3.2 + build_runner: ^2.2.0 + freezed: ^2.4.1 + +flutter: + uses-material-design: true + + assets: + - assets/img/ + - assets/svg/ diff --git a/packages/database/.metadata b/packages/database/.metadata new file mode 100644 index 00000000..9596faee --- /dev/null +++ b/packages/database/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 796c8ef79279f9c774545b3771238c3098dbefab + channel: stable + +project_type: package diff --git a/packages/database/analysis_options.yaml b/packages/database/analysis_options.yaml new file mode 100644 index 00000000..7e11cc27 --- /dev/null +++ b/packages/database/analysis_options.yaml @@ -0,0 +1,24 @@ +include: package:flutter_lints/flutter.yaml +linter: + rules: + always_use_package_imports: true + avoid_relative_lib_imports: true + prefer_relative_imports: false + prefer_single_quotes: true + avoid_void_async: true + constant_identifier_names: false + +analyzer: + errors: + missing_enum_constant_in_switch: error + exhaustive_cases: error + unused_element: error + type_annotate_public_apis: error + missing_required_param: error + invalid_use_of_protected_member: error + unused_import: error + + exclude: + - lib/src/**.pb*.dart + - lib/src/data/*.g.dart + - lib/src/*.g.dart diff --git a/packages/database/lib/database.dart b/packages/database/lib/database.dart new file mode 100644 index 00000000..4fba40d5 --- /dev/null +++ b/packages/database/lib/database.dart @@ -0,0 +1,8 @@ +library database; + +export 'src/models/project.dart'; + +export 'src/utils/date_time_converter.dart'; + +export 'src/project_dao.dart'; +export 'src/project_database.dart'; diff --git a/lib/data/model/project.dart b/packages/database/lib/src/models/project.dart similarity index 100% rename from lib/data/model/project.dart rename to packages/database/lib/src/models/project.dart diff --git a/lib/data/project_dao.dart b/packages/database/lib/src/project_dao.dart similarity index 92% rename from lib/data/project_dao.dart rename to packages/database/lib/src/project_dao.dart index ca60fb07..0f173cca 100644 --- a/lib/data/project_dao.dart +++ b/packages/database/lib/src/project_dao.dart @@ -1,5 +1,5 @@ +import 'package:database/src/models/project.dart'; import 'package:floor/floor.dart'; -import 'package:paintroid/data/model/project.dart'; @dao abstract class ProjectDAO { diff --git a/lib/data/project_database.dart b/packages/database/lib/src/project_database.dart similarity index 73% rename from lib/data/project_database.dart rename to packages/database/lib/src/project_database.dart index 15c27544..bfde21c2 100644 --- a/lib/data/project_database.dart +++ b/packages/database/lib/src/project_database.dart @@ -1,10 +1,11 @@ import 'dart:async'; +import 'package:database/src/models/project.dart'; +import 'package:database/src/project_dao.dart'; +import 'package:database/src/utils/date_time_converter.dart'; import 'package:floor/floor.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/data/model/project.dart'; -import 'package:paintroid/data/project_dao.dart'; -import 'package:paintroid/data/typeconverters/date_time_converter.dart'; + import 'package:sqflite/sqflite.dart' as sqflite; part 'project_database.g.dart'; diff --git a/packages/database/lib/src/project_database.g.dart b/packages/database/lib/src/project_database.g.dart new file mode 100644 index 00000000..ea36ed0d --- /dev/null +++ b/packages/database/lib/src/project_database.g.dart @@ -0,0 +1,204 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'project_database.dart'; + +// ************************************************************************** +// FloorGenerator +// ************************************************************************** + +// ignore: avoid_classes_with_only_static_members +class $FloorProjectDatabase { + /// Creates a database builder for a persistent database. + /// Once a database is built, you should keep a reference to it and re-use it. + static _$ProjectDatabaseBuilder databaseBuilder(String name) => + _$ProjectDatabaseBuilder(name); + + /// Creates a database builder for an in memory database. + /// Information stored in an in memory database disappears when the process is killed. + /// Once a database is built, you should keep a reference to it and re-use it. + static _$ProjectDatabaseBuilder inMemoryDatabaseBuilder() => + _$ProjectDatabaseBuilder(null); +} + +class _$ProjectDatabaseBuilder { + _$ProjectDatabaseBuilder(this.name); + + final String? name; + + final List _migrations = []; + + Callback? _callback; + + /// Adds migrations to the builder. + _$ProjectDatabaseBuilder addMigrations(List migrations) { + _migrations.addAll(migrations); + return this; + } + + /// Adds a database [Callback] to the builder. + _$ProjectDatabaseBuilder addCallback(Callback callback) { + _callback = callback; + return this; + } + + /// Creates the database and initializes it. + Future build() async { + final path = name != null + ? await sqfliteDatabaseFactory.getDatabasePath(name!) + : ':memory:'; + final database = _$ProjectDatabase(); + database.database = await database.open( + path, + _migrations, + _callback, + ); + return database; + } +} + +class _$ProjectDatabase extends ProjectDatabase { + _$ProjectDatabase([StreamController? listener]) { + changeListener = listener ?? StreamController.broadcast(); + } + + ProjectDAO? _projectDAOInstance; + + Future open( + String path, + List migrations, [ + Callback? callback, + ]) async { + final databaseOptions = sqflite.OpenDatabaseOptions( + version: 1, + onConfigure: (database) async { + await database.execute('PRAGMA foreign_keys = ON'); + await callback?.onConfigure?.call(database); + }, + onOpen: (database) async { + await callback?.onOpen?.call(database); + }, + onUpgrade: (database, startVersion, endVersion) async { + await MigrationAdapter.runMigrations( + database, startVersion, endVersion, migrations); + + await callback?.onUpgrade?.call(database, startVersion, endVersion); + }, + onCreate: (database, version) async { + await database.execute( + 'CREATE TABLE IF NOT EXISTS `Project` (`name` TEXT NOT NULL, `path` TEXT NOT NULL, `lastModified` INTEGER NOT NULL, `creationDate` INTEGER NOT NULL, `resolution` TEXT, `format` TEXT, `size` INTEGER, `imagePreviewPath` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT)'); + + await callback?.onCreate?.call(database, version); + }, + ); + return sqfliteDatabaseFactory.openDatabase(path, options: databaseOptions); + } + + @override + ProjectDAO get projectDAO { + return _projectDAOInstance ??= _$ProjectDAO(database, changeListener); + } +} + +class _$ProjectDAO extends ProjectDAO { + _$ProjectDAO( + this.database, + this.changeListener, + ) : _queryAdapter = QueryAdapter(database), + _projectInsertionAdapter = InsertionAdapter( + database, + 'Project', + (Project item) => { + 'name': item.name, + 'path': item.path, + 'lastModified': _dateTimeConverter.encode(item.lastModified), + 'creationDate': _dateTimeConverter.encode(item.creationDate), + 'resolution': item.resolution, + 'format': item.format, + 'size': item.size, + 'imagePreviewPath': item.imagePreviewPath, + 'id': item.id + }), + _projectDeletionAdapter = DeletionAdapter( + database, + 'Project', + ['id'], + (Project item) => { + 'name': item.name, + 'path': item.path, + 'lastModified': _dateTimeConverter.encode(item.lastModified), + 'creationDate': _dateTimeConverter.encode(item.creationDate), + 'resolution': item.resolution, + 'format': item.format, + 'size': item.size, + 'imagePreviewPath': item.imagePreviewPath, + 'id': item.id + }); + + final sqflite.DatabaseExecutor database; + + final StreamController changeListener; + + final QueryAdapter _queryAdapter; + + final InsertionAdapter _projectInsertionAdapter; + + final DeletionAdapter _projectDeletionAdapter; + + @override + Future deleteProject(int id) async { + await _queryAdapter + .queryNoReturn('DELETE FROM Project WHERE id = ?1', arguments: [id]); + } + + @override + Future> getProjects() async { + return _queryAdapter.queryList( + 'SELECT * FROM Project order by lastModified desc', + mapper: (Map row) => Project( + name: row['name'] as String, + path: row['path'] as String, + lastModified: _dateTimeConverter.decode(row['lastModified'] as int), + creationDate: _dateTimeConverter.decode(row['creationDate'] as int), + resolution: row['resolution'] as String?, + format: row['format'] as String?, + size: row['size'] as int?, + imagePreviewPath: row['imagePreviewPath'] as String?, + id: row['id'] as int?)); + } + + @override + Future getProjectByName(String name) async { + return _queryAdapter.query('SELECT * FROM Project WHERE name = ?1', + mapper: (Map row) => Project( + name: row['name'] as String, + path: row['path'] as String, + lastModified: _dateTimeConverter.decode(row['lastModified'] as int), + creationDate: _dateTimeConverter.decode(row['creationDate'] as int), + resolution: row['resolution'] as String?, + format: row['format'] as String?, + size: row['size'] as int?, + imagePreviewPath: row['imagePreviewPath'] as String?, + id: row['id'] as int?), + arguments: [name]); + } + + @override + Future insertProject(Project project) { + return _projectInsertionAdapter.insertAndReturnId( + project, OnConflictStrategy.replace); + } + + @override + Future> insertProjects(List projects) { + return _projectInsertionAdapter.insertListAndReturnIds( + projects, OnConflictStrategy.replace); + } + + @override + Future deleteProjects(List projects) async { + await _projectDeletionAdapter.deleteList(projects); + } +} + +// ignore_for_file: unused_element +final _dateTimeConverter = DateTimeConverter(); diff --git a/lib/data/typeconverters/date_time_converter.dart b/packages/database/lib/src/utils/date_time_converter.dart similarity index 100% rename from lib/data/typeconverters/date_time_converter.dart rename to packages/database/lib/src/utils/date_time_converter.dart diff --git a/packages/database/pubspec.yaml b/packages/database/pubspec.yaml new file mode 100644 index 00000000..ebe35ad8 --- /dev/null +++ b/packages/database/pubspec.yaml @@ -0,0 +1,35 @@ +name: database +description: A new Flutter package project. +version: 0.0.1 +publish_to: "none" + +environment: + sdk: ">=3.0.5 <4.0.0" + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + + flutter_riverpod: ^2.3.6 + riverpod_annotation: ^2.1.1 + freezed_annotation: ^2.4.1 + + floor: ^1.2.0 + sqflite: + +dev_dependencies: + flutter_test: + sdk: flutter + + mockito: ^5.2.0 + flutter_launcher_icons: ^0.9.3 + flutter_lints: ^2.0.1 + floor_generator: ^1.2.0 + riverpod_generator: ^2.2.3 + riverpod_lint: ^1.3.2 + build_runner: ^2.2.0 + freezed: ^2.4.1 + +flutter: + uses-material-design: true diff --git a/test/unit/data/project_database_test.dart b/packages/database/test/unit/project_database_test.dart similarity index 95% rename from test/unit/data/project_database_test.dart rename to packages/database/test/unit/project_database_test.dart index 0274e171..dc00547a 100644 --- a/test/unit/data/project_database_test.dart +++ b/packages/database/test/unit/project_database_test.dart @@ -1,8 +1,6 @@ +import 'package:database/database.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:paintroid/data/model/project.dart'; -import 'package:paintroid/data/project_database.dart'; -import 'package:paintroid/data/typeconverters/date_time_converter.dart'; void main() async { TestWidgetsFlutterBinding.ensureInitialized(); diff --git a/packages/features/landing_page_screen/.metadata b/packages/features/landing_page_screen/.metadata new file mode 100644 index 00000000..9596faee --- /dev/null +++ b/packages/features/landing_page_screen/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 796c8ef79279f9c774545b3771238c3098dbefab + channel: stable + +project_type: package diff --git a/packages/features/landing_page_screen/analysis_options.yaml b/packages/features/landing_page_screen/analysis_options.yaml new file mode 100644 index 00000000..1ee68bd9 --- /dev/null +++ b/packages/features/landing_page_screen/analysis_options.yaml @@ -0,0 +1,23 @@ +include: package:flutter_lints/flutter.yaml +linter: + rules: + always_use_package_imports: true + avoid_relative_lib_imports: true + prefer_relative_imports: false + prefer_single_quotes: true + avoid_void_async: true + constant_identifier_names: false + +analyzer: + errors: + missing_enum_constant_in_switch: error + exhaustive_cases: error + unused_element: error + type_annotate_public_apis: error + missing_required_param: error + invalid_use_of_protected_member: error + unused_import: error + + exclude: + - lib/src/**.pb*.dart + - lib/src/data/*.g.dart diff --git a/packages/features/landing_page_screen/lib/landing_page_screen.dart b/packages/features/landing_page_screen/lib/landing_page_screen.dart new file mode 100644 index 00000000..51869a2e --- /dev/null +++ b/packages/features/landing_page_screen/lib/landing_page_screen.dart @@ -0,0 +1,9 @@ +library landing_page_screen; + +export 'src/components/custom_action_button.dart'; +export 'src/components/image_preview.dart'; +export 'src/components/main_overflow_menu.dart'; +export 'src/components/project_list_tile.dart'; +export 'src/components/project_overflow_menu.dart'; + +export 'src/landing_page.dart'; diff --git a/lib/ui/landing_page/custom_action_button.dart b/packages/features/landing_page_screen/lib/src/components/custom_action_button.dart similarity index 100% rename from lib/ui/landing_page/custom_action_button.dart rename to packages/features/landing_page_screen/lib/src/components/custom_action_button.dart diff --git a/lib/ui/landing_page/image_preview.dart b/packages/features/landing_page_screen/lib/src/components/image_preview.dart similarity index 89% rename from lib/ui/landing_page/image_preview.dart rename to packages/features/landing_page_screen/lib/src/components/image_preview.dart index f2e11b6a..31a6b886 100644 --- a/lib/ui/landing_page/image_preview.dart +++ b/packages/features/landing_page_screen/lib/src/components/image_preview.dart @@ -1,8 +1,8 @@ +import 'package:component_library/component_library.dart'; +import 'package:database/database.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:paintroid/core/toast_utils.dart'; -import 'package:paintroid/data/model/project.dart'; -import 'package:paintroid/io/src/service/image_service.dart'; +import 'package:io_library/io_library.dart'; class ImagePreview extends StatelessWidget { final Project? project; diff --git a/lib/ui/landing_page/main_overflow_menu.dart b/packages/features/landing_page_screen/lib/src/components/main_overflow_menu.dart similarity index 91% rename from lib/ui/landing_page/main_overflow_menu.dart rename to packages/features/landing_page_screen/lib/src/components/main_overflow_menu.dart index 6ad8290b..ab968f0c 100644 --- a/lib/ui/landing_page/main_overflow_menu.dart +++ b/packages/features/landing_page_screen/lib/src/components/main_overflow_menu.dart @@ -1,11 +1,9 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:io_library/io_library.dart'; import 'package:launch_review/launch_review.dart'; import 'package:package_info_plus/package_info_plus.dart'; -import 'package:paintroid/io/src/ui/about_dialog.dart'; -import 'package:paintroid/ui/pop_menu_button.dart'; -import 'package:paintroid/ui/styles.dart'; -import 'package:paintroid/ui/util.dart'; enum MainOverflowMenuOption { rate('Rate us!'), diff --git a/lib/ui/landing_page/project_list_tile.dart b/packages/features/landing_page_screen/lib/src/components/project_list_tile.dart similarity index 84% rename from lib/ui/landing_page/project_list_tile.dart rename to packages/features/landing_page_screen/lib/src/components/project_list_tile.dart index 4ea7012d..c087f805 100644 --- a/lib/ui/landing_page/project_list_tile.dart +++ b/packages/features/landing_page_screen/lib/src/components/project_list_tile.dart @@ -1,9 +1,8 @@ +import 'package:database/database.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; -import 'package:paintroid/data/model/project.dart'; -import 'package:paintroid/io/io.dart'; -import 'package:paintroid/ui/landing_page/image_preview.dart'; -import 'package:paintroid/ui/landing_page/project_overflow_menu.dart'; +import 'package:io_library/io_library.dart'; +import 'package:landing_page_screen/landing_page_screen.dart'; class ProjectListTile extends StatelessWidget { final Project project; diff --git a/lib/ui/landing_page/project_overflow_menu.dart b/packages/features/landing_page_screen/lib/src/components/project_overflow_menu.dart similarity index 89% rename from lib/ui/landing_page/project_overflow_menu.dart rename to packages/features/landing_page_screen/lib/src/components/project_overflow_menu.dart index bd2fd762..78d68833 100644 --- a/lib/ui/landing_page/project_overflow_menu.dart +++ b/packages/features/landing_page_screen/lib/src/components/project_overflow_menu.dart @@ -1,12 +1,10 @@ import 'dart:io'; +import 'package:component_library/component_library.dart'; +import 'package:database/database.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/core/toast_utils.dart'; -import 'package:paintroid/data/model/project.dart'; -import 'package:paintroid/data/project_database.dart'; -import 'package:paintroid/io/src/ui/delete_project_dialog.dart'; -import 'package:paintroid/io/src/ui/project_details_dialog.dart'; +import 'package:io_library/io_library.dart'; enum ProjectOverflowMenuOption { deleteProject('Delete'), diff --git a/lib/ui/landing_page/landing_page.dart b/packages/features/landing_page_screen/lib/src/landing_page.dart similarity index 87% rename from lib/ui/landing_page/landing_page.dart rename to packages/features/landing_page_screen/lib/src/landing_page.dart index df2c45e1..9170a6da 100644 --- a/lib/ui/landing_page/landing_page.dart +++ b/packages/features/landing_page_screen/lib/src/landing_page.dart @@ -1,21 +1,12 @@ +import 'package:component_library/component_library.dart'; +import 'package:database/database.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_svg/flutter_svg.dart'; +import 'package:io_library/io_library.dart'; +import 'package:landing_page_screen/landing_page_screen.dart'; import 'package:oxidized/oxidized.dart'; -import 'package:paintroid/core/toast_utils.dart'; -import 'package:paintroid/data/model/project.dart'; -import 'package:paintroid/data/project_database.dart'; -import 'package:paintroid/io/io.dart'; -import 'package:paintroid/ui/color_schemes.dart'; -import 'package:paintroid/ui/io_handler.dart'; -import 'package:paintroid/ui/landing_page/custom_action_button.dart'; -import 'package:paintroid/ui/landing_page/image_preview.dart'; -import 'package:paintroid/ui/landing_page/main_overflow_menu.dart'; -import 'package:paintroid/ui/landing_page/project_list_tile.dart'; -import 'package:paintroid/ui/landing_page/project_overflow_menu.dart'; -import 'package:paintroid/workspace/src/state/canvas/canvas_state_provider.dart'; -import 'package:paintroid/workspace/src/state/workspace_state_notifier.dart'; import 'package:toast/toast.dart'; +import 'package:workspace_screen/workspace_screen.dart'; class LandingPage extends ConsumerStatefulWidget { final String title; @@ -224,10 +215,10 @@ class _ProjectPreview extends StatelessWidget { openProject(); } }, - icon: SvgPicture.asset( - 'assets/svg/ic_edit_circle.svg', - height: 264, - width: 264, + icon: const IconSvg( + path: 'assets/svg/ic_edit_circle.svg', + height: 264.0, + width: 264.0, ), ), ), diff --git a/packages/features/landing_page_screen/pubspec.yaml b/packages/features/landing_page_screen/pubspec.yaml new file mode 100644 index 00000000..09e115ea --- /dev/null +++ b/packages/features/landing_page_screen/pubspec.yaml @@ -0,0 +1,55 @@ +name: landing_page_screen +description: A new Flutter package project. +version: 0.0.1 +publish_to: "none" + +environment: + sdk: ">=3.0.5 <4.0.0" + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + + flutter_riverpod: ^2.3.6 + riverpod_annotation: ^2.1.1 + freezed_annotation: ^2.4.1 + + intl: ^0.18.0 + toast: ^0.3.0 + oxidized: ^5.2.0 + flutter_svg: ^1.1.0 + launch_review: ^3.0.1 + package_info_plus: ^4.0.1 + filesize: ^2.0.1 + + # Internal packages + component_library: + path: ../../component_library + database: + path: ../../database + io_library: + path: ../../io_library + workspace_screen: + path: ../workspace_screen + paintroid: + path: ../../../ + +dev_dependencies: + flutter_test: + sdk: flutter + + mockito: ^5.2.0 + flutter_launcher_icons: ^0.9.3 + flutter_lints: ^2.0.1 + floor_generator: ^1.2.0 + riverpod_generator: ^2.2.3 + riverpod_lint: ^1.3.2 + build_runner: ^2.2.0 + freezed: ^2.4.1 + +flutter: + uses-material-design: true + + assets: + - test/fixture/image/ diff --git a/test/fixture/image/test.jpg b/packages/features/landing_page_screen/test/fixture/image/test.jpg similarity index 100% rename from test/fixture/image/test.jpg rename to packages/features/landing_page_screen/test/fixture/image/test.jpg diff --git a/test/fixture/image/test.png b/packages/features/landing_page_screen/test/fixture/image/test.png similarity index 100% rename from test/fixture/image/test.png rename to packages/features/landing_page_screen/test/fixture/image/test.png diff --git a/packages/features/landing_page_screen/test/fixture/image/test1.png b/packages/features/landing_page_screen/test/fixture/image/test1.png new file mode 100644 index 0000000000000000000000000000000000000000..a2e03a09329b7d4e7a056b28eacf63b33208aa44 GIT binary patch literal 1272 zcmVPx#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91GN1zh1ONa40RR91G5`Po0Cmf+s{jB19BD*PQ~&?~0ssI20000082|tP zC;$Ke82|tP82|tRcubKn-~a#uL`g(JRA>e4mS1R(Q5eTJTUbQ2WGKH(;)1IwmYNH0 zkPD(@ZY39FrM6O1a^c1WrCmtd4M|btf+XZZDJ5=}6c@9JY(g9J=kuv^>U7$cHcM~b zZ+$xFInR5}`#jHi&-=brRi(-bloco|P*$Lq z6halEyb3=cCh(qqEBsT{ad!{sOPH5MvJSfg+F&s>z&kL3A-D!-;Tf!iDV4#U1V2o9 zptBi!00!0%^`Lw_u0yQ2tySLuej9FrkCt+6{aqSUp=uW04agGQ03_K3@F*CSz}8vX6-i_rWg6b%Fu?Ry^G$uR8$xx-}B5pB;ZI+uafeSaXTqA!%nM)u;$qVvmv5a9 z;5A2bXRtl+?o?dMD&GN%RDrS7jKeu^p=PX$#vAwT@d#Yx3-}gV52>uG!8`}Ay8@~F zQ#}u}!k}xK=zVbKVp6tG;4qA~Q$69@{QeA&uNK_B;0<0wd+1-HO|=Rm2J?pg+{C$^ z{`fX@a0QQA@U8vp?R|2m1qasU7U>PbXFRPB~cC`3^d z$1(XVkp(H)OtP?$Y*?_cP!?=Rb{0OCB4H~QN(o8HN?8$>%0?m^N;VX-p;(Zj5c&H3 zr~7hyo@S`YOYhWg&bjBDd+)ht-n%mi314Lp*DJikI^;ry8SkTQNo4Q@%I&iPwU&Rx z@_%Qh5@>`?&{|iJ1CDfI$UosYqUjV8p5XQs-zLlxYa@hti`GR!2cH~5>$vCQcw zNgK?2B&%DB-5af(B#1?NNIHcj7=v5TS`82v3A3s;&_-#l9a>FH@kI!^;u`9kUWQ9( z0Y|1WG|y&%u^zLy$qp-P!zR}bdRg^?DyECU7QJ_Nv2Tn!tOONY1Z^+?H4t~{W(O6! z;<3}HiOpECZ0s%Le?;p7DS$thd@9h@tfJhvR|!5H@&=MY*XJI{cMiG~d?n89)$CE# zAwCse2hJgmu?xX>(o01ucFv=+DHFRe`UtIW(U($2RXT_|?Ur^Niird8?IEZw^87!c zb^BzNmw84x>bftV{hzdIgJk{p%KOPAKj!N9A?(M(f|`O31RV%E i5Og5uK+u8z(18ymm;N57p2}zd0000 extends _i1.SmartFake + implements _i3.StreamController { + _FakeStreamController_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeDatabaseExecutor_2 extends _i1.SmartFake + implements _i4.DatabaseExecutor { + _FakeDatabaseExecutor_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeResult_3 extends _i1.SmartFake + implements _i5.Result { + _FakeResult_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [ProjectDatabase]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockProjectDatabase extends _i1.Mock implements _i6.ProjectDatabase { + MockProjectDatabase() { + _i1.throwOnMissingStub(this); + } + + @override + _i2.ProjectDAO get projectDAO => (super.noSuchMethod( + Invocation.getter(#projectDAO), + returnValue: _FakeProjectDAO_0( + this, + Invocation.getter(#projectDAO), + ), + ) as _i2.ProjectDAO); + + @override + _i3.StreamController get changeListener => (super.noSuchMethod( + Invocation.getter(#changeListener), + returnValue: _FakeStreamController_1( + this, + Invocation.getter(#changeListener), + ), + ) as _i3.StreamController); + + @override + set changeListener(_i3.StreamController? _changeListener) => + super.noSuchMethod( + Invocation.setter( + #changeListener, + _changeListener, + ), + returnValueForMissingStub: null, + ); + + @override + _i4.DatabaseExecutor get database => (super.noSuchMethod( + Invocation.getter(#database), + returnValue: _FakeDatabaseExecutor_2( + this, + Invocation.getter(#database), + ), + ) as _i4.DatabaseExecutor); + + @override + set database(_i4.DatabaseExecutor? _database) => super.noSuchMethod( + Invocation.setter( + #database, + _database, + ), + returnValueForMissingStub: null, + ); + + @override + _i3.Future close() => (super.noSuchMethod( + Invocation.method( + #close, + [], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); +} + +/// A class which mocks [ProjectDAO]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockProjectDAO extends _i1.Mock implements _i2.ProjectDAO { + MockProjectDAO() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.Future insertProject(_i7.Project? project) => (super.noSuchMethod( + Invocation.method( + #insertProject, + [project], + ), + returnValue: _i3.Future.value(0), + ) as _i3.Future); + + @override + _i3.Future> insertProjects(List<_i7.Project>? projects) => + (super.noSuchMethod( + Invocation.method( + #insertProjects, + [projects], + ), + returnValue: _i3.Future>.value([]), + ) as _i3.Future>); + + @override + _i3.Future deleteProject(int? id) => (super.noSuchMethod( + Invocation.method( + #deleteProject, + [id], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future deleteProjects(List<_i7.Project>? projects) => + (super.noSuchMethod( + Invocation.method( + #deleteProjects, + [projects], + ), + returnValue: _i3.Future.value(), + returnValueForMissingStub: _i3.Future.value(), + ) as _i3.Future); + + @override + _i3.Future> getProjects() => (super.noSuchMethod( + Invocation.method( + #getProjects, + [], + ), + returnValue: _i3.Future>.value(<_i7.Project>[]), + ) as _i3.Future>); + + @override + _i3.Future<_i7.Project?> getProjectByName(String? name) => + (super.noSuchMethod( + Invocation.method( + #getProjectByName, + [name], + ), + returnValue: _i3.Future<_i7.Project?>.value(), + ) as _i3.Future<_i7.Project?>); +} + +/// A class which mocks [IImageService]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIImageService extends _i1.Mock implements _i8.IImageService { + MockIImageService() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.Future<_i5.Result<_i9.Image, _i8.Failure>> import( + _i10.Uint8List? fileData) => + (super.noSuchMethod( + Invocation.method( + #import, + [fileData], + ), + returnValue: _i3.Future<_i5.Result<_i9.Image, _i8.Failure>>.value( + _FakeResult_3<_i9.Image, _i8.Failure>( + this, + Invocation.method( + #import, + [fileData], + ), + )), + ) as _i3.Future<_i5.Result<_i9.Image, _i8.Failure>>); + + @override + _i3.Future<_i5.Result<_i10.Uint8List, _i8.Failure>> exportAsJpg( + _i9.Image? image, + int? quality, + ) => + (super.noSuchMethod( + Invocation.method( + #exportAsJpg, + [ + image, + quality, + ], + ), + returnValue: _i3.Future<_i5.Result<_i10.Uint8List, _i8.Failure>>.value( + _FakeResult_3<_i10.Uint8List, _i8.Failure>( + this, + Invocation.method( + #exportAsJpg, + [ + image, + quality, + ], + ), + )), + ) as _i3.Future<_i5.Result<_i10.Uint8List, _i8.Failure>>); + + @override + _i3.Future<_i5.Result<_i10.Uint8List, _i8.Failure>> exportAsPng( + _i9.Image? image) => + (super.noSuchMethod( + Invocation.method( + #exportAsPng, + [image], + ), + returnValue: _i3.Future<_i5.Result<_i10.Uint8List, _i8.Failure>>.value( + _FakeResult_3<_i10.Uint8List, _i8.Failure>( + this, + Invocation.method( + #exportAsPng, + [image], + ), + )), + ) as _i3.Future<_i5.Result<_i10.Uint8List, _i8.Failure>>); + + @override + _i5.Result<_i10.Uint8List, _i8.Failure> getProjectPreview(String? path) => + (super.noSuchMethod( + Invocation.method( + #getProjectPreview, + [path], + ), + returnValue: _FakeResult_3<_i10.Uint8List, _i8.Failure>( + this, + Invocation.method( + #getProjectPreview, + [path], + ), + ), + ) as _i5.Result<_i10.Uint8List, _i8.Failure>); +} + +/// A class which mocks [IFileService]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIFileService extends _i1.Mock implements _i8.IFileService { + MockIFileService() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.Future<_i5.Result<_i11.File, _i8.Failure>> save( + String? filename, + _i10.Uint8List? data, + ) => + (super.noSuchMethod( + Invocation.method( + #save, + [ + filename, + data, + ], + ), + returnValue: _i3.Future<_i5.Result<_i11.File, _i8.Failure>>.value( + _FakeResult_3<_i11.File, _i8.Failure>( + this, + Invocation.method( + #save, + [ + filename, + data, + ], + ), + )), + ) as _i3.Future<_i5.Result<_i11.File, _i8.Failure>>); + + @override + _i3.Future<_i5.Result<_i11.File, _i8.Failure>> saveToApplicationDirectory( + String? filename, + _i10.Uint8List? data, + ) => + (super.noSuchMethod( + Invocation.method( + #saveToApplicationDirectory, + [ + filename, + data, + ], + ), + returnValue: _i3.Future<_i5.Result<_i11.File, _i8.Failure>>.value( + _FakeResult_3<_i11.File, _i8.Failure>( + this, + Invocation.method( + #saveToApplicationDirectory, + [ + filename, + data, + ], + ), + )), + ) as _i3.Future<_i5.Result<_i11.File, _i8.Failure>>); + + @override + _i3.Future<_i5.Result<_i11.File, _i8.Failure>> pick() => (super.noSuchMethod( + Invocation.method( + #pick, + [], + ), + returnValue: _i3.Future<_i5.Result<_i11.File, _i8.Failure>>.value( + _FakeResult_3<_i11.File, _i8.Failure>( + this, + Invocation.method( + #pick, + [], + ), + )), + ) as _i3.Future<_i5.Result<_i11.File, _i8.Failure>>); + + @override + _i5.Result<_i11.File, _i8.Failure> getFile(String? path) => + (super.noSuchMethod( + Invocation.method( + #getFile, + [path], + ), + returnValue: _FakeResult_3<_i11.File, _i8.Failure>( + this, + Invocation.method( + #getFile, + [path], + ), + ), + ) as _i5.Result<_i11.File, _i8.Failure>); + + @override + _i3.Future checkIfFileExistsInApplicationDirectory(String? fileName) => + (super.noSuchMethod( + Invocation.method( + #checkIfFileExistsInApplicationDirectory, + [fileName], + ), + returnValue: _i3.Future.value(false), + ) as _i3.Future); + + @override + _i3.Future<_i5.Result<_i11.FileSystemEntity, _i8.Failure>> + deleteFileInApplicationDirectory(String? fileName) => (super.noSuchMethod( + Invocation.method( + #deleteFileInApplicationDirectory, + [fileName], + ), + returnValue: _i3 + .Future<_i5.Result<_i11.FileSystemEntity, _i8.Failure>>.value( + _FakeResult_3<_i11.FileSystemEntity, _i8.Failure>( + this, + Invocation.method( + #deleteFileInApplicationDirectory, + [fileName], + ), + )), + ) as _i3.Future<_i5.Result<_i11.FileSystemEntity, _i8.Failure>>); +} diff --git a/packages/features/onboarding_screen/.metadata b/packages/features/onboarding_screen/.metadata new file mode 100644 index 00000000..9596faee --- /dev/null +++ b/packages/features/onboarding_screen/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 796c8ef79279f9c774545b3771238c3098dbefab + channel: stable + +project_type: package diff --git a/packages/features/onboarding_screen/analysis_options.yaml b/packages/features/onboarding_screen/analysis_options.yaml new file mode 100644 index 00000000..1ee68bd9 --- /dev/null +++ b/packages/features/onboarding_screen/analysis_options.yaml @@ -0,0 +1,23 @@ +include: package:flutter_lints/flutter.yaml +linter: + rules: + always_use_package_imports: true + avoid_relative_lib_imports: true + prefer_relative_imports: false + prefer_single_quotes: true + avoid_void_async: true + constant_identifier_names: false + +analyzer: + errors: + missing_enum_constant_in_switch: error + exhaustive_cases: error + unused_element: error + type_annotate_public_apis: error + missing_required_param: error + invalid_use_of_protected_member: error + unused_import: error + + exclude: + - lib/src/**.pb*.dart + - lib/src/data/*.g.dart diff --git a/packages/features/onboarding_screen/lib/onboarding_screen.dart b/packages/features/onboarding_screen/lib/onboarding_screen.dart new file mode 100644 index 00000000..a1f4acac --- /dev/null +++ b/packages/features/onboarding_screen/lib/onboarding_screen.dart @@ -0,0 +1,13 @@ +library onboarding_screen; + +export 'src/components/bottom_nav_bar_container.dart'; +export 'src/components/onboarding_page_app_bar.dart'; +export 'src/components/onboarding_page_bottom_nav_bar.dart'; + +export 'src/screens/screen1.dart'; +export 'src/screens/screen2.dart'; +export 'src/screens/screen3.dart'; +export 'src/screens/screen4.dart'; +export 'src/screens/screen5.dart'; + +export 'src/onboarding_screen.dart'; diff --git a/lib/ui/onboarding/bottom_nav_bar_container.dart b/packages/features/onboarding_screen/lib/src/components/bottom_nav_bar_container.dart similarity index 83% rename from lib/ui/onboarding/bottom_nav_bar_container.dart rename to packages/features/onboarding_screen/lib/src/components/bottom_nav_bar_container.dart index 543910fa..d043b7ba 100644 --- a/lib/ui/onboarding/bottom_nav_bar_container.dart +++ b/packages/features/onboarding_screen/lib/src/components/bottom_nav_bar_container.dart @@ -1,6 +1,6 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; -import 'package:paintroid/ui/color_schemes.dart'; -import 'package:paintroid/ui/onboarding/onboarding_page_bottom_nav_bar.dart'; +import 'package:onboarding_screen/onboarding_screen.dart'; class BottomNavigationBarContainer extends StatelessWidget { final List navBarItems; diff --git a/lib/ui/onboarding/onboarding_page_app_bar.dart b/packages/features/onboarding_screen/lib/src/components/onboarding_page_app_bar.dart similarity index 100% rename from lib/ui/onboarding/onboarding_page_app_bar.dart rename to packages/features/onboarding_screen/lib/src/components/onboarding_page_app_bar.dart diff --git a/lib/ui/onboarding/onboarding_page_bottom_nav_bar.dart b/packages/features/onboarding_screen/lib/src/components/onboarding_page_bottom_nav_bar.dart similarity index 94% rename from lib/ui/onboarding/onboarding_page_bottom_nav_bar.dart rename to packages/features/onboarding_screen/lib/src/components/onboarding_page_bottom_nav_bar.dart index 1fa5b6dc..2c4a0b26 100644 --- a/lib/ui/onboarding/onboarding_page_bottom_nav_bar.dart +++ b/packages/features/onboarding_screen/lib/src/components/onboarding_page_bottom_nav_bar.dart @@ -1,5 +1,5 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; -import 'package:paintroid/ui/color_schemes.dart'; class OnboardingPageBottomNavigationBar extends StatefulWidget { final List onPressedFunctions; diff --git a/lib/ui/onboarding/onboarding_page.dart b/packages/features/onboarding_screen/lib/src/onboarding_screen.dart similarity index 90% rename from lib/ui/onboarding/onboarding_page.dart rename to packages/features/onboarding_screen/lib/src/onboarding_screen.dart index c1b65732..46ff21c8 100644 --- a/lib/ui/onboarding/onboarding_page.dart +++ b/packages/features/onboarding_screen/lib/src/onboarding_screen.dart @@ -1,11 +1,8 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:paintroid/ui/color_schemes.dart'; -import 'package:paintroid/ui/onboarding/onboarding_screens/screen1.dart'; -import 'package:paintroid/ui/onboarding/onboarding_screens/screen2.dart'; -import 'package:paintroid/ui/onboarding/onboarding_screens/screen3.dart'; -import 'package:paintroid/ui/onboarding/onboarding_screens/screen4.dart'; -import 'package:paintroid/ui/onboarding/onboarding_screens/screen5.dart'; +import 'package:onboarding_screen/onboarding_screen.dart'; + import 'package:shared_preferences/shared_preferences.dart'; import 'package:smooth_page_indicator/smooth_page_indicator.dart'; import 'package:toast/toast.dart'; diff --git a/lib/ui/onboarding/onboarding_screens/screen1.dart b/packages/features/onboarding_screen/lib/src/screens/screen1.dart similarity index 94% rename from lib/ui/onboarding/onboarding_screens/screen1.dart rename to packages/features/onboarding_screen/lib/src/screens/screen1.dart index 373e7a8a..a58dec9b 100644 --- a/lib/ui/onboarding/onboarding_screens/screen1.dart +++ b/packages/features/onboarding_screen/lib/src/screens/screen1.dart @@ -1,5 +1,5 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; -import 'package:paintroid/ui/color_schemes.dart'; class Screen1 extends StatelessWidget { const Screen1({Key? key}) : super(key: key); diff --git a/lib/ui/onboarding/onboarding_screens/screen2.dart b/packages/features/onboarding_screen/lib/src/screens/screen2.dart similarity index 93% rename from lib/ui/onboarding/onboarding_screens/screen2.dart rename to packages/features/onboarding_screen/lib/src/screens/screen2.dart index ac379b06..b9b8628c 100644 --- a/lib/ui/onboarding/onboarding_screens/screen2.dart +++ b/packages/features/onboarding_screen/lib/src/screens/screen2.dart @@ -1,8 +1,7 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; -import 'package:paintroid/ui/onboarding/onboarding_page_app_bar.dart'; -import 'package:paintroid/ui/onboarding/onboarding_page_bottom_nav_bar.dart'; -import 'package:paintroid/ui/shared/bottom_nav_bar_icon.dart'; -import 'package:paintroid/workspace/src/ui/drawing_canvas.dart'; +import 'package:onboarding_screen/onboarding_screen.dart'; +import 'package:workspace_screen/workspace_screen.dart'; class Screen2 extends StatefulWidget { const Screen2({Key? key}) : super(key: key); diff --git a/lib/ui/onboarding/onboarding_screens/screen3.dart b/packages/features/onboarding_screen/lib/src/screens/screen3.dart similarity index 94% rename from lib/ui/onboarding/onboarding_screens/screen3.dart rename to packages/features/onboarding_screen/lib/src/screens/screen3.dart index 57721000..a7a2d1a8 100644 --- a/lib/ui/onboarding/onboarding_screens/screen3.dart +++ b/packages/features/onboarding_screen/lib/src/screens/screen3.dart @@ -1,8 +1,6 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:paintroid/ui/color_schemes.dart'; -import 'package:paintroid/ui/onboarding/bottom_nav_bar_container.dart'; -import 'package:paintroid/ui/shared/bottom_nav_bar_icon.dart'; +import 'package:onboarding_screen/onboarding_screen.dart'; class Screen3 extends StatefulWidget { const Screen3({Key? key}) : super(key: key); @@ -107,10 +105,11 @@ class _Screen3State extends State { textAlign: TextAlign.start, ), Container( - padding: const EdgeInsets.only(left: 50), - child: SvgPicture.asset( - icons[i], - height: 24, + padding: const EdgeInsets.only(left: 50.0), + child: IconSvg( + path: icons[i], + height: 24.0, + width: 24.0, color: Theme.of(context).colorScheme.onSurface, ), ), diff --git a/lib/ui/onboarding/onboarding_screens/screen4.dart b/packages/features/onboarding_screen/lib/src/screens/screen4.dart similarity index 86% rename from lib/ui/onboarding/onboarding_screens/screen4.dart rename to packages/features/onboarding_screen/lib/src/screens/screen4.dart index cf8cb6a1..ff72ffa4 100644 --- a/lib/ui/onboarding/onboarding_screens/screen4.dart +++ b/packages/features/onboarding_screen/lib/src/screens/screen4.dart @@ -1,5 +1,5 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; -import 'package:paintroid/ui/color_schemes.dart'; class Screen4 extends StatelessWidget { const Screen4({Key? key}) : super(key: key); @@ -39,14 +39,11 @@ class Screen4 extends StatelessWidget { ), ), ), - Expanded( + const Expanded( flex: 6, child: SizedBox( width: double.infinity, - child: Image.asset( - 'assets/icon/pocketpaint_intro_landscape.png', - fit: BoxFit.contain, - ), + child: PocketPaintIntroLandscape(), ), ), ], diff --git a/lib/ui/onboarding/onboarding_screens/screen5.dart b/packages/features/onboarding_screen/lib/src/screens/screen5.dart similarity index 88% rename from lib/ui/onboarding/onboarding_screens/screen5.dart rename to packages/features/onboarding_screen/lib/src/screens/screen5.dart index 11c2fbaa..c7b4053e 100644 --- a/lib/ui/onboarding/onboarding_screens/screen5.dart +++ b/packages/features/onboarding_screen/lib/src/screens/screen5.dart @@ -1,5 +1,5 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; -import 'package:paintroid/ui/color_schemes.dart'; class Screen5 extends StatelessWidget { const Screen5({Key? key}) : super(key: key); @@ -44,10 +44,7 @@ class Screen5 extends StatelessWidget { child: Container( alignment: Alignment.center, padding: const EdgeInsets.only(bottom: 10), - child: Image.asset( - 'assets/icon/pocketpaint_intro_portrait.png', - fit: BoxFit.fitHeight, - ), + child: const PocketPaintIntroPortrait(), ), ), ], diff --git a/packages/features/onboarding_screen/pubspec.yaml b/packages/features/onboarding_screen/pubspec.yaml new file mode 100644 index 00000000..491ce31e --- /dev/null +++ b/packages/features/onboarding_screen/pubspec.yaml @@ -0,0 +1,46 @@ +name: onboarding_screen +description: A new Flutter package project. +version: 0.0.1 +publish_to: "none" + +environment: + sdk: ">=3.0.5 <4.0.0" + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + + flutter_riverpod: ^2.3.6 + riverpod_annotation: ^2.1.1 + smooth_page_indicator: ^1.0.0+2 + shared_preferences: ^2.0.15 + toast: ^0.3.0 + flutter_svg: ^1.1.0 + flutter_localization: ^0.1.12 + + # Internal packages + component_library: + path: ../../component_library + tools: + path: ../../tools + workspace_screen: + path: ../workspace_screen + +dev_dependencies: + flutter_test: + sdk: flutter + + mockito: ^5.2.0 + flutter_launcher_icons: ^0.9.3 + flutter_lints: ^2.0.1 + floor_generator: ^1.2.0 + riverpod_generator: ^2.2.3 + riverpod_lint: ^1.3.2 + build_runner: ^2.2.0 + freezed: ^2.4.1 + +flutter: + uses-material-design: true diff --git a/test/widget/ui/onboarding_page_test.dart b/packages/features/onboarding_screen/test/widget/onboarding_screen_test.dart similarity index 97% rename from test/widget/ui/onboarding_page_test.dart rename to packages/features/onboarding_screen/test/widget/onboarding_screen_test.dart index ffd48867..773ea4a4 100644 --- a/test/widget/ui/onboarding_page_test.dart +++ b/packages/features/onboarding_screen/test/widget/onboarding_screen_test.dart @@ -1,10 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:paintroid/ui/onboarding/onboarding_page.dart'; -import 'package:paintroid/ui/onboarding/onboarding_page_app_bar.dart'; -import 'package:paintroid/ui/onboarding/onboarding_page_bottom_nav_bar.dart'; +import 'package:onboarding_screen/onboarding_screen.dart'; import 'package:smooth_page_indicator/smooth_page_indicator.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; void main() { late Widget sut; @@ -49,6 +48,9 @@ void main() { sut = const ProviderScope( child: MaterialApp( home: OnboardingPage(), + localizationsDelegates: [ + GlobalMaterialLocalizations.delegate, + ], ), ); }); diff --git a/packages/features/workspace_screen/.metadata b/packages/features/workspace_screen/.metadata new file mode 100644 index 00000000..9596faee --- /dev/null +++ b/packages/features/workspace_screen/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 796c8ef79279f9c774545b3771238c3098dbefab + channel: stable + +project_type: package diff --git a/packages/features/workspace_screen/analysis_options.yaml b/packages/features/workspace_screen/analysis_options.yaml new file mode 100644 index 00000000..1ee68bd9 --- /dev/null +++ b/packages/features/workspace_screen/analysis_options.yaml @@ -0,0 +1,23 @@ +include: package:flutter_lints/flutter.yaml +linter: + rules: + always_use_package_imports: true + avoid_relative_lib_imports: true + prefer_relative_imports: false + prefer_single_quotes: true + avoid_void_async: true + constant_identifier_names: false + +analyzer: + errors: + missing_enum_constant_in_switch: error + exhaustive_cases: error + unused_element: error + type_annotate_public_apis: error + missing_required_param: error + invalid_use_of_protected_member: error + unused_import: error + + exclude: + - lib/src/**.pb*.dart + - lib/src/data/*.g.dart diff --git a/lib/ui/drawing_space/bottom_brush_tool_options.dart b/packages/features/workspace_screen/lib/src/components/bottom_brush_tool_options.dart similarity index 95% rename from lib/ui/drawing_space/bottom_brush_tool_options.dart rename to packages/features/workspace_screen/lib/src/components/bottom_brush_tool_options.dart index 6dd6d294..eb2b7142 100644 --- a/lib/ui/drawing_space/bottom_brush_tool_options.dart +++ b/packages/features/workspace_screen/lib/src/components/bottom_brush_tool_options.dart @@ -1,7 +1,7 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/tool/src/brush_tool/brush_tool_state_provider.dart'; -import 'package:paintroid/ui/shared/custom_action_chip.dart'; +import 'package:tools/tools.dart'; class BottomBrushToolOptions extends ConsumerStatefulWidget { const BottomBrushToolOptions({super.key}); diff --git a/lib/ui/drawing_space/bottom_nav_bar.dart b/packages/features/workspace_screen/lib/src/components/bottom_nav_bar.dart similarity index 79% rename from lib/ui/drawing_space/bottom_nav_bar.dart rename to packages/features/workspace_screen/lib/src/components/bottom_nav_bar.dart index 772ad00c..6db2cafe 100644 --- a/lib/ui/drawing_space/bottom_nav_bar.dart +++ b/packages/features/workspace_screen/lib/src/components/bottom_nav_bar.dart @@ -1,25 +1,16 @@ import 'package:colorpicker/colorpicker.dart'; +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/core/app_localizations.dart'; -import 'package:paintroid/tool/tool.dart'; -import 'package:paintroid/ui/drawing_space/tools_bottom_sheet.dart'; -import 'package:paintroid/ui/shared/bottom_nav_bar_icon.dart'; -import 'package:paintroid/ui/styles.dart'; +import 'package:l10n/l10n.dart'; +import 'package:tools/tools.dart'; +import 'package:workspace_screen/workspace_screen.dart'; -Color selectedColor = Colors.black; -final selectedColorProvider = StateProvider((ref) => Colors.black); - -class BottomNavBar extends StatefulWidget { +class BottomNavBar extends StatelessWidget { static const height = 64.0; const BottomNavBar({Key? key}) : super(key: key); - @override - State createState() => _BottomNavBarState(); -} - -class _BottomNavBarState extends State { void _onNavigationItemSelected(int index, BuildContext context) { if (index == 0) { showModalBottomSheet( @@ -30,6 +21,7 @@ class _BottomNavBarState extends State { ), ); } + if (index == 2) { showModalBottomSheet( context: context, @@ -50,15 +42,13 @@ class _BottomNavBarState extends State { } } - - @override Widget build(BuildContext context) { final localizations = AppLocalizations.of(context); return NavigationBarTheme( data: WidgetThemes.bottomNavBarThemeData, child: NavigationBar( - height: BottomNavBar.height, + height: height, onDestinationSelected: (index) => _onNavigationItemSelected(index, context), destinations: [ @@ -86,9 +76,9 @@ class _BottomNavBarState extends State { NavigationDestination( label: localizations.color, icon: Icon( - Icons.square, + Icons.check_box_outline_blank, size: 24, - color: selectedColor, + color: Theme.of(context).colorScheme.onSurface, ), ), NavigationDestination( diff --git a/lib/workspace/src/ui/canvas_painter.dart b/packages/features/workspace_screen/lib/src/components/canvas_painter.dart similarity index 83% rename from lib/workspace/src/ui/canvas_painter.dart rename to packages/features/workspace_screen/lib/src/components/canvas_painter.dart index 09663f3e..3de42d23 100644 --- a/lib/workspace/src/ui/canvas_painter.dart +++ b/packages/features/workspace_screen/lib/src/components/canvas_painter.dart @@ -1,10 +1,7 @@ +import 'package:command/command_providers.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/command/src/command_manager_provider.dart'; -import 'package:paintroid/workspace/src/state/canvas/canvas_state_provider.dart'; -import 'package:paintroid/workspace/src/state/canvas_dirty_state.dart'; -import 'package:paintroid/workspace/src/ui/checkerboard_pattern.dart'; -import 'package:paintroid/workspace/src/ui/command_painter.dart'; +import 'package:workspace_screen/workspace_screen.dart'; class CanvasPainter extends ConsumerWidget { const CanvasPainter({super.key}); diff --git a/lib/workspace/src/ui/checkerboard_pattern.dart b/packages/features/workspace_screen/lib/src/components/checkerboard_pattern.dart similarity index 57% rename from lib/workspace/src/ui/checkerboard_pattern.dart rename to packages/features/workspace_screen/lib/src/components/checkerboard_pattern.dart index 999750eb..f61c58be 100644 --- a/lib/workspace/src/ui/checkerboard_pattern.dart +++ b/packages/features/workspace_screen/lib/src/components/checkerboard_pattern.dart @@ -1,3 +1,4 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; class CheckerboardPattern extends StatelessWidget { @@ -9,14 +10,8 @@ class CheckerboardPattern extends StatelessWidget { Widget build(BuildContext context) { return Stack( children: [ - Positioned.fill( - child: Image.asset( - 'assets/img/checkerboard.png', - repeat: ImageRepeat.repeat, - cacheWidth: 50, - cacheHeight: 50, - filterQuality: FilterQuality.none, - ), + const Positioned.fill( + child: CheckerboardImg(), ), if (child != null) child!, ], diff --git a/lib/workspace/src/ui/command_painter.dart b/packages/features/workspace_screen/lib/src/components/command_painter.dart similarity index 89% rename from lib/workspace/src/ui/command_painter.dart rename to packages/features/workspace_screen/lib/src/components/command_painter.dart index 6b7cef88..dc50e60b 100644 --- a/lib/workspace/src/ui/command_painter.dart +++ b/packages/features/workspace_screen/lib/src/components/command_painter.dart @@ -1,5 +1,5 @@ +import 'package:command/command.dart'; import 'package:flutter/material.dart'; -import 'package:paintroid/command/command.dart'; class CommandPainter extends CustomPainter { CommandPainter(this.commandManager); diff --git a/lib/workspace/src/ui/drawing_canvas.dart b/packages/features/workspace_screen/lib/src/components/drawing_canvas.dart similarity index 90% rename from lib/workspace/src/ui/drawing_canvas.dart rename to packages/features/workspace_screen/lib/src/components/drawing_canvas.dart index def06be6..23c5d02e 100644 --- a/lib/workspace/src/ui/drawing_canvas.dart +++ b/packages/features/workspace_screen/lib/src/components/drawing_canvas.dart @@ -1,12 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/service/device_service.dart'; -import 'package:paintroid/tool/src/tool_types.dart'; -import 'package:paintroid/tool/src/toolbox/toolbox_state_provider.dart'; -import 'package:paintroid/workspace/src/state/canvas/canvas_state_provider.dart'; -import 'package:paintroid/workspace/src/state/canvas_dirty_state.dart'; -import 'package:paintroid/workspace/src/state/workspace_state_notifier.dart'; -import 'package:paintroid/workspace/src/ui/canvas_painter.dart'; +import 'package:tools/tools.dart'; +import 'package:workspace_screen/workspace_screen.dart'; class DrawingCanvas extends ConsumerStatefulWidget { const DrawingCanvas({Key? key}) : super(key: key); diff --git a/lib/ui/drawing_space/exit_fullscreen_button.dart b/packages/features/workspace_screen/lib/src/components/exit_fullscreen_button.dart similarity index 88% rename from lib/ui/drawing_space/exit_fullscreen_button.dart rename to packages/features/workspace_screen/lib/src/components/exit_fullscreen_button.dart index 5cda12f2..9acf6e3f 100644 --- a/lib/ui/drawing_space/exit_fullscreen_button.dart +++ b/packages/features/workspace_screen/lib/src/components/exit_fullscreen_button.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/tool/tool.dart'; -import 'package:paintroid/workspace/workspace.dart'; +import 'package:tools/tools.dart'; +import 'package:workspace_screen/workspace_screen.dart'; class ExitFullscreenButton extends ConsumerWidget { const ExitFullscreenButton({Key? key}) : super(key: key); diff --git a/lib/ui/shared/overflow_menu.dart b/packages/features/workspace_screen/lib/src/components/overflow_menu.dart similarity index 89% rename from lib/ui/shared/overflow_menu.dart rename to packages/features/workspace_screen/lib/src/components/overflow_menu.dart index 3eb5f7ca..238c4863 100644 --- a/lib/ui/shared/overflow_menu.dart +++ b/packages/features/workspace_screen/lib/src/components/overflow_menu.dart @@ -1,18 +1,12 @@ +import 'package:component_library/component_library.dart'; +import 'package:database/database.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:io_library/io_library.dart'; +import 'package:l10n/l10n.dart'; import 'package:oxidized/oxidized.dart'; -import 'package:paintroid/core/app_localizations.dart'; -import 'package:paintroid/data/model/project.dart'; -import 'package:paintroid/data/project_database.dart'; -import 'package:paintroid/io/src/entity/image_meta_data.dart'; -import 'package:paintroid/io/src/service/file_service.dart'; -import 'package:paintroid/io/src/ui/overwrite_dialog.dart'; -import 'package:paintroid/io/src/ui/save_image_dialog.dart'; -import 'package:paintroid/ui/io_handler.dart'; -import 'package:paintroid/ui/pop_menu_button.dart'; -import 'package:paintroid/ui/styles.dart'; -import 'package:paintroid/workspace/workspace.dart'; import 'package:toast/toast.dart'; +import 'package:workspace_screen/workspace_screen.dart'; enum OverflowMenuOption { fullscreen, diff --git a/lib/ui/shared/tool_button.dart b/packages/features/workspace_screen/lib/src/components/tool_button.dart similarity index 70% rename from lib/ui/shared/tool_button.dart rename to packages/features/workspace_screen/lib/src/components/tool_button.dart index bb9b2517..3f346879 100644 --- a/lib/ui/shared/tool_button.dart +++ b/packages/features/workspace_screen/lib/src/components/tool_button.dart @@ -1,8 +1,7 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:paintroid/tool/tool.dart'; -import 'package:paintroid/ui/shared/icon_button_with_label.dart'; +import 'package:tools/tools.dart'; class ToolButton extends StatelessWidget { final ToolData toolData; @@ -17,10 +16,10 @@ class ToolButton extends StatelessWidget { return Consumer( builder: (context, ref, child) { return IconButtonWithLabel( - icon: SvgPicture.asset( - toolData.svgAssetPath, - height: 24, - width: 24, + icon: IconSvg( + path: toolData.svgAssetPath, + height: 24.0, + width: 24.0, color: Colors.white, ), label: toolData.name, diff --git a/lib/ui/drawing_space/tool_options.dart b/packages/features/workspace_screen/lib/src/components/tool_options.dart similarity index 72% rename from lib/ui/drawing_space/tool_options.dart rename to packages/features/workspace_screen/lib/src/components/tool_options.dart index db7c0b80..f46147a1 100644 --- a/lib/ui/drawing_space/tool_options.dart +++ b/packages/features/workspace_screen/lib/src/components/tool_options.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:paintroid/ui/drawing_space/bottom_brush_tool_options.dart'; -import 'package:paintroid/ui/drawing_space/top_brush_tool_options.dart'; +import 'package:workspace_screen/workspace_screen.dart'; class ToolOptions extends StatelessWidget { const ToolOptions({super.key}); diff --git a/lib/ui/drawing_space/tools_bottom_sheet.dart b/packages/features/workspace_screen/lib/src/components/tools_bottom_sheet.dart similarity index 83% rename from lib/ui/drawing_space/tools_bottom_sheet.dart rename to packages/features/workspace_screen/lib/src/components/tools_bottom_sheet.dart index ed28055d..638f6be8 100644 --- a/lib/ui/drawing_space/tools_bottom_sheet.dart +++ b/packages/features/workspace_screen/lib/src/components/tools_bottom_sheet.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:paintroid/tool/tool.dart'; -import 'package:paintroid/ui/shared/tool_button.dart'; +import 'package:tools/tools.dart'; +import 'package:workspace_screen/workspace_screen.dart'; class ToolsBottomSheet extends StatelessWidget { const ToolsBottomSheet({ diff --git a/lib/ui/shared/top_app_bar.dart b/packages/features/workspace_screen/lib/src/components/top_app_bar.dart similarity index 82% rename from lib/ui/shared/top_app_bar.dart rename to packages/features/workspace_screen/lib/src/components/top_app_bar.dart index 0d8d7aa5..fa21bad8 100644 --- a/lib/ui/shared/top_app_bar.dart +++ b/packages/features/workspace_screen/lib/src/components/top_app_bar.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:paintroid/ui/shared/overflow_menu.dart'; +import 'package:workspace_screen/workspace_screen.dart'; class TopAppBar extends AppBar { TopAppBar({Key? key, required String title}) diff --git a/lib/ui/drawing_space/top_brush_tool_options.dart b/packages/features/workspace_screen/lib/src/components/top_brush_tool_options.dart similarity index 95% rename from lib/ui/drawing_space/top_brush_tool_options.dart rename to packages/features/workspace_screen/lib/src/components/top_brush_tool_options.dart index 4b306c8a..22356f36 100644 --- a/lib/ui/drawing_space/top_brush_tool_options.dart +++ b/packages/features/workspace_screen/lib/src/components/top_brush_tool_options.dart @@ -1,8 +1,8 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/tool/src/brush_tool/brush_tool_state_provider.dart'; -import 'package:paintroid/ui/styles.dart'; +import 'package:tools/tools.dart'; class TopBrushToolOptions extends ConsumerStatefulWidget { const TopBrushToolOptions({super.key}); diff --git a/lib/core/image_with_pixel_info.dart b/packages/features/workspace_screen/lib/src/models/image_with_pixel_info.dart similarity index 100% rename from lib/core/image_with_pixel_info.dart rename to packages/features/workspace_screen/lib/src/models/image_with_pixel_info.dart diff --git a/lib/service/device_service.dart b/packages/features/workspace_screen/lib/src/service/device_service.dart similarity index 100% rename from lib/service/device_service.dart rename to packages/features/workspace_screen/lib/src/service/device_service.dart diff --git a/lib/workspace/src/state/canvas_dirty_state.dart b/packages/features/workspace_screen/lib/src/states/canvas_dirty_state.dart similarity index 100% rename from lib/workspace/src/state/canvas_dirty_state.dart rename to packages/features/workspace_screen/lib/src/states/canvas_dirty_state.dart diff --git a/lib/workspace/src/state/canvas/canvas_state_data.dart b/packages/features/workspace_screen/lib/src/states/canvas_state_data.dart similarity index 80% rename from lib/workspace/src/state/canvas/canvas_state_data.dart rename to packages/features/workspace_screen/lib/src/states/canvas_state_data.dart index a1d8ccb6..31c66e55 100644 --- a/lib/workspace/src/state/canvas/canvas_state_data.dart +++ b/packages/features/workspace_screen/lib/src/states/canvas_state_data.dart @@ -1,9 +1,9 @@ import 'dart:ui' as ui; +import 'package:command/command.dart'; +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:paintroid/command/src/command_manager.dart'; -import 'package:paintroid/core/graphic_factory.dart'; part 'canvas_state_data.freezed.dart'; diff --git a/packages/features/workspace_screen/lib/src/states/canvas_state_data.freezed.dart b/packages/features/workspace_screen/lib/src/states/canvas_state_data.freezed.dart new file mode 100644 index 00000000..63ce1189 --- /dev/null +++ b/packages/features/workspace_screen/lib/src/states/canvas_state_data.freezed.dart @@ -0,0 +1,221 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'canvas_state_data.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + +/// @nodoc +mixin _$CanvasStateData { + ui.Image? get backgroundImage => throw _privateConstructorUsedError; + ui.Image? get cachedImage => throw _privateConstructorUsedError; + ui.Size get size => throw _privateConstructorUsedError; + CommandManager get commandManager => throw _privateConstructorUsedError; + GraphicFactory get graphicFactory => throw _privateConstructorUsedError; + + @JsonKey(ignore: true) + $CanvasStateDataCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $CanvasStateDataCopyWith<$Res> { + factory $CanvasStateDataCopyWith( + CanvasStateData value, $Res Function(CanvasStateData) then) = + _$CanvasStateDataCopyWithImpl<$Res, CanvasStateData>; + @useResult + $Res call( + {ui.Image? backgroundImage, + ui.Image? cachedImage, + ui.Size size, + CommandManager commandManager, + GraphicFactory graphicFactory}); +} + +/// @nodoc +class _$CanvasStateDataCopyWithImpl<$Res, $Val extends CanvasStateData> + implements $CanvasStateDataCopyWith<$Res> { + _$CanvasStateDataCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? backgroundImage = freezed, + Object? cachedImage = freezed, + Object? size = null, + Object? commandManager = null, + Object? graphicFactory = null, + }) { + return _then(_value.copyWith( + backgroundImage: freezed == backgroundImage + ? _value.backgroundImage + : backgroundImage // ignore: cast_nullable_to_non_nullable + as ui.Image?, + cachedImage: freezed == cachedImage + ? _value.cachedImage + : cachedImage // ignore: cast_nullable_to_non_nullable + as ui.Image?, + size: null == size + ? _value.size + : size // ignore: cast_nullable_to_non_nullable + as ui.Size, + commandManager: null == commandManager + ? _value.commandManager + : commandManager // ignore: cast_nullable_to_non_nullable + as CommandManager, + graphicFactory: null == graphicFactory + ? _value.graphicFactory + : graphicFactory // ignore: cast_nullable_to_non_nullable + as GraphicFactory, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$_CanvasStateDataCopyWith<$Res> + implements $CanvasStateDataCopyWith<$Res> { + factory _$$_CanvasStateDataCopyWith( + _$_CanvasStateData value, $Res Function(_$_CanvasStateData) then) = + __$$_CanvasStateDataCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {ui.Image? backgroundImage, + ui.Image? cachedImage, + ui.Size size, + CommandManager commandManager, + GraphicFactory graphicFactory}); +} + +/// @nodoc +class __$$_CanvasStateDataCopyWithImpl<$Res> + extends _$CanvasStateDataCopyWithImpl<$Res, _$_CanvasStateData> + implements _$$_CanvasStateDataCopyWith<$Res> { + __$$_CanvasStateDataCopyWithImpl( + _$_CanvasStateData _value, $Res Function(_$_CanvasStateData) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? backgroundImage = freezed, + Object? cachedImage = freezed, + Object? size = null, + Object? commandManager = null, + Object? graphicFactory = null, + }) { + return _then(_$_CanvasStateData( + backgroundImage: freezed == backgroundImage + ? _value.backgroundImage + : backgroundImage // ignore: cast_nullable_to_non_nullable + as ui.Image?, + cachedImage: freezed == cachedImage + ? _value.cachedImage + : cachedImage // ignore: cast_nullable_to_non_nullable + as ui.Image?, + size: null == size + ? _value.size + : size // ignore: cast_nullable_to_non_nullable + as ui.Size, + commandManager: null == commandManager + ? _value.commandManager + : commandManager // ignore: cast_nullable_to_non_nullable + as CommandManager, + graphicFactory: null == graphicFactory + ? _value.graphicFactory + : graphicFactory // ignore: cast_nullable_to_non_nullable + as GraphicFactory, + )); + } +} + +/// @nodoc + +class _$_CanvasStateData implements _CanvasStateData { + const _$_CanvasStateData( + {this.backgroundImage, + this.cachedImage, + required this.size, + required this.commandManager, + required this.graphicFactory}); + + @override + final ui.Image? backgroundImage; + @override + final ui.Image? cachedImage; + @override + final ui.Size size; + @override + final CommandManager commandManager; + @override + final GraphicFactory graphicFactory; + + @override + String toString() { + return 'CanvasStateData(backgroundImage: $backgroundImage, cachedImage: $cachedImage, size: $size, commandManager: $commandManager, graphicFactory: $graphicFactory)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_CanvasStateData && + (identical(other.backgroundImage, backgroundImage) || + other.backgroundImage == backgroundImage) && + (identical(other.cachedImage, cachedImage) || + other.cachedImage == cachedImage) && + (identical(other.size, size) || other.size == size) && + (identical(other.commandManager, commandManager) || + other.commandManager == commandManager) && + (identical(other.graphicFactory, graphicFactory) || + other.graphicFactory == graphicFactory)); + } + + @override + int get hashCode => Object.hash(runtimeType, backgroundImage, cachedImage, + size, commandManager, graphicFactory); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$_CanvasStateDataCopyWith<_$_CanvasStateData> get copyWith => + __$$_CanvasStateDataCopyWithImpl<_$_CanvasStateData>(this, _$identity); +} + +abstract class _CanvasStateData implements CanvasStateData { + const factory _CanvasStateData( + {final ui.Image? backgroundImage, + final ui.Image? cachedImage, + required final ui.Size size, + required final CommandManager commandManager, + required final GraphicFactory graphicFactory}) = _$_CanvasStateData; + + @override + ui.Image? get backgroundImage; + @override + ui.Image? get cachedImage; + @override + ui.Size get size; + @override + CommandManager get commandManager; + @override + GraphicFactory get graphicFactory; + @override + @JsonKey(ignore: true) + _$$_CanvasStateDataCopyWith<_$_CanvasStateData> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/workspace/src/state/canvas/canvas_state_provider.dart b/packages/features/workspace_screen/lib/src/states/canvas_state_provider.dart similarity index 89% rename from lib/workspace/src/state/canvas/canvas_state_provider.dart rename to packages/features/workspace_screen/lib/src/states/canvas_state_provider.dart index 07db2775..5faa5ad1 100644 --- a/lib/workspace/src/state/canvas/canvas_state_provider.dart +++ b/packages/features/workspace_screen/lib/src/states/canvas_state_provider.dart @@ -1,13 +1,14 @@ import 'dart:ui'; +import 'package:command/command.dart'; +import 'package:command/command_providers.dart'; +import 'package:component_library/component_library.dart'; import 'package:flutter/painting.dart'; import 'package:flutter/widgets.dart' as widgets; -import 'package:paintroid/command/command.dart'; -import 'package:paintroid/command/src/command_manager_provider.dart'; -import 'package:paintroid/core/graphic_factory_provider.dart'; -import 'package:paintroid/service/device_service.dart'; -import 'package:paintroid/workspace/src/state/canvas/canvas_state_data.dart'; + import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:workspace_screen/src/service/device_service.dart'; +import 'package:workspace_screen/src/states/canvas_state_data.dart'; part 'canvas_state_provider.g.dart'; diff --git a/packages/features/workspace_screen/lib/src/states/canvas_state_provider.g.dart b/packages/features/workspace_screen/lib/src/states/canvas_state_provider.g.dart new file mode 100644 index 00000000..870eb159 --- /dev/null +++ b/packages/features/workspace_screen/lib/src/states/canvas_state_provider.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'canvas_state_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$canvasStateHash() => r'90efe9797953e15366a523a27d015f733d8597db'; + +/// See also [CanvasState]. +@ProviderFor(CanvasState) +final canvasStateProvider = + NotifierProvider.internal( + CanvasState.new, + name: r'canvasStateProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') ? null : _$canvasStateHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef _$CanvasState = Notifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/lib/workspace/src/state/workspace_state.dart b/packages/features/workspace_screen/lib/src/states/workspace_state.dart similarity index 100% rename from lib/workspace/src/state/workspace_state.dart rename to packages/features/workspace_screen/lib/src/states/workspace_state.dart diff --git a/lib/workspace/src/state/workspace_state_notifier.dart b/packages/features/workspace_screen/lib/src/states/workspace_state_notifier.dart similarity index 88% rename from lib/workspace/src/state/workspace_state_notifier.dart rename to packages/features/workspace_screen/lib/src/states/workspace_state_notifier.dart index b7b32729..30518c5d 100644 --- a/lib/workspace/src/state/workspace_state_notifier.dart +++ b/packages/features/workspace_screen/lib/src/states/workspace_state_notifier.dart @@ -1,7 +1,7 @@ +import 'package:command/command.dart'; +import 'package:command/command_providers.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/command/command.dart'; -import 'package:paintroid/command/src/command_manager_provider.dart'; part 'workspace_state.dart'; diff --git a/lib/workspace/src/usecase/render_image_for_export.dart b/packages/features/workspace_screen/lib/src/usecase/render_image_for_export.dart similarity index 88% rename from lib/workspace/src/usecase/render_image_for_export.dart rename to packages/features/workspace_screen/lib/src/usecase/render_image_for_export.dart index e9905202..da842b8f 100644 --- a/lib/workspace/src/usecase/render_image_for_export.dart +++ b/packages/features/workspace_screen/lib/src/usecase/render_image_for_export.dart @@ -1,12 +1,11 @@ import 'dart:ui'; +import 'package:command/command.dart'; +import 'package:command/command_providers.dart'; +import 'package:component_library/component_library.dart'; import 'package:flutter/painting.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/command/command.dart'; -import 'package:paintroid/command/src/command_manager_provider.dart'; -import 'package:paintroid/core/graphic_factory.dart'; -import 'package:paintroid/core/graphic_factory_provider.dart'; -import 'package:paintroid/workspace/src/state/canvas/canvas_state_provider.dart'; +import 'package:workspace_screen/workspace_screen.dart'; class RenderImageForExport { final Ref _ref; diff --git a/lib/ui/pocket_paint.dart b/packages/features/workspace_screen/lib/src/workspace_screen.dart similarity index 77% rename from lib/ui/pocket_paint.dart rename to packages/features/workspace_screen/lib/src/workspace_screen.dart index ee487439..9994f891 100644 --- a/lib/ui/pocket_paint.dart +++ b/packages/features/workspace_screen/lib/src/workspace_screen.dart @@ -1,23 +1,19 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/io/io.dart'; -import 'package:paintroid/ui/drawing_space/bottom_nav_bar.dart'; -import 'package:paintroid/ui/drawing_space/exit_fullscreen_button.dart'; -import 'package:paintroid/ui/drawing_space/tool_options.dart'; -import 'package:paintroid/ui/io_handler.dart'; -import 'package:paintroid/ui/shared/top_app_bar.dart'; -import 'package:paintroid/workspace/workspace.dart'; +import 'package:io_library/io_library.dart'; + import 'package:toast/toast.dart'; +import 'package:workspace_screen/workspace_screen.dart'; -class PocketPaint extends ConsumerStatefulWidget { - const PocketPaint({Key? key}) : super(key: key); +class WorkspaceScreen extends ConsumerStatefulWidget { + const WorkspaceScreen({Key? key}) : super(key: key); @override - ConsumerState createState() => _PocketPaintState(); + ConsumerState createState() => _WorkspaceScreenState(); } -class _PocketPaintState extends ConsumerState { +class _WorkspaceScreenState extends ConsumerState { void _toggleStatusBar(bool isFullscreen) { SystemChrome.setEnabledSystemUIMode( isFullscreen ? SystemUiMode.immersiveSticky : SystemUiMode.manual, diff --git a/packages/features/workspace_screen/lib/workspace_screen.dart b/packages/features/workspace_screen/lib/workspace_screen.dart new file mode 100644 index 00000000..73242770 --- /dev/null +++ b/packages/features/workspace_screen/lib/workspace_screen.dart @@ -0,0 +1,28 @@ +library workspace_screen; + +export 'src/components/bottom_brush_tool_options.dart'; +export 'src/components/bottom_nav_bar.dart'; +export 'src/components/canvas_painter.dart'; +export 'src/components/checkerboard_pattern.dart'; +export 'src/components/command_painter.dart'; +export 'src/components/drawing_canvas.dart'; +export 'src/components/exit_fullscreen_button.dart'; +export 'src/components/overflow_menu.dart'; +export 'src/components/tool_button.dart'; +export 'src/components/tool_options.dart'; +export 'src/components/tools_bottom_sheet.dart'; +export 'src/components/top_app_bar.dart'; +export 'src/components/top_brush_tool_options.dart'; + +export 'src/models/image_with_pixel_info.dart'; + +export 'src/service/device_service.dart'; + +export 'src/states/canvas_dirty_state.dart'; +export 'src/states/canvas_state_data.dart'; +export 'src/states/canvas_state_provider.dart'; +export 'src/states/workspace_state_notifier.dart'; + +export 'src/usecase/render_image_for_export.dart'; + +export 'src/workspace_screen.dart'; diff --git a/packages/features/workspace_screen/pubspec.yaml b/packages/features/workspace_screen/pubspec.yaml new file mode 100644 index 00000000..a2f5b8de --- /dev/null +++ b/packages/features/workspace_screen/pubspec.yaml @@ -0,0 +1,57 @@ +name: workspace_screen +description: A new Flutter package project. +version: 0.0.1 +publish_to: "none" + +environment: + sdk: ">=3.0.5 <4.0.0" + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + + flutter_localization: ^0.1.12 + intl: ^0.18.0 + flutter_riverpod: ^2.3.6 + riverpod_annotation: ^2.1.1 + freezed_annotation: ^2.4.1 + toast: ^0.3.0 + image: ^3.2.0 + oxidized: ^5.2.0 + + # Internal packages + component_library: + path: ../../component_library + l10n: + path: ../../l10n + database: + path: ../../database + command: + path: ../../command + io_library: + path: ../../io_library + tools: + path: ../../tools + colorpicker: + path: ../../colorpicker + +dev_dependencies: + flutter_test: + sdk: flutter + integration_test: + sdk: flutter + + mockito: ^5.2.0 + flutter_launcher_icons: ^0.9.3 + flutter_lints: ^2.0.1 + floor_generator: ^1.2.0 + riverpod_generator: ^2.2.3 + riverpod_lint: ^1.3.2 + build_runner: ^2.2.0 + freezed: ^2.4.1 + +flutter: + uses-material-design: true diff --git a/test/unit/workspace/usecase/render_image_for_export_test.dart b/packages/features/workspace_screen/test/unit/render_image_for_export_test.dart similarity index 93% rename from test/unit/workspace/usecase/render_image_for_export_test.dart rename to packages/features/workspace_screen/test/unit/render_image_for_export_test.dart index bf6c3f74..d7c92bec 100644 --- a/test/unit/workspace/usecase/render_image_for_export_test.dart +++ b/packages/features/workspace_screen/test/unit/render_image_for_export_test.dart @@ -1,17 +1,13 @@ import 'dart:ui'; +import 'package:command/command_providers.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; -import 'package:paintroid/command/command.dart'; -import 'package:paintroid/command/src/command_manager_provider.dart'; -import 'package:paintroid/core/graphic_factory.dart'; -import 'package:paintroid/core/graphic_factory_provider.dart'; -import 'package:paintroid/core/image_with_pixel_info.dart'; -import 'package:paintroid/workspace/src/state/canvas/canvas_state_data.dart'; -import 'package:paintroid/workspace/src/state/canvas/canvas_state_provider.dart'; -import 'package:paintroid/workspace/workspace.dart'; +import 'package:workspace_screen/workspace_screen.dart'; +import 'package:command/command.dart'; +import 'package:component_library/component_library.dart'; import 'render_image_for_export_test.mocks.dart'; diff --git a/packages/features/workspace_screen/test/unit/render_image_for_export_test.mocks.dart b/packages/features/workspace_screen/test/unit/render_image_for_export_test.mocks.dart new file mode 100644 index 00000000..9bfa614d --- /dev/null +++ b/packages/features/workspace_screen/test/unit/render_image_for_export_test.mocks.dart @@ -0,0 +1,684 @@ +// Mocks generated by Mockito 5.4.2 from annotations +// in workspace_screen/test/unit/render_image_for_export_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:typed_data' as _i3; +import 'dart:ui' as _i2; + +import 'package:command/command.dart' as _i4; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeRect_0 extends _i1.SmartFake implements _i2.Rect { + _FakeRect_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [Canvas]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCanvas extends _i1.Mock implements _i2.Canvas { + MockCanvas() { + _i1.throwOnMissingStub(this); + } + + @override + void save() => super.noSuchMethod( + Invocation.method( + #save, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void saveLayer( + _i2.Rect? bounds, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #saveLayer, + [ + bounds, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void restore() => super.noSuchMethod( + Invocation.method( + #restore, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void restoreToCount(int? count) => super.noSuchMethod( + Invocation.method( + #restoreToCount, + [count], + ), + returnValueForMissingStub: null, + ); + + @override + int getSaveCount() => (super.noSuchMethod( + Invocation.method( + #getSaveCount, + [], + ), + returnValue: 0, + ) as int); + + @override + void translate( + double? dx, + double? dy, + ) => + super.noSuchMethod( + Invocation.method( + #translate, + [ + dx, + dy, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void scale( + double? sx, [ + double? sy, + ]) => + super.noSuchMethod( + Invocation.method( + #scale, + [ + sx, + sy, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void rotate(double? radians) => super.noSuchMethod( + Invocation.method( + #rotate, + [radians], + ), + returnValueForMissingStub: null, + ); + + @override + void skew( + double? sx, + double? sy, + ) => + super.noSuchMethod( + Invocation.method( + #skew, + [ + sx, + sy, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void transform(_i3.Float64List? matrix4) => super.noSuchMethod( + Invocation.method( + #transform, + [matrix4], + ), + returnValueForMissingStub: null, + ); + + @override + _i3.Float64List getTransform() => (super.noSuchMethod( + Invocation.method( + #getTransform, + [], + ), + returnValue: _i3.Float64List(0), + ) as _i3.Float64List); + + @override + void clipRect( + _i2.Rect? rect, { + _i2.ClipOp? clipOp = _i2.ClipOp.intersect, + bool? doAntiAlias = true, + }) => + super.noSuchMethod( + Invocation.method( + #clipRect, + [rect], + { + #clipOp: clipOp, + #doAntiAlias: doAntiAlias, + }, + ), + returnValueForMissingStub: null, + ); + + @override + void clipRRect( + _i2.RRect? rrect, { + bool? doAntiAlias = true, + }) => + super.noSuchMethod( + Invocation.method( + #clipRRect, + [rrect], + {#doAntiAlias: doAntiAlias}, + ), + returnValueForMissingStub: null, + ); + + @override + void clipPath( + _i2.Path? path, { + bool? doAntiAlias = true, + }) => + super.noSuchMethod( + Invocation.method( + #clipPath, + [path], + {#doAntiAlias: doAntiAlias}, + ), + returnValueForMissingStub: null, + ); + + @override + _i2.Rect getLocalClipBounds() => (super.noSuchMethod( + Invocation.method( + #getLocalClipBounds, + [], + ), + returnValue: _FakeRect_0( + this, + Invocation.method( + #getLocalClipBounds, + [], + ), + ), + ) as _i2.Rect); + + @override + _i2.Rect getDestinationClipBounds() => (super.noSuchMethod( + Invocation.method( + #getDestinationClipBounds, + [], + ), + returnValue: _FakeRect_0( + this, + Invocation.method( + #getDestinationClipBounds, + [], + ), + ), + ) as _i2.Rect); + + @override + void drawColor( + _i2.Color? color, + _i2.BlendMode? blendMode, + ) => + super.noSuchMethod( + Invocation.method( + #drawColor, + [ + color, + blendMode, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawLine( + _i2.Offset? p1, + _i2.Offset? p2, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawLine, + [ + p1, + p2, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawPaint(_i2.Paint? paint) => super.noSuchMethod( + Invocation.method( + #drawPaint, + [paint], + ), + returnValueForMissingStub: null, + ); + + @override + void drawRect( + _i2.Rect? rect, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawRect, + [ + rect, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawRRect( + _i2.RRect? rrect, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawRRect, + [ + rrect, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawDRRect( + _i2.RRect? outer, + _i2.RRect? inner, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawDRRect, + [ + outer, + inner, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawOval( + _i2.Rect? rect, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawOval, + [ + rect, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawCircle( + _i2.Offset? c, + double? radius, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawCircle, + [ + c, + radius, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawArc( + _i2.Rect? rect, + double? startAngle, + double? sweepAngle, + bool? useCenter, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawArc, + [ + rect, + startAngle, + sweepAngle, + useCenter, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawPath( + _i2.Path? path, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawPath, + [ + path, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawImage( + _i2.Image? image, + _i2.Offset? offset, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawImage, + [ + image, + offset, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawImageRect( + _i2.Image? image, + _i2.Rect? src, + _i2.Rect? dst, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawImageRect, + [ + image, + src, + dst, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawImageNine( + _i2.Image? image, + _i2.Rect? center, + _i2.Rect? dst, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawImageNine, + [ + image, + center, + dst, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawPicture(_i2.Picture? picture) => super.noSuchMethod( + Invocation.method( + #drawPicture, + [picture], + ), + returnValueForMissingStub: null, + ); + + @override + void drawParagraph( + _i2.Paragraph? paragraph, + _i2.Offset? offset, + ) => + super.noSuchMethod( + Invocation.method( + #drawParagraph, + [ + paragraph, + offset, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawPoints( + _i2.PointMode? pointMode, + List<_i2.Offset>? points, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawPoints, + [ + pointMode, + points, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawRawPoints( + _i2.PointMode? pointMode, + _i3.Float32List? points, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawRawPoints, + [ + pointMode, + points, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawVertices( + _i2.Vertices? vertices, + _i2.BlendMode? blendMode, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawVertices, + [ + vertices, + blendMode, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawAtlas( + _i2.Image? atlas, + List<_i2.RSTransform>? transforms, + List<_i2.Rect>? rects, + List<_i2.Color>? colors, + _i2.BlendMode? blendMode, + _i2.Rect? cullRect, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawAtlas, + [ + atlas, + transforms, + rects, + colors, + blendMode, + cullRect, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawRawAtlas( + _i2.Image? atlas, + _i3.Float32List? rstTransforms, + _i3.Float32List? rects, + _i3.Int32List? colors, + _i2.BlendMode? blendMode, + _i2.Rect? cullRect, + _i2.Paint? paint, + ) => + super.noSuchMethod( + Invocation.method( + #drawRawAtlas, + [ + atlas, + rstTransforms, + rects, + colors, + blendMode, + cullRect, + paint, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void drawShadow( + _i2.Path? path, + _i2.Color? color, + double? elevation, + bool? transparentOccluder, + ) => + super.noSuchMethod( + Invocation.method( + #drawShadow, + [ + path, + color, + elevation, + transparentOccluder, + ], + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [CommandManager]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCommandManager extends _i1.Mock implements _i4.CommandManager { + MockCommandManager() { + _i1.throwOnMissingStub(this); + } + + @override + Iterable<_i4.Command> get history => (super.noSuchMethod( + Invocation.getter(#history), + returnValue: <_i4.Command>[], + ) as Iterable<_i4.Command>); + + @override + int get count => (super.noSuchMethod( + Invocation.getter(#count), + returnValue: 0, + ) as int); + + @override + void addGraphicCommand(_i4.GraphicCommand? command) => super.noSuchMethod( + Invocation.method( + #addGraphicCommand, + [command], + ), + returnValueForMissingStub: null, + ); + + @override + void executeLastCommand(_i2.Canvas? canvas) => super.noSuchMethod( + Invocation.method( + #executeLastCommand, + [canvas], + ), + returnValueForMissingStub: null, + ); + + @override + void executeAllCommands(_i2.Canvas? canvas) => super.noSuchMethod( + Invocation.method( + #executeAllCommands, + [canvas], + ), + returnValueForMissingStub: null, + ); + + @override + void discardLastCommand() => super.noSuchMethod( + Invocation.method( + #discardLastCommand, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void clearHistory({Iterable<_i4.Command>? newCommands}) => super.noSuchMethod( + Invocation.method( + #clearHistory, + [], + {#newCommands: newCommands}, + ), + returnValueForMissingStub: null, + ); +} diff --git a/test/widget/ui/bottom_control_navigation_bar_test.dart b/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart similarity index 70% rename from test/widget/ui/bottom_control_navigation_bar_test.dart rename to packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart index 8b80c7dc..14f1d25c 100644 --- a/test/widget/ui/bottom_control_navigation_bar_test.dart +++ b/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart @@ -2,10 +2,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:paintroid/tool/tool.dart'; -import 'package:paintroid/ui/pocket_paint.dart'; +import 'package:l10n/l10n.dart'; +import 'package:tools/tools.dart'; +import 'package:workspace_screen/workspace_screen.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; -import '../utils/utils.dart'; +import 'bottom_nav_bar_interactions.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); @@ -19,7 +21,11 @@ void main() { await tester.pumpWidget( const ProviderScope( child: MaterialApp( - home: PocketPaint(), + home: WorkspaceScreen(), + localizationsDelegates: [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + ], ), ), ); diff --git a/test/widget/utils/interactions/bottom_nav_bar_interactions.dart b/packages/features/workspace_screen/test/widget/bottom_nav_bar_interactions.dart similarity index 91% rename from test/widget/utils/interactions/bottom_nav_bar_interactions.dart rename to packages/features/workspace_screen/test/widget/bottom_nav_bar_interactions.dart index f7f888ce..d1306061 100644 --- a/test/widget/utils/interactions/bottom_nav_bar_interactions.dart +++ b/packages/features/workspace_screen/test/widget/bottom_nav_bar_interactions.dart @@ -1,8 +1,7 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:paintroid/tool/tool.dart'; -import 'package:paintroid/ui/shared/bottom_nav_bar_icon.dart'; -import 'package:paintroid/ui/shared/icon_button_with_label.dart'; +import 'package:tools/tools.dart'; class BottomNavBarInteractions { final WidgetTester _tester; diff --git a/test/widget/utils/interactions/canvas_interactions.dart b/packages/features/workspace_screen/test/widget/canvas_interactions.dart similarity index 96% rename from test/widget/utils/interactions/canvas_interactions.dart rename to packages/features/workspace_screen/test/widget/canvas_interactions.dart index a1fceb54..bccc2904 100644 --- a/test/widget/utils/interactions/canvas_interactions.dart +++ b/packages/features/workspace_screen/test/widget/canvas_interactions.dart @@ -5,7 +5,7 @@ import 'dart:ui' as ui; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:image/image.dart' as img; -import 'package:paintroid/workspace/workspace.dart'; +import 'package:workspace_screen/workspace_screen.dart'; class CanvasInteractions { final WidgetTester _tester; diff --git a/test/widget/tool/eraser_tool_test.dart b/packages/features/workspace_screen/test/widget/eraser_tool_test.dart similarity index 75% rename from test/widget/tool/eraser_tool_test.dart rename to packages/features/workspace_screen/test/widget/eraser_tool_test.dart index 6f41b41e..79610ee7 100644 --- a/test/widget/tool/eraser_tool_test.dart +++ b/packages/features/workspace_screen/test/widget/eraser_tool_test.dart @@ -2,11 +2,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:paintroid/service/device_service.dart'; -import 'package:paintroid/tool/tool.dart'; -import 'package:paintroid/ui/pocket_paint.dart'; +import 'package:l10n/l10n.dart'; +import 'package:tools/tools.dart'; +import 'package:workspace_screen/workspace_screen.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; -import '../utils/utils.dart'; +import 'bottom_nav_bar_interactions.dart'; +import 'canvas_interactions.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); @@ -21,7 +23,11 @@ void main() { .overrideWith((ref) => Future.value(const Size(600, 600))) ], child: const MaterialApp( - home: PocketPaint(), + home: WorkspaceScreen(), + localizationsDelegates: [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + ], ), ), ); diff --git a/test/widget/tool/hand_tool_test.dart b/packages/features/workspace_screen/test/widget/hand_tool_test.dart similarity index 83% rename from test/widget/tool/hand_tool_test.dart rename to packages/features/workspace_screen/test/widget/hand_tool_test.dart index 0f8edb82..8230eccd 100644 --- a/test/widget/tool/hand_tool_test.dart +++ b/packages/features/workspace_screen/test/widget/hand_tool_test.dart @@ -1,13 +1,14 @@ import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:paintroid/service/device_service.dart'; -import 'package:paintroid/tool/tool.dart'; -import 'package:paintroid/ui/pocket_paint.dart'; +import 'package:l10n/l10n.dart'; +import 'package:tools/tools.dart'; +import 'package:workspace_screen/workspace_screen.dart'; -import '../utils/utils.dart'; -import '../utils/interactions/interactive_viewer_interactions.dart'; +import 'bottom_nav_bar_interactions.dart'; +import 'interactive_viewer_interactions.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); @@ -21,7 +22,11 @@ void main() { .overrideWith((ref) => Future.value(const Size(600, 600))) ], child: const MaterialApp( - home: PocketPaint(), + home: WorkspaceScreen(), + localizationsDelegates: [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + ], ), ); }); diff --git a/test/widget/utils/interactions/interactive_viewer_interactions.dart b/packages/features/workspace_screen/test/widget/interactive_viewer_interactions.dart similarity index 100% rename from test/widget/utils/interactions/interactive_viewer_interactions.dart rename to packages/features/workspace_screen/test/widget/interactive_viewer_interactions.dart diff --git a/test/widget/ui/pocket_paint_test.dart b/packages/features/workspace_screen/test/widget/workspace_screen_test.dart similarity index 83% rename from test/widget/ui/pocket_paint_test.dart rename to packages/features/workspace_screen/test/widget/workspace_screen_test.dart index fb603ad0..bd05bca4 100644 --- a/test/widget/ui/pocket_paint_test.dart +++ b/packages/features/workspace_screen/test/widget/workspace_screen_test.dart @@ -1,11 +1,10 @@ +import 'package:command/command.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:paintroid/command/command.dart' show CommandManager; -import 'package:paintroid/ui/pocket_paint.dart'; -import 'package:paintroid/ui/shared/overflow_menu.dart'; -import 'package:paintroid/ui/shared/top_app_bar.dart'; -import 'package:paintroid/workspace/workspace.dart'; +import 'package:l10n/l10n.dart'; +import 'package:workspace_screen/workspace_screen.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; class FakeCommandManager extends Fake implements CommandManager {} @@ -15,7 +14,11 @@ void main() { setUp(() { sut = const ProviderScope( child: MaterialApp( - home: PocketPaint(), + home: WorkspaceScreen(), + localizationsDelegates: [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + ], ), ); }); @@ -57,7 +60,11 @@ void main() { WorkspaceStateNotifier(testWorkspaceState, fakeCommandManager)) ], child: const MaterialApp( - home: PocketPaint(), + home: WorkspaceScreen(), + localizationsDelegates: [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + ], ), ); }); diff --git a/packages/io_library/.metadata b/packages/io_library/.metadata new file mode 100644 index 00000000..9596faee --- /dev/null +++ b/packages/io_library/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 796c8ef79279f9c774545b3771238c3098dbefab + channel: stable + +project_type: package diff --git a/packages/io_library/analysis_options.yaml b/packages/io_library/analysis_options.yaml new file mode 100644 index 00000000..1ee68bd9 --- /dev/null +++ b/packages/io_library/analysis_options.yaml @@ -0,0 +1,23 @@ +include: package:flutter_lints/flutter.yaml +linter: + rules: + always_use_package_imports: true + avoid_relative_lib_imports: true + prefer_relative_imports: false + prefer_single_quotes: true + avoid_void_async: true + constant_identifier_names: false + +analyzer: + errors: + missing_enum_constant_in_switch: error + exhaustive_cases: error + unused_element: error + type_annotate_public_apis: error + missing_required_param: error + invalid_use_of_protected_member: error + unused_import: error + + exclude: + - lib/src/**.pb*.dart + - lib/src/data/*.g.dart diff --git a/packages/io_library/lib/io_library.dart b/packages/io_library/lib/io_library.dart new file mode 100644 index 00000000..acd0a174 --- /dev/null +++ b/packages/io_library/lib/io_library.dart @@ -0,0 +1,43 @@ +library io_library; + +export 'src/enums/image_format.dart'; +export 'src/enums/image_location.dart'; + +export 'src/failure/load_image_failure.dart'; +export 'src/failure/save_image_failure.dart'; + +export 'src/models/catrobat_image.dart'; +export 'src/models/failure.dart'; +export 'src/models/image_from_file.dart'; +export 'src/models/image_meta_data.dart'; +export 'src/models/loggable_mixin.dart'; + +export 'src/serialization/proto/protos.dart'; +export 'src/serialization/serializer/command/graphic/draw_path_command_serializer.dart'; +export 'src/serialization/serializer/graphic/paint_serializer.dart'; +export 'src/serialization/serializer/graphic/path_serializer.dart'; +export 'src/serialization/serializer/catrobat_image_serializer.dart'; +export 'src/serialization/proto_serializer_with_versioning.dart'; +export 'src/serialization/version_serializer.dart'; + +export 'src/service/file_service.dart'; +export 'src/service/image_service.dart'; +export 'src/service/permission_service.dart'; +export 'src/service/photo_library_service.dart'; + +export 'src/ui/about_dialog.dart'; +export 'src/ui/delete_project_dialog.dart'; +export 'src/ui/discard_changes_dialog.dart'; +export 'src/ui/generic_dialog.dart'; +export 'src/ui/image_format_info.dart'; +export 'src/ui/load_image_dialog.dart'; +export 'src/ui/overwrite_dialog.dart'; +export 'src/ui/project_details_dialog.dart'; +export 'src/ui/save_image_dialog.dart'; + +export 'src/usecase/load_image_from_file_manager.dart'; +export 'src/usecase/load_image_from_photo_library.dart'; +export 'src/usecase/save_as_catrobat_image.dart'; +export 'src/usecase/save_as_raster_image.dart'; + +export 'src/io_handler.dart'; diff --git a/lib/io/serialization.dart b/packages/io_library/lib/serialization.dart similarity index 100% rename from lib/io/serialization.dart rename to packages/io_library/lib/serialization.dart diff --git a/lib/io/src/entity/image_format.dart b/packages/io_library/lib/src/enums/image_format.dart similarity index 81% rename from lib/io/src/entity/image_format.dart rename to packages/io_library/lib/src/enums/image_format.dart index 204d6d4b..b0f81771 100644 --- a/lib/io/src/entity/image_format.dart +++ b/packages/io_library/lib/src/enums/image_format.dart @@ -1,5 +1,3 @@ -part of 'image_meta_data.dart'; - enum ImageFormat { png('png'), jpg('jpg'), diff --git a/lib/io/src/entity/image_location.dart b/packages/io_library/lib/src/enums/image_location.dart similarity index 100% rename from lib/io/src/entity/image_location.dart rename to packages/io_library/lib/src/enums/image_location.dart diff --git a/lib/io/src/failure/load_image_failure.dart b/packages/io_library/lib/src/failure/load_image_failure.dart similarity index 90% rename from lib/io/src/failure/load_image_failure.dart rename to packages/io_library/lib/src/failure/load_image_failure.dart index 8d3b9b1c..191a66a0 100644 --- a/lib/io/src/failure/load_image_failure.dart +++ b/packages/io_library/lib/src/failure/load_image_failure.dart @@ -1,4 +1,4 @@ -import 'package:paintroid/core/failure.dart'; +import 'package:io_library/io_library.dart'; class LoadImageFailure extends Failure { const LoadImageFailure._(super.message); diff --git a/lib/io/src/failure/save_image_failure.dart b/packages/io_library/lib/src/failure/save_image_failure.dart similarity index 90% rename from lib/io/src/failure/save_image_failure.dart rename to packages/io_library/lib/src/failure/save_image_failure.dart index e00594bb..a0b4aff4 100644 --- a/lib/io/src/failure/save_image_failure.dart +++ b/packages/io_library/lib/src/failure/save_image_failure.dart @@ -1,4 +1,4 @@ -import 'package:paintroid/core/failure.dart'; +import 'package:io_library/io_library.dart'; class SaveImageFailure extends Failure { const SaveImageFailure._(super.message); diff --git a/lib/ui/io_handler.dart b/packages/io_library/lib/src/io_handler.dart similarity index 95% rename from lib/ui/io_handler.dart rename to packages/io_library/lib/src/io_handler.dart index 4b7ef0e8..0713e174 100644 --- a/lib/ui/io_handler.dart +++ b/packages/io_library/lib/src/io_handler.dart @@ -1,14 +1,12 @@ import 'dart:io'; -import 'package:flutter/widgets.dart'; +import 'package:command/command_providers.dart'; +import 'package:component_library/component_library.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; -import 'package:paintroid/command/src/command_manager_provider.dart'; -import 'package:paintroid/core/failure.dart'; -import 'package:paintroid/core/toast_utils.dart'; -import 'package:paintroid/io/io.dart'; -import 'package:paintroid/workspace/src/state/canvas/canvas_state_provider.dart'; -import 'package:paintroid/workspace/workspace.dart'; +import 'package:workspace_screen/workspace_screen.dart'; class IOHandler { final Ref ref; diff --git a/lib/io/src/entity/catrobat_image.dart b/packages/io_library/lib/src/models/catrobat_image.dart similarity index 86% rename from lib/io/src/entity/catrobat_image.dart rename to packages/io_library/lib/src/models/catrobat_image.dart index 67e6a703..99b28a3a 100644 --- a/lib/io/src/entity/catrobat_image.dart +++ b/packages/io_library/lib/src/models/catrobat_image.dart @@ -1,6 +1,6 @@ import 'dart:ui'; -import 'package:paintroid/command/command.dart' show Command; +import 'package:command/command.dart'; class CatrobatImage { static const magicValue = 'CATROBAT'; diff --git a/lib/core/failure.dart b/packages/io_library/lib/src/models/failure.dart similarity index 100% rename from lib/core/failure.dart rename to packages/io_library/lib/src/models/failure.dart diff --git a/lib/io/src/entity/image_from_file.dart b/packages/io_library/lib/src/models/image_from_file.dart similarity index 89% rename from lib/io/src/entity/image_from_file.dart rename to packages/io_library/lib/src/models/image_from_file.dart index 86a63de1..7183b72c 100644 --- a/lib/io/src/entity/image_from_file.dart +++ b/packages/io_library/lib/src/models/image_from_file.dart @@ -1,6 +1,6 @@ import 'dart:ui'; -import 'package:paintroid/io/io.dart'; +import 'package:io_library/io_library.dart'; class ImageFromFile { final Image? rasterImage; diff --git a/lib/io/src/entity/image_meta_data.dart b/packages/io_library/lib/src/models/image_meta_data.dart similarity index 94% rename from lib/io/src/entity/image_meta_data.dart rename to packages/io_library/lib/src/models/image_meta_data.dart index 4e25638a..ee9385c3 100644 --- a/lib/io/src/entity/image_meta_data.dart +++ b/packages/io_library/lib/src/models/image_meta_data.dart @@ -1,4 +1,4 @@ -part 'image_format.dart'; +import 'package:io_library/io_library.dart'; abstract class ImageMetaData { final String name; diff --git a/lib/core/loggable_mixin.dart b/packages/io_library/lib/src/models/loggable_mixin.dart similarity index 100% rename from lib/core/loggable_mixin.dart rename to packages/io_library/lib/src/models/loggable_mixin.dart diff --git a/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pb.dart b/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pb.dart new file mode 100644 index 00000000..d6f0e1d3 --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pb.dart @@ -0,0 +1,161 @@ +// +// Generated code. Do not modify. +// source: catrobat_image.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'google/protobuf/any.pb.dart' as $2; + +class SerializableCatrobatImage extends $pb.GeneratedMessage { + factory SerializableCatrobatImage({ + $core.String? magicValue, + $core.int? version, + $core.int? width, + $core.int? height, + $core.Iterable<$2.Any>? commands, + $core.List<$core.int>? backgroundImage, + }) { + final $result = create(); + if (magicValue != null) { + $result.magicValue = magicValue; + } + if (version != null) { + $result.version = version; + } + if (width != null) { + $result.width = width; + } + if (height != null) { + $result.height = height; + } + if (commands != null) { + $result.commands.addAll(commands); + } + if (backgroundImage != null) { + $result.backgroundImage = backgroundImage; + } + return $result; + } + SerializableCatrobatImage._() : super(); + factory SerializableCatrobatImage.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory SerializableCatrobatImage.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'SerializableCatrobatImage', + createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'magicValue', protoName: 'magicValue') + ..a<$core.int>(2, _omitFieldNames ? '' : 'version', $pb.PbFieldType.O3) + ..a<$core.int>(3, _omitFieldNames ? '' : 'width', $pb.PbFieldType.OU3) + ..a<$core.int>(4, _omitFieldNames ? '' : 'height', $pb.PbFieldType.OU3) + ..pc<$2.Any>(5, _omitFieldNames ? '' : 'commands', $pb.PbFieldType.PM, + subBuilder: $2.Any.create) + ..a<$core.List<$core.int>>( + 6, _omitFieldNames ? '' : 'backgroundImage', $pb.PbFieldType.OY, + protoName: 'backgroundImage') + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SerializableCatrobatImage clone() => + SerializableCatrobatImage()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SerializableCatrobatImage copyWith( + void Function(SerializableCatrobatImage) updates) => + super.copyWith((message) => updates(message as SerializableCatrobatImage)) + as SerializableCatrobatImage; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SerializableCatrobatImage create() => SerializableCatrobatImage._(); + SerializableCatrobatImage createEmptyInstance() => create(); + static $pb.PbList createRepeated() => + $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SerializableCatrobatImage getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SerializableCatrobatImage? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get magicValue => $_getSZ(0); + @$pb.TagNumber(1) + set magicValue($core.String v) { + $_setString(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasMagicValue() => $_has(0); + @$pb.TagNumber(1) + void clearMagicValue() => clearField(1); + + @$pb.TagNumber(2) + $core.int get version => $_getIZ(1); + @$pb.TagNumber(2) + set version($core.int v) { + $_setSignedInt32(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasVersion() => $_has(1); + @$pb.TagNumber(2) + void clearVersion() => clearField(2); + + @$pb.TagNumber(3) + $core.int get width => $_getIZ(2); + @$pb.TagNumber(3) + set width($core.int v) { + $_setUnsignedInt32(2, v); + } + + @$pb.TagNumber(3) + $core.bool hasWidth() => $_has(2); + @$pb.TagNumber(3) + void clearWidth() => clearField(3); + + @$pb.TagNumber(4) + $core.int get height => $_getIZ(3); + @$pb.TagNumber(4) + set height($core.int v) { + $_setUnsignedInt32(3, v); + } + + @$pb.TagNumber(4) + $core.bool hasHeight() => $_has(3); + @$pb.TagNumber(4) + void clearHeight() => clearField(4); + + @$pb.TagNumber(5) + $core.List<$2.Any> get commands => $_getList(4); + + @$pb.TagNumber(6) + $core.List<$core.int> get backgroundImage => $_getN(5); + @$pb.TagNumber(6) + set backgroundImage($core.List<$core.int> v) { + $_setBytes(5, v); + } + + @$pb.TagNumber(6) + $core.bool hasBackgroundImage() => $_has(5); + @$pb.TagNumber(6) + void clearBackgroundImage() => clearField(6); +} + +const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); +const _omitMessageNames = + $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbenum.dart b/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbenum.dart new file mode 100644 index 00000000..9cf6956b --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbenum.dart @@ -0,0 +1,10 @@ +// +// Generated code. Do not modify. +// source: catrobat_image.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import diff --git a/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbjson.dart b/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbjson.dart new file mode 100644 index 00000000..13afd26d --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbjson.dart @@ -0,0 +1,42 @@ +// +// Generated code. Do not modify. +// source: catrobat_image.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:convert' as $convert; +import 'dart:core' as $core; +import 'dart:typed_data' as $typed_data; + +@$core.Deprecated('Use serializableCatrobatImageDescriptor instead') +const SerializableCatrobatImage$json = { + '1': 'SerializableCatrobatImage', + '2': [ + {'1': 'magicValue', '3': 1, '4': 1, '5': 9, '10': 'magicValue'}, + {'1': 'version', '3': 2, '4': 1, '5': 5, '10': 'version'}, + {'1': 'width', '3': 3, '4': 1, '5': 13, '10': 'width'}, + {'1': 'height', '3': 4, '4': 1, '5': 13, '10': 'height'}, + { + '1': 'commands', + '3': 5, + '4': 3, + '5': 11, + '6': '.google.protobuf.Any', + '10': 'commands' + }, + {'1': 'backgroundImage', '3': 6, '4': 1, '5': 12, '10': 'backgroundImage'}, + ], +}; + +/// Descriptor for `SerializableCatrobatImage`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List serializableCatrobatImageDescriptor = $convert.base64Decode( + 'ChlTZXJpYWxpemFibGVDYXRyb2JhdEltYWdlEh4KCm1hZ2ljVmFsdWUYASABKAlSCm1hZ2ljVm' + 'FsdWUSGAoHdmVyc2lvbhgCIAEoBVIHdmVyc2lvbhIUCgV3aWR0aBgDIAEoDVIFd2lkdGgSFgoG' + 'aGVpZ2h0GAQgASgNUgZoZWlnaHQSMAoIY29tbWFuZHMYBSADKAsyFC5nb29nbGUucHJvdG9idW' + 'YuQW55Ughjb21tYW5kcxIoCg9iYWNrZ3JvdW5kSW1hZ2UYBiABKAxSD2JhY2tncm91bmRJbWFn' + 'ZQ=='); diff --git a/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbserver.dart b/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbserver.dart new file mode 100644 index 00000000..3971a739 --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbserver.dart @@ -0,0 +1,13 @@ +// +// Generated code. Do not modify. +// source: catrobat_image.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names +// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +export 'catrobat_image.pb.dart'; diff --git a/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pb.dart b/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pb.dart new file mode 100644 index 00000000..6311b5fc --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pb.dart @@ -0,0 +1,108 @@ +// +// Generated code. Do not modify. +// source: command/graphic/draw_path_command.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import '../../graphic/paint.pb.dart' as $0; +import '../../graphic/path.pb.dart' as $1; + +class SerializableDrawPathCommand extends $pb.GeneratedMessage { + factory SerializableDrawPathCommand({ + $0.SerializablePaint? paint, + $1.SerializablePath? path, + }) { + final $result = create(); + if (paint != null) { + $result.paint = paint; + } + if (path != null) { + $result.path = path; + } + return $result; + } + SerializableDrawPathCommand._() : super(); + factory SerializableDrawPathCommand.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory SerializableDrawPathCommand.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'SerializableDrawPathCommand', + createEmptyInstance: create) + ..aOM<$0.SerializablePaint>(1, _omitFieldNames ? '' : 'paint', + subBuilder: $0.SerializablePaint.create) + ..aOM<$1.SerializablePath>(2, _omitFieldNames ? '' : 'path', + subBuilder: $1.SerializablePath.create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SerializableDrawPathCommand clone() => + SerializableDrawPathCommand()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SerializableDrawPathCommand copyWith( + void Function(SerializableDrawPathCommand) updates) => + super.copyWith( + (message) => updates(message as SerializableDrawPathCommand)) + as SerializableDrawPathCommand; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SerializableDrawPathCommand create() => + SerializableDrawPathCommand._(); + SerializableDrawPathCommand createEmptyInstance() => create(); + static $pb.PbList createRepeated() => + $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SerializableDrawPathCommand getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SerializableDrawPathCommand? _defaultInstance; + + @$pb.TagNumber(1) + $0.SerializablePaint get paint => $_getN(0); + @$pb.TagNumber(1) + set paint($0.SerializablePaint v) { + setField(1, v); + } + + @$pb.TagNumber(1) + $core.bool hasPaint() => $_has(0); + @$pb.TagNumber(1) + void clearPaint() => clearField(1); + @$pb.TagNumber(1) + $0.SerializablePaint ensurePaint() => $_ensure(0); + + @$pb.TagNumber(2) + $1.SerializablePath get path => $_getN(1); + @$pb.TagNumber(2) + set path($1.SerializablePath v) { + setField(2, v); + } + + @$pb.TagNumber(2) + $core.bool hasPath() => $_has(1); + @$pb.TagNumber(2) + void clearPath() => clearField(2); + @$pb.TagNumber(2) + $1.SerializablePath ensurePath() => $_ensure(1); +} + +const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); +const _omitMessageNames = + $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbenum.dart b/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbenum.dart new file mode 100644 index 00000000..dbe32309 --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbenum.dart @@ -0,0 +1,10 @@ +// +// Generated code. Do not modify. +// source: command/graphic/draw_path_command.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import diff --git a/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbjson.dart b/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbjson.dart new file mode 100644 index 00000000..3ff6d2c5 --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbjson.dart @@ -0,0 +1,43 @@ +// +// Generated code. Do not modify. +// source: command/graphic/draw_path_command.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:convert' as $convert; +import 'dart:core' as $core; +import 'dart:typed_data' as $typed_data; + +@$core.Deprecated('Use serializableDrawPathCommandDescriptor instead') +const SerializableDrawPathCommand$json = { + '1': 'SerializableDrawPathCommand', + '2': [ + { + '1': 'paint', + '3': 1, + '4': 1, + '5': 11, + '6': '.SerializablePaint', + '10': 'paint' + }, + { + '1': 'path', + '3': 2, + '4': 1, + '5': 11, + '6': '.SerializablePath', + '10': 'path' + }, + ], +}; + +/// Descriptor for `SerializableDrawPathCommand`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List serializableDrawPathCommandDescriptor = + $convert.base64Decode( + 'ChtTZXJpYWxpemFibGVEcmF3UGF0aENvbW1hbmQSKAoFcGFpbnQYASABKAsyEi5TZXJpYWxpem' + 'FibGVQYWludFIFcGFpbnQSJQoEcGF0aBgCIAEoCzIRLlNlcmlhbGl6YWJsZVBhdGhSBHBhdGg='); diff --git a/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbserver.dart b/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbserver.dart new file mode 100644 index 00000000..5dc7a54f --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbserver.dart @@ -0,0 +1,13 @@ +// +// Generated code. Do not modify. +// source: command/graphic/draw_path_command.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names +// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +export 'draw_path_command.pb.dart'; diff --git a/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pb.dart b/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pb.dart new file mode 100644 index 00000000..9f9d4c72 --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pb.dart @@ -0,0 +1,224 @@ +// +// Generated code. Do not modify. +// source: google/protobuf/any.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; +import 'package:protobuf/src/protobuf/mixins/well_known.dart' as $mixin; + +/// `Any` contains an arbitrary serialized protocol buffer message along with a +/// URL that describes the type of the serialized message. +/// +/// Protobuf library provides support to pack/unpack Any values in the form +/// of utility functions or additional generated methods of the Any type. +/// +/// Example 1: Pack and unpack a message in C++. +/// +/// Foo foo = ...; +/// Any any; +/// any.PackFrom(foo); +/// ... +/// if (any.UnpackTo(&foo)) { +/// ... +/// } +/// +/// Example 2: Pack and unpack a message in Java. +/// +/// Foo foo = ...; +/// Any any = Any.pack(foo); +/// ... +/// if (any.is(Foo.class)) { +/// foo = any.unpack(Foo.class); +/// } +/// // or ... +/// if (any.isSameTypeAs(Foo.getDefaultInstance())) { +/// foo = any.unpack(Foo.getDefaultInstance()); +/// } +/// +/// Example 3: Pack and unpack a message in Python. +/// +/// foo = Foo(...) +/// any = Any() +/// any.Pack(foo) +/// ... +/// if any.Is(Foo.DESCRIPTOR): +/// any.Unpack(foo) +/// ... +/// +/// Example 4: Pack and unpack a message in Go +/// +/// foo := &pb.Foo{...} +/// any, err := anypb.New(foo) +/// if err != nil { +/// ... +/// } +/// ... +/// foo := &pb.Foo{} +/// if err := any.UnmarshalTo(foo); err != nil { +/// ... +/// } +/// +/// The pack methods provided by protobuf library will by default use +/// 'type.googleapis.com/full.type.name' as the type URL and the unpack +/// methods only use the fully qualified type name after the last '/' +/// in the type URL, for example "foo.bar.com/x/y.z" will yield type +/// name "y.z". +/// +/// JSON +/// ==== +/// The JSON representation of an `Any` value uses the regular +/// representation of the deserialized, embedded message, with an +/// additional field `@type` which contains the type URL. Example: +/// +/// package google.profile; +/// message Person { +/// string first_name = 1; +/// string last_name = 2; +/// } +/// +/// { +/// "@type": "type.googleapis.com/google.profile.Person", +/// "firstName": , +/// "lastName": +/// } +/// +/// If the embedded message type is well-known and has a custom JSON +/// representation, that representation will be embedded adding a field +/// `value` which holds the custom JSON in addition to the `@type` +/// field. Example (for message [google.protobuf.Duration][]): +/// +/// { +/// "@type": "type.googleapis.com/google.protobuf.Duration", +/// "value": "1.212s" +/// } +class Any extends $pb.GeneratedMessage with $mixin.AnyMixin { + factory Any({ + $core.String? typeUrl, + $core.List<$core.int>? value, + }) { + final $result = create(); + if (typeUrl != null) { + $result.typeUrl = typeUrl; + } + if (value != null) { + $result.value = value; + } + return $result; + } + Any._() : super(); + factory Any.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory Any.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'Any', + package: + const $pb.PackageName(_omitMessageNames ? '' : 'google.protobuf'), + createEmptyInstance: create, + toProto3Json: $mixin.AnyMixin.toProto3JsonHelper, + fromProto3Json: $mixin.AnyMixin.fromProto3JsonHelper) + ..aOS(1, _omitFieldNames ? '' : 'typeUrl') + ..a<$core.List<$core.int>>( + 2, _omitFieldNames ? '' : 'value', $pb.PbFieldType.OY) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Any clone() => Any()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Any copyWith(void Function(Any) updates) => + super.copyWith((message) => updates(message as Any)) as Any; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static Any create() => Any._(); + Any createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Any getDefault() => + _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Any? _defaultInstance; + + /// A URL/resource name that uniquely identifies the type of the serialized + /// protocol buffer message. This string must contain at least + /// one "/" character. The last segment of the URL's path must represent + /// the fully qualified name of the type (as in + /// `path/google.protobuf.Duration`). The name should be in a canonical form + /// (e.g., leading "." is not accepted). + /// + /// In practice, teams usually precompile into the binary all types that they + /// expect it to use in the context of Any. However, for URLs which use the + /// scheme `http`, `https`, or no scheme, one can optionally set up a type + /// server that maps type URLs to message definitions as follows: + /// + /// * If no scheme is provided, `https` is assumed. + /// * An HTTP GET on the URL must yield a [google.protobuf.Type][] + /// value in binary format, or produce an error. + /// * Applications are allowed to cache lookup results based on the + /// URL, or have them precompiled into a binary to avoid any + /// lookup. Therefore, binary compatibility needs to be preserved + /// on changes to types. (Use versioned type names to manage + /// breaking changes.) + /// + /// Note: this functionality is not currently available in the official + /// protobuf release, and it is not used for type URLs beginning with + /// type.googleapis.com. As of May 2023, there are no widely used type server + /// implementations and no plans to implement one. + /// + /// Schemes other than `http`, `https` (or the empty scheme) might be + /// used with implementation specific semantics. + @$pb.TagNumber(1) + $core.String get typeUrl => $_getSZ(0); + @$pb.TagNumber(1) + set typeUrl($core.String v) { + $_setString(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasTypeUrl() => $_has(0); + @$pb.TagNumber(1) + void clearTypeUrl() => clearField(1); + + /// Must be a valid serialized protocol buffer of the above specified type. + @$pb.TagNumber(2) + $core.List<$core.int> get value => $_getN(1); + @$pb.TagNumber(2) + set value($core.List<$core.int> v) { + $_setBytes(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasValue() => $_has(1); + @$pb.TagNumber(2) + void clearValue() => clearField(2); + + /// Creates a new [Any] encoding [message]. + /// + /// The [typeUrl] will be [typeUrlPrefix]/`fullName` where `fullName` is + /// the fully qualified name of the type of [message]. + static Any pack($pb.GeneratedMessage message, + {$core.String typeUrlPrefix = 'type.googleapis.com'}) { + final result = create(); + $mixin.AnyMixin.packIntoAny(result, message, typeUrlPrefix: typeUrlPrefix); + return result; + } +} + +const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); +const _omitMessageNames = + $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbenum.dart b/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbenum.dart new file mode 100644 index 00000000..3744f124 --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbenum.dart @@ -0,0 +1,10 @@ +// +// Generated code. Do not modify. +// source: google/protobuf/any.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import diff --git a/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbjson.dart b/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbjson.dart new file mode 100644 index 00000000..eafbc6bd --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbjson.dart @@ -0,0 +1,27 @@ +// +// Generated code. Do not modify. +// source: google/protobuf/any.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:convert' as $convert; +import 'dart:core' as $core; +import 'dart:typed_data' as $typed_data; + +@$core.Deprecated('Use anyDescriptor instead') +const Any$json = { + '1': 'Any', + '2': [ + {'1': 'type_url', '3': 1, '4': 1, '5': 9, '10': 'typeUrl'}, + {'1': 'value', '3': 2, '4': 1, '5': 12, '10': 'value'}, + ], +}; + +/// Descriptor for `Any`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List anyDescriptor = $convert.base64Decode( + 'CgNBbnkSGQoIdHlwZV91cmwYASABKAlSB3R5cGVVcmwSFAoFdmFsdWUYAiABKAxSBXZhbHVl'); diff --git a/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbserver.dart b/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbserver.dart new file mode 100644 index 00000000..227b7b2c --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbserver.dart @@ -0,0 +1,13 @@ +// +// Generated code. Do not modify. +// source: google/protobuf/any.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names +// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +export 'any.pb.dart'; diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pb.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pb.dart new file mode 100644 index 00000000..7598857a --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pb.dart @@ -0,0 +1,187 @@ +// +// Generated code. Do not modify. +// source: graphic/paint.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'paint.pbenum.dart'; + +export 'paint.pbenum.dart'; + +class SerializablePaint extends $pb.GeneratedMessage { + factory SerializablePaint({ + $core.int? color, + $core.double? strokeWidth, + SerializablePaint_StrokeCap? cap, + SerializablePaint_PaintingStyle? style, + SerializablePaint_BlendMode? blendMode, + SerializablePaint_StrokeJoin? strokeJoin, + }) { + final $result = create(); + if (color != null) { + $result.color = color; + } + if (strokeWidth != null) { + $result.strokeWidth = strokeWidth; + } + if (cap != null) { + $result.cap = cap; + } + if (style != null) { + $result.style = style; + } + if (blendMode != null) { + $result.blendMode = blendMode; + } + if (strokeJoin != null) { + $result.strokeJoin = strokeJoin; + } + return $result; + } + SerializablePaint._() : super(); + factory SerializablePaint.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory SerializablePaint.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'SerializablePaint', + createEmptyInstance: create) + ..a<$core.int>(1, _omitFieldNames ? '' : 'color', $pb.PbFieldType.OU3) + ..a<$core.double>( + 2, _omitFieldNames ? '' : 'strokeWidth', $pb.PbFieldType.OF, + protoName: 'strokeWidth') + ..e( + 3, _omitFieldNames ? '' : 'cap', $pb.PbFieldType.OE, + defaultOrMaker: SerializablePaint_StrokeCap.STROKE_CAP_ROUND, + valueOf: SerializablePaint_StrokeCap.valueOf, + enumValues: SerializablePaint_StrokeCap.values) + ..e( + 4, _omitFieldNames ? '' : 'style', $pb.PbFieldType.OE, + defaultOrMaker: SerializablePaint_PaintingStyle.PAINTING_STYLE_FILL, + valueOf: SerializablePaint_PaintingStyle.valueOf, + enumValues: SerializablePaint_PaintingStyle.values) + ..e( + 5, _omitFieldNames ? '' : 'blendMode', $pb.PbFieldType.OE, + protoName: 'blendMode', + defaultOrMaker: SerializablePaint_BlendMode.BLEND_MODE_SCR_OVER, + valueOf: SerializablePaint_BlendMode.valueOf, + enumValues: SerializablePaint_BlendMode.values) + ..e( + 6, _omitFieldNames ? '' : 'strokeJoin', $pb.PbFieldType.OE, + protoName: 'strokeJoin', + defaultOrMaker: SerializablePaint_StrokeJoin.STROKE_JOIN_MITER, + valueOf: SerializablePaint_StrokeJoin.valueOf, + enumValues: SerializablePaint_StrokeJoin.values) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SerializablePaint clone() => SerializablePaint()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SerializablePaint copyWith(void Function(SerializablePaint) updates) => + super.copyWith((message) => updates(message as SerializablePaint)) + as SerializablePaint; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SerializablePaint create() => SerializablePaint._(); + SerializablePaint createEmptyInstance() => create(); + static $pb.PbList createRepeated() => + $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SerializablePaint getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SerializablePaint? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get color => $_getIZ(0); + @$pb.TagNumber(1) + set color($core.int v) { + $_setUnsignedInt32(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasColor() => $_has(0); + @$pb.TagNumber(1) + void clearColor() => clearField(1); + + @$pb.TagNumber(2) + $core.double get strokeWidth => $_getN(1); + @$pb.TagNumber(2) + set strokeWidth($core.double v) { + $_setFloat(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasStrokeWidth() => $_has(1); + @$pb.TagNumber(2) + void clearStrokeWidth() => clearField(2); + + @$pb.TagNumber(3) + SerializablePaint_StrokeCap get cap => $_getN(2); + @$pb.TagNumber(3) + set cap(SerializablePaint_StrokeCap v) { + setField(3, v); + } + + @$pb.TagNumber(3) + $core.bool hasCap() => $_has(2); + @$pb.TagNumber(3) + void clearCap() => clearField(3); + + @$pb.TagNumber(4) + SerializablePaint_PaintingStyle get style => $_getN(3); + @$pb.TagNumber(4) + set style(SerializablePaint_PaintingStyle v) { + setField(4, v); + } + + @$pb.TagNumber(4) + $core.bool hasStyle() => $_has(3); + @$pb.TagNumber(4) + void clearStyle() => clearField(4); + + @$pb.TagNumber(5) + SerializablePaint_BlendMode get blendMode => $_getN(4); + @$pb.TagNumber(5) + set blendMode(SerializablePaint_BlendMode v) { + setField(5, v); + } + + @$pb.TagNumber(5) + $core.bool hasBlendMode() => $_has(4); + @$pb.TagNumber(5) + void clearBlendMode() => clearField(5); + + @$pb.TagNumber(6) + SerializablePaint_StrokeJoin get strokeJoin => $_getN(5); + @$pb.TagNumber(6) + set strokeJoin(SerializablePaint_StrokeJoin v) { + setField(6, v); + } + + @$pb.TagNumber(6) + $core.bool hasStrokeJoin() => $_has(5); + @$pb.TagNumber(6) + void clearStrokeJoin() => clearField(6); +} + +const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); +const _omitMessageNames = + $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbenum.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbenum.dart new file mode 100644 index 00000000..fd71611c --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbenum.dart @@ -0,0 +1,115 @@ +// +// Generated code. Do not modify. +// source: graphic/paint.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class SerializablePaint_StrokeCap extends $pb.ProtobufEnum { + static const SerializablePaint_StrokeCap STROKE_CAP_ROUND = + SerializablePaint_StrokeCap._( + 0, _omitEnumNames ? '' : 'STROKE_CAP_ROUND'); + static const SerializablePaint_StrokeCap STROKE_CAP_BUTT = + SerializablePaint_StrokeCap._(1, _omitEnumNames ? '' : 'STROKE_CAP_BUTT'); + static const SerializablePaint_StrokeCap STROKE_CAP_SQUARE = + SerializablePaint_StrokeCap._( + 2, _omitEnumNames ? '' : 'STROKE_CAP_SQUARE'); + + static const $core.List values = + [ + STROKE_CAP_ROUND, + STROKE_CAP_BUTT, + STROKE_CAP_SQUARE, + ]; + + static final $core.Map<$core.int, SerializablePaint_StrokeCap> _byValue = + $pb.ProtobufEnum.initByValue(values); + static SerializablePaint_StrokeCap? valueOf($core.int value) => + _byValue[value]; + + const SerializablePaint_StrokeCap._($core.int v, $core.String n) + : super(v, n); +} + +class SerializablePaint_PaintingStyle extends $pb.ProtobufEnum { + static const SerializablePaint_PaintingStyle PAINTING_STYLE_FILL = + SerializablePaint_PaintingStyle._( + 0, _omitEnumNames ? '' : 'PAINTING_STYLE_FILL'); + static const SerializablePaint_PaintingStyle PAINTING_STYLE_STROKE = + SerializablePaint_PaintingStyle._( + 1, _omitEnumNames ? '' : 'PAINTING_STYLE_STROKE'); + + static const $core.List values = + [ + PAINTING_STYLE_FILL, + PAINTING_STYLE_STROKE, + ]; + + static final $core.Map<$core.int, SerializablePaint_PaintingStyle> _byValue = + $pb.ProtobufEnum.initByValue(values); + static SerializablePaint_PaintingStyle? valueOf($core.int value) => + _byValue[value]; + + const SerializablePaint_PaintingStyle._($core.int v, $core.String n) + : super(v, n); +} + +class SerializablePaint_BlendMode extends $pb.ProtobufEnum { + static const SerializablePaint_BlendMode BLEND_MODE_SCR_OVER = + SerializablePaint_BlendMode._( + 0, _omitEnumNames ? '' : 'BLEND_MODE_SCR_OVER'); + static const SerializablePaint_BlendMode BLEND_MODE_CLEAR = + SerializablePaint_BlendMode._( + 1, _omitEnumNames ? '' : 'BLEND_MODE_CLEAR'); + + static const $core.List values = + [ + BLEND_MODE_SCR_OVER, + BLEND_MODE_CLEAR, + ]; + + static final $core.Map<$core.int, SerializablePaint_BlendMode> _byValue = + $pb.ProtobufEnum.initByValue(values); + static SerializablePaint_BlendMode? valueOf($core.int value) => + _byValue[value]; + + const SerializablePaint_BlendMode._($core.int v, $core.String n) + : super(v, n); +} + +class SerializablePaint_StrokeJoin extends $pb.ProtobufEnum { + static const SerializablePaint_StrokeJoin STROKE_JOIN_MITER = + SerializablePaint_StrokeJoin._( + 0, _omitEnumNames ? '' : 'STROKE_JOIN_MITER'); + static const SerializablePaint_StrokeJoin STROKE_JOIN_ROUND = + SerializablePaint_StrokeJoin._( + 1, _omitEnumNames ? '' : 'STROKE_JOIN_ROUND'); + static const SerializablePaint_StrokeJoin STROKE_JOIN_BEVEL = + SerializablePaint_StrokeJoin._( + 2, _omitEnumNames ? '' : 'STROKE_JOIN_BEVEL'); + + static const $core.List values = + [ + STROKE_JOIN_MITER, + STROKE_JOIN_ROUND, + STROKE_JOIN_BEVEL, + ]; + + static final $core.Map<$core.int, SerializablePaint_StrokeJoin> _byValue = + $pb.ProtobufEnum.initByValue(values); + static SerializablePaint_StrokeJoin? valueOf($core.int value) => + _byValue[value]; + + const SerializablePaint_StrokeJoin._($core.int v, $core.String n) + : super(v, n); +} + +const _omitEnumNames = $core.bool.fromEnvironment('protobuf.omit_enum_names'); diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbjson.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbjson.dart new file mode 100644 index 00000000..98ae48cc --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbjson.dart @@ -0,0 +1,113 @@ +// +// Generated code. Do not modify. +// source: graphic/paint.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:convert' as $convert; +import 'dart:core' as $core; +import 'dart:typed_data' as $typed_data; + +@$core.Deprecated('Use serializablePaintDescriptor instead') +const SerializablePaint$json = { + '1': 'SerializablePaint', + '2': [ + {'1': 'color', '3': 1, '4': 1, '5': 13, '10': 'color'}, + {'1': 'strokeWidth', '3': 2, '4': 1, '5': 2, '10': 'strokeWidth'}, + { + '1': 'cap', + '3': 3, + '4': 1, + '5': 14, + '6': '.SerializablePaint.StrokeCap', + '10': 'cap' + }, + { + '1': 'style', + '3': 4, + '4': 1, + '5': 14, + '6': '.SerializablePaint.PaintingStyle', + '10': 'style' + }, + { + '1': 'blendMode', + '3': 5, + '4': 1, + '5': 14, + '6': '.SerializablePaint.BlendMode', + '10': 'blendMode' + }, + { + '1': 'strokeJoin', + '3': 6, + '4': 1, + '5': 14, + '6': '.SerializablePaint.StrokeJoin', + '10': 'strokeJoin' + }, + ], + '4': [ + SerializablePaint_StrokeCap$json, + SerializablePaint_PaintingStyle$json, + SerializablePaint_BlendMode$json, + SerializablePaint_StrokeJoin$json + ], +}; + +@$core.Deprecated('Use serializablePaintDescriptor instead') +const SerializablePaint_StrokeCap$json = { + '1': 'StrokeCap', + '2': [ + {'1': 'STROKE_CAP_ROUND', '2': 0}, + {'1': 'STROKE_CAP_BUTT', '2': 1}, + {'1': 'STROKE_CAP_SQUARE', '2': 2}, + ], +}; + +@$core.Deprecated('Use serializablePaintDescriptor instead') +const SerializablePaint_PaintingStyle$json = { + '1': 'PaintingStyle', + '2': [ + {'1': 'PAINTING_STYLE_FILL', '2': 0}, + {'1': 'PAINTING_STYLE_STROKE', '2': 1}, + ], +}; + +@$core.Deprecated('Use serializablePaintDescriptor instead') +const SerializablePaint_BlendMode$json = { + '1': 'BlendMode', + '2': [ + {'1': 'BLEND_MODE_SCR_OVER', '2': 0}, + {'1': 'BLEND_MODE_CLEAR', '2': 1}, + ], +}; + +@$core.Deprecated('Use serializablePaintDescriptor instead') +const SerializablePaint_StrokeJoin$json = { + '1': 'StrokeJoin', + '2': [ + {'1': 'STROKE_JOIN_MITER', '2': 0}, + {'1': 'STROKE_JOIN_ROUND', '2': 1}, + {'1': 'STROKE_JOIN_BEVEL', '2': 2}, + ], +}; + +/// Descriptor for `SerializablePaint`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List serializablePaintDescriptor = $convert.base64Decode( + 'ChFTZXJpYWxpemFibGVQYWludBIUCgVjb2xvchgBIAEoDVIFY29sb3ISIAoLc3Ryb2tlV2lkdG' + 'gYAiABKAJSC3N0cm9rZVdpZHRoEi4KA2NhcBgDIAEoDjIcLlNlcmlhbGl6YWJsZVBhaW50LlN0' + 'cm9rZUNhcFIDY2FwEjYKBXN0eWxlGAQgASgOMiAuU2VyaWFsaXphYmxlUGFpbnQuUGFpbnRpbm' + 'dTdHlsZVIFc3R5bGUSOgoJYmxlbmRNb2RlGAUgASgOMhwuU2VyaWFsaXphYmxlUGFpbnQuQmxl' + 'bmRNb2RlUglibGVuZE1vZGUSPQoKc3Ryb2tlSm9pbhgGIAEoDjIdLlNlcmlhbGl6YWJsZVBhaW' + '50LlN0cm9rZUpvaW5SCnN0cm9rZUpvaW4iTQoJU3Ryb2tlQ2FwEhQKEFNUUk9LRV9DQVBfUk9V' + 'TkQQABITCg9TVFJPS0VfQ0FQX0JVVFQQARIVChFTVFJPS0VfQ0FQX1NRVUFSRRACIkMKDVBhaW' + '50aW5nU3R5bGUSFwoTUEFJTlRJTkdfU1RZTEVfRklMTBAAEhkKFVBBSU5USU5HX1NUWUxFX1NU' + 'Uk9LRRABIjoKCUJsZW5kTW9kZRIXChNCTEVORF9NT0RFX1NDUl9PVkVSEAASFAoQQkxFTkRfTU' + '9ERV9DTEVBUhABIlEKClN0cm9rZUpvaW4SFQoRU1RST0tFX0pPSU5fTUlURVIQABIVChFTVFJP' + 'S0VfSk9JTl9ST1VORBABEhUKEVNUUk9LRV9KT0lOX0JFVkVMEAI='); diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbserver.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbserver.dart new file mode 100644 index 00000000..4b9c3196 --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbserver.dart @@ -0,0 +1,13 @@ +// +// Generated code. Do not modify. +// source: graphic/paint.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names +// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +export 'paint.pb.dart'; diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/path.pb.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/path.pb.dart new file mode 100644 index 00000000..1e21d472 --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/graphic/path.pb.dart @@ -0,0 +1,420 @@ +// +// Generated code. Do not modify. +// source: graphic/path.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +import 'path.pbenum.dart'; + +export 'path.pbenum.dart'; + +class SerializablePath_Action_MoveTo extends $pb.GeneratedMessage { + factory SerializablePath_Action_MoveTo({ + $core.double? x, + $core.double? y, + }) { + final $result = create(); + if (x != null) { + $result.x = x; + } + if (y != null) { + $result.y = y; + } + return $result; + } + SerializablePath_Action_MoveTo._() : super(); + factory SerializablePath_Action_MoveTo.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory SerializablePath_Action_MoveTo.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'SerializablePath.Action.MoveTo', + createEmptyInstance: create) + ..a<$core.double>(1, _omitFieldNames ? '' : 'x', $pb.PbFieldType.OD) + ..a<$core.double>(2, _omitFieldNames ? '' : 'y', $pb.PbFieldType.OD) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SerializablePath_Action_MoveTo clone() => + SerializablePath_Action_MoveTo()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SerializablePath_Action_MoveTo copyWith( + void Function(SerializablePath_Action_MoveTo) updates) => + super.copyWith( + (message) => updates(message as SerializablePath_Action_MoveTo)) + as SerializablePath_Action_MoveTo; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SerializablePath_Action_MoveTo create() => + SerializablePath_Action_MoveTo._(); + SerializablePath_Action_MoveTo createEmptyInstance() => create(); + static $pb.PbList createRepeated() => + $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SerializablePath_Action_MoveTo getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SerializablePath_Action_MoveTo? _defaultInstance; + + @$pb.TagNumber(1) + $core.double get x => $_getN(0); + @$pb.TagNumber(1) + set x($core.double v) { + $_setDouble(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasX() => $_has(0); + @$pb.TagNumber(1) + void clearX() => clearField(1); + + @$pb.TagNumber(2) + $core.double get y => $_getN(1); + @$pb.TagNumber(2) + set y($core.double v) { + $_setDouble(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasY() => $_has(1); + @$pb.TagNumber(2) + void clearY() => clearField(2); +} + +class SerializablePath_Action_LineTo extends $pb.GeneratedMessage { + factory SerializablePath_Action_LineTo({ + $core.double? x, + $core.double? y, + }) { + final $result = create(); + if (x != null) { + $result.x = x; + } + if (y != null) { + $result.y = y; + } + return $result; + } + SerializablePath_Action_LineTo._() : super(); + factory SerializablePath_Action_LineTo.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory SerializablePath_Action_LineTo.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'SerializablePath.Action.LineTo', + createEmptyInstance: create) + ..a<$core.double>(1, _omitFieldNames ? '' : 'x', $pb.PbFieldType.OD) + ..a<$core.double>(2, _omitFieldNames ? '' : 'y', $pb.PbFieldType.OD) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SerializablePath_Action_LineTo clone() => + SerializablePath_Action_LineTo()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SerializablePath_Action_LineTo copyWith( + void Function(SerializablePath_Action_LineTo) updates) => + super.copyWith( + (message) => updates(message as SerializablePath_Action_LineTo)) + as SerializablePath_Action_LineTo; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SerializablePath_Action_LineTo create() => + SerializablePath_Action_LineTo._(); + SerializablePath_Action_LineTo createEmptyInstance() => create(); + static $pb.PbList createRepeated() => + $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SerializablePath_Action_LineTo getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SerializablePath_Action_LineTo? _defaultInstance; + + @$pb.TagNumber(1) + $core.double get x => $_getN(0); + @$pb.TagNumber(1) + set x($core.double v) { + $_setDouble(0, v); + } + + @$pb.TagNumber(1) + $core.bool hasX() => $_has(0); + @$pb.TagNumber(1) + void clearX() => clearField(1); + + @$pb.TagNumber(2) + $core.double get y => $_getN(1); + @$pb.TagNumber(2) + set y($core.double v) { + $_setDouble(1, v); + } + + @$pb.TagNumber(2) + $core.bool hasY() => $_has(1); + @$pb.TagNumber(2) + void clearY() => clearField(2); +} + +class SerializablePath_Action_Close extends $pb.GeneratedMessage { + factory SerializablePath_Action_Close() => create(); + SerializablePath_Action_Close._() : super(); + factory SerializablePath_Action_Close.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory SerializablePath_Action_Close.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'SerializablePath.Action.Close', + createEmptyInstance: create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SerializablePath_Action_Close clone() => + SerializablePath_Action_Close()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SerializablePath_Action_Close copyWith( + void Function(SerializablePath_Action_Close) updates) => + super.copyWith( + (message) => updates(message as SerializablePath_Action_Close)) + as SerializablePath_Action_Close; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SerializablePath_Action_Close create() => + SerializablePath_Action_Close._(); + SerializablePath_Action_Close createEmptyInstance() => create(); + static $pb.PbList createRepeated() => + $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SerializablePath_Action_Close getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SerializablePath_Action_Close? _defaultInstance; +} + +enum SerializablePath_Action_Action { moveTo, lineTo, close, notSet } + +class SerializablePath_Action extends $pb.GeneratedMessage { + factory SerializablePath_Action({ + SerializablePath_Action_MoveTo? moveTo, + SerializablePath_Action_LineTo? lineTo, + SerializablePath_Action_Close? close, + }) { + final $result = create(); + if (moveTo != null) { + $result.moveTo = moveTo; + } + if (lineTo != null) { + $result.lineTo = lineTo; + } + if (close != null) { + $result.close = close; + } + return $result; + } + SerializablePath_Action._() : super(); + factory SerializablePath_Action.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory SerializablePath_Action.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static const $core.Map<$core.int, SerializablePath_Action_Action> + _SerializablePath_Action_ActionByTag = { + 1: SerializablePath_Action_Action.moveTo, + 2: SerializablePath_Action_Action.lineTo, + 3: SerializablePath_Action_Action.close, + 0: SerializablePath_Action_Action.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'SerializablePath.Action', + createEmptyInstance: create) + ..oo(0, [1, 2, 3]) + ..aOM(1, _omitFieldNames ? '' : 'moveTo', + subBuilder: SerializablePath_Action_MoveTo.create) + ..aOM(2, _omitFieldNames ? '' : 'lineTo', + subBuilder: SerializablePath_Action_LineTo.create) + ..aOM(3, _omitFieldNames ? '' : 'close', + subBuilder: SerializablePath_Action_Close.create) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SerializablePath_Action clone() => + SerializablePath_Action()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SerializablePath_Action copyWith( + void Function(SerializablePath_Action) updates) => + super.copyWith((message) => updates(message as SerializablePath_Action)) + as SerializablePath_Action; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SerializablePath_Action create() => SerializablePath_Action._(); + SerializablePath_Action createEmptyInstance() => create(); + static $pb.PbList createRepeated() => + $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SerializablePath_Action getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SerializablePath_Action? _defaultInstance; + + SerializablePath_Action_Action whichAction() => + _SerializablePath_Action_ActionByTag[$_whichOneof(0)]!; + void clearAction() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + SerializablePath_Action_MoveTo get moveTo => $_getN(0); + @$pb.TagNumber(1) + set moveTo(SerializablePath_Action_MoveTo v) { + setField(1, v); + } + + @$pb.TagNumber(1) + $core.bool hasMoveTo() => $_has(0); + @$pb.TagNumber(1) + void clearMoveTo() => clearField(1); + @$pb.TagNumber(1) + SerializablePath_Action_MoveTo ensureMoveTo() => $_ensure(0); + + @$pb.TagNumber(2) + SerializablePath_Action_LineTo get lineTo => $_getN(1); + @$pb.TagNumber(2) + set lineTo(SerializablePath_Action_LineTo v) { + setField(2, v); + } + + @$pb.TagNumber(2) + $core.bool hasLineTo() => $_has(1); + @$pb.TagNumber(2) + void clearLineTo() => clearField(2); + @$pb.TagNumber(2) + SerializablePath_Action_LineTo ensureLineTo() => $_ensure(1); + + @$pb.TagNumber(3) + SerializablePath_Action_Close get close => $_getN(2); + @$pb.TagNumber(3) + set close(SerializablePath_Action_Close v) { + setField(3, v); + } + + @$pb.TagNumber(3) + $core.bool hasClose() => $_has(2); + @$pb.TagNumber(3) + void clearClose() => clearField(3); + @$pb.TagNumber(3) + SerializablePath_Action_Close ensureClose() => $_ensure(2); +} + +class SerializablePath extends $pb.GeneratedMessage { + factory SerializablePath({ + $core.Iterable? actions, + SerializablePath_FillType? fillType, + }) { + final $result = create(); + if (actions != null) { + $result.actions.addAll(actions); + } + if (fillType != null) { + $result.fillType = fillType; + } + return $result; + } + SerializablePath._() : super(); + factory SerializablePath.fromBuffer($core.List<$core.int> i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(i, r); + factory SerializablePath.fromJson($core.String i, + [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'SerializablePath', + createEmptyInstance: create) + ..pc( + 1, _omitFieldNames ? '' : 'actions', $pb.PbFieldType.PM, + subBuilder: SerializablePath_Action.create) + ..e( + 2, _omitFieldNames ? '' : 'fillType', $pb.PbFieldType.OE, + defaultOrMaker: SerializablePath_FillType.NON_ZERO, + valueOf: SerializablePath_FillType.valueOf, + enumValues: SerializablePath_FillType.values) + ..hasRequiredFields = false; + + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + SerializablePath clone() => SerializablePath()..mergeFromMessage(this); + @$core.Deprecated('Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + SerializablePath copyWith(void Function(SerializablePath) updates) => + super.copyWith((message) => updates(message as SerializablePath)) + as SerializablePath; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static SerializablePath create() => SerializablePath._(); + SerializablePath createEmptyInstance() => create(); + static $pb.PbList createRepeated() => + $pb.PbList(); + @$core.pragma('dart2js:noInline') + static SerializablePath getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static SerializablePath? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get actions => $_getList(0); + + @$pb.TagNumber(2) + SerializablePath_FillType get fillType => $_getN(1); + @$pb.TagNumber(2) + set fillType(SerializablePath_FillType v) { + setField(2, v); + } + + @$pb.TagNumber(2) + $core.bool hasFillType() => $_has(1); + @$pb.TagNumber(2) + void clearFillType() => clearField(2); +} + +const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); +const _omitMessageNames = + $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbenum.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbenum.dart new file mode 100644 index 00000000..a942740d --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbenum.dart @@ -0,0 +1,35 @@ +// +// Generated code. Do not modify. +// source: graphic/path.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class SerializablePath_FillType extends $pb.ProtobufEnum { + static const SerializablePath_FillType NON_ZERO = + SerializablePath_FillType._(0, _omitEnumNames ? '' : 'NON_ZERO'); + static const SerializablePath_FillType EVEN_ODD = + SerializablePath_FillType._(1, _omitEnumNames ? '' : 'EVEN_ODD'); + + static const $core.List values = + [ + NON_ZERO, + EVEN_ODD, + ]; + + static final $core.Map<$core.int, SerializablePath_FillType> _byValue = + $pb.ProtobufEnum.initByValue(values); + static SerializablePath_FillType? valueOf($core.int value) => _byValue[value]; + + const SerializablePath_FillType._($core.int v, $core.String n) : super(v, n); +} + +const _omitEnumNames = $core.bool.fromEnvironment('protobuf.omit_enum_names'); diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbjson.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbjson.dart new file mode 100644 index 00000000..f209b2c4 --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbjson.dart @@ -0,0 +1,125 @@ +// +// Generated code. Do not modify. +// source: graphic/path.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:convert' as $convert; +import 'dart:core' as $core; +import 'dart:typed_data' as $typed_data; + +@$core.Deprecated('Use serializablePathDescriptor instead') +const SerializablePath$json = { + '1': 'SerializablePath', + '2': [ + { + '1': 'actions', + '3': 1, + '4': 3, + '5': 11, + '6': '.SerializablePath.Action', + '10': 'actions' + }, + { + '1': 'fill_type', + '3': 2, + '4': 1, + '5': 14, + '6': '.SerializablePath.FillType', + '10': 'fillType' + }, + ], + '3': [SerializablePath_Action$json], + '4': [SerializablePath_FillType$json], +}; + +@$core.Deprecated('Use serializablePathDescriptor instead') +const SerializablePath_Action$json = { + '1': 'Action', + '2': [ + { + '1': 'move_to', + '3': 1, + '4': 1, + '5': 11, + '6': '.SerializablePath.Action.MoveTo', + '9': 0, + '10': 'moveTo' + }, + { + '1': 'line_to', + '3': 2, + '4': 1, + '5': 11, + '6': '.SerializablePath.Action.LineTo', + '9': 0, + '10': 'lineTo' + }, + { + '1': 'close', + '3': 3, + '4': 1, + '5': 11, + '6': '.SerializablePath.Action.Close', + '9': 0, + '10': 'close' + }, + ], + '3': [ + SerializablePath_Action_MoveTo$json, + SerializablePath_Action_LineTo$json, + SerializablePath_Action_Close$json + ], + '8': [ + {'1': 'action'}, + ], +}; + +@$core.Deprecated('Use serializablePathDescriptor instead') +const SerializablePath_Action_MoveTo$json = { + '1': 'MoveTo', + '2': [ + {'1': 'x', '3': 1, '4': 1, '5': 1, '10': 'x'}, + {'1': 'y', '3': 2, '4': 1, '5': 1, '10': 'y'}, + ], +}; + +@$core.Deprecated('Use serializablePathDescriptor instead') +const SerializablePath_Action_LineTo$json = { + '1': 'LineTo', + '2': [ + {'1': 'x', '3': 1, '4': 1, '5': 1, '10': 'x'}, + {'1': 'y', '3': 2, '4': 1, '5': 1, '10': 'y'}, + ], +}; + +@$core.Deprecated('Use serializablePathDescriptor instead') +const SerializablePath_Action_Close$json = { + '1': 'Close', +}; + +@$core.Deprecated('Use serializablePathDescriptor instead') +const SerializablePath_FillType$json = { + '1': 'FillType', + '2': [ + {'1': 'NON_ZERO', '2': 0}, + {'1': 'EVEN_ODD', '2': 1}, + ], +}; + +/// Descriptor for `SerializablePath`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List serializablePathDescriptor = $convert.base64Decode( + 'ChBTZXJpYWxpemFibGVQYXRoEjIKB2FjdGlvbnMYASADKAsyGC5TZXJpYWxpemFibGVQYXRoLk' + 'FjdGlvblIHYWN0aW9ucxI3CglmaWxsX3R5cGUYAiABKA4yGi5TZXJpYWxpemFibGVQYXRoLkZp' + 'bGxUeXBlUghmaWxsVHlwZRqXAgoGQWN0aW9uEjoKB21vdmVfdG8YASABKAsyHy5TZXJpYWxpem' + 'FibGVQYXRoLkFjdGlvbi5Nb3ZlVG9IAFIGbW92ZVRvEjoKB2xpbmVfdG8YAiABKAsyHy5TZXJp' + 'YWxpemFibGVQYXRoLkFjdGlvbi5MaW5lVG9IAFIGbGluZVRvEjYKBWNsb3NlGAMgASgLMh4uU2' + 'VyaWFsaXphYmxlUGF0aC5BY3Rpb24uQ2xvc2VIAFIFY2xvc2UaJAoGTW92ZVRvEgwKAXgYASAB' + 'KAFSAXgSDAoBeRgCIAEoAVIBeRokCgZMaW5lVG8SDAoBeBgBIAEoAVIBeBIMCgF5GAIgASgBUg' + 'F5GgcKBUNsb3NlQggKBmFjdGlvbiImCghGaWxsVHlwZRIMCghOT05fWkVSTxAAEgwKCEVWRU5f' + 'T0REEAE='); diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbserver.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbserver.dart new file mode 100644 index 00000000..a406ef5d --- /dev/null +++ b/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbserver.dart @@ -0,0 +1,13 @@ +// +// Generated code. Do not modify. +// source: graphic/path.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names +// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +export 'path.pb.dart'; diff --git a/lib/io/src/serialization/proto/protos.dart b/packages/io_library/lib/src/serialization/proto/protos.dart similarity index 100% rename from lib/io/src/serialization/proto/protos.dart rename to packages/io_library/lib/src/serialization/proto/protos.dart diff --git a/lib/io/src/serialization/proto/schema/catrobat_image.proto b/packages/io_library/lib/src/serialization/proto/schema/catrobat_image.proto similarity index 100% rename from lib/io/src/serialization/proto/schema/catrobat_image.proto rename to packages/io_library/lib/src/serialization/proto/schema/catrobat_image.proto diff --git a/lib/io/src/serialization/proto/schema/command/graphic/draw_path_command.proto b/packages/io_library/lib/src/serialization/proto/schema/command/graphic/draw_path_command.proto similarity index 100% rename from lib/io/src/serialization/proto/schema/command/graphic/draw_path_command.proto rename to packages/io_library/lib/src/serialization/proto/schema/command/graphic/draw_path_command.proto diff --git a/lib/io/src/serialization/proto/schema/graphic/paint.proto b/packages/io_library/lib/src/serialization/proto/schema/graphic/paint.proto similarity index 100% rename from lib/io/src/serialization/proto/schema/graphic/paint.proto rename to packages/io_library/lib/src/serialization/proto/schema/graphic/paint.proto diff --git a/lib/io/src/serialization/proto/schema/graphic/path.proto b/packages/io_library/lib/src/serialization/proto/schema/graphic/path.proto similarity index 100% rename from lib/io/src/serialization/proto/schema/graphic/path.proto rename to packages/io_library/lib/src/serialization/proto/schema/graphic/path.proto diff --git a/lib/io/src/serialization/proto_serializer_with_versioning.dart b/packages/io_library/lib/src/serialization/proto_serializer_with_versioning.dart similarity index 90% rename from lib/io/src/serialization/proto_serializer_with_versioning.dart rename to packages/io_library/lib/src/serialization/proto_serializer_with_versioning.dart index df24ba22..808b1026 100644 --- a/lib/io/src/serialization/proto_serializer_with_versioning.dart +++ b/packages/io_library/lib/src/serialization/proto_serializer_with_versioning.dart @@ -1,5 +1,5 @@ import 'package:flutter/foundation.dart'; -import 'package:paintroid/io/src/serialization/version_serializer.dart'; +import 'package:io_library/io_library.dart'; import 'package:protobuf/protobuf.dart' show GeneratedMessage; abstract class ProtoSerializerWithVersioning { diff --git a/lib/io/src/serialization/serializer/command/graphic/draw_path_command_serializer.dart b/packages/io_library/lib/src/serialization/serializer/command/graphic/draw_path_command_serializer.dart similarity index 87% rename from lib/io/src/serialization/serializer/command/graphic/draw_path_command_serializer.dart rename to packages/io_library/lib/src/serialization/serializer/command/graphic/draw_path_command_serializer.dart index 1e1fbeea..41f05511 100644 --- a/lib/io/src/serialization/serializer/command/graphic/draw_path_command_serializer.dart +++ b/packages/io_library/lib/src/serialization/serializer/command/graphic/draw_path_command_serializer.dart @@ -1,8 +1,7 @@ +import 'package:command/command.dart'; +import 'package:command/command_providers.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/command/command.dart' - show CommandFactory, DrawPathCommand; -import 'package:paintroid/command/src/command_factory_provider.dart'; -import 'package:paintroid/io/serialization.dart'; +import 'package:io_library/io_library.dart'; class DrawPathCommandSerializer extends ProtoSerializerWithVersioning< DrawPathCommand, SerializableDrawPathCommand> { diff --git a/lib/io/src/serialization/serializer/graphic/paint_serializer.dart b/packages/io_library/lib/src/serialization/serializer/graphic/paint_serializer.dart similarity index 86% rename from lib/io/src/serialization/serializer/graphic/paint_serializer.dart rename to packages/io_library/lib/src/serialization/serializer/graphic/paint_serializer.dart index 0836ab48..96124bf9 100644 --- a/lib/io/src/serialization/serializer/graphic/paint_serializer.dart +++ b/packages/io_library/lib/src/serialization/serializer/graphic/paint_serializer.dart @@ -1,31 +1,30 @@ import 'dart:ui'; -import 'package:flutter_riverpod/flutter_riverpod.dart' show Provider; -import 'package:paintroid/core/graphic_factory.dart'; -import 'package:paintroid/core/graphic_factory_provider.dart'; -import 'package:paintroid/io/serialization.dart'; +import 'package:component_library/component_library.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:io_library/io_library.dart'; class PaintSerializer extends ProtoSerializerWithVersioning { final GraphicFactory _graphicFactory; - static const _capMap = { + static final _capMap = { SerializablePaint_StrokeCap.STROKE_CAP_BUTT: StrokeCap.butt, SerializablePaint_StrokeCap.STROKE_CAP_ROUND: StrokeCap.round, SerializablePaint_StrokeCap.STROKE_CAP_SQUARE: StrokeCap.square, }; - static const _styleMap = { + static final _styleMap = { SerializablePaint_PaintingStyle.PAINTING_STYLE_FILL: PaintingStyle.fill, SerializablePaint_PaintingStyle.PAINTING_STYLE_STROKE: PaintingStyle.stroke, }; - static const _blendModeMap = { + static final _blendModeMap = { SerializablePaint_BlendMode.BLEND_MODE_SCR_OVER: BlendMode.srcOver, SerializablePaint_BlendMode.BLEND_MODE_CLEAR: BlendMode.clear, }; - static const _strokeJoinMap = { + static final _strokeJoinMap = { SerializablePaint_StrokeJoin.STROKE_JOIN_MITER: StrokeJoin.miter, SerializablePaint_StrokeJoin.STROKE_JOIN_ROUND: StrokeJoin.round, SerializablePaint_StrokeJoin.STROKE_JOIN_BEVEL: StrokeJoin.bevel, diff --git a/lib/io/src/serialization/serializer/graphic/path_serializer.dart b/packages/io_library/lib/src/serialization/serializer/graphic/path_serializer.dart similarity index 90% rename from lib/io/src/serialization/serializer/graphic/path_serializer.dart rename to packages/io_library/lib/src/serialization/serializer/graphic/path_serializer.dart index c60f99c9..9c45db4a 100644 --- a/lib/io/src/serialization/serializer/graphic/path_serializer.dart +++ b/packages/io_library/lib/src/serialization/serializer/graphic/path_serializer.dart @@ -1,11 +1,8 @@ import 'dart:ui'; +import 'package:component_library/component_library.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/core/graphic_factory.dart'; -import 'package:paintroid/core/graphic_factory_provider.dart'; -import 'package:paintroid/core/loggable_mixin.dart'; -import 'package:paintroid/core/path_with_action_history.dart'; -import 'package:paintroid/io/serialization.dart'; +import 'package:io_library/io_library.dart'; class PathSerializer extends ProtoSerializerWithVersioning< PathWithActionHistory, SerializablePath> with LoggableMixin { diff --git a/lib/io/src/serialization/version_serializer.dart b/packages/io_library/lib/src/serialization/version_serializer.dart similarity index 100% rename from lib/io/src/serialization/version_serializer.dart rename to packages/io_library/lib/src/serialization/version_serializer.dart diff --git a/lib/io/src/service/file_service.dart b/packages/io_library/lib/src/service/file_service.dart similarity index 96% rename from lib/io/src/service/file_service.dart rename to packages/io_library/lib/src/service/file_service.dart index 26dbafda..2d72e9b9 100644 --- a/lib/io/src/service/file_service.dart +++ b/packages/io_library/lib/src/service/file_service.dart @@ -3,10 +3,9 @@ import 'dart:typed_data'; import 'package:file_picker/file_picker.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; -import 'package:paintroid/core/failure.dart'; -import 'package:paintroid/core/loggable_mixin.dart'; -import 'package:paintroid/io/io.dart'; + import 'package:path_provider/path_provider.dart'; abstract class IFileService { diff --git a/lib/io/src/service/image_service.dart b/packages/io_library/lib/src/service/image_service.dart similarity index 91% rename from lib/io/src/service/image_service.dart rename to packages/io_library/lib/src/service/image_service.dart index b6a68a57..353a736c 100644 --- a/lib/io/src/service/image_service.dart +++ b/packages/io_library/lib/src/service/image_service.dart @@ -5,11 +5,8 @@ import 'dart:ui' as ui; import 'package:flutter/painting.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:image/image.dart'; +import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; -import 'package:paintroid/core/failure.dart'; -import 'package:paintroid/core/loggable_mixin.dart'; -import 'package:paintroid/io/src/failure/load_image_failure.dart'; -import 'package:paintroid/io/src/failure/save_image_failure.dart'; abstract class IImageService { Future> import(Uint8List fileData); diff --git a/lib/io/src/service/permission_service.dart b/packages/io_library/lib/src/service/permission_service.dart similarity index 94% rename from lib/io/src/service/permission_service.dart rename to packages/io_library/lib/src/service/permission_service.dart index 327ae91f..1095f64e 100644 --- a/lib/io/src/service/permission_service.dart +++ b/packages/io_library/lib/src/service/permission_service.dart @@ -2,7 +2,7 @@ import 'dart:io'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/core/loggable_mixin.dart'; +import 'package:io_library/io_library.dart'; import 'package:permission_handler/permission_handler.dart'; abstract class IPermissionService { @@ -97,6 +97,10 @@ class PermissionService with LoggableMixin implements IPermissionService { case PermissionStatus.denied: logger.warning('User explicitly denied $permission'); break; + default: + logger + .warning('Undefinied permission status. This should never happen.'); + break; } return false; } diff --git a/lib/io/src/service/photo_library_service.dart b/packages/io_library/lib/src/service/photo_library_service.dart similarity index 88% rename from lib/io/src/service/photo_library_service.dart rename to packages/io_library/lib/src/service/photo_library_service.dart index 853d9556..1d247b55 100644 --- a/lib/io/src/service/photo_library_service.dart +++ b/packages/io_library/lib/src/service/photo_library_service.dart @@ -1,11 +1,8 @@ import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:image_picker/image_picker.dart'; +import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; -import 'package:paintroid/core/failure.dart'; -import 'package:paintroid/core/loggable_mixin.dart'; -import 'package:paintroid/io/src/failure/load_image_failure.dart'; -import 'package:paintroid/io/src/failure/save_image_failure.dart'; abstract class IPhotoLibraryService { Future> save(String filename, Uint8List data); diff --git a/lib/io/src/ui/about_dialog.dart b/packages/io_library/lib/src/ui/about_dialog.dart similarity index 94% rename from lib/io/src/ui/about_dialog.dart rename to packages/io_library/lib/src/ui/about_dialog.dart index 1bd92c5a..f672d6af 100644 --- a/lib/io/src/ui/about_dialog.dart +++ b/packages/io_library/lib/src/ui/about_dialog.dart @@ -1,8 +1,8 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:paintroid/io/src/ui/generic_dialog.dart'; -import 'package:paintroid/ui/util.dart'; +import 'package:io_library/io_library.dart'; Future showMyAboutDialog(BuildContext context, String version) => showGeneralDialog( @@ -58,7 +58,7 @@ class _MyAboutDialogState extends ConsumerState { crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ - Image.asset('assets/icon/pocketpaint_logo_small.png'), + const PocketPaintLogoSmall(), Text( 'Version ${widget.version}', style: const TextStyle(fontSize: 9), diff --git a/lib/io/src/ui/delete_project_dialog.dart b/packages/io_library/lib/src/ui/delete_project_dialog.dart similarity index 93% rename from lib/io/src/ui/delete_project_dialog.dart rename to packages/io_library/lib/src/ui/delete_project_dialog.dart index ccb895a2..667f45e4 100644 --- a/lib/io/src/ui/delete_project_dialog.dart +++ b/packages/io_library/lib/src/ui/delete_project_dialog.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:paintroid/io/src/ui/generic_dialog.dart'; +import 'package:io_library/io_library.dart'; /// Returns [true] if user chose to delete the project or [null] if user /// dismiss the dialog by tapping outside diff --git a/lib/io/src/ui/discard_changes_dialog.dart b/packages/io_library/lib/src/ui/discard_changes_dialog.dart similarity index 94% rename from lib/io/src/ui/discard_changes_dialog.dart rename to packages/io_library/lib/src/ui/discard_changes_dialog.dart index c21875fe..2f2d1e65 100644 --- a/lib/io/src/ui/discard_changes_dialog.dart +++ b/packages/io_library/lib/src/ui/discard_changes_dialog.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:paintroid/io/src/ui/generic_dialog.dart'; +import 'package:io_library/io_library.dart'; /// Returns [true] if user chose to discard changes or [null] if user /// dismissed the dialog by tapping outside diff --git a/lib/io/src/ui/generic_dialog.dart b/packages/io_library/lib/src/ui/generic_dialog.dart similarity index 100% rename from lib/io/src/ui/generic_dialog.dart rename to packages/io_library/lib/src/ui/generic_dialog.dart diff --git a/lib/io/src/ui/image_format_info.dart b/packages/io_library/lib/src/ui/image_format_info.dart similarity index 93% rename from lib/io/src/ui/image_format_info.dart rename to packages/io_library/lib/src/ui/image_format_info.dart index 854ec79b..78fbcd8e 100644 --- a/lib/io/src/ui/image_format_info.dart +++ b/packages/io_library/lib/src/ui/image_format_info.dart @@ -1,4 +1,5 @@ -part of 'save_image_dialog.dart'; +import 'package:flutter/material.dart'; +import 'package:io_library/io_library.dart'; extension on ImageFormat { TextSpan get info { diff --git a/lib/io/src/ui/load_image_dialog.dart b/packages/io_library/lib/src/ui/load_image_dialog.dart similarity index 88% rename from lib/io/src/ui/load_image_dialog.dart rename to packages/io_library/lib/src/ui/load_image_dialog.dart index 9b1140ac..50840894 100644 --- a/lib/io/src/ui/load_image_dialog.dart +++ b/packages/io_library/lib/src/ui/load_image_dialog.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:paintroid/io/src/entity/image_location.dart'; -import 'package:paintroid/io/src/ui/generic_dialog.dart'; +import 'package:io_library/io_library.dart'; /// Returns [null] if user dismissed the dialog by tapping outside Future showLoadImageDialog(BuildContext context) => diff --git a/lib/io/src/ui/overwrite_dialog.dart b/packages/io_library/lib/src/ui/overwrite_dialog.dart similarity index 92% rename from lib/io/src/ui/overwrite_dialog.dart rename to packages/io_library/lib/src/ui/overwrite_dialog.dart index 28d98bc1..e625c53b 100644 --- a/lib/io/src/ui/overwrite_dialog.dart +++ b/packages/io_library/lib/src/ui/overwrite_dialog.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:paintroid/io/src/ui/generic_dialog.dart'; +import 'package:io_library/io_library.dart'; Future showOverwriteDialog(BuildContext context) => showGeneralDialog( diff --git a/lib/io/src/ui/project_details_dialog.dart b/packages/io_library/lib/src/ui/project_details_dialog.dart similarity index 93% rename from lib/io/src/ui/project_details_dialog.dart rename to packages/io_library/lib/src/ui/project_details_dialog.dart index 97d5d163..33687d8f 100644 --- a/lib/io/src/ui/project_details_dialog.dart +++ b/packages/io_library/lib/src/ui/project_details_dialog.dart @@ -1,13 +1,11 @@ +import 'package:component_library/component_library.dart'; +import 'package:database/database.dart'; import 'package:filesize/filesize.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; +import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; -import 'package:paintroid/core/toast_utils.dart'; -import 'package:paintroid/data/model/project.dart'; -import 'package:paintroid/io/io.dart'; -import 'package:paintroid/io/src/ui/generic_dialog.dart'; -import 'package:paintroid/ui/color_schemes.dart'; Future showDetailsDialog(BuildContext context, Project project) => showGeneralDialog( diff --git a/lib/io/src/ui/save_image_dialog.dart b/packages/io_library/lib/src/ui/save_image_dialog.dart similarity index 97% rename from lib/io/src/ui/save_image_dialog.dart rename to packages/io_library/lib/src/ui/save_image_dialog.dart index 3e036730..104f4bb5 100644 --- a/lib/io/src/ui/save_image_dialog.dart +++ b/packages/io_library/lib/src/ui/save_image_dialog.dart @@ -1,9 +1,6 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; -import 'package:paintroid/io/io.dart'; -import 'package:paintroid/ui/color_schemes.dart'; -import 'package:paintroid/ui/styles.dart'; - -part 'image_format_info.dart'; +import 'package:io_library/io_library.dart'; /// Returns [null] if user dismissed the dialog by tapping outside Future showSaveImageDialog( diff --git a/lib/io/src/usecase/load_image_from_file_manager.dart b/packages/io_library/lib/src/usecase/load_image_from_file_manager.dart similarity index 94% rename from lib/io/src/usecase/load_image_from_file_manager.dart rename to packages/io_library/lib/src/usecase/load_image_from_file_manager.dart index 328489c2..53a96d9f 100644 --- a/lib/io/src/usecase/load_image_from_file_manager.dart +++ b/packages/io_library/lib/src/usecase/load_image_from_file_manager.dart @@ -1,10 +1,8 @@ import 'dart:io'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; -import 'package:paintroid/core/failure.dart'; -import 'package:paintroid/core/loggable_mixin.dart'; -import 'package:paintroid/io/io.dart'; extension on File { String? get extension { diff --git a/lib/io/src/usecase/load_image_from_photo_library.dart b/packages/io_library/lib/src/usecase/load_image_from_photo_library.dart similarity index 77% rename from lib/io/src/usecase/load_image_from_photo_library.dart rename to packages/io_library/lib/src/usecase/load_image_from_photo_library.dart index 46faf8b0..92366e3f 100644 --- a/lib/io/src/usecase/load_image_from_photo_library.dart +++ b/packages/io_library/lib/src/usecase/load_image_from_photo_library.dart @@ -1,12 +1,8 @@ import 'dart:ui'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; -import 'package:paintroid/core/failure.dart'; -import 'package:paintroid/io/src/failure/load_image_failure.dart'; -import 'package:paintroid/io/src/service/image_service.dart'; -import 'package:paintroid/io/src/service/permission_service.dart'; -import 'package:paintroid/io/src/service/photo_library_service.dart'; class LoadImageFromPhotoLibrary { final IImageService imageService; diff --git a/lib/io/src/usecase/save_as_catrobat_image.dart b/packages/io_library/lib/src/usecase/save_as_catrobat_image.dart similarity index 81% rename from lib/io/src/usecase/save_as_catrobat_image.dart rename to packages/io_library/lib/src/usecase/save_as_catrobat_image.dart index 376ad31a..ba7b9cc4 100644 --- a/lib/io/src/usecase/save_as_catrobat_image.dart +++ b/packages/io_library/lib/src/usecase/save_as_catrobat_image.dart @@ -1,17 +1,8 @@ import 'dart:io'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; -import 'package:paintroid/core/failure.dart'; -import 'package:paintroid/core/loggable_mixin.dart'; -import 'package:paintroid/io/io.dart' - show - CatrobatImage, - CatrobatImageMetaData, - CatrobatImageSerializer, - IFileService, - SaveImageFailure; -import 'package:paintroid/io/src/service/permission_service.dart'; class SaveAsCatrobatImage with LoggableMixin { final IFileService _fileService; diff --git a/lib/io/src/usecase/save_as_raster_image.dart b/packages/io_library/lib/src/usecase/save_as_raster_image.dart similarity index 93% rename from lib/io/src/usecase/save_as_raster_image.dart rename to packages/io_library/lib/src/usecase/save_as_raster_image.dart index 49227f84..2051142e 100644 --- a/lib/io/src/usecase/save_as_raster_image.dart +++ b/packages/io_library/lib/src/usecase/save_as_raster_image.dart @@ -1,9 +1,8 @@ import 'dart:ui'; import 'package:flutter_riverpod/flutter_riverpod.dart' show Provider; +import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; -import 'package:paintroid/core/failure.dart'; -import 'package:paintroid/io/io.dart'; class SaveAsRasterImage { final IImageService imageService; diff --git a/packages/io_library/pubspec.yaml b/packages/io_library/pubspec.yaml new file mode 100644 index 00000000..cda4d8dd --- /dev/null +++ b/packages/io_library/pubspec.yaml @@ -0,0 +1,56 @@ +name: io_library +description: A new Flutter package project. +version: 0.0.1 +publish_to: "none" + +environment: + sdk: ">=3.0.5 <4.0.0" + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + + flutter_riverpod: ^2.3.6 + riverpod_annotation: ^2.1.1 + freezed_annotation: ^2.4.1 + logging: ^1.0.2 + protobuf: ^2.1.0 + path_provider: ^2.0.11 + file_picker: ^5.3.1 + image: ^3.2.0 + package_info_plus: ^4.0.1 + device_info_plus: ^9.0.3 + permission_handler: ^10.0.0 + image_picker: ^0.8.5+3 + filesize: ^2.0.1 + oxidized: ^5.2.0 + intl: ^0.18.0 + + # Internal packages: + component_library: + path: ../component_library + command: + path: ../command + database: + path: ../database + workspace_screen: + path: ../features/workspace_screen + +dev_dependencies: + flutter_test: + sdk: flutter + + mockito: ^5.2.0 + flutter_launcher_icons: ^0.9.3 + flutter_lints: ^2.0.1 + floor_generator: ^1.2.0 + riverpod_generator: ^2.2.3 + riverpod_lint: ^1.3.2 + build_runner: ^2.2.0 + freezed: ^2.4.1 + +flutter: + uses-material-design: true + assets: + - test/fixture/image/ diff --git a/packages/io_library/test/fixture/image/test.jpg b/packages/io_library/test/fixture/image/test.jpg new file mode 100644 index 0000000000000000000000000000000000000000..04ff2033529566cf1bd1277a6d96ef80e038c9c9 GIT binary patch literal 1731 zcmbW0c~DbF9LM+NB_tpe0s%#x4Yk&-|lbs^L7^*K*oT~5i<)j z06_p8Mhig3fdh@{?h1gVCC~%_5C8^}1u*I$w15bAfE9TF)X^RQI34;LO~h9VN^i3@+vBGSqL|#o~WqLP94Mu|!?DSRflv%zh8)*PU z0?+|EFhm9zA_Nm5gaee&9pNC6MAOg)!oXOZ7@i<5u?`(jE`x3zhA~(ehZ8OX1)_0) zCE{e2wN1q2Y|h}x-XxuCu^9vv)8a;X+b*7}u8U8wxP-#`4T>Ap)VFDD*VNmycb~q2 z;lV>RGxNh1N9^p6pE&8@_~XxK&$+tM-Ope0^}EbqUhxkJ4GWLBej_q2J|QtFIVCmi zUgrI*?3~=Z-%Co%$}1`#RaG}V;WR&OX>EJf-P7CmvVUN3Xq-Fo=j+L-H`6l( z_;HE<>9ddv{hwd3(Dn=2f4GP!7Y2)kv3MaDgkcE5iCCPnwwSDm4gQR`99icYfn*w+ zQQRo5qHD{Ock$_xP*BwyS6dLGiO9YUEckzst$}^z8U_aeMkE-6o)QeBCxu0Y!{da) z6YwGt{*i=8>x7b86M`mz&>ZMwG4zuX$BVDUzS$rn=(WTmLqHOS(8~l90Tl>V?nP<< zQGL8)V&6M$p6(bfwu+z66&RUS(U0-mv#pG5t88M7Z|hh7FrMNmDff$iQDGuWDV^mj zC^GiQSh42c@yc7-&8Llzn2w(0jfQY;c^14~+FPJnQTtMn;1S^W(`JfE+kA|I84xI; zOTkE|V6J!3a^Inzg7RCgb112X6L)fEk`_)-j#9Xy8ry15v$k+K0LMGuwp|J2w=AD! zM%eSbW)t&hV;vEOl*ZD2wz^Y;dQEk*B3uk>+p=3j1lJ6p|u)bf0Hc1AI4P~}=o3E2?i5Fba1POX!7H>5Vy57)FH zK!UQ<^TVj*iUThxnoE@)GLda|lj?}bH1z9B(9V?*k63C34YUmn+^hQa8m2pikvIR5*=;QD@|#>AYiEDSbmiw#?O-?{cj)1~=5WLH)~J?k9!XG} z*M7bcZxff+|0~NI0oeJQwl|wbC5^Wio?_;3{L3E(Qy84O&3%U`IRg(gbBCVQ?3!`{ z7#(08$4+G_3)1T#eowR3vJp$6d%nCD-<0Ovligd^z9*ZP73X-*tU~Nlbh2s~L4suX z2tTz=58_fK5#VYySTiBrc$%@S(rl>3xx0m#{3Pa0S_db|`5TmT$GN-cC@++B8uQv9Mmj3aeXc`|O&BMhbGy`ql=Sr;%e!DHkft^-2#b z91Epvl6k?&-SL?^CLL1u9p95%_&u}!33*zJz4d&thhd4O29wr%@u6ZE=2m1QWA9N} z&ig0;%_P{+KoHU;SSbvzzaWk0r&%enJ4WSKr0&0(@$U#-RT-G>4{yTX8SC7`e>H3u z=S*?9ubH=H=>j<6!toGbQQ757Aro==cS_zJhaYGg kxW&G39J#@8alE0LHk+G{iPR8PX{7sKuk_1ng^|I(0T;!^UjP6A literal 0 HcmV?d00001 diff --git a/packages/io_library/test/fixture/image/test.png b/packages/io_library/test/fixture/image/test.png new file mode 100644 index 0000000000000000000000000000000000000000..a2e03a09329b7d4e7a056b28eacf63b33208aa44 GIT binary patch literal 1272 zcmVPx#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91GN1zh1ONa40RR91G5`Po0Cmf+s{jB19BD*PQ~&?~0ssI20000082|tP zC;$Ke82|tP82|tRcubKn-~a#uL`g(JRA>e4mS1R(Q5eTJTUbQ2WGKH(;)1IwmYNH0 zkPD(@ZY39FrM6O1a^c1WrCmtd4M|btf+XZZDJ5=}6c@9JY(g9J=kuv^>U7$cHcM~b zZ+$xFInR5}`#jHi&-=brRi(-bloco|P*$Lq z6halEyb3=cCh(qqEBsT{ad!{sOPH5MvJSfg+F&s>z&kL3A-D!-;Tf!iDV4#U1V2o9 zptBi!00!0%^`Lw_u0yQ2tySLuej9FrkCt+6{aqSUp=uW04agGQ03_K3@F*CSz}8vX6-i_rWg6b%Fu?Ry^G$uR8$xx-}B5pB;ZI+uafeSaXTqA!%nM)u;$qVvmv5a9 z;5A2bXRtl+?o?dMD&GN%RDrS7jKeu^p=PX$#vAwT@d#Yx3-}gV52>uG!8`}Ay8@~F zQ#}u}!k}xK=zVbKVp6tG;4qA~Q$69@{QeA&uNK_B;0<0wd+1-HO|=Rm2J?pg+{C$^ z{`fX@a0QQA@U8vp?R|2m1qasU7U>PbXFRPB~cC`3^d z$1(XVkp(H)OtP?$Y*?_cP!?=Rb{0OCB4H~QN(o8HN?8$>%0?m^N;VX-p;(Zj5c&H3 zr~7hyo@S`YOYhWg&bjBDd+)ht-n%mi314Lp*DJikI^;ry8SkTQNo4Q@%I&iPwU&Rx z@_%Qh5@>`?&{|iJ1CDfI$UosYqUjV8p5XQs-zLlxYa@hti`GR!2cH~5>$vCQcw zNgK?2B&%DB-5af(B#1?NNIHcj7=v5TS`82v3A3s;&_-#l9a>FH@kI!^;u`9kUWQ9( z0Y|1WG|y&%u^zLy$qp-P!zR}bdRg^?DyECU7QJ_Nv2Tn!tOONY1Z^+?H4t~{W(O6! z;<3}HiOpECZ0s%Le?;p7DS$thd@9h@tfJhvR|!5H@&=MY*XJI{cMiG~d?n89)$CE# zAwCse2hJgmu?xX>(o01ucFv=+DHFRe`UtIW(U($2RXT_|?Ur^Niird8?IEZw^87!c zb^BzNmw84x>bftV{hzdIgJk{p%KOPAKj!N9A?(M(f|`O31RV%E i5Og5uK+u8z(18ymm;N57p2}zd0000Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91GN1zh1ONa40RR91G5`Po0Cmf+s{jB19BD*PQ~&?~0ssI20000082|tP zC;$Ke82|tP82|tRcubKn-~a#uL`g(JRA>e4mS1R(Q5eTJTUbQ2WGKH(;)1IwmYNH0 zkPD(@ZY39FrM6O1a^c1WrCmtd4M|btf+XZZDJ5=}6c@9JY(g9J=kuv^>U7$cHcM~b zZ+$xFInR5}`#jHi&-=brRi(-bloco|P*$Lq z6halEyb3=cCh(qqEBsT{ad!{sOPH5MvJSfg+F&s>z&kL3A-D!-;Tf!iDV4#U1V2o9 zptBi!00!0%^`Lw_u0yQ2tySLuej9FrkCt+6{aqSUp=uW04agGQ03_K3@F*CSz}8vX6-i_rWg6b%Fu?Ry^G$uR8$xx-}B5pB;ZI+uafeSaXTqA!%nM)u;$qVvmv5a9 z;5A2bXRtl+?o?dMD&GN%RDrS7jKeu^p=PX$#vAwT@d#Yx3-}gV52>uG!8`}Ay8@~F zQ#}u}!k}xK=zVbKVp6tG;4qA~Q$69@{QeA&uNK_B;0<0wd+1-HO|=Rm2J?pg+{C$^ z{`fX@a0QQA@U8vp?R|2m1qasU7U>PbXFRPB~cC`3^d z$1(XVkp(H)OtP?$Y*?_cP!?=Rb{0OCB4H~QN(o8HN?8$>%0?m^N;VX-p;(Zj5c&H3 zr~7hyo@S`YOYhWg&bjBDd+)ht-n%mi314Lp*DJikI^;ry8SkTQNo4Q@%I&iPwU&Rx z@_%Qh5@>`?&{|iJ1CDfI$UosYqUjV8p5XQs-zLlxYa@hti`GR!2cH~5>$vCQcw zNgK?2B&%DB-5af(B#1?NNIHcj7=v5TS`82v3A3s;&_-#l9a>FH@kI!^;u`9kUWQ9( z0Y|1WG|y&%u^zLy$qp-P!zR}bdRg^?DyECU7QJ_Nv2Tn!tOONY1Z^+?H4t~{W(O6! z;<3}HiOpECZ0s%Le?;p7DS$thd@9h@tfJhvR|!5H@&=MY*XJI{cMiG~d?n89)$CE# zAwCse2hJgmu?xX>(o01ucFv=+DHFRe`UtIW(U($2RXT_|?Ur^Niird8?IEZw^87!c zb^BzNmw84x>bftV{hzdIgJk{p%KOPAKj!N9A?(M(f|`O31RV%E i5Og5uK+u8z(18ymm;N57p2}zd0000 null); final result = await sut.pick(); - expect(result, const Err(LoadImageFailure.userCancelled)); + expect(result, + const Err(LoadImageFailure.userCancelled)); verify(mockImagePicker.pickImage(source: anyNamed('source'))); verifyNoMoreInteractions(mockImagePicker); verifyZeroInteractions(mockMethodChannel); @@ -121,7 +121,8 @@ void main() { when(mockImagePicker.pickImage(source: anyNamed('source'))) .thenThrow(testException); final result = await sut.pick(); - expect(result, const Err(LoadImageFailure.unidentified)); + expect(result, + const Err(LoadImageFailure.unidentified)); verify(mockImagePicker.pickImage(source: anyNamed('source'))); verifyNoMoreInteractions(mockImagePicker); verifyZeroInteractions(mockMethodChannel); @@ -133,7 +134,8 @@ void main() { .thenAnswer((_) async => mockImageXFile); when(mockImageXFile.readAsBytes()).thenThrow(testException); final result = await sut.pick(); - expect(result, const Err(LoadImageFailure.unidentified)); + expect(result, + const Err(LoadImageFailure.unidentified)); verify(mockImagePicker.pickImage(source: anyNamed('source'))); verify(mockImageXFile.readAsBytes()); verifyNoMoreInteractions(mockImageXFile); @@ -148,7 +150,8 @@ void main() { when(mockImagePicker.pickImage(source: anyNamed('source'))) .thenThrow(testPlatformException); final result = await sut.pick(); - expect(result, const Err(LoadImageFailure.unidentified)); + expect(result, + const Err(LoadImageFailure.unidentified)); verify(mockImagePicker.pickImage(source: anyNamed('source'))); verifyNoMoreInteractions(mockImagePicker); verifyZeroInteractions(mockMethodChannel); diff --git a/packages/io_library/test/unit/service/photo_library_service_test.mocks.dart b/packages/io_library/test/unit/service/photo_library_service_test.mocks.dart new file mode 100644 index 00000000..5cc7a2d9 --- /dev/null +++ b/packages/io_library/test/unit/service/photo_library_service_test.mocks.dart @@ -0,0 +1,480 @@ +// Mocks generated by Mockito 5.4.2 from annotations +// in io_library/test/unit/service/photo_library_service_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i6; +import 'dart:convert' as _i8; +import 'dart:typed_data' as _i9; + +import 'package:flutter/src/services/binary_messenger.dart' as _i4; +import 'package:flutter/src/services/message_codec.dart' as _i3; +import 'package:flutter/src/services/platform_channel.dart' as _i7; +import 'package:image_picker/image_picker.dart' as _i5; +import 'package:image_picker_platform_interface/image_picker_platform_interface.dart' + as _i2; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeLostData_0 extends _i1.SmartFake implements _i2.LostData { + _FakeLostData_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeLostDataResponse_1 extends _i1.SmartFake + implements _i2.LostDataResponse { + _FakeLostDataResponse_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeMethodCodec_2 extends _i1.SmartFake implements _i3.MethodCodec { + _FakeMethodCodec_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeBinaryMessenger_3 extends _i1.SmartFake + implements _i4.BinaryMessenger { + _FakeBinaryMessenger_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeDateTime_4 extends _i1.SmartFake implements DateTime { + _FakeDateTime_4( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [ImagePicker]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockImagePicker extends _i1.Mock implements _i5.ImagePicker { + MockImagePicker() { + _i1.throwOnMissingStub(this); + } + + @override + _i6.Future<_i2.PickedFile?> getImage({ + required _i2.ImageSource? source, + double? maxWidth, + double? maxHeight, + int? imageQuality, + _i2.CameraDevice? preferredCameraDevice = _i2.CameraDevice.rear, + }) => + (super.noSuchMethod( + Invocation.method( + #getImage, + [], + { + #source: source, + #maxWidth: maxWidth, + #maxHeight: maxHeight, + #imageQuality: imageQuality, + #preferredCameraDevice: preferredCameraDevice, + }, + ), + returnValue: _i6.Future<_i2.PickedFile?>.value(), + ) as _i6.Future<_i2.PickedFile?>); + + @override + _i6.Future?> getMultiImage({ + double? maxWidth, + double? maxHeight, + int? imageQuality, + }) => + (super.noSuchMethod( + Invocation.method( + #getMultiImage, + [], + { + #maxWidth: maxWidth, + #maxHeight: maxHeight, + #imageQuality: imageQuality, + }, + ), + returnValue: _i6.Future?>.value(), + ) as _i6.Future?>); + + @override + _i6.Future<_i2.PickedFile?> getVideo({ + required _i2.ImageSource? source, + _i2.CameraDevice? preferredCameraDevice = _i2.CameraDevice.rear, + Duration? maxDuration, + }) => + (super.noSuchMethod( + Invocation.method( + #getVideo, + [], + { + #source: source, + #preferredCameraDevice: preferredCameraDevice, + #maxDuration: maxDuration, + }, + ), + returnValue: _i6.Future<_i2.PickedFile?>.value(), + ) as _i6.Future<_i2.PickedFile?>); + + @override + _i6.Future<_i2.LostData> getLostData() => (super.noSuchMethod( + Invocation.method( + #getLostData, + [], + ), + returnValue: _i6.Future<_i2.LostData>.value(_FakeLostData_0( + this, + Invocation.method( + #getLostData, + [], + ), + )), + ) as _i6.Future<_i2.LostData>); + + @override + _i6.Future<_i2.XFile?> pickImage({ + required _i2.ImageSource? source, + double? maxWidth, + double? maxHeight, + int? imageQuality, + _i2.CameraDevice? preferredCameraDevice = _i2.CameraDevice.rear, + bool? requestFullMetadata = true, + }) => + (super.noSuchMethod( + Invocation.method( + #pickImage, + [], + { + #source: source, + #maxWidth: maxWidth, + #maxHeight: maxHeight, + #imageQuality: imageQuality, + #preferredCameraDevice: preferredCameraDevice, + #requestFullMetadata: requestFullMetadata, + }, + ), + returnValue: _i6.Future<_i2.XFile?>.value(), + ) as _i6.Future<_i2.XFile?>); + + @override + _i6.Future> pickMultiImage({ + double? maxWidth, + double? maxHeight, + int? imageQuality, + bool? requestFullMetadata = true, + }) => + (super.noSuchMethod( + Invocation.method( + #pickMultiImage, + [], + { + #maxWidth: maxWidth, + #maxHeight: maxHeight, + #imageQuality: imageQuality, + #requestFullMetadata: requestFullMetadata, + }, + ), + returnValue: _i6.Future>.value(<_i2.XFile>[]), + ) as _i6.Future>); + + @override + _i6.Future<_i2.XFile?> pickMedia({ + double? maxWidth, + double? maxHeight, + int? imageQuality, + bool? requestFullMetadata = true, + }) => + (super.noSuchMethod( + Invocation.method( + #pickMedia, + [], + { + #maxWidth: maxWidth, + #maxHeight: maxHeight, + #imageQuality: imageQuality, + #requestFullMetadata: requestFullMetadata, + }, + ), + returnValue: _i6.Future<_i2.XFile?>.value(), + ) as _i6.Future<_i2.XFile?>); + + @override + _i6.Future> pickMultipleMedia({ + double? maxWidth, + double? maxHeight, + int? imageQuality, + bool? requestFullMetadata = true, + }) => + (super.noSuchMethod( + Invocation.method( + #pickMultipleMedia, + [], + { + #maxWidth: maxWidth, + #maxHeight: maxHeight, + #imageQuality: imageQuality, + #requestFullMetadata: requestFullMetadata, + }, + ), + returnValue: _i6.Future>.value(<_i2.XFile>[]), + ) as _i6.Future>); + + @override + _i6.Future<_i2.XFile?> pickVideo({ + required _i2.ImageSource? source, + _i2.CameraDevice? preferredCameraDevice = _i2.CameraDevice.rear, + Duration? maxDuration, + }) => + (super.noSuchMethod( + Invocation.method( + #pickVideo, + [], + { + #source: source, + #preferredCameraDevice: preferredCameraDevice, + #maxDuration: maxDuration, + }, + ), + returnValue: _i6.Future<_i2.XFile?>.value(), + ) as _i6.Future<_i2.XFile?>); + + @override + _i6.Future<_i2.LostDataResponse> retrieveLostData() => (super.noSuchMethod( + Invocation.method( + #retrieveLostData, + [], + ), + returnValue: + _i6.Future<_i2.LostDataResponse>.value(_FakeLostDataResponse_1( + this, + Invocation.method( + #retrieveLostData, + [], + ), + )), + ) as _i6.Future<_i2.LostDataResponse>); + + @override + bool supportsImageSource(_i2.ImageSource? source) => (super.noSuchMethod( + Invocation.method( + #supportsImageSource, + [source], + ), + returnValue: false, + ) as bool); +} + +/// A class which mocks [MethodChannel]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockMethodChannel extends _i1.Mock implements _i7.MethodChannel { + MockMethodChannel() { + _i1.throwOnMissingStub(this); + } + + @override + String get name => (super.noSuchMethod( + Invocation.getter(#name), + returnValue: '', + ) as String); + + @override + _i3.MethodCodec get codec => (super.noSuchMethod( + Invocation.getter(#codec), + returnValue: _FakeMethodCodec_2( + this, + Invocation.getter(#codec), + ), + ) as _i3.MethodCodec); + + @override + _i4.BinaryMessenger get binaryMessenger => (super.noSuchMethod( + Invocation.getter(#binaryMessenger), + returnValue: _FakeBinaryMessenger_3( + this, + Invocation.getter(#binaryMessenger), + ), + ) as _i4.BinaryMessenger); + + @override + _i6.Future invokeMethod( + String? method, [ + dynamic arguments, + ]) => + (super.noSuchMethod( + Invocation.method( + #invokeMethod, + [ + method, + arguments, + ], + ), + returnValue: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future?> invokeListMethod( + String? method, [ + dynamic arguments, + ]) => + (super.noSuchMethod( + Invocation.method( + #invokeListMethod, + [ + method, + arguments, + ], + ), + returnValue: _i6.Future?>.value(), + ) as _i6.Future?>); + + @override + _i6.Future?> invokeMapMethod( + String? method, [ + dynamic arguments, + ]) => + (super.noSuchMethod( + Invocation.method( + #invokeMapMethod, + [ + method, + arguments, + ], + ), + returnValue: _i6.Future?>.value(), + ) as _i6.Future?>); + + @override + void setMethodCallHandler( + _i6.Future Function(_i3.MethodCall)? handler) => + super.noSuchMethod( + Invocation.method( + #setMethodCallHandler, + [handler], + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [XFile]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockXFile extends _i1.Mock implements _i2.XFile { + MockXFile() { + _i1.throwOnMissingStub(this); + } + + @override + String get path => (super.noSuchMethod( + Invocation.getter(#path), + returnValue: '', + ) as String); + + @override + String get name => (super.noSuchMethod( + Invocation.getter(#name), + returnValue: '', + ) as String); + + @override + _i6.Future saveTo(String? path) => (super.noSuchMethod( + Invocation.method( + #saveTo, + [path], + ), + returnValue: _i6.Future.value(), + returnValueForMissingStub: _i6.Future.value(), + ) as _i6.Future); + + @override + _i6.Future length() => (super.noSuchMethod( + Invocation.method( + #length, + [], + ), + returnValue: _i6.Future.value(0), + ) as _i6.Future); + + @override + _i6.Future readAsString( + {_i8.Encoding? encoding = const _i8.Utf8Codec()}) => + (super.noSuchMethod( + Invocation.method( + #readAsString, + [], + {#encoding: encoding}, + ), + returnValue: _i6.Future.value(''), + ) as _i6.Future); + + @override + _i6.Future<_i9.Uint8List> readAsBytes() => (super.noSuchMethod( + Invocation.method( + #readAsBytes, + [], + ), + returnValue: _i6.Future<_i9.Uint8List>.value(_i9.Uint8List(0)), + ) as _i6.Future<_i9.Uint8List>); + + @override + _i6.Stream<_i9.Uint8List> openRead([ + int? start, + int? end, + ]) => + (super.noSuchMethod( + Invocation.method( + #openRead, + [ + start, + end, + ], + ), + returnValue: _i6.Stream<_i9.Uint8List>.empty(), + ) as _i6.Stream<_i9.Uint8List>); + + @override + _i6.Future lastModified() => (super.noSuchMethod( + Invocation.method( + #lastModified, + [], + ), + returnValue: _i6.Future.value(_FakeDateTime_4( + this, + Invocation.method( + #lastModified, + [], + ), + )), + ) as _i6.Future); +} diff --git a/test/unit/io/usecase/load_image_from_photo_library_test.dart b/packages/io_library/test/unit/usecase/load_image_from_photo_library_test.dart similarity index 97% rename from test/unit/io/usecase/load_image_from_photo_library_test.dart rename to packages/io_library/test/unit/usecase/load_image_from_photo_library_test.dart index 5a54dead..dea81939 100644 --- a/test/unit/io/usecase/load_image_from_photo_library_test.dart +++ b/packages/io_library/test/unit/usecase/load_image_from_photo_library_test.dart @@ -3,11 +3,10 @@ import 'dart:ui'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:io_library/io_library.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:oxidized/oxidized.dart'; -import 'package:paintroid/core/failure.dart'; -import 'package:paintroid/io/io.dart'; import 'load_image_from_photo_library_test.mocks.dart'; diff --git a/packages/io_library/test/unit/usecase/load_image_from_photo_library_test.mocks.dart b/packages/io_library/test/unit/usecase/load_image_from_photo_library_test.mocks.dart new file mode 100644 index 00000000..2793e86e --- /dev/null +++ b/packages/io_library/test/unit/usecase/load_image_from_photo_library_test.mocks.dart @@ -0,0 +1,211 @@ +// Mocks generated by Mockito 5.4.2 from annotations +// in io_library/test/unit/usecase/load_image_from_photo_library_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; +import 'dart:typed_data' as _i6; +import 'dart:ui' as _i5; + +import 'package:io_library/io_library.dart' as _i3; +import 'package:mockito/mockito.dart' as _i1; +import 'package:oxidized/oxidized.dart' as _i2; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeResult_0 extends _i1.SmartFake + implements _i2.Result { + _FakeResult_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [IImageService]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIImageService extends _i1.Mock implements _i3.IImageService { + MockIImageService() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future<_i2.Result<_i5.Image, _i3.Failure>> import( + _i6.Uint8List? fileData) => + (super.noSuchMethod( + Invocation.method( + #import, + [fileData], + ), + returnValue: _i4.Future<_i2.Result<_i5.Image, _i3.Failure>>.value( + _FakeResult_0<_i5.Image, _i3.Failure>( + this, + Invocation.method( + #import, + [fileData], + ), + )), + ) as _i4.Future<_i2.Result<_i5.Image, _i3.Failure>>); + + @override + _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>> exportAsJpg( + _i5.Image? image, + int? quality, + ) => + (super.noSuchMethod( + Invocation.method( + #exportAsJpg, + [ + image, + quality, + ], + ), + returnValue: _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>.value( + _FakeResult_0<_i6.Uint8List, _i3.Failure>( + this, + Invocation.method( + #exportAsJpg, + [ + image, + quality, + ], + ), + )), + ) as _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>); + + @override + _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>> exportAsPng( + _i5.Image? image) => + (super.noSuchMethod( + Invocation.method( + #exportAsPng, + [image], + ), + returnValue: _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>.value( + _FakeResult_0<_i6.Uint8List, _i3.Failure>( + this, + Invocation.method( + #exportAsPng, + [image], + ), + )), + ) as _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>); + + @override + _i2.Result<_i6.Uint8List, _i3.Failure> getProjectPreview(String? path) => + (super.noSuchMethod( + Invocation.method( + #getProjectPreview, + [path], + ), + returnValue: _FakeResult_0<_i6.Uint8List, _i3.Failure>( + this, + Invocation.method( + #getProjectPreview, + [path], + ), + ), + ) as _i2.Result<_i6.Uint8List, _i3.Failure>); +} + +/// A class which mocks [IPermissionService]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIPermissionService extends _i1.Mock + implements _i3.IPermissionService { + MockIPermissionService() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future requestAccessToPickPhotos() => (super.noSuchMethod( + Invocation.method( + #requestAccessToPickPhotos, + [], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future requestAccessForSavingToPhotos() => (super.noSuchMethod( + Invocation.method( + #requestAccessForSavingToPhotos, + [], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future requestAccessToSharedFileStorage() => (super.noSuchMethod( + Invocation.method( + #requestAccessToSharedFileStorage, + [], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); +} + +/// A class which mocks [IPhotoLibraryService]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIPhotoLibraryService extends _i1.Mock + implements _i3.IPhotoLibraryService { + MockIPhotoLibraryService() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future<_i2.Result<_i2.Unit, _i3.Failure>> save( + String? filename, + _i6.Uint8List? data, + ) => + (super.noSuchMethod( + Invocation.method( + #save, + [ + filename, + data, + ], + ), + returnValue: _i4.Future<_i2.Result<_i2.Unit, _i3.Failure>>.value( + _FakeResult_0<_i2.Unit, _i3.Failure>( + this, + Invocation.method( + #save, + [ + filename, + data, + ], + ), + )), + ) as _i4.Future<_i2.Result<_i2.Unit, _i3.Failure>>); + + @override + _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>> pick() => + (super.noSuchMethod( + Invocation.method( + #pick, + [], + ), + returnValue: _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>.value( + _FakeResult_0<_i6.Uint8List, _i3.Failure>( + this, + Invocation.method( + #pick, + [], + ), + )), + ) as _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>); +} diff --git a/test/unit/io/usecase/save_as_raster_image_test.dart b/packages/io_library/test/unit/usecase/save_as_raster_image_test.dart similarity index 97% rename from test/unit/io/usecase/save_as_raster_image_test.dart rename to packages/io_library/test/unit/usecase/save_as_raster_image_test.dart index 78a68dda..2fb49a39 100644 --- a/test/unit/io/usecase/save_as_raster_image_test.dart +++ b/packages/io_library/test/unit/usecase/save_as_raster_image_test.dart @@ -3,11 +3,10 @@ import 'dart:ui'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:io_library/io_library.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:oxidized/oxidized.dart'; -import 'package:paintroid/core/failure.dart'; -import 'package:paintroid/io/io.dart'; import 'save_as_raster_image_test.mocks.dart'; @@ -183,7 +182,8 @@ void main() { .thenAnswer((_) async => false); final testMetaData = JpgMetaData(testName, testQuality); final result = await sut(testMetaData, fakeImage); - expect(result, const Err(SaveImageFailure.permissionDenied)); + expect(result, + const Err(SaveImageFailure.permissionDenied)); verify(mockPermissionService.requestAccessForSavingToPhotos()); verifyNoMoreInteractions(mockPermissionService); verifyZeroInteractions(mockImageService); @@ -195,7 +195,8 @@ void main() { .thenAnswer((_) async => false); final testMetaData = PngMetaData(testName); final result = await sut(testMetaData, fakeImage); - expect(result, const Err(SaveImageFailure.permissionDenied)); + expect(result, + const Err(SaveImageFailure.permissionDenied)); verify(mockPermissionService.requestAccessForSavingToPhotos()); verifyNoMoreInteractions(mockPermissionService); verifyZeroInteractions(mockImageService); diff --git a/packages/io_library/test/unit/usecase/save_as_raster_image_test.mocks.dart b/packages/io_library/test/unit/usecase/save_as_raster_image_test.mocks.dart new file mode 100644 index 00000000..9916e150 --- /dev/null +++ b/packages/io_library/test/unit/usecase/save_as_raster_image_test.mocks.dart @@ -0,0 +1,333 @@ +// Mocks generated by Mockito 5.4.2 from annotations +// in io_library/test/unit/usecase/save_as_raster_image_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; +import 'dart:io' as _i7; +import 'dart:typed_data' as _i6; +import 'dart:ui' as _i5; + +import 'package:io_library/io_library.dart' as _i3; +import 'package:mockito/mockito.dart' as _i1; +import 'package:oxidized/oxidized.dart' as _i2; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeResult_0 extends _i1.SmartFake + implements _i2.Result { + _FakeResult_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [IImageService]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIImageService extends _i1.Mock implements _i3.IImageService { + MockIImageService() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future<_i2.Result<_i5.Image, _i3.Failure>> import( + _i6.Uint8List? fileData) => + (super.noSuchMethod( + Invocation.method( + #import, + [fileData], + ), + returnValue: _i4.Future<_i2.Result<_i5.Image, _i3.Failure>>.value( + _FakeResult_0<_i5.Image, _i3.Failure>( + this, + Invocation.method( + #import, + [fileData], + ), + )), + ) as _i4.Future<_i2.Result<_i5.Image, _i3.Failure>>); + + @override + _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>> exportAsJpg( + _i5.Image? image, + int? quality, + ) => + (super.noSuchMethod( + Invocation.method( + #exportAsJpg, + [ + image, + quality, + ], + ), + returnValue: _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>.value( + _FakeResult_0<_i6.Uint8List, _i3.Failure>( + this, + Invocation.method( + #exportAsJpg, + [ + image, + quality, + ], + ), + )), + ) as _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>); + + @override + _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>> exportAsPng( + _i5.Image? image) => + (super.noSuchMethod( + Invocation.method( + #exportAsPng, + [image], + ), + returnValue: _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>.value( + _FakeResult_0<_i6.Uint8List, _i3.Failure>( + this, + Invocation.method( + #exportAsPng, + [image], + ), + )), + ) as _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>); + + @override + _i2.Result<_i6.Uint8List, _i3.Failure> getProjectPreview(String? path) => + (super.noSuchMethod( + Invocation.method( + #getProjectPreview, + [path], + ), + returnValue: _FakeResult_0<_i6.Uint8List, _i3.Failure>( + this, + Invocation.method( + #getProjectPreview, + [path], + ), + ), + ) as _i2.Result<_i6.Uint8List, _i3.Failure>); +} + +/// A class which mocks [IPhotoLibraryService]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIPhotoLibraryService extends _i1.Mock + implements _i3.IPhotoLibraryService { + MockIPhotoLibraryService() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future<_i2.Result<_i2.Unit, _i3.Failure>> save( + String? filename, + _i6.Uint8List? data, + ) => + (super.noSuchMethod( + Invocation.method( + #save, + [ + filename, + data, + ], + ), + returnValue: _i4.Future<_i2.Result<_i2.Unit, _i3.Failure>>.value( + _FakeResult_0<_i2.Unit, _i3.Failure>( + this, + Invocation.method( + #save, + [ + filename, + data, + ], + ), + )), + ) as _i4.Future<_i2.Result<_i2.Unit, _i3.Failure>>); + + @override + _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>> pick() => + (super.noSuchMethod( + Invocation.method( + #pick, + [], + ), + returnValue: _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>.value( + _FakeResult_0<_i6.Uint8List, _i3.Failure>( + this, + Invocation.method( + #pick, + [], + ), + )), + ) as _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>); +} + +/// A class which mocks [IFileService]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIFileService extends _i1.Mock implements _i3.IFileService { + MockIFileService() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future<_i2.Result<_i7.File, _i3.Failure>> save( + String? filename, + _i6.Uint8List? data, + ) => + (super.noSuchMethod( + Invocation.method( + #save, + [ + filename, + data, + ], + ), + returnValue: _i4.Future<_i2.Result<_i7.File, _i3.Failure>>.value( + _FakeResult_0<_i7.File, _i3.Failure>( + this, + Invocation.method( + #save, + [ + filename, + data, + ], + ), + )), + ) as _i4.Future<_i2.Result<_i7.File, _i3.Failure>>); + + @override + _i4.Future<_i2.Result<_i7.File, _i3.Failure>> saveToApplicationDirectory( + String? filename, + _i6.Uint8List? data, + ) => + (super.noSuchMethod( + Invocation.method( + #saveToApplicationDirectory, + [ + filename, + data, + ], + ), + returnValue: _i4.Future<_i2.Result<_i7.File, _i3.Failure>>.value( + _FakeResult_0<_i7.File, _i3.Failure>( + this, + Invocation.method( + #saveToApplicationDirectory, + [ + filename, + data, + ], + ), + )), + ) as _i4.Future<_i2.Result<_i7.File, _i3.Failure>>); + + @override + _i4.Future<_i2.Result<_i7.File, _i3.Failure>> pick() => (super.noSuchMethod( + Invocation.method( + #pick, + [], + ), + returnValue: _i4.Future<_i2.Result<_i7.File, _i3.Failure>>.value( + _FakeResult_0<_i7.File, _i3.Failure>( + this, + Invocation.method( + #pick, + [], + ), + )), + ) as _i4.Future<_i2.Result<_i7.File, _i3.Failure>>); + + @override + _i2.Result<_i7.File, _i3.Failure> getFile(String? path) => + (super.noSuchMethod( + Invocation.method( + #getFile, + [path], + ), + returnValue: _FakeResult_0<_i7.File, _i3.Failure>( + this, + Invocation.method( + #getFile, + [path], + ), + ), + ) as _i2.Result<_i7.File, _i3.Failure>); + + @override + _i4.Future checkIfFileExistsInApplicationDirectory(String? fileName) => + (super.noSuchMethod( + Invocation.method( + #checkIfFileExistsInApplicationDirectory, + [fileName], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future<_i2.Result<_i7.FileSystemEntity, _i3.Failure>> + deleteFileInApplicationDirectory(String? fileName) => (super.noSuchMethod( + Invocation.method( + #deleteFileInApplicationDirectory, + [fileName], + ), + returnValue: + _i4.Future<_i2.Result<_i7.FileSystemEntity, _i3.Failure>>.value( + _FakeResult_0<_i7.FileSystemEntity, _i3.Failure>( + this, + Invocation.method( + #deleteFileInApplicationDirectory, + [fileName], + ), + )), + ) as _i4.Future<_i2.Result<_i7.FileSystemEntity, _i3.Failure>>); +} + +/// A class which mocks [IPermissionService]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIPermissionService extends _i1.Mock + implements _i3.IPermissionService { + MockIPermissionService() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.Future requestAccessToPickPhotos() => (super.noSuchMethod( + Invocation.method( + #requestAccessToPickPhotos, + [], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future requestAccessForSavingToPhotos() => (super.noSuchMethod( + Invocation.method( + #requestAccessForSavingToPhotos, + [], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); + + @override + _i4.Future requestAccessToSharedFileStorage() => (super.noSuchMethod( + Invocation.method( + #requestAccessToSharedFileStorage, + [], + ), + returnValue: _i4.Future.value(false), + ) as _i4.Future); +} diff --git a/packages/l10n/.metadata b/packages/l10n/.metadata new file mode 100644 index 00000000..9596faee --- /dev/null +++ b/packages/l10n/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 796c8ef79279f9c774545b3771238c3098dbefab + channel: stable + +project_type: package diff --git a/packages/l10n/analysis_options.yaml b/packages/l10n/analysis_options.yaml new file mode 100644 index 00000000..068a0a7e --- /dev/null +++ b/packages/l10n/analysis_options.yaml @@ -0,0 +1,25 @@ +include: package:flutter_lints/flutter.yaml +linter: + rules: + always_use_package_imports: true + avoid_relative_lib_imports: true + prefer_relative_imports: false + prefer_single_quotes: true + avoid_void_async: true + constant_identifier_names: false + +analyzer: + errors: + missing_enum_constant_in_switch: error + exhaustive_cases: error + unused_element: error + type_annotate_public_apis: error + missing_required_param: error + invalid_use_of_protected_member: error + unused_import: error + + exclude: + - lib/src/**.pb*.dart + - lib/src/data/*.g.dart + - lib/src/l10n/app_localizations.dart + - lib/src/l10n/app_localizations_en.dart diff --git a/packages/l10n/l10n.yaml b/packages/l10n/l10n.yaml new file mode 100644 index 00000000..160abcd7 --- /dev/null +++ b/packages/l10n/l10n.yaml @@ -0,0 +1,6 @@ +arb-dir: lib/src/l10n +template-arb-file: app_translations_en.arb +output-localization-file: app_localizations.dart +output-class: AppLocalizations +synthetic-package: false +nullable-getter: false diff --git a/packages/l10n/lib/l10n.dart b/packages/l10n/lib/l10n.dart new file mode 100644 index 00000000..5ef74664 --- /dev/null +++ b/packages/l10n/lib/l10n.dart @@ -0,0 +1,4 @@ +library l10n; + +export 'src/l10n/app_localizations.dart'; +export 'src/l10n/app_localizations_en.dart'; diff --git a/packages/l10n/lib/src/l10n/app_localizations.dart b/packages/l10n/lib/src/l10n/app_localizations.dart new file mode 100644 index 00000000..1fecd5db --- /dev/null +++ b/packages/l10n/lib/src/l10n/app_localizations.dart @@ -0,0 +1,178 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:intl/intl.dart' as intl; + +import 'app_localizations_en.dart'; + +/// Callers can lookup localized strings with an instance of AppLocalizations +/// returned by `AppLocalizations.of(context)`. +/// +/// Applications need to include `AppLocalizations.delegate()` in their app's +/// `localizationDelegates` list, and the locales they support in the app's +/// `supportedLocales` list. For example: +/// +/// ```dart +/// import 'l10n/app_localizations.dart'; +/// +/// return MaterialApp( +/// localizationsDelegates: AppLocalizations.localizationsDelegates, +/// supportedLocales: AppLocalizations.supportedLocales, +/// home: MyApplicationHome(), +/// ); +/// ``` +/// +/// ## Update pubspec.yaml +/// +/// Please make sure to update your pubspec.yaml to include the following +/// packages: +/// +/// ```yaml +/// dependencies: +/// # Internationalization support. +/// flutter_localizations: +/// sdk: flutter +/// intl: any # Use the pinned version from flutter_localizations +/// +/// # Rest of dependencies +/// ``` +/// +/// ## iOS Applications +/// +/// iOS applications define key application metadata, including supported +/// locales, in an Info.plist file that is built into the application bundle. +/// To configure the locales supported by your app, you’ll need to edit this +/// file. +/// +/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file. +/// Then, in the Project Navigator, open the Info.plist file under the Runner +/// project’s Runner folder. +/// +/// Next, select the Information Property List item, select Add Item from the +/// Editor menu, then select Localizations from the pop-up menu. +/// +/// Select and expand the newly-created Localizations item then, for each +/// locale your application supports, add a new item and select the locale +/// you wish to add from the pop-up menu in the Value field. This list should +/// be consistent with the languages listed in the AppLocalizations.supportedLocales +/// property. +abstract class AppLocalizations { + AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString()); + + final String localeName; + + static AppLocalizations of(BuildContext context) { + return Localizations.of(context, AppLocalizations)!; + } + + static const LocalizationsDelegate delegate = _AppLocalizationsDelegate(); + + /// A list of this localizations delegate along with the default localizations + /// delegates. + /// + /// Returns a list of localizations delegates containing this delegate along with + /// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, + /// and GlobalWidgetsLocalizations.delegate. + /// + /// Additional delegates can be added by appending to this list in + /// MaterialApp. This list does not have to be used at all if a custom list + /// of delegates is preferred or required. + static const List> localizationsDelegates = >[ + delegate, + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ]; + + /// A list of this localizations delegate's supported locales. + static const List supportedLocales = [ + Locale('en') + ]; + + /// No description provided for @fullscreen. + /// + /// In en, this message translates to: + /// **'Fullscreen'** + String get fullscreen; + + /// No description provided for @saveImage. + /// + /// In en, this message translates to: + /// **'Save image'** + String get saveImage; + + /// No description provided for @loadImage. + /// + /// In en, this message translates to: + /// **'Load image'** + String get loadImage; + + /// No description provided for @newImage. + /// + /// In en, this message translates to: + /// **'New image'** + String get newImage; + + /// No description provided for @saveProject. + /// + /// In en, this message translates to: + /// **'Save project'** + String get saveProject; + + /// No description provided for @tools. + /// + /// In en, this message translates to: + /// **'Tools'** + String get tools; + + /// No description provided for @brush. + /// + /// In en, this message translates to: + /// **'Brush'** + String get brush; + + /// No description provided for @color. + /// + /// In en, this message translates to: + /// **'Color'** + String get color; + + /// No description provided for @layers. + /// + /// In en, this message translates to: + /// **'Layers'** + String get layers; +} + +class _AppLocalizationsDelegate extends LocalizationsDelegate { + const _AppLocalizationsDelegate(); + + @override + Future load(Locale locale) { + return SynchronousFuture(lookupAppLocalizations(locale)); + } + + @override + bool isSupported(Locale locale) => ['en'].contains(locale.languageCode); + + @override + bool shouldReload(_AppLocalizationsDelegate old) => false; +} + +AppLocalizations lookupAppLocalizations(Locale locale) { + + + // Lookup logic when only language code is specified. + switch (locale.languageCode) { + case 'en': return AppLocalizationsEn(); + } + + throw FlutterError( + 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.' + ); +} diff --git a/packages/l10n/lib/src/l10n/app_localizations_en.dart b/packages/l10n/lib/src/l10n/app_localizations_en.dart new file mode 100644 index 00000000..3d07e5cc --- /dev/null +++ b/packages/l10n/lib/src/l10n/app_localizations_en.dart @@ -0,0 +1,33 @@ +import 'app_localizations.dart'; + +/// The translations for English (`en`). +class AppLocalizationsEn extends AppLocalizations { + AppLocalizationsEn([String locale = 'en']) : super(locale); + + @override + String get fullscreen => 'Fullscreen'; + + @override + String get saveImage => 'Save image'; + + @override + String get loadImage => 'Load image'; + + @override + String get newImage => 'New image'; + + @override + String get saveProject => 'Save project'; + + @override + String get tools => 'Tools'; + + @override + String get brush => 'Brush'; + + @override + String get color => 'Color'; + + @override + String get layers => 'Layers'; +} diff --git a/assets/l10n/en.arb b/packages/l10n/lib/src/l10n/app_translations_en.arb similarity index 100% rename from assets/l10n/en.arb rename to packages/l10n/lib/src/l10n/app_translations_en.arb diff --git a/packages/l10n/pubspec.yaml b/packages/l10n/pubspec.yaml new file mode 100644 index 00000000..3510cdb1 --- /dev/null +++ b/packages/l10n/pubspec.yaml @@ -0,0 +1,26 @@ +name: l10n +description: A new Flutter package project. +version: 0.0.1 +publish_to: "none" + +environment: + sdk: ">=3.0.5 <4.0.0" + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + + flutter_localization: ^0.1.12 + intl: ^0.18.0 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^2.0.0 + + build_runner: ^2.2.0 + +flutter: diff --git a/packages/tools/.metadata b/packages/tools/.metadata new file mode 100644 index 00000000..9596faee --- /dev/null +++ b/packages/tools/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 796c8ef79279f9c774545b3771238c3098dbefab + channel: stable + +project_type: package diff --git a/packages/tools/analysis_options.yaml b/packages/tools/analysis_options.yaml new file mode 100644 index 00000000..1ee68bd9 --- /dev/null +++ b/packages/tools/analysis_options.yaml @@ -0,0 +1,23 @@ +include: package:flutter_lints/flutter.yaml +linter: + rules: + always_use_package_imports: true + avoid_relative_lib_imports: true + prefer_relative_imports: false + prefer_single_quotes: true + avoid_void_async: true + constant_identifier_names: false + +analyzer: + errors: + missing_enum_constant_in_switch: error + exhaustive_cases: error + unused_element: error + type_annotate_public_apis: error + missing_required_param: error + invalid_use_of_protected_member: error + unused_import: error + + exclude: + - lib/src/**.pb*.dart + - lib/src/data/*.g.dart diff --git a/lib/tool/src/brush_tool/brush_tool.dart b/packages/tools/lib/src/brush_tool/brush_tool.dart similarity index 82% rename from lib/tool/src/brush_tool/brush_tool.dart rename to packages/tools/lib/src/brush_tool/brush_tool.dart index 983dc824..440a683e 100644 --- a/lib/tool/src/brush_tool/brush_tool.dart +++ b/packages/tools/lib/src/brush_tool/brush_tool.dart @@ -1,13 +1,10 @@ import 'dart:ui'; +import 'package:command/command.dart'; +import 'package:component_library/component_library.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart'; -import 'package:paintroid/command/src/command_factory.dart'; -import 'package:paintroid/command/src/command_manager.dart'; -import 'package:paintroid/core/graphic_factory.dart'; -import 'package:paintroid/core/path_with_action_history.dart'; -import 'package:paintroid/tool/src/tool.dart'; -import 'package:paintroid/tool/src/tool_types.dart'; +import 'package:tools/tools.dart'; class BrushTool extends Tool with EquatableMixin { BrushTool({ diff --git a/lib/tool/src/brush_tool/brush_tool_provider.dart b/packages/tools/lib/src/brush_tool/brush_tool_provider.dart similarity index 52% rename from lib/tool/src/brush_tool/brush_tool_provider.dart rename to packages/tools/lib/src/brush_tool/brush_tool_provider.dart index aad06315..863f528a 100644 --- a/lib/tool/src/brush_tool/brush_tool_provider.dart +++ b/packages/tools/lib/src/brush_tool/brush_tool_provider.dart @@ -1,10 +1,7 @@ -import 'package:paintroid/command/src/command_factory_provider.dart'; -import 'package:paintroid/command/src/command_manager_provider.dart'; -import 'package:paintroid/core/graphic_factory_provider.dart'; -import 'package:paintroid/tool/src/brush_tool/brush_tool.dart'; -import 'package:paintroid/tool/src/brush_tool/brush_tool_state_provider.dart'; -import 'package:paintroid/tool/src/tool_types.dart'; +import 'package:component_library/component_library.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:tools/tools.dart'; +import 'package:command/command_providers.dart'; part 'brush_tool_provider.g.dart'; diff --git a/packages/tools/lib/src/brush_tool/brush_tool_provider.g.dart b/packages/tools/lib/src/brush_tool/brush_tool_provider.g.dart new file mode 100644 index 00000000..b08cd4a0 --- /dev/null +++ b/packages/tools/lib/src/brush_tool/brush_tool_provider.g.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'brush_tool_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$brushToolHash() => r'dfa4f2e7a9cb8734828ec99dd983c7904c231e46'; + +/// See also [brushTool]. +@ProviderFor(brushTool) +final brushToolProvider = AutoDisposeProvider.internal( + brushTool, + name: r'brushToolProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') ? null : _$brushToolHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef BrushToolRef = AutoDisposeProviderRef; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/lib/tool/src/brush_tool/brush_tool_state_data.dart b/packages/tools/lib/src/brush_tool/brush_tool_state_data.dart similarity index 100% rename from lib/tool/src/brush_tool/brush_tool_state_data.dart rename to packages/tools/lib/src/brush_tool/brush_tool_state_data.dart diff --git a/packages/tools/lib/src/brush_tool/brush_tool_state_data.freezed.dart b/packages/tools/lib/src/brush_tool/brush_tool_state_data.freezed.dart new file mode 100644 index 00000000..f48b047f --- /dev/null +++ b/packages/tools/lib/src/brush_tool/brush_tool_state_data.freezed.dart @@ -0,0 +1,134 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'brush_tool_state_data.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + +/// @nodoc +mixin _$BrushToolStateData { + Paint get paint => throw _privateConstructorUsedError; + + @JsonKey(ignore: true) + $BrushToolStateDataCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $BrushToolStateDataCopyWith<$Res> { + factory $BrushToolStateDataCopyWith( + BrushToolStateData value, $Res Function(BrushToolStateData) then) = + _$BrushToolStateDataCopyWithImpl<$Res, BrushToolStateData>; + @useResult + $Res call({Paint paint}); +} + +/// @nodoc +class _$BrushToolStateDataCopyWithImpl<$Res, $Val extends BrushToolStateData> + implements $BrushToolStateDataCopyWith<$Res> { + _$BrushToolStateDataCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? paint = null, + }) { + return _then(_value.copyWith( + paint: null == paint + ? _value.paint + : paint // ignore: cast_nullable_to_non_nullable + as Paint, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$_BrushToolStateDataCopyWith<$Res> + implements $BrushToolStateDataCopyWith<$Res> { + factory _$$_BrushToolStateDataCopyWith(_$_BrushToolStateData value, + $Res Function(_$_BrushToolStateData) then) = + __$$_BrushToolStateDataCopyWithImpl<$Res>; + @override + @useResult + $Res call({Paint paint}); +} + +/// @nodoc +class __$$_BrushToolStateDataCopyWithImpl<$Res> + extends _$BrushToolStateDataCopyWithImpl<$Res, _$_BrushToolStateData> + implements _$$_BrushToolStateDataCopyWith<$Res> { + __$$_BrushToolStateDataCopyWithImpl( + _$_BrushToolStateData _value, $Res Function(_$_BrushToolStateData) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? paint = null, + }) { + return _then(_$_BrushToolStateData( + paint: null == paint + ? _value.paint + : paint // ignore: cast_nullable_to_non_nullable + as Paint, + )); + } +} + +/// @nodoc + +class _$_BrushToolStateData implements _BrushToolStateData { + const _$_BrushToolStateData({required this.paint}); + + @override + final Paint paint; + + @override + String toString() { + return 'BrushToolStateData(paint: $paint)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_BrushToolStateData && + (identical(other.paint, paint) || other.paint == paint)); + } + + @override + int get hashCode => Object.hash(runtimeType, paint); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$_BrushToolStateDataCopyWith<_$_BrushToolStateData> get copyWith => + __$$_BrushToolStateDataCopyWithImpl<_$_BrushToolStateData>( + this, _$identity); +} + +abstract class _BrushToolStateData implements BrushToolStateData { + const factory _BrushToolStateData({required final Paint paint}) = + _$_BrushToolStateData; + + @override + Paint get paint; + @override + @JsonKey(ignore: true) + _$$_BrushToolStateDataCopyWith<_$_BrushToolStateData> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/tool/src/brush_tool/brush_tool_state_provider.dart b/packages/tools/lib/src/brush_tool/brush_tool_state_provider.dart similarity index 89% rename from lib/tool/src/brush_tool/brush_tool_state_provider.dart rename to packages/tools/lib/src/brush_tool/brush_tool_state_provider.dart index dd3c224f..228146d5 100644 --- a/lib/tool/src/brush_tool/brush_tool_state_provider.dart +++ b/packages/tools/lib/src/brush_tool/brush_tool_state_provider.dart @@ -1,8 +1,8 @@ import 'dart:ui'; -import 'package:paintroid/core/graphic_factory_provider.dart'; -import 'package:paintroid/tool/src/brush_tool/brush_tool_state_data.dart'; +import 'package:component_library/component_library.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:tools/tools.dart'; part 'brush_tool_state_provider.g.dart'; diff --git a/packages/tools/lib/src/brush_tool/brush_tool_state_provider.g.dart b/packages/tools/lib/src/brush_tool/brush_tool_state_provider.g.dart new file mode 100644 index 00000000..4bffdbde --- /dev/null +++ b/packages/tools/lib/src/brush_tool/brush_tool_state_provider.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'brush_tool_state_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$brushToolStateHash() => r'1dbb16d53ddafba863e739874849eb790b4db667'; + +/// See also [BrushToolState]. +@ProviderFor(BrushToolState) +final brushToolStateProvider = + AutoDisposeNotifierProvider.internal( + BrushToolState.new, + name: r'brushToolStateProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$brushToolStateHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef _$BrushToolState = AutoDisposeNotifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/lib/tool/src/tool_types.dart b/packages/tools/lib/src/enums/tool_types.dart similarity index 100% rename from lib/tool/src/tool_types.dart rename to packages/tools/lib/src/enums/tool_types.dart diff --git a/lib/tool/src/eraser_tool/eraser_tool_provider.dart b/packages/tools/lib/src/eraser_tool/eraser_tool_provider.dart similarity index 52% rename from lib/tool/src/eraser_tool/eraser_tool_provider.dart rename to packages/tools/lib/src/eraser_tool/eraser_tool_provider.dart index 434e2cf3..9d6221ab 100644 --- a/lib/tool/src/eraser_tool/eraser_tool_provider.dart +++ b/packages/tools/lib/src/eraser_tool/eraser_tool_provider.dart @@ -1,10 +1,7 @@ -import 'package:paintroid/command/src/command_factory_provider.dart'; -import 'package:paintroid/command/src/command_manager_provider.dart'; -import 'package:paintroid/core/graphic_factory_provider.dart'; -import 'package:paintroid/tool/src/brush_tool/brush_tool.dart'; -import 'package:paintroid/tool/src/brush_tool/brush_tool_state_provider.dart'; -import 'package:paintroid/tool/src/tool_types.dart'; +import 'package:component_library/component_library.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:tools/tools.dart'; +import 'package:command/command_providers.dart'; part 'eraser_tool_provider.g.dart'; diff --git a/packages/tools/lib/src/eraser_tool/eraser_tool_provider.g.dart b/packages/tools/lib/src/eraser_tool/eraser_tool_provider.g.dart new file mode 100644 index 00000000..6de891a9 --- /dev/null +++ b/packages/tools/lib/src/eraser_tool/eraser_tool_provider.g.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'eraser_tool_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$eraserToolHash() => r'a92e9502cc061e5298bc9c8a20fcb30f8759e1e4'; + +/// See also [eraserTool]. +@ProviderFor(eraserTool) +final eraserToolProvider = AutoDisposeProvider.internal( + eraserTool, + name: r'eraserToolProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') ? null : _$eraserToolHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef EraserToolRef = AutoDisposeProviderRef; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/lib/tool/src/hand_tool/hand_tool.dart b/packages/tools/lib/src/hand_tool/hand_tool.dart similarity index 76% rename from lib/tool/src/hand_tool/hand_tool.dart rename to packages/tools/lib/src/hand_tool/hand_tool.dart index cd60dad9..ad845b39 100644 --- a/lib/tool/src/hand_tool/hand_tool.dart +++ b/packages/tools/lib/src/hand_tool/hand_tool.dart @@ -1,11 +1,9 @@ import 'dart:ui'; +import 'package:command/command.dart'; +import 'package:component_library/component_library.dart'; import 'package:equatable/equatable.dart'; -import 'package:paintroid/command/src/command_factory.dart'; -import 'package:paintroid/command/src/command_manager.dart'; -import 'package:paintroid/core/graphic_factory.dart'; -import 'package:paintroid/tool/src/tool.dart'; -import 'package:paintroid/tool/src/tool_types.dart'; +import 'package:tools/tools.dart'; class HandTool extends Tool with EquatableMixin { HandTool({ diff --git a/lib/tool/src/hand_tool/hand_tool_provider.dart b/packages/tools/lib/src/hand_tool/hand_tool_provider.dart similarity index 53% rename from lib/tool/src/hand_tool/hand_tool_provider.dart rename to packages/tools/lib/src/hand_tool/hand_tool_provider.dart index fc3e5ed2..334d58e9 100644 --- a/lib/tool/src/hand_tool/hand_tool_provider.dart +++ b/packages/tools/lib/src/hand_tool/hand_tool_provider.dart @@ -1,9 +1,6 @@ -import 'package:paintroid/command/src/command_factory_provider.dart'; -import 'package:paintroid/command/src/command_manager_provider.dart'; -import 'package:paintroid/tool/src/brush_tool/brush_tool_state_provider.dart'; -import 'package:paintroid/tool/src/hand_tool/hand_tool.dart'; -import 'package:paintroid/tool/src/tool_types.dart'; +import 'package:command/command_providers.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:tools/tools.dart'; part 'hand_tool_provider.g.dart'; diff --git a/packages/tools/lib/src/hand_tool/hand_tool_provider.g.dart b/packages/tools/lib/src/hand_tool/hand_tool_provider.g.dart new file mode 100644 index 00000000..9788d25b --- /dev/null +++ b/packages/tools/lib/src/hand_tool/hand_tool_provider.g.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'hand_tool_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$handToolHash() => r'693afd99b7c1ad8fb5857ebf4c75d1482f0facc5'; + +/// See also [handTool]. +@ProviderFor(handTool) +final handToolProvider = AutoDisposeProvider.internal( + handTool, + name: r'handToolProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') ? null : _$handToolHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef HandToolRef = AutoDisposeProviderRef; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/lib/tool/src/tool.dart b/packages/tools/lib/src/tool.dart similarity index 80% rename from lib/tool/src/tool.dart rename to packages/tools/lib/src/tool.dart index 9a4bdd76..78ac0831 100644 --- a/lib/tool/src/tool.dart +++ b/packages/tools/lib/src/tool.dart @@ -1,7 +1,7 @@ import 'dart:ui'; -import 'package:paintroid/command/command.dart'; -import 'package:paintroid/tool/src/tool_types.dart'; +import 'package:command/command.dart'; +import 'package:tools/src/enums/tool_types.dart'; abstract class Tool { const Tool({ diff --git a/lib/tool/src/tool_data.dart b/packages/tools/lib/src/tool_data.dart similarity index 97% rename from lib/tool/src/tool_data.dart rename to packages/tools/lib/src/tool_data.dart index 968809e0..bb0a161e 100644 --- a/lib/tool/src/tool_data.dart +++ b/packages/tools/lib/src/tool_data.dart @@ -1,4 +1,4 @@ -import 'package:paintroid/tool/src/tool_types.dart'; +import 'package:tools/src/enums/tool_types.dart'; class ToolData { final String name; diff --git a/lib/tool/src/toolbox/toolbox_state_data.dart b/packages/tools/lib/src/toolbox/toolbox_state_data.dart similarity index 88% rename from lib/tool/src/toolbox/toolbox_state_data.dart rename to packages/tools/lib/src/toolbox/toolbox_state_data.dart index 9833c65b..6d0719de 100644 --- a/lib/tool/src/toolbox/toolbox_state_data.dart +++ b/packages/tools/lib/src/toolbox/toolbox_state_data.dart @@ -1,5 +1,5 @@ import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:paintroid/tool/tool.dart'; +import 'package:tools/tools.dart'; part 'toolbox_state_data.freezed.dart'; diff --git a/packages/tools/lib/src/toolbox/toolbox_state_data.freezed.dart b/packages/tools/lib/src/toolbox/toolbox_state_data.freezed.dart new file mode 100644 index 00000000..a7c007ad --- /dev/null +++ b/packages/tools/lib/src/toolbox/toolbox_state_data.freezed.dart @@ -0,0 +1,173 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'toolbox_state_data.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + +/// @nodoc +mixin _$ToolBoxStateData { + Tool get currentTool => throw _privateConstructorUsedError; + ToolType get currentToolType => throw _privateConstructorUsedError; + bool get isDown => throw _privateConstructorUsedError; + + @JsonKey(ignore: true) + $ToolBoxStateDataCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ToolBoxStateDataCopyWith<$Res> { + factory $ToolBoxStateDataCopyWith( + ToolBoxStateData value, $Res Function(ToolBoxStateData) then) = + _$ToolBoxStateDataCopyWithImpl<$Res, ToolBoxStateData>; + @useResult + $Res call({Tool currentTool, ToolType currentToolType, bool isDown}); +} + +/// @nodoc +class _$ToolBoxStateDataCopyWithImpl<$Res, $Val extends ToolBoxStateData> + implements $ToolBoxStateDataCopyWith<$Res> { + _$ToolBoxStateDataCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? currentTool = null, + Object? currentToolType = null, + Object? isDown = null, + }) { + return _then(_value.copyWith( + currentTool: null == currentTool + ? _value.currentTool + : currentTool // ignore: cast_nullable_to_non_nullable + as Tool, + currentToolType: null == currentToolType + ? _value.currentToolType + : currentToolType // ignore: cast_nullable_to_non_nullable + as ToolType, + isDown: null == isDown + ? _value.isDown + : isDown // ignore: cast_nullable_to_non_nullable + as bool, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$_ToolBoxStateDataCopyWith<$Res> + implements $ToolBoxStateDataCopyWith<$Res> { + factory _$$_ToolBoxStateDataCopyWith( + _$_ToolBoxStateData value, $Res Function(_$_ToolBoxStateData) then) = + __$$_ToolBoxStateDataCopyWithImpl<$Res>; + @override + @useResult + $Res call({Tool currentTool, ToolType currentToolType, bool isDown}); +} + +/// @nodoc +class __$$_ToolBoxStateDataCopyWithImpl<$Res> + extends _$ToolBoxStateDataCopyWithImpl<$Res, _$_ToolBoxStateData> + implements _$$_ToolBoxStateDataCopyWith<$Res> { + __$$_ToolBoxStateDataCopyWithImpl( + _$_ToolBoxStateData _value, $Res Function(_$_ToolBoxStateData) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? currentTool = null, + Object? currentToolType = null, + Object? isDown = null, + }) { + return _then(_$_ToolBoxStateData( + currentTool: null == currentTool + ? _value.currentTool + : currentTool // ignore: cast_nullable_to_non_nullable + as Tool, + currentToolType: null == currentToolType + ? _value.currentToolType + : currentToolType // ignore: cast_nullable_to_non_nullable + as ToolType, + isDown: null == isDown + ? _value.isDown + : isDown // ignore: cast_nullable_to_non_nullable + as bool, + )); + } +} + +/// @nodoc + +class _$_ToolBoxStateData implements _ToolBoxStateData { + const _$_ToolBoxStateData( + {required this.currentTool, + required this.currentToolType, + required this.isDown}); + + @override + final Tool currentTool; + @override + final ToolType currentToolType; + @override + final bool isDown; + + @override + String toString() { + return 'ToolBoxStateData(currentTool: $currentTool, currentToolType: $currentToolType, isDown: $isDown)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_ToolBoxStateData && + (identical(other.currentTool, currentTool) || + other.currentTool == currentTool) && + (identical(other.currentToolType, currentToolType) || + other.currentToolType == currentToolType) && + (identical(other.isDown, isDown) || other.isDown == isDown)); + } + + @override + int get hashCode => + Object.hash(runtimeType, currentTool, currentToolType, isDown); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$_ToolBoxStateDataCopyWith<_$_ToolBoxStateData> get copyWith => + __$$_ToolBoxStateDataCopyWithImpl<_$_ToolBoxStateData>(this, _$identity); +} + +abstract class _ToolBoxStateData implements ToolBoxStateData { + const factory _ToolBoxStateData( + {required final Tool currentTool, + required final ToolType currentToolType, + required final bool isDown}) = _$_ToolBoxStateData; + + @override + Tool get currentTool; + @override + ToolType get currentToolType; + @override + bool get isDown; + @override + @JsonKey(ignore: true) + _$$_ToolBoxStateDataCopyWith<_$_ToolBoxStateData> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/tool/src/toolbox/toolbox_state_provider.dart b/packages/tools/lib/src/toolbox/toolbox_state_provider.dart similarity index 94% rename from lib/tool/src/toolbox/toolbox_state_provider.dart rename to packages/tools/lib/src/toolbox/toolbox_state_provider.dart index 5c08008b..e2a98847 100644 --- a/lib/tool/src/toolbox/toolbox_state_provider.dart +++ b/packages/tools/lib/src/toolbox/toolbox_state_provider.dart @@ -1,9 +1,8 @@ import 'dart:ui'; -import 'package:paintroid/tool/src/hand_tool/hand_tool_provider.dart'; -import 'package:paintroid/tool/tool.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:toast/toast.dart'; +import 'package:tools/tools.dart'; part 'toolbox_state_provider.g.dart'; diff --git a/packages/tools/lib/src/toolbox/toolbox_state_provider.g.dart b/packages/tools/lib/src/toolbox/toolbox_state_provider.g.dart new file mode 100644 index 00000000..ef1abc1d --- /dev/null +++ b/packages/tools/lib/src/toolbox/toolbox_state_provider.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'toolbox_state_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$toolBoxStateHash() => r'2a54e69ebf608acfacc008c0d05cbd140315c6b0'; + +/// See also [ToolBoxState]. +@ProviderFor(ToolBoxState) +final toolBoxStateProvider = + AutoDisposeNotifierProvider.internal( + ToolBoxState.new, + name: r'toolBoxStateProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') ? null : _$toolBoxStateHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef _$ToolBoxState = AutoDisposeNotifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/lib/tool/tool.dart b/packages/tools/lib/tools.dart similarity index 73% rename from lib/tool/tool.dart rename to packages/tools/lib/tools.dart index 07c23993..6a434f3c 100644 --- a/lib/tool/tool.dart +++ b/packages/tools/lib/tools.dart @@ -1,10 +1,19 @@ +library tools; + export 'src/brush_tool/brush_tool.dart'; export 'src/brush_tool/brush_tool_provider.dart'; export 'src/brush_tool/brush_tool_state_data.dart'; export 'src/brush_tool/brush_tool_state_provider.dart'; + +export 'src/enums/tool_types.dart'; + +export 'src/hand_tool/hand_tool.dart'; +export 'src/hand_tool/hand_tool_provider.dart'; + export 'src/eraser_tool/eraser_tool_provider.dart'; -export 'src/tool.dart'; -export 'src/tool_data.dart'; -export 'src/tool_types.dart'; + export 'src/toolbox/toolbox_state_data.dart'; export 'src/toolbox/toolbox_state_provider.dart'; + +export 'src/tool_data.dart'; +export 'src/tool.dart'; diff --git a/packages/tools/pubspec.yaml b/packages/tools/pubspec.yaml new file mode 100644 index 00000000..d00c2f2a --- /dev/null +++ b/packages/tools/pubspec.yaml @@ -0,0 +1,45 @@ +name: tools +description: A new Flutter package project. +version: 0.0.1 +publish_to: "none" + +environment: + sdk: ">=3.0.5 <4.0.0" + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + + flutter_riverpod: ^2.3.6 + riverpod_annotation: ^2.1.1 + freezed_annotation: ^2.4.1 + + equatable: ^2.0.3 + toast: ^0.3.0 + + # Internal packages + component_library: + path: ../component_library + database: + path: ../database + command: + path: ../command + workspace_screen: + path: ../features/workspace_screen + +dev_dependencies: + flutter_test: + sdk: flutter + + mockito: ^5.2.0 + flutter_launcher_icons: ^0.9.3 + flutter_lints: ^2.0.1 + floor_generator: ^1.2.0 + riverpod_generator: ^2.2.3 + riverpod_lint: ^1.3.2 + build_runner: ^2.2.0 + freezed: ^2.4.1 + +flutter: + uses-material-design: true diff --git a/test/unit/tool/brush_tool_state_test.dart b/packages/tools/test/unit/brush_tool_state_test.dart similarity index 91% rename from test/unit/tool/brush_tool_state_test.dart rename to packages/tools/test/unit/brush_tool_state_test.dart index d6de7653..8a61393f 100644 --- a/test/unit/tool/brush_tool_state_test.dart +++ b/packages/tools/test/unit/brush_tool_state_test.dart @@ -1,9 +1,9 @@ +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; // needed for Paint, Color, etc. +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import 'package:paintroid/core/graphic_factory.dart'; -import 'package:paintroid/tool/src/brush_tool/brush_tool_state_provider.dart'; -import 'package:riverpod/riverpod.dart'; +import 'package:tools/tools.dart'; class MockGraphicFactory extends Mock implements GraphicFactory {} diff --git a/test/unit/tool/brush_tool_test.dart b/packages/tools/test/unit/brush_tool_test.dart similarity index 95% rename from test/unit/tool/brush_tool_test.dart rename to packages/tools/test/unit/brush_tool_test.dart index 8a6b9141..a3dfb462 100644 --- a/test/unit/tool/brush_tool_test.dart +++ b/packages/tools/test/unit/brush_tool_test.dart @@ -1,12 +1,11 @@ import 'dart:ui'; +import 'package:command/command.dart'; +import 'package:component_library/component_library.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; -import 'package:paintroid/command/command.dart'; -import 'package:paintroid/core/graphic_factory.dart'; -import 'package:paintroid/core/path_with_action_history.dart'; -import 'package:paintroid/tool/tool.dart'; +import 'package:tools/tools.dart'; import 'brush_tool_test.mocks.dart'; diff --git a/packages/tools/test/unit/brush_tool_test.mocks.dart b/packages/tools/test/unit/brush_tool_test.mocks.dart new file mode 100644 index 00000000..25e8e73a --- /dev/null +++ b/packages/tools/test/unit/brush_tool_test.mocks.dart @@ -0,0 +1,1079 @@ +// Mocks generated by Mockito 5.4.2 from annotations +// in tools/test/unit/brush_tool_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:typed_data' as _i5; +import 'dart:ui' as _i2; + +import 'package:command/command.dart' as _i4; +import 'package:component_library/component_library.dart' as _i3; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakePath_0 extends _i1.SmartFake implements _i2.Path { + _FakePath_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeRect_1 extends _i1.SmartFake implements _i2.Rect { + _FakeRect_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePathMetrics_2 extends _i1.SmartFake implements _i2.PathMetrics { + _FakePathMetrics_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeOffset_3 extends _i1.SmartFake implements _i2.Offset { + _FakeOffset_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePathWithActionHistory_4 extends _i1.SmartFake + implements _i3.PathWithActionHistory { + _FakePathWithActionHistory_4( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePaint_5 extends _i1.SmartFake implements _i2.Paint { + _FakePaint_5( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeDrawPathCommand_6 extends _i1.SmartFake + implements _i4.DrawPathCommand { + _FakeDrawPathCommand_6( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePictureRecorder_7 extends _i1.SmartFake + implements _i2.PictureRecorder { + _FakePictureRecorder_7( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCanvas_8 extends _i1.SmartFake implements _i2.Canvas { + _FakeCanvas_8( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [PathWithActionHistory]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockPathWithActionHistory extends _i1.Mock + implements _i3.PathWithActionHistory { + MockPathWithActionHistory() { + _i1.throwOnMissingStub(this); + } + + @override + List<_i3.PathAction> get actions => (super.noSuchMethod( + Invocation.getter(#actions), + returnValue: <_i3.PathAction>[], + ) as List<_i3.PathAction>); + + @override + _i2.PathFillType get fillType => (super.noSuchMethod( + Invocation.getter(#fillType), + returnValue: _i2.PathFillType.nonZero, + ) as _i2.PathFillType); + + @override + set fillType(_i2.PathFillType? value) => super.noSuchMethod( + Invocation.setter( + #fillType, + value, + ), + returnValueForMissingStub: null, + ); + + @override + void moveTo( + double? x, + double? y, + ) => + super.noSuchMethod( + Invocation.method( + #moveTo, + [ + x, + y, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void lineTo( + double? x, + double? y, + ) => + super.noSuchMethod( + Invocation.method( + #lineTo, + [ + x, + y, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void close() => super.noSuchMethod( + Invocation.method( + #close, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void relativeMoveTo( + double? dx, + double? dy, + ) => + super.noSuchMethod( + Invocation.method( + #relativeMoveTo, + [ + dx, + dy, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void relativeLineTo( + double? dx, + double? dy, + ) => + super.noSuchMethod( + Invocation.method( + #relativeLineTo, + [ + dx, + dy, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void quadraticBezierTo( + double? x1, + double? y1, + double? x2, + double? y2, + ) => + super.noSuchMethod( + Invocation.method( + #quadraticBezierTo, + [ + x1, + y1, + x2, + y2, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void relativeQuadraticBezierTo( + double? x1, + double? y1, + double? x2, + double? y2, + ) => + super.noSuchMethod( + Invocation.method( + #relativeQuadraticBezierTo, + [ + x1, + y1, + x2, + y2, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void cubicTo( + double? x1, + double? y1, + double? x2, + double? y2, + double? x3, + double? y3, + ) => + super.noSuchMethod( + Invocation.method( + #cubicTo, + [ + x1, + y1, + x2, + y2, + x3, + y3, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void relativeCubicTo( + double? x1, + double? y1, + double? x2, + double? y2, + double? x3, + double? y3, + ) => + super.noSuchMethod( + Invocation.method( + #relativeCubicTo, + [ + x1, + y1, + x2, + y2, + x3, + y3, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void conicTo( + double? x1, + double? y1, + double? x2, + double? y2, + double? w, + ) => + super.noSuchMethod( + Invocation.method( + #conicTo, + [ + x1, + y1, + x2, + y2, + w, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void relativeConicTo( + double? x1, + double? y1, + double? x2, + double? y2, + double? w, + ) => + super.noSuchMethod( + Invocation.method( + #relativeConicTo, + [ + x1, + y1, + x2, + y2, + w, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void arcTo( + _i2.Rect? rect, + double? startAngle, + double? sweepAngle, + bool? forceMoveTo, + ) => + super.noSuchMethod( + Invocation.method( + #arcTo, + [ + rect, + startAngle, + sweepAngle, + forceMoveTo, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void arcToPoint( + _i2.Offset? arcEnd, { + _i2.Radius? radius = _i2.Radius.zero, + double? rotation = 0.0, + bool? largeArc = false, + bool? clockwise = true, + }) => + super.noSuchMethod( + Invocation.method( + #arcToPoint, + [arcEnd], + { + #radius: radius, + #rotation: rotation, + #largeArc: largeArc, + #clockwise: clockwise, + }, + ), + returnValueForMissingStub: null, + ); + + @override + void relativeArcToPoint( + _i2.Offset? arcEndDelta, { + _i2.Radius? radius = _i2.Radius.zero, + double? rotation = 0.0, + bool? largeArc = false, + bool? clockwise = true, + }) => + super.noSuchMethod( + Invocation.method( + #relativeArcToPoint, + [arcEndDelta], + { + #radius: radius, + #rotation: rotation, + #largeArc: largeArc, + #clockwise: clockwise, + }, + ), + returnValueForMissingStub: null, + ); + + @override + void addRect(_i2.Rect? rect) => super.noSuchMethod( + Invocation.method( + #addRect, + [rect], + ), + returnValueForMissingStub: null, + ); + + @override + void addOval(_i2.Rect? oval) => super.noSuchMethod( + Invocation.method( + #addOval, + [oval], + ), + returnValueForMissingStub: null, + ); + + @override + void addArc( + _i2.Rect? oval, + double? startAngle, + double? sweepAngle, + ) => + super.noSuchMethod( + Invocation.method( + #addArc, + [ + oval, + startAngle, + sweepAngle, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void addPolygon( + List<_i2.Offset>? points, + bool? close, + ) => + super.noSuchMethod( + Invocation.method( + #addPolygon, + [ + points, + close, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void addRRect(_i2.RRect? rrect) => super.noSuchMethod( + Invocation.method( + #addRRect, + [rrect], + ), + returnValueForMissingStub: null, + ); + + @override + void addPath( + _i2.Path? path, + _i2.Offset? offset, { + _i5.Float64List? matrix4, + }) => + super.noSuchMethod( + Invocation.method( + #addPath, + [ + path, + offset, + ], + {#matrix4: matrix4}, + ), + returnValueForMissingStub: null, + ); + + @override + void extendWithPath( + _i2.Path? path, + _i2.Offset? offset, { + _i5.Float64List? matrix4, + }) => + super.noSuchMethod( + Invocation.method( + #extendWithPath, + [ + path, + offset, + ], + {#matrix4: matrix4}, + ), + returnValueForMissingStub: null, + ); + + @override + void reset() => super.noSuchMethod( + Invocation.method( + #reset, + [], + ), + returnValueForMissingStub: null, + ); + + @override + bool contains(_i2.Offset? point) => (super.noSuchMethod( + Invocation.method( + #contains, + [point], + ), + returnValue: false, + ) as bool); + + @override + _i2.Path shift(_i2.Offset? offset) => (super.noSuchMethod( + Invocation.method( + #shift, + [offset], + ), + returnValue: _FakePath_0( + this, + Invocation.method( + #shift, + [offset], + ), + ), + ) as _i2.Path); + + @override + _i2.Path transform(_i5.Float64List? matrix4) => (super.noSuchMethod( + Invocation.method( + #transform, + [matrix4], + ), + returnValue: _FakePath_0( + this, + Invocation.method( + #transform, + [matrix4], + ), + ), + ) as _i2.Path); + + @override + _i2.Rect getBounds() => (super.noSuchMethod( + Invocation.method( + #getBounds, + [], + ), + returnValue: _FakeRect_1( + this, + Invocation.method( + #getBounds, + [], + ), + ), + ) as _i2.Rect); + + @override + _i2.PathMetrics computeMetrics({bool? forceClosed = false}) => + (super.noSuchMethod( + Invocation.method( + #computeMetrics, + [], + {#forceClosed: forceClosed}, + ), + returnValue: _FakePathMetrics_2( + this, + Invocation.method( + #computeMetrics, + [], + {#forceClosed: forceClosed}, + ), + ), + ) as _i2.PathMetrics); +} + +/// A class which mocks [Offset]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockOffset extends _i1.Mock implements _i2.Offset { + MockOffset() { + _i1.throwOnMissingStub(this); + } + + @override + double get dx => (super.noSuchMethod( + Invocation.getter(#dx), + returnValue: 0.0, + ) as double); + + @override + double get dy => (super.noSuchMethod( + Invocation.getter(#dy), + returnValue: 0.0, + ) as double); + + @override + double get distance => (super.noSuchMethod( + Invocation.getter(#distance), + returnValue: 0.0, + ) as double); + + @override + double get distanceSquared => (super.noSuchMethod( + Invocation.getter(#distanceSquared), + returnValue: 0.0, + ) as double); + + @override + double get direction => (super.noSuchMethod( + Invocation.getter(#direction), + returnValue: 0.0, + ) as double); + + @override + bool get isInfinite => (super.noSuchMethod( + Invocation.getter(#isInfinite), + returnValue: false, + ) as bool); + + @override + bool get isFinite => (super.noSuchMethod( + Invocation.getter(#isFinite), + returnValue: false, + ) as bool); + + @override + _i2.Offset scale( + double? scaleX, + double? scaleY, + ) => + (super.noSuchMethod( + Invocation.method( + #scale, + [ + scaleX, + scaleY, + ], + ), + returnValue: _FakeOffset_3( + this, + Invocation.method( + #scale, + [ + scaleX, + scaleY, + ], + ), + ), + ) as _i2.Offset); + + @override + _i2.Offset translate( + double? translateX, + double? translateY, + ) => + (super.noSuchMethod( + Invocation.method( + #translate, + [ + translateX, + translateY, + ], + ), + returnValue: _FakeOffset_3( + this, + Invocation.method( + #translate, + [ + translateX, + translateY, + ], + ), + ), + ) as _i2.Offset); + + @override + _i2.Offset operator -() => (super.noSuchMethod( + Invocation.method( + #-, + [], + ), + returnValue: _FakeOffset_3( + this, + Invocation.method( + #-, + [], + ), + ), + ) as _i2.Offset); + + @override + _i2.Offset operator -(_i2.Offset? other) => (super.noSuchMethod( + Invocation.method( + #-, + [other], + ), + returnValue: _FakeOffset_3( + this, + Invocation.method( + #-, + [other], + ), + ), + ) as _i2.Offset); + + @override + _i2.Offset operator +(_i2.Offset? other) => (super.noSuchMethod( + Invocation.method( + #+, + [other], + ), + returnValue: _FakeOffset_3( + this, + Invocation.method( + #+, + [other], + ), + ), + ) as _i2.Offset); + + @override + _i2.Offset operator *(double? operand) => (super.noSuchMethod( + Invocation.method( + #*, + [operand], + ), + returnValue: _FakeOffset_3( + this, + Invocation.method( + #*, + [operand], + ), + ), + ) as _i2.Offset); + + @override + _i2.Offset operator /(double? operand) => (super.noSuchMethod( + Invocation.method( + #/, + [operand], + ), + returnValue: _FakeOffset_3( + this, + Invocation.method( + #/, + [operand], + ), + ), + ) as _i2.Offset); + + @override + _i2.Offset operator ~/(double? operand) => (super.noSuchMethod( + Invocation.method( + #~/, + [operand], + ), + returnValue: _FakeOffset_3( + this, + Invocation.method( + #~/, + [operand], + ), + ), + ) as _i2.Offset); + + @override + _i2.Offset operator %(double? operand) => (super.noSuchMethod( + Invocation.method( + #%, + [operand], + ), + returnValue: _FakeOffset_3( + this, + Invocation.method( + #%, + [operand], + ), + ), + ) as _i2.Offset); + + @override + _i2.Rect operator &(_i2.Size? other) => (super.noSuchMethod( + Invocation.method( + #&, + [other], + ), + returnValue: _FakeRect_1( + this, + Invocation.method( + #&, + [other], + ), + ), + ) as _i2.Rect); + + @override + bool operator <(_i2.OffsetBase? other) => (super.noSuchMethod( + Invocation.method( + #<, + [other], + ), + returnValue: false, + ) as bool); + + @override + bool operator <=(_i2.OffsetBase? other) => (super.noSuchMethod( + Invocation.method( + #<=, + [other], + ), + returnValue: false, + ) as bool); + + @override + bool operator >(_i2.OffsetBase? other) => (super.noSuchMethod( + Invocation.method( + #>, + [other], + ), + returnValue: false, + ) as bool); + + @override + bool operator >=(_i2.OffsetBase? other) => (super.noSuchMethod( + Invocation.method( + #>=, + [other], + ), + returnValue: false, + ) as bool); +} + +/// A class which mocks [DrawPathCommand]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockDrawPathCommand extends _i1.Mock implements _i4.DrawPathCommand { + MockDrawPathCommand() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.PathWithActionHistory get path => (super.noSuchMethod( + Invocation.getter(#path), + returnValue: _FakePathWithActionHistory_4( + this, + Invocation.getter(#path), + ), + ) as _i3.PathWithActionHistory); + + @override + List get props => (super.noSuchMethod( + Invocation.getter(#props), + returnValue: [], + ) as List); + + @override + _i2.Paint get paint => (super.noSuchMethod( + Invocation.getter(#paint), + returnValue: _FakePaint_5( + this, + Invocation.getter(#paint), + ), + ) as _i2.Paint); + + @override + void call(_i2.Canvas? canvas) => super.noSuchMethod( + Invocation.method( + #call, + [canvas], + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [CommandManager]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCommandManager extends _i1.Mock implements _i4.CommandManager { + MockCommandManager() { + _i1.throwOnMissingStub(this); + } + + @override + Iterable<_i4.Command> get history => (super.noSuchMethod( + Invocation.getter(#history), + returnValue: <_i4.Command>[], + ) as Iterable<_i4.Command>); + + @override + int get count => (super.noSuchMethod( + Invocation.getter(#count), + returnValue: 0, + ) as int); + + @override + void addGraphicCommand(_i4.GraphicCommand? command) => super.noSuchMethod( + Invocation.method( + #addGraphicCommand, + [command], + ), + returnValueForMissingStub: null, + ); + + @override + void executeLastCommand(_i2.Canvas? canvas) => super.noSuchMethod( + Invocation.method( + #executeLastCommand, + [canvas], + ), + returnValueForMissingStub: null, + ); + + @override + void executeAllCommands(_i2.Canvas? canvas) => super.noSuchMethod( + Invocation.method( + #executeAllCommands, + [canvas], + ), + returnValueForMissingStub: null, + ); + + @override + void discardLastCommand() => super.noSuchMethod( + Invocation.method( + #discardLastCommand, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void clearHistory({Iterable<_i4.Command>? newCommands}) => super.noSuchMethod( + Invocation.method( + #clearHistory, + [], + {#newCommands: newCommands}, + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [CommandFactory]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCommandFactory extends _i1.Mock implements _i4.CommandFactory { + MockCommandFactory() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.DrawPathCommand createDrawPathCommand( + _i3.PathWithActionHistory? path, + _i2.Paint? paint, + ) => + (super.noSuchMethod( + Invocation.method( + #createDrawPathCommand, + [ + path, + paint, + ], + ), + returnValue: _FakeDrawPathCommand_6( + this, + Invocation.method( + #createDrawPathCommand, + [ + path, + paint, + ], + ), + ), + ) as _i4.DrawPathCommand); +} + +/// A class which mocks [GraphicFactory]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockGraphicFactory extends _i1.Mock implements _i3.GraphicFactory { + MockGraphicFactory() { + _i1.throwOnMissingStub(this); + } + + @override + _i2.Paint createPaint() => (super.noSuchMethod( + Invocation.method( + #createPaint, + [], + ), + returnValue: _FakePaint_5( + this, + Invocation.method( + #createPaint, + [], + ), + ), + ) as _i2.Paint); + + @override + _i3.PathWithActionHistory createPathWithActionHistory() => + (super.noSuchMethod( + Invocation.method( + #createPathWithActionHistory, + [], + ), + returnValue: _FakePathWithActionHistory_4( + this, + Invocation.method( + #createPathWithActionHistory, + [], + ), + ), + ) as _i3.PathWithActionHistory); + + @override + _i2.PictureRecorder createPictureRecorder() => (super.noSuchMethod( + Invocation.method( + #createPictureRecorder, + [], + ), + returnValue: _FakePictureRecorder_7( + this, + Invocation.method( + #createPictureRecorder, + [], + ), + ), + ) as _i2.PictureRecorder); + + @override + _i2.Canvas createCanvasWithRecorder(_i2.PictureRecorder? recorder) => + (super.noSuchMethod( + Invocation.method( + #createCanvasWithRecorder, + [recorder], + ), + returnValue: _FakeCanvas_8( + this, + Invocation.method( + #createCanvasWithRecorder, + [recorder], + ), + ), + ) as _i2.Canvas); + + @override + _i2.Paint copyPaint(_i2.Paint? original) => (super.noSuchMethod( + Invocation.method( + #copyPaint, + [original], + ), + returnValue: _FakePaint_5( + this, + Invocation.method( + #copyPaint, + [original], + ), + ), + ) as _i2.Paint); +} diff --git a/test/unit/tool/hand_tool_test.dart b/packages/tools/test/unit/hand_tool_test.dart similarity index 88% rename from test/unit/tool/hand_tool_test.dart rename to packages/tools/test/unit/hand_tool_test.dart index c6caa5b3..8bb28a7b 100644 --- a/test/unit/tool/hand_tool_test.dart +++ b/packages/tools/test/unit/hand_tool_test.dart @@ -1,12 +1,10 @@ import 'dart:ui'; +import 'package:command/command.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; -import 'package:paintroid/command/src/command_factory.dart'; -import 'package:paintroid/command/src/command_manager.dart'; -import 'package:paintroid/tool/src/hand_tool/hand_tool.dart'; -import 'package:paintroid/tool/src/tool_types.dart'; +import 'package:tools/tools.dart'; import 'hand_tool_test.mocks.dart'; diff --git a/packages/tools/test/unit/hand_tool_test.mocks.dart b/packages/tools/test/unit/hand_tool_test.mocks.dart new file mode 100644 index 00000000..52c43e50 --- /dev/null +++ b/packages/tools/test/unit/hand_tool_test.mocks.dart @@ -0,0 +1,341 @@ +// Mocks generated by Mockito 5.4.2 from annotations +// in tools/test/unit/hand_tool_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:ui' as _i2; + +import 'package:command/command.dart' as _i3; +import 'package:component_library/component_library.dart' as _i4; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeColor_0 extends _i1.SmartFake implements _i2.Color { + _FakeColor_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeDrawPathCommand_1 extends _i1.SmartFake + implements _i3.DrawPathCommand { + _FakeDrawPathCommand_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [Paint]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockPaint extends _i1.Mock implements _i2.Paint { + MockPaint() { + _i1.throwOnMissingStub(this); + } + + @override + bool get isAntiAlias => (super.noSuchMethod( + Invocation.getter(#isAntiAlias), + returnValue: false, + ) as bool); + + @override + set isAntiAlias(bool? value) => super.noSuchMethod( + Invocation.setter( + #isAntiAlias, + value, + ), + returnValueForMissingStub: null, + ); + + @override + _i2.Color get color => (super.noSuchMethod( + Invocation.getter(#color), + returnValue: _FakeColor_0( + this, + Invocation.getter(#color), + ), + ) as _i2.Color); + + @override + set color(_i2.Color? value) => super.noSuchMethod( + Invocation.setter( + #color, + value, + ), + returnValueForMissingStub: null, + ); + + @override + _i2.BlendMode get blendMode => (super.noSuchMethod( + Invocation.getter(#blendMode), + returnValue: _i2.BlendMode.clear, + ) as _i2.BlendMode); + + @override + set blendMode(_i2.BlendMode? value) => super.noSuchMethod( + Invocation.setter( + #blendMode, + value, + ), + returnValueForMissingStub: null, + ); + + @override + _i2.PaintingStyle get style => (super.noSuchMethod( + Invocation.getter(#style), + returnValue: _i2.PaintingStyle.fill, + ) as _i2.PaintingStyle); + + @override + set style(_i2.PaintingStyle? value) => super.noSuchMethod( + Invocation.setter( + #style, + value, + ), + returnValueForMissingStub: null, + ); + + @override + double get strokeWidth => (super.noSuchMethod( + Invocation.getter(#strokeWidth), + returnValue: 0.0, + ) as double); + + @override + set strokeWidth(double? value) => super.noSuchMethod( + Invocation.setter( + #strokeWidth, + value, + ), + returnValueForMissingStub: null, + ); + + @override + _i2.StrokeCap get strokeCap => (super.noSuchMethod( + Invocation.getter(#strokeCap), + returnValue: _i2.StrokeCap.butt, + ) as _i2.StrokeCap); + + @override + set strokeCap(_i2.StrokeCap? value) => super.noSuchMethod( + Invocation.setter( + #strokeCap, + value, + ), + returnValueForMissingStub: null, + ); + + @override + _i2.StrokeJoin get strokeJoin => (super.noSuchMethod( + Invocation.getter(#strokeJoin), + returnValue: _i2.StrokeJoin.miter, + ) as _i2.StrokeJoin); + + @override + set strokeJoin(_i2.StrokeJoin? value) => super.noSuchMethod( + Invocation.setter( + #strokeJoin, + value, + ), + returnValueForMissingStub: null, + ); + + @override + double get strokeMiterLimit => (super.noSuchMethod( + Invocation.getter(#strokeMiterLimit), + returnValue: 0.0, + ) as double); + + @override + set strokeMiterLimit(double? value) => super.noSuchMethod( + Invocation.setter( + #strokeMiterLimit, + value, + ), + returnValueForMissingStub: null, + ); + + @override + set maskFilter(_i2.MaskFilter? value) => super.noSuchMethod( + Invocation.setter( + #maskFilter, + value, + ), + returnValueForMissingStub: null, + ); + + @override + _i2.FilterQuality get filterQuality => (super.noSuchMethod( + Invocation.getter(#filterQuality), + returnValue: _i2.FilterQuality.none, + ) as _i2.FilterQuality); + + @override + set filterQuality(_i2.FilterQuality? value) => super.noSuchMethod( + Invocation.setter( + #filterQuality, + value, + ), + returnValueForMissingStub: null, + ); + + @override + set shader(_i2.Shader? value) => super.noSuchMethod( + Invocation.setter( + #shader, + value, + ), + returnValueForMissingStub: null, + ); + + @override + set colorFilter(_i2.ColorFilter? value) => super.noSuchMethod( + Invocation.setter( + #colorFilter, + value, + ), + returnValueForMissingStub: null, + ); + + @override + set imageFilter(_i2.ImageFilter? value) => super.noSuchMethod( + Invocation.setter( + #imageFilter, + value, + ), + returnValueForMissingStub: null, + ); + + @override + bool get invertColors => (super.noSuchMethod( + Invocation.getter(#invertColors), + returnValue: false, + ) as bool); + + @override + set invertColors(bool? value) => super.noSuchMethod( + Invocation.setter( + #invertColors, + value, + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [CommandManager]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCommandManager extends _i1.Mock implements _i3.CommandManager { + MockCommandManager() { + _i1.throwOnMissingStub(this); + } + + @override + Iterable<_i3.Command> get history => (super.noSuchMethod( + Invocation.getter(#history), + returnValue: <_i3.Command>[], + ) as Iterable<_i3.Command>); + + @override + int get count => (super.noSuchMethod( + Invocation.getter(#count), + returnValue: 0, + ) as int); + + @override + void addGraphicCommand(_i3.GraphicCommand? command) => super.noSuchMethod( + Invocation.method( + #addGraphicCommand, + [command], + ), + returnValueForMissingStub: null, + ); + + @override + void executeLastCommand(_i2.Canvas? canvas) => super.noSuchMethod( + Invocation.method( + #executeLastCommand, + [canvas], + ), + returnValueForMissingStub: null, + ); + + @override + void executeAllCommands(_i2.Canvas? canvas) => super.noSuchMethod( + Invocation.method( + #executeAllCommands, + [canvas], + ), + returnValueForMissingStub: null, + ); + + @override + void discardLastCommand() => super.noSuchMethod( + Invocation.method( + #discardLastCommand, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void clearHistory({Iterable<_i3.Command>? newCommands}) => super.noSuchMethod( + Invocation.method( + #clearHistory, + [], + {#newCommands: newCommands}, + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [CommandFactory]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCommandFactory extends _i1.Mock implements _i3.CommandFactory { + MockCommandFactory() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.DrawPathCommand createDrawPathCommand( + _i4.PathWithActionHistory? path, + _i2.Paint? paint, + ) => + (super.noSuchMethod( + Invocation.method( + #createDrawPathCommand, + [ + path, + paint, + ], + ), + returnValue: _FakeDrawPathCommand_1( + this, + Invocation.method( + #createDrawPathCommand, + [ + path, + paint, + ], + ), + ), + ) as _i3.DrawPathCommand); +} diff --git a/pubspec.lock b/pubspec.lock index c745224f..7b577238 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -25,22 +25,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.11.2" + ansi_styles: + dependency: transitive + description: + name: ansi_styles + sha256: "9c656cc12b3c27b17dd982b2cc5c0cfdfbdabd7bc8f3ae5e8542d9867b47ce8a" + url: "https://pub.dev" + source: hosted + version: "0.3.2+1" archive: dependency: transitive description: name: archive - sha256: "80e5141fafcb3361653ce308776cfd7d45e6e9fbb429e14eec571382c0c5fecb" + sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b" url: "https://pub.dev" source: hosted - version: "3.3.2" + version: "3.4.9" args: dependency: transitive description: name: args - sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.2" async: dependency: transitive description: @@ -61,10 +69,10 @@ packages: dependency: transitive description: name: build - sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777" + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.4.1" build_config: dependency: transitive description: @@ -77,34 +85,34 @@ packages: dependency: transitive description: name: build_daemon - sha256: "757153e5d9cd88253cb13f28c2fb55a537dc31fefd98137549895b5beb7c6169" + sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "4.0.1" build_resolvers: dependency: transitive description: name: build_resolvers - sha256: db49b8609ef8c81cca2b310618c3017c00f03a92af44c04d310b907b2d692d95 + sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.4.2" build_runner: dependency: "direct dev" description: name: build_runner - sha256: b0a8a7b8a76c493e85f1b84bffa0588859a06197863dba8c9036b15581fd9727 + sha256: "67d591d602906ef9201caf93452495ad1812bea2074f04e25dbd7c133785821b" url: "https://pub.dev" source: hosted - version: "2.3.3" + version: "2.4.7" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: "0671ad4162ed510b70d0eb4ad6354c249f8429cab4ae7a4cec86bbc2886eb76e" + sha256: c9e32d21dd6626b5c163d48b037ce906bbe428bc23ab77bcd77bb21e593b6185 url: "https://pub.dev" source: hosted - version: "7.2.7+1" + version: "7.2.11" built_collection: dependency: transitive description: @@ -117,10 +125,10 @@ packages: dependency: transitive description: name: built_value - sha256: "7dd62d9faf105c434f3d829bbe9c4be02ec67f5ed94832222116122df67c5452" + sha256: c9aabae0718ec394e5bc3c7272e6bb0dc0b32201a08fe185ec1d8401d3e39309 url: "https://pub.dev" source: hosted - version: "8.6.0" + version: "8.8.1" characters: dependency: transitive description: @@ -153,14 +161,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.0" + cli_launcher: + dependency: transitive + description: + name: cli_launcher + sha256: "5e7e0282b79e8642edd6510ee468ae2976d847a0a29b3916e85f5fa1bfe24005" + url: "https://pub.dev" + source: hosted + version: "0.3.1" cli_util: dependency: transitive description: name: cli_util - sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7 + sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19 url: "https://pub.dev" source: hosted - version: "0.4.0" + version: "0.4.1" clock: dependency: transitive description: @@ -173,25 +189,47 @@ packages: dependency: transitive description: name: code_builder - sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe" + sha256: feee43a5c05e7b3199bb375a86430b8ada1b04104f2923d0e03cc01ca87b6d84 url: "https://pub.dev" source: hosted - version: "4.4.0" + version: "4.9.0" collection: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" colorpicker: dependency: "direct main" description: - path: colorpicker + path: "packages/colorpicker" + relative: true + source: path + version: "0.0.1" + command: + dependency: "direct main" + description: + path: "packages/command" relative: true source: path version: "0.0.1" + component_library: + dependency: "direct main" + description: + path: "packages/component_library" + relative: true + source: path + version: "0.0.1" + conventional_commit: + dependency: transitive + description: + name: conventional_commit + sha256: dec15ad1118f029c618651a4359eb9135d8b88f761aa24e4016d061cd45948f2 + url: "https://pub.dev" + source: hosted + version: "0.6.0+1" convert: dependency: transitive description: @@ -204,18 +242,18 @@ packages: dependency: transitive description: name: cross_file - sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9" + sha256: "2f9d2cbccb76127ba28528cb3ae2c2326a122446a83de5a056aaa3880d3882c5" url: "https://pub.dev" source: hosted - version: "0.3.3+4" + version: "0.3.3+7" crypto: dependency: transitive description: name: crypto - sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" custom_lint: dependency: transitive description: @@ -244,18 +282,25 @@ packages: dependency: transitive description: name: dart_style - sha256: f4f1f73ab3fd2afcbcca165ee601fe980d966af6a21b5970c6c9376955c528ad + sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" + database: + dependency: transitive + description: + path: "packages/database" + relative: true + source: path + version: "0.0.1" device_info_plus: - dependency: "direct main" + dependency: transitive description: name: device_info_plus - sha256: "86add5ef97215562d2e090535b0a16f197902b10c369c558a100e74ea06e8659" + sha256: "0042cb3b2a76413ea5f8a2b40cec2a33e01d0c937e91f0f7c211fde4f7739ba6" url: "https://pub.dev" source: hosted - version: "9.0.3" + version: "9.1.1" device_info_plus_platform_interface: dependency: transitive description: @@ -265,7 +310,7 @@ packages: source: hosted version: "7.0.0" equatable: - dependency: "direct main" + dependency: transitive description: name: equatable sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 @@ -284,10 +329,10 @@ packages: dependency: transitive description: name: ffi - sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.1.0" file: dependency: transitive description: @@ -297,15 +342,47 @@ packages: source: hosted version: "6.1.4" file_picker: - dependency: "direct main" + dependency: transitive description: name: file_picker - sha256: "9d6e95ec73abbd31ec54d0e0df8a961017e165aba1395e462e5b31ea0c165daf" + sha256: be325344c1f3070354a1d84a231a1ba75ea85d413774ec4bdf444c023342e030 + url: "https://pub.dev" + source: hosted + version: "5.5.0" + file_selector_linux: + dependency: transitive + description: + name: file_selector_linux + sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492" + url: "https://pub.dev" + source: hosted + version: "0.9.2+1" + file_selector_macos: + dependency: transitive + description: + name: file_selector_macos + sha256: b15c3da8bd4908b9918111fa486903f5808e388b8d1c559949f584725a6594d6 + url: "https://pub.dev" + source: hosted + version: "0.9.3+3" + file_selector_platform_interface: + dependency: transitive + description: + name: file_selector_platform_interface + sha256: "0aa47a725c346825a2bd396343ce63ac00bda6eff2fbc43eabe99737dede8262" url: "https://pub.dev" source: hosted - version: "5.3.1" + version: "2.6.1" + file_selector_windows: + dependency: transitive + description: + name: file_selector_windows + sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0 + url: "https://pub.dev" + source: hosted + version: "0.9.3+1" filesize: - dependency: "direct main" + dependency: transitive description: name: filesize sha256: f53df1f27ff60e466eefcd9df239e02d4722d5e2debee92a87dfd99ac66de2af @@ -321,7 +398,7 @@ packages: source: hosted version: "1.1.0" floor: - dependency: "direct main" + dependency: transitive description: name: floor sha256: "52a8eac2c8d274e7c0c54251226f59786bb5b749365a2d8537d8095aa5132d92" @@ -366,20 +443,20 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c + sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.3" flutter_localization: dependency: "direct main" description: name: flutter_localization - sha256: "9afed0ae301ee3ca547bceb5132b50d0d2d539ad4da4131ea7fc89e3bdeb67d3" + sha256: a65ae241b865f2780f2ef624a4cdd019ca894d0b7df0a0b77190746ef0b9c8fa url: "https://pub.dev" source: hosted - version: "0.1.12" + version: "0.1.14" flutter_localizations: - dependency: transitive + dependency: "direct main" description: flutter source: sdk version: "0.0.0" @@ -387,10 +464,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "950e77c2bbe1692bc0874fc7fb491b96a4dc340457f4ea1641443d0a6c1ea360" + sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da url: "https://pub.dev" source: hosted - version: "2.0.15" + version: "2.0.17" flutter_riverpod: dependency: "direct main" description: @@ -400,7 +477,7 @@ packages: source: hosted version: "2.4.9" flutter_svg: - dependency: "direct main" + dependency: transitive description: name: flutter_svg sha256: "6ff9fa12892ae074092de2fa6a9938fb21dbabfdaa2ff57dc697ff912fc8d4b2" @@ -474,10 +551,10 @@ packages: dependency: transitive description: name: http - sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" + sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" url: "https://pub.dev" source: hosted - version: "0.13.6" + version: "1.1.0" http_multi_server: dependency: transitive description: @@ -495,7 +572,7 @@ packages: source: hosted version: "4.0.2" image: - dependency: "direct main" + dependency: transitive description: name: image sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6" @@ -503,45 +580,69 @@ packages: source: hosted version: "3.3.0" image_picker: - dependency: "direct main" + dependency: transitive description: name: image_picker - sha256: "9978d3510af4e6a902e545ce19229b926e6de6a1828d6134d3aab2e129a4d270" + sha256: b6951e25b795d053a6ba03af5f710069c99349de9341af95155d52665cb4607c url: "https://pub.dev" source: hosted - version: "0.8.7+5" + version: "0.8.9" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: c2f3c66400649bd132f721c88218945d6406f693092b2f741b79ae9cdb046e59 + sha256: ecdc963d2aa67af5195e723a40580f802d4392e31457a12a562b3e2bd6a396fe url: "https://pub.dev" source: hosted - version: "0.8.6+16" + version: "0.8.9+1" image_picker_for_web: dependency: transitive description: name: image_picker_for_web - sha256: "98f50d6b9f294c8ba35e25cc0d13b04bfddd25dbc8d32fa9d566a6572f2c081c" + sha256: "869fe8a64771b7afbc99fc433a5f7be2fea4d1cb3d7c11a48b6b579eb9c797f0" url: "https://pub.dev" source: hosted - version: "2.1.12" + version: "2.2.0" image_picker_ios: dependency: transitive description: name: image_picker_ios - sha256: d779210bda268a03b57e923fb1e410f32f5c5e708ad256348bcbf1f44f558fd0 + sha256: eac0a62104fa12feed213596df0321f57ce5a572562f72a68c4ff81e9e4caacf + url: "https://pub.dev" + source: hosted + version: "0.8.9" + image_picker_linux: + dependency: transitive + description: + name: image_picker_linux + sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" + image_picker_macos: + dependency: transitive + description: + name: image_picker_macos + sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62" url: "https://pub.dev" source: hosted - version: "0.8.7+4" + version: "0.2.1+1" image_picker_platform_interface: dependency: transitive description: name: image_picker_platform_interface - sha256: "1991219d9dbc42a99aff77e663af8ca51ced592cd6685c9485e3458302d3d4f8" + sha256: ed9b00e63977c93b0d2d2b343685bed9c324534ba5abafbb3dfbd6a780b1b514 url: "https://pub.dev" source: hosted - version: "2.6.3" + version: "2.9.1" + image_picker_windows: + dependency: transitive + description: + name: image_picker_windows + sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" integration_test: dependency: "direct dev" description: flutter @@ -563,6 +664,13 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + io_library: + dependency: "direct main" + description: + path: "packages/io_library" + relative: true + source: path + version: "0.0.1" js: dependency: transitive description: @@ -579,8 +687,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.8.1" - launch_review: + l10n: + dependency: "direct main" + description: + path: "packages/l10n" + relative: true + source: path + version: "0.0.1" + landing_page_screen: dependency: "direct main" + description: + path: "packages/features/landing_page_screen" + relative: true + source: path + version: "0.0.1" + launch_review: + dependency: transitive description: name: launch_review sha256: "04cdaf752033cefd53bc0fa9c22105801ef53791a93d8b6cdd00fcb3c1c1604b" @@ -591,10 +713,10 @@ packages: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.1" lists: dependency: transitive description: @@ -627,14 +749,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.0" + melos: + dependency: "direct main" + description: + name: melos + sha256: "96e64bbade5712c3f010137e195bca9f1b351fac34ab1f322af492ae34032067" + url: "https://pub.dev" + source: hosted + version: "3.4.0" meta: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" mime: dependency: transitive description: @@ -647,12 +777,27 @@ packages: dependency: "direct dev" description: name: mockito - sha256: "8b46d7eb40abdda92d62edd01546051f0c27365e65608c284de336dccfef88cc" + sha256: "7d5b53bcd556c1bc7ffbe4e4d5a19c3e112b7e925e9e172dd7c6ad0630812616" url: "https://pub.dev" source: hosted - version: "5.4.1" - oxidized: + version: "5.4.2" + mustache_template: + dependency: transitive + description: + name: mustache_template + sha256: a46e26f91445bfb0b60519be280555b06792460b27b19e2b19ad5b9740df5d1c + url: "https://pub.dev" + source: hosted + version: "2.0.0" + onboarding_screen: dependency: "direct main" + description: + path: "packages/features/onboarding_screen" + relative: true + source: path + version: "0.0.1" + oxidized: + dependency: transitive description: name: oxidized sha256: "2058b9818815546124f6d0fee813483b571ca133b4db6f63c9628897f191e6b5" @@ -668,13 +813,13 @@ packages: source: hosted version: "2.1.0" package_info_plus: - dependency: "direct main" + dependency: transitive description: name: package_info_plus - sha256: "28386bbe89ab5a7919a47cea99cdd1128e5a6e0bbd7eaafe20440ead84a15de3" + sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" url: "https://pub.dev" source: hosted - version: "4.0.1" + version: "4.2.0" package_info_plus_platform_interface: dependency: transitive description: @@ -684,7 +829,7 @@ packages: source: hosted version: "2.0.1" path: - dependency: "direct main" + dependency: transitive description: name: path sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" @@ -708,117 +853,125 @@ packages: source: hosted version: "1.0.1" path_provider: - dependency: "direct main" + dependency: transitive description: name: path_provider - sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2" + sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa url: "https://pub.dev" source: hosted - version: "2.0.15" + version: "2.1.1" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86" + sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" url: "https://pub.dev" source: hosted - version: "2.0.27" + version: "2.2.2" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3" + sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.3.1" path_provider_linux: dependency: transitive description: name: path_provider_linux - sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57 + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 url: "https://pub.dev" source: hosted - version: "2.1.11" + version: "2.2.1" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" + sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" url: "https://pub.dev" source: hosted - version: "2.0.6" + version: "2.1.1" path_provider_windows: dependency: transitive description: name: path_provider_windows - sha256: d3f80b32e83ec208ac95253e0cd4d298e104fbc63cb29c5c69edaed43b0c69d6 + sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" url: "https://pub.dev" source: hosted - version: "2.1.6" + version: "2.2.1" permission_handler: - dependency: "direct main" + dependency: transitive description: name: permission_handler - sha256: "33c6a1253d1f95fd06fa74b65b7ba907ae9811f9d5c1d3150e51417d04b8d6a8" + sha256: bc56bfe9d3f44c3c612d8d393bd9b174eb796d706759f9b495ac254e4294baa5 url: "https://pub.dev" source: hosted - version: "10.2.0" + version: "10.4.5" permission_handler_android: dependency: transitive description: name: permission_handler_android - sha256: d8cc6a62ded6d0f49c6eac337e080b066ee3bce4d405bd9439a61e1f1927bfe8 + sha256: "59c6322171c29df93a22d150ad95f3aa19ed86542eaec409ab2691b8f35f9a47" url: "https://pub.dev" source: hosted - version: "10.2.1" + version: "10.3.6" permission_handler_apple: dependency: transitive description: name: permission_handler_apple - sha256: ee96ac32f5a8e6f80756e25b25b9f8e535816c8e6665a96b6d70681f8c4f7e85 + sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5" url: "https://pub.dev" source: hosted - version: "9.0.8" + version: "9.1.4" permission_handler_platform_interface: dependency: transitive description: name: permission_handler_platform_interface - sha256: "68abbc472002b5e6dfce47fe9898c6b7d8328d58b5d2524f75e277c07a97eb84" + sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4" url: "https://pub.dev" source: hosted - version: "3.9.0" + version: "3.12.0" permission_handler_windows: dependency: transitive description: name: permission_handler_windows - sha256: f67cab14b4328574938ecea2db3475dad7af7ead6afab6338772c5f88963e38b + sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098 url: "https://pub.dev" source: hosted - version: "0.1.2" + version: "0.1.3" petitparser: dependency: transitive description: name: petitparser - sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" + sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "5.4.0" platform: dependency: transitive description: name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.2" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc" + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.7" + pointycastle: + dependency: transitive + description: + name: pointycastle + sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + url: "https://pub.dev" + source: hosted + version: "3.7.3" pool: dependency: transitive description: @@ -835,8 +988,16 @@ packages: url: "https://pub.dev" source: hosted version: "4.2.4" + prompts: + dependency: transitive + description: + name: prompts + sha256: "3773b845e85a849f01e793c4fc18a45d52d7783b4cb6c0569fad19f9d0a774a1" + url: "https://pub.dev" + source: hosted + version: "2.0.0" protobuf: - dependency: "direct main" + dependency: transitive description: name: protobuf sha256: "01dd9bd0fa02548bf2ceee13545d4a0ec6046459d847b6b061d8a27237108a08" @@ -851,6 +1012,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + pub_updater: + dependency: transitive + description: + name: pub_updater + sha256: b06600619c8c219065a548f8f7c192b3e080beff95488ed692780f48f69c0625 + url: "https://pub.dev" + source: hosted + version: "0.3.1" + pubspec: + dependency: transitive + description: + name: pubspec + sha256: f534a50a2b4d48dc3bc0ec147c8bd7c304280fff23b153f3f11803c4d49d927e + url: "https://pub.dev" + source: hosted + version: "2.3.0" pubspec_parse: dependency: transitive description: @@ -859,6 +1036,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.3" + quiver: + dependency: transitive + description: + name: quiver + sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 + url: "https://pub.dev" + source: hosted + version: "3.2.1" riverpod: dependency: "direct dev" description: @@ -879,26 +1064,26 @@ packages: dependency: "direct main" description: name: riverpod_annotation - sha256: cedd6a54b6f5764ffd5c05df57b6676bfc8c01978e14ee60a2c16891038820fe + sha256: b70e95fbd5ca7ce42f5148092022971bb2e9843b6ab71e97d479e8ab52e98979 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.3.3" riverpod_generator: dependency: "direct dev" description: name: riverpod_generator - sha256: cd0595de57ccf5d944ff4b0f68289e11ac6a2eff1e3dfd1d884a43f6f3bcee5e + sha256: "691180275664a5420c87d72c1ed26ef8404d32b823807540172bfd1660425376" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.2.4" riverpod_lint: dependency: "direct dev" description: name: riverpod_lint - sha256: "043ff016011be4c5887b3239bfbca05d284bdb68db0a5363cee0242b7567e250" + sha256: "17ad319914ac6863c64524e598913c0f17e30688aca8f5b7509e96d6e372d493" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" rxdart: dependency: transitive description: @@ -911,58 +1096,58 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: "16d3fb6b3692ad244a695c0183fca18cf81fd4b821664394a781de42386bf022" + sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.2.2" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "6478c6bbbecfe9aced34c483171e90d7c078f5883558b30ec3163cf18402c749" + sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.1" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: e014107bb79d6d3297196f4f2d0db54b5d1f85b8ea8ff63b8e8b391a02700feb + sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.3.4" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - sha256: "9d387433ca65717bbf1be88f4d5bb18f10508917a8fa2fb02e0fd0d7479a9afa" + sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.2" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - sha256: fb5cf25c0235df2d0640ac1b1174f6466bd311f621574997ac59018a6664548d + sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.1" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - sha256: "74083203a8eae241e0de4a0d597dbedab3b8fef5563f33cf3c12d7e93c655ca5" + sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.2.1" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - sha256: "5e588e2efef56916a3b229c3bfe81e6a525665a454519ca51dbcc4236a274173" + sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.2" shelf: dependency: transitive description: @@ -985,7 +1170,7 @@ packages: source: sdk version: "0.0.99" smooth_page_indicator: - dependency: "direct main" + dependency: transitive description: name: smooth_page_indicator sha256: "725bc638d5e79df0c84658e1291449996943f93bacbc2cec49963dbbab48d8ae" @@ -996,10 +1181,10 @@ packages: dependency: transitive description: name: source_gen - sha256: "373f96cf5a8744bc9816c1ff41cf5391bbdbe3d7a96fe98c622b6738a8a7bd33" + sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.5.0" source_span: dependency: transitive description: @@ -1009,37 +1194,37 @@ packages: source: hosted version: "1.10.0" sqflite: - dependency: "direct main" + dependency: transitive description: name: sqflite - sha256: b4d6710e1200e96845747e37338ea8a819a12b51689a3bcf31eff0003b37a0b9 + sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a" url: "https://pub.dev" source: hosted - version: "2.2.8+4" + version: "2.3.0" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: e77abf6ff961d69dfef41daccbb66b51e9983cdd5cb35bf30733598057401555 + sha256: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6 url: "https://pub.dev" source: hosted - version: "2.4.5" + version: "2.5.0+2" sqflite_common_ffi: dependency: transitive description: name: sqflite_common_ffi - sha256: f86de82d37403af491b21920a696b19f01465b596f545d1acd4d29a0a72418ad + sha256: "35d2fce1e971707c227cc4775cc017d5eafe06c2654c3435ebd5c3ad6c170f5f" url: "https://pub.dev" source: hosted - version: "2.2.5" + version: "2.3.0+4" sqlite3: dependency: transitive description: name: sqlite3 - sha256: "2cef47b59d310e56f8275b13734ee80a9cf4a48a43172020cb55a620121fbf66" + sha256: db65233e6b99e99b2548932f55a987961bc06d82a31a0665451fa0b4fff4c3fb url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "2.1.0" sqlparser: dependency: transitive description: @@ -1052,26 +1237,26 @@ packages: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" state_notifier: dependency: transitive description: name: state_notifier - sha256: "8fe42610f179b843b12371e40db58c9444f8757f8b69d181c97e50787caed289" + sha256: b8677376aa54f2d7c58280d5a007f9e8774f1968d1fb1c096adcb4792fba29bb url: "https://pub.dev" source: hosted - version: "0.7.2+1" + version: "1.0.0" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" stream_transform: dependency: transitive description: @@ -1108,10 +1293,10 @@ packages: dependency: transitive description: name: synchronized - sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" + sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.0+1" term_glyph: dependency: transitive description: @@ -1124,10 +1309,10 @@ packages: dependency: transitive description: name: test_api - sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.6.0" + version: "0.6.1" timing: dependency: transitive description: @@ -1137,21 +1322,28 @@ packages: source: hosted version: "1.0.1" toast: - dependency: "direct main" + dependency: transitive description: name: toast sha256: "12433091e3e5a25b3a25f670126e42547c9ade135de30ad9ace45d1ddccd57c9" url: "https://pub.dev" source: hosted version: "0.3.0" + tools: + dependency: "direct main" + description: + path: "packages/tools" + relative: true + source: path + version: "0.0.1" typed_data: dependency: transitive description: name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" unicode: dependency: transitive description: @@ -1160,70 +1352,78 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.1" + uri: + dependency: transitive + description: + name: uri + sha256: "889eea21e953187c6099802b7b4cf5219ba8f3518f604a1033064d45b1b8268a" + url: "https://pub.dev" + source: hosted + version: "1.0.0" url_launcher: - dependency: "direct main" + dependency: transitive description: name: url_launcher - sha256: eb1e00ab44303d50dd487aab67ebc575456c146c6af44422f9c13889984c00f3 + sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27" url: "https://pub.dev" source: hosted - version: "6.1.11" + version: "6.1.14" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "1a5848f598acc5b7d8f7c18b8cb834ab667e59a13edc3c93e9d09cf38cc6bc87" + sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def" url: "https://pub.dev" source: hosted - version: "6.0.34" + version: "6.2.0" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2" + sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3 url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "6.2.1" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5" + sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811 url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.1.1" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: "91ee3e75ea9dadf38036200c5d3743518f4a5eb77a8d13fda1ee5764373f185e" + sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234 url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.1.0" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface - sha256: "6c9ca697a5ae218ce56cece69d46128169a58aa8653c1b01d26fcd4aad8c4370" + sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.2.0" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: "6bb1e5d7fe53daf02a8fee85352432a40b1f868a81880e99ec7440113d5cfcab" + sha256: ba140138558fcc3eead51a1c42e92a9fb074a1b1149ed3c73e66035b2ccd94f2 url: "https://pub.dev" source: hosted - version: "2.0.17" + version: "2.0.19" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "254708f17f7c20a9c8c471f67d86d76d4a3f9c1591aad1e15292008aceb82771" + sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7 url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.1.1" uuid: dependency: transitive description: @@ -1244,26 +1444,26 @@ packages: dependency: transitive description: name: vm_service - sha256: c620a6f783fa22436da68e42db7ebbf18b8c44b9a46ab911f666ff09ffd9153f + sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583 url: "https://pub.dev" source: hosted - version: "11.7.1" + version: "11.10.0" watcher: dependency: transitive description: name: watcher - sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.1.0" web: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" web_socket_channel: dependency: transitive description: @@ -1284,34 +1484,41 @@ packages: dependency: transitive description: name: win32 - sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c" + sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" url: "https://pub.dev" source: hosted - version: "4.1.4" + version: "5.0.9" win32_registry: dependency: transitive description: name: win32_registry - sha256: "1c52f994bdccb77103a6231ad4ea331a244dbcef5d1f37d8462f713143b0bfae" + sha256: e4506d60b7244251bc59df15656a3093501c37fb5af02105a944d73eb95be4c9 url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" + workspace_screen: + dependency: "direct main" + description: + path: "packages/features/workspace_screen" + relative: true + source: path + version: "0.0.1" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1 + sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.0.3" xml: dependency: transitive description: name: xml - sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5" + sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" url: "https://pub.dev" source: hosted - version: "6.2.2" + version: "6.3.0" yaml: dependency: transitive description: @@ -1320,6 +1527,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.2" + yaml_edit: + dependency: transitive + description: + name: yaml_edit + sha256: "1579d4a0340a83cf9e4d580ea51a16329c916973bffd5bd4b45e911b25d46bfd" + url: "https://pub.dev" + source: hosted + version: "2.1.1" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" - flutter: ">=3.3.0" + dart: ">=3.2.0-194.0.dev <4.0.0" + flutter: ">=3.10.0" diff --git a/pubspec.yaml b/pubspec.yaml index dbdc8a32..82c8b039 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: paintroid description: The standard image manipulation app for Catroid. -publish_to: 'none' +publish_to: "none" version: 1.0.0+1 @@ -11,56 +11,56 @@ environment: dependencies: flutter: sdk: flutter + flutter_localizations: + sdk: flutter + flutter_localization: ^0.1.12 intl: ^0.18.0 - equatable: ^2.0.3 - flutter_svg: ^1.1.0 - image: ^3.2.0 - protobuf: ^2.1.0 - path: ^1.8.1 - path_provider: ^2.0.11 + logging: ^1.0.2 flutter_riverpod: ^2.3.6 riverpod_annotation: ^2.1.1 - freezed_annotation: ^2.4.1 - image_picker: ^0.8.5+3 - oxidized: ^5.2.0 - logging: ^1.0.2 - file_picker: ^5.3.1 - floor: ^1.2.0 - filesize: ^2.0.1 - toast: ^0.3.0 - sqflite: - permission_handler: ^10.0.0 - url_launcher: ^6.1.5 - package_info_plus: ^4.0.1 - device_info_plus: ^9.0.3 - launch_review: ^3.0.1 - smooth_page_indicator: ^1.0.0+2 shared_preferences: ^2.0.15 + freezed_annotation: ^2.4.1 + melos: ^3.4.0 + + # Internal packages: + component_library: + path: ./packages/component_library + l10n: + path: ./packages/l10n + command: + path: ./packages/command + io_library: + path: ./packages/io_library + tools: + path: ./packages/tools + workspace_screen: + path: ./packages/features/workspace_screen + landing_page_screen: + path: ./packages/features/landing_page_screen + onboarding_screen: + path: ./packages/features/onboarding_screen colorpicker: - path: ./colorpicker + path: ./packages/colorpicker dev_dependencies: flutter_test: sdk: flutter integration_test: sdk: flutter + mockito: ^5.2.0 - build_runner: ^2.2.0 flutter_launcher_icons: ^0.9.3 flutter_lints: ^2.0.1 floor_generator: ^1.2.0 riverpod_generator: ^2.2.3 riverpod_lint: ^1.3.2 + build_runner: ^2.2.0 freezed: ^2.4.1 riverpod: ^2.3.7 flutter: - generate: true uses-material-design: true assets: - assets/icon/ - - assets/svg/ - - assets/img/ - - test/fixture/image/ diff --git a/setup_melos.sh b/setup_melos.sh new file mode 100755 index 00000000..10cfa6e3 --- /dev/null +++ b/setup_melos.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# Check if the 'melos' command is available +if ! command -v melos &> /dev/null; then + echo "Melos is not installed. Installing Melos globally using Dart." + make melos + + if [ $? -eq 0 ]; then + echo "Successfully installed Melos." + else + echo "Failed to install Melos." + exit 1 + fi +fi \ No newline at end of file diff --git a/setup_sdk.sh b/setup_sdk.sh new file mode 100755 index 00000000..680ef818 --- /dev/null +++ b/setup_sdk.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +MELOS_CONFIG="melos.yaml" +MAKEFILE="Makefile" + +# Try running 'fvm flutter pub get' to check if FVM is properly configured +if fvm flutter pub get; then + echo "FVM Flutter SDK is properly configured." + + # Use sed to set the sdkPath to '.fvm/flutter_sdk' in melos.yaml + sed -i.bak 's|sdkPath: .*|sdkPath: .fvm/flutter_sdk|' "$MELOS_CONFIG" && rm "${MELOS_CONFIG}.bak" + + if [ $? -eq 0 ]; then + echo " -> Successfully set sdkPath to .fvm/flutter_sdk in melos.yaml." + else + echo " -> Failed to set sdkPath in melos.yaml." + exit 1 + fi + + # Use sed to set the FLUTTER variable to 'fvm flutter' in Makefile + sed -i.bak 's|FLUTTER := .*|FLUTTER := fvm flutter|' "$MAKEFILE" && rm "${MAKEFILE}.bak" + + if [ $? -eq 0 ]; then + echo " -> Successfully set FLUTTER to 'fvm flutter' in Makefile." + else + echo " -> Failed to set FLUTTER in Makefile." + exit 1 + fi + + sed -i.bak 's|DART := .*|DART := fvm dart|' "$MAKEFILE" && rm "${MAKEFILE}.bak" + + if [ $? -eq 0 ]; then + echo " -> Successfully set DART to 'fvm dart' in Makefile." + else + echo " -> Failed to set DART in Makefile." + exit 1 + fi + +else + echo "FVM Flutter SDK not properly configured." + + # Use sed to replace the sdkPath with 'auto' in melos.yaml + sed -i.bak 's|sdkPath: .*|sdkPath: auto|' "$MELOS_CONFIG" && rm "${MELOS_CONFIG}.bak" + + if [ $? -eq 0 ]; then + echo " -> Successfully updated sdkPath to auto in melos.yaml." + else + echo " -> Failed to update sdkPath in melos.yaml." + exit 1 + fi + + # Use sed to replace the FLUTTER with 'flutter' in Makefile + sed -i.bak 's|FLUTTER := .*|FLUTTER := flutter|' "$MAKEFILE" && rm "${MAKEFILE}.bak" + + if [ $? -eq 0 ]; then + echo " -> Successfully updated FLUTTER to 'flutter' in Makefile." + else + echo " -> Failed to update FLUTTER in Makefile." + exit 1 + fi + + sed -i.bak 's|DART := .*|DART := dart|' "$MAKEFILE" && rm "${MAKEFILE}.bak" + + if [ $? -eq 0 ]; then + echo " -> Successfully updated DART to 'dart' in Makefile." + else + echo " -> Failed to update DART in Makefile." + exit 1 + fi + + flutter pub get +fi diff --git a/test/widget/utils/utils.dart b/test/widget/utils/utils.dart deleted file mode 100644 index 7a4db9b7..00000000 --- a/test/widget/utils/utils.dart +++ /dev/null @@ -1,2 +0,0 @@ -export 'interactions/bottom_nav_bar_interactions.dart'; -export 'interactions/canvas_interactions.dart'; From 492d8c1af277f6f3f4cf0d59c6bc8a408d9f14fc Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Tue, 23 Jan 2024 03:17:22 +0530 Subject: [PATCH 05/39] Fix issues --- .../src/models/path_with_action_history.dart | 144 +----------------- 1 file changed, 5 insertions(+), 139 deletions(-) diff --git a/packages/component_library/lib/src/models/path_with_action_history.dart b/packages/component_library/lib/src/models/path_with_action_history.dart index 596c07b7..a9ad9e14 100644 --- a/packages/component_library/lib/src/models/path_with_action_history.dart +++ b/packages/component_library/lib/src/models/path_with_action_history.dart @@ -1,158 +1,24 @@ -import 'dart:typed_data'; import 'dart:ui'; -class PathWithActionHistory implements Path { +class PathWithActionHistory extends Path { final actions = []; - final Path _path = Path(); - @override void moveTo(double x, double y) { actions.add(MoveToAction(x, y)); - _path.moveTo(x, y); + super.moveTo(x, y); } @override void lineTo(double x, double y) { actions.add(LineToAction(x, y)); - _path.lineTo(x, y); + super.lineTo(x, y); } @override void close() { actions.add(const CloseAction()); - _path.close(); - } - - @override - PathFillType get fillType => _path.fillType; - - @override - set fillType(PathFillType value) => _path.fillType = value; - - @override - void addArc(Rect oval, double startAngle, double sweepAngle) { - // TODO: implement addArc - } - - @override - void addOval(Rect oval) { - // TODO: implement addOval - } - - @override - void addPath(Path path, Offset offset, {Float64List? matrix4}) { - // TODO: implement addPath - } - - @override - void addPolygon(List points, bool close) { - // TODO: implement addPolygon - } - - @override - void addRRect(RRect rrect) { - // TODO: implement addRRect - } - - @override - void addRect(Rect rect) { - // TODO: implement addRect - } - - @override - void arcTo(Rect rect, double startAngle, double sweepAngle, bool forceMoveTo) { - // TODO: implement arcTo - } - - @override - void arcToPoint(Offset arcEnd, {Radius radius = Radius.zero, double rotation = 0.0, bool largeArc = false, bool clockwise = true}) { - // TODO: implement arcToPoint - } - - @override - PathMetrics computeMetrics({bool forceClosed = false}) { - // TODO: implement computeMetrics - throw UnimplementedError(); - } - - @override - void conicTo(double x1, double y1, double x2, double y2, double w) { - // TODO: implement conicTo - } - - @override - bool contains(Offset point) { - // TODO: implement contains - throw UnimplementedError(); - } - - @override - void cubicTo(double x1, double y1, double x2, double y2, double x3, double y3) { - // TODO: implement cubicTo - } - - @override - void extendWithPath(Path path, Offset offset, {Float64List? matrix4}) { - // TODO: implement extendWithPath - } - - @override - Rect getBounds() { - // TODO: implement getBounds - throw UnimplementedError(); - } - - @override - void quadraticBezierTo(double x1, double y1, double x2, double y2) { - // TODO: implement quadraticBezierTo - } - - @override - void relativeArcToPoint(Offset arcEndDelta, {Radius radius = Radius.zero, double rotation = 0.0, bool largeArc = false, bool clockwise = true}) { - // TODO: implement relativeArcToPoint - } - - @override - void relativeConicTo(double x1, double y1, double x2, double y2, double w) { - // TODO: implement relativeConicTo - } - - @override - void relativeCubicTo(double x1, double y1, double x2, double y2, double x3, double y3) { - // TODO: implement relativeCubicTo - } - - @override - void relativeLineTo(double dx, double dy) { - // TODO: implement relativeLineTo - } - - @override - void relativeMoveTo(double dx, double dy) { - // TODO: implement relativeMoveTo - } - - @override - void relativeQuadraticBezierTo(double x1, double y1, double x2, double y2) { - // TODO: implement relativeQuadraticBezierTo - } - - @override - void reset() { - // TODO: implement reset - } - - @override - Path shift(Offset offset) { - // TODO: implement shift - throw UnimplementedError(); - } - - @override - Path transform(Float64List matrix4) { - // TODO: implement transform - throw UnimplementedError(); + super.close(); } } @@ -176,4 +42,4 @@ class LineToAction extends PathAction { class CloseAction extends PathAction { const CloseAction(); -} +} \ No newline at end of file From eca8dcd540055af25459968c7ed3bd6639e985d9 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Tue, 23 Jan 2024 03:31:10 +0530 Subject: [PATCH 06/39] Resolve pubspec errors --- pubspec.lock | 160 +++++++++++++++++++++++---------------------------- 1 file changed, 73 insertions(+), 87 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index f930b3a5..af8a521b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: archive - sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b" + sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d" url: "https://pub.dev" source: hosted - version: "3.4.9" + version: "3.4.10" args: dependency: transitive description: @@ -101,10 +101,10 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "67d591d602906ef9201caf93452495ad1812bea2074f04e25dbd7c133785821b" + sha256: "581bacf68f89ec8792f5e5a0b2c4decd1c948e97ce659dc783688c8a88fbec21" url: "https://pub.dev" source: hosted - version: "2.4.7" + version: "2.4.8" build_runner_core: dependency: transitive description: @@ -189,10 +189,10 @@ packages: dependency: transitive description: name: code_builder - sha256: feee43a5c05e7b3199bb375a86430b8ada1b04104f2923d0e03cc01ca87b6d84 + sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 url: "https://pub.dev" source: hosted - version: "4.9.0" + version: "4.10.0" collection: dependency: transitive description: @@ -222,28 +222,6 @@ packages: relative: true source: path version: "0.0.1" - conventional_commit: - dependency: transitive - description: - name: conventional_commit - sha256: dec15ad1118f029c618651a4359eb9135d8b88f761aa24e4016d061cd45948f2 - url: "https://pub.dev" - source: hosted - version: "1.17.1" - command: - dependency: "direct main" - description: - path: "packages/command" - relative: true - source: path - version: "0.0.1" - component_library: - dependency: "direct main" - description: - path: "packages/component_library" - relative: true - source: path - version: "0.0.1" conventional_commit: dependency: transitive description: @@ -264,10 +242,10 @@ packages: dependency: transitive description: name: cross_file - sha256: "2f9d2cbccb76127ba28528cb3ae2c2326a122446a83de5a056aaa3880d3882c5" + sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e url: "https://pub.dev" source: hosted - version: "0.3.3+7" + version: "0.3.3+8" crypto: dependency: transitive description: @@ -391,10 +369,10 @@ packages: dependency: transitive description: name: file_selector_platform_interface - sha256: "0aa47a725c346825a2bd396343ce63ac00bda6eff2fbc43eabe99737dede8262" + sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b url: "https://pub.dev" source: hosted - version: "2.6.1" + version: "2.6.2" file_selector_windows: dependency: transitive description: @@ -573,10 +551,10 @@ packages: dependency: transitive description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.0" http_multi_server: dependency: transitive description: @@ -613,10 +591,10 @@ packages: dependency: transitive description: name: image_picker_android - sha256: ecdc963d2aa67af5195e723a40580f802d4392e31457a12a562b3e2bd6a396fe + sha256: "39f2bfe497e495450c81abcd44b62f56c2a36a37a175da7d137b4454977b51b1" url: "https://pub.dev" source: hosted - version: "0.8.9+1" + version: "0.8.9+3" image_picker_for_web: dependency: transitive description: @@ -629,10 +607,10 @@ packages: dependency: transitive description: name: image_picker_ios - sha256: eac0a62104fa12feed213596df0321f57ce5a572562f72a68c4ff81e9e4caacf + sha256: fadafce49e8569257a0cad56d24438a6fa1f0cbd7ee0af9b631f7492818a4ca3 url: "https://pub.dev" source: hosted - version: "0.8.9" + version: "0.8.9+1" image_picker_linux: dependency: transitive description: @@ -653,10 +631,10 @@ packages: dependency: transitive description: name: image_picker_platform_interface - sha256: ed9b00e63977c93b0d2d2b343685bed9c324534ba5abafbb3dfbd6a780b1b514 + sha256: fa4e815e6fcada50e35718727d83ba1c92f1edf95c0b4436554cec301b56233b url: "https://pub.dev" source: hosted - version: "2.9.1" + version: "2.9.3" image_picker_windows: dependency: transitive description: @@ -770,7 +748,7 @@ packages: sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.5.0" melos: dependency: "direct main" description: @@ -799,10 +777,10 @@ packages: dependency: "direct dev" description: name: mockito - sha256: "7d5b53bcd556c1bc7ffbe4e4d5a19c3e112b7e925e9e172dd7c6ad0630812616" + sha256: "6841eed20a7befac0ce07df8116c8b8233ed1f4486a7647c7fc5a02ae6163917" url: "https://pub.dev" source: hosted - version: "5.4.2" + version: "5.4.4" mustache_template: dependency: transitive description: @@ -878,10 +856,10 @@ packages: dependency: transitive description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_android: dependency: transitive description: @@ -894,10 +872,10 @@ packages: dependency: transitive description: name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" path_provider_linux: dependency: transitive description: @@ -910,10 +888,10 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_windows: dependency: transitive description: @@ -966,10 +944,10 @@ packages: dependency: transitive description: name: petitparser - sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 url: "https://pub.dev" source: hosted - version: "5.4.0" + version: "6.0.2" platform: dependency: transitive description: @@ -982,18 +960,18 @@ packages: dependency: transitive description: name: plugin_platform_interface - sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" url: "https://pub.dev" source: hosted - version: "2.1.7" + version: "2.1.8" pointycastle: dependency: transitive description: name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" url: "https://pub.dev" source: hosted - version: "3.7.3" + version: "3.7.4" pool: dependency: transitive description: @@ -1134,10 +1112,10 @@ packages: dependency: transitive description: name: shared_preferences_foundation - sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7" + sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c" url: "https://pub.dev" source: hosted - version: "2.3.4" + version: "2.3.5" shared_preferences_linux: dependency: transitive description: @@ -1150,18 +1128,18 @@ packages: dependency: transitive description: name: shared_preferences_platform_interface - sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a + sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf + sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" shared_preferences_windows: dependency: transitive description: @@ -1227,26 +1205,26 @@ packages: dependency: transitive description: name: sqflite_common - sha256: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6 + sha256: "76db4d324c8cbb16ca5b60ad2f3d25cec953107c93ae65aafa480d3e6fb69f14" url: "https://pub.dev" source: hosted - version: "2.5.0+2" + version: "2.5.2-1" sqflite_common_ffi: dependency: transitive description: name: sqflite_common_ffi - sha256: "35d2fce1e971707c227cc4775cc017d5eafe06c2654c3435ebd5c3ad6c170f5f" + sha256: d0e3f0d04fdf668e57db8db1df758f56c4193cb429092c708e7bfcc6ab04b27e url: "https://pub.dev" source: hosted - version: "2.3.0+4" + version: "2.3.2" sqlite3: dependency: transitive description: name: sqlite3 - sha256: db65233e6b99e99b2548932f55a987961bc06d82a31a0665451fa0b4fff4c3fb + sha256: c4a4c5a4b2a32e2d0f6837b33d7c91a67903891a5b7dbe706cf4b1f6b0c798c5 url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.3.0" sqlparser: dependency: transitive description: @@ -1386,26 +1364,26 @@ packages: dependency: transitive description: name: url_launcher - sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27" + sha256: d25bb0ca00432a5e1ee40e69c36c85863addf7cc45e433769d61bed3fe81fd96 url: "https://pub.dev" source: hosted - version: "6.1.14" + version: "6.2.3" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def" + sha256: "507dc655b1d9cb5ebc756032eb785f114e415f91557b73bf60b7e201dfedeb2f" url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.2.2" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3 + sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03" url: "https://pub.dev" source: hosted - version: "6.2.1" + version: "6.2.4" url_launcher_linux: dependency: transitive description: @@ -1426,18 +1404,18 @@ packages: dependency: transitive description: name: url_launcher_platform_interface - sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50" + sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.1" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: ba140138558fcc3eead51a1c42e92a9fb074a1b1149ed3c73e66035b2ccd94f2 + sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b url: "https://pub.dev" source: hosted - version: "2.0.19" + version: "2.2.3" url_launcher_windows: dependency: transitive description: @@ -1478,6 +1456,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + url: "https://pub.dev" + source: hosted + version: "0.3.0" web_socket_channel: dependency: transitive description: @@ -1498,18 +1484,18 @@ packages: dependency: transitive description: name: win32 - sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" + sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8" url: "https://pub.dev" source: hosted - version: "5.0.9" + version: "5.2.0" win32_registry: dependency: transitive description: name: win32_registry - sha256: e4506d60b7244251bc59df15656a3093501c37fb5af02105a944d73eb95be4c9 + sha256: "41fd8a189940d8696b1b810efb9abcf60827b6cbfab90b0c43e8439e3a39d85a" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" workspace_screen: dependency: "direct main" description: @@ -1521,18 +1507,18 @@ packages: dependency: transitive description: name: xdg_directories - sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" + sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.0.4" xml: dependency: transitive description: name: xml - sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "6.5.0" yaml: dependency: transitive description: @@ -1550,5 +1536,5 @@ packages: source: hosted version: "2.1.1" sdks: - dart: ">=3.0.5 <4.0.0" - flutter: ">=3.10.0" + dart: ">=3.2.0 <4.0.0" + flutter: ">=3.16.0" From 0a14b444a3426068acf9c3e9a519bfd36feeab53 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Mon, 19 Feb 2024 02:27:17 +0530 Subject: [PATCH 07/39] address requested changes --- .github/workflows/main.yml | 4 - Makefile | 4 +- generate_protos.sh | 3 - melos.yaml | 2 +- packages/colorpicker/.gitignore | 29 -- packages/colorpicker/CHANGELOG.md | 3 - packages/colorpicker/LICENSE | 1 - packages/colorpicker/README.md | 39 -- packages/colorpicker/analysis_options.yaml | 23 +- packages/colorpicker/lib/colorpicker.dart | 119 +---- packages/colorpicker/lib/src/colorpicker.dart | 123 +++++ .../lib/{ => src}/constants/colors.dart | 0 .../lib/{ => src}/widgets/color_compare.dart | 15 +- .../lib/{ => src}/widgets/slider.dart | 16 +- .../{ => src}/widgets/slider_indicator.dart | 0 packages/colorpicker/pubspec.yaml | 30 +- .../colorpicker/test/colorpicker_test.dart | 7 - packages/command/lib/command.dart | 15 +- packages/command/lib/command_providers.dart | 5 +- .../lib/graphic_factory}/graphic_factory.dart | 2 +- .../graphic_factory_provider.dart | 2 +- .../graphic_factory_provider.g.dart | 0 packages/command/lib/src/command.dart | 5 - .../command_factory.dart | 1 - .../command_factory_provider.dart | 0 .../command_factory_provider.g.dart | 0 .../src/command_implementation/command.dart | 19 + .../graphic/draw_path_command.dart | 51 +++ .../graphic/draw_path_command.g.dart | 24 + .../graphic}/graphic_command.dart | 2 + .../command_manager.dart | 0 .../command_manager_provider.dart | 0 .../command_manager_provider.g.dart | 0 .../sync_command_manager.dart | 0 .../lib/src/graphic/draw_path_command.dart | 18 - .../lib/utils/path_with_action_history.dart | 236 ++++++++++ packages/command/pubspec.yaml | 6 + .../test/unit/command_factory_test.dart | 3 +- .../test/unit/draw_path_command_test.dart | 1 - .../lib/component_library.dart | 11 +- .../src/models/path_with_action_history.dart | 45 -- packages/component_library/pubspec.yaml | 2 + .../components/bottom_bar/bottom_nav_bar.dart | 112 +++++ .../bottom_bar/bottom_nav_bar_items.dart | 6 + .../tool_options/stroke_cap_tool_option.dart} | 11 +- .../tool_options/stroke_tool_options.dart | 14 + .../stroke_width_tool_option.dart} | 9 +- .../bottom_bar/tool_options/tool_option.dart | 28 ++ .../bottom_bar/tool_options/tool_options.dart | 30 ++ .../{ => bottom_bar/tools}/tool_button.dart | 0 .../tools}/tools_bottom_sheet.dart | 1 + .../lib/src/components/bottom_nav_bar.dart | 91 ---- .../{ => drawing_surface}/canvas_painter.dart | 0 .../checkerboard_pattern.dart | 0 .../command_painter.dart | 0 .../{ => drawing_surface}/drawing_canvas.dart | 0 .../exit_fullscreen_button.dart | 0 .../lib/src/components/tool_options.dart | 20 - .../{ => top_bar}/overflow_menu.dart | 0 .../components/{ => top_bar}/top_app_bar.dart | 0 .../lib/src/states/canvas_state_data.dart | 1 - .../lib/src/states/canvas_state_provider.dart | 2 - ...ool_options_visibility_state_provider.dart | 15 + ...l_options_visibility_state_provider.g.dart | 27 ++ .../src/usecase/render_image_for_export.dart | 1 - .../lib/workspace_screen.dart | 35 +- .../unit/render_image_for_export_test.dart | 3 +- .../bottom_control_navigation_bar_test.dart | 166 ++++++- .../widget/bottom_nav_bar_interactions.dart | 18 + packages/io_library/lib/io_library.dart | 21 +- packages/io_library/lib/serialization.dart | 10 - packages/io_library/lib/src/io_handler.dart | 17 +- .../converter/paint_converter.dart | 50 +++ .../converter/path_action_converter.dart | 44 ++ .../path_with_action_history_converter.dart | 34 ++ .../versioning/serializer_version.dart | 19 + .../versioning/version_strategy.dart | 25 ++ .../lib/src/models/catrobat_image.dart | 51 ++- .../lib/src/models/catrobat_image.g.dart | 28 ++ .../proto/output/catrobat_image.pb.dart | 161 ------- .../proto/output/catrobat_image.pbenum.dart | 10 - .../proto/output/catrobat_image.pbjson.dart | 42 -- .../proto/output/catrobat_image.pbserver.dart | 13 - .../command/graphic/draw_path_command.pb.dart | 108 ----- .../graphic/draw_path_command.pbenum.dart | 10 - .../graphic/draw_path_command.pbjson.dart | 43 -- .../graphic/draw_path_command.pbserver.dart | 13 - .../proto/output/google/protobuf/any.pb.dart | 224 ---------- .../output/google/protobuf/any.pbenum.dart | 10 - .../output/google/protobuf/any.pbjson.dart | 27 -- .../output/google/protobuf/any.pbserver.dart | 13 - .../proto/output/graphic/paint.pb.dart | 187 -------- .../proto/output/graphic/paint.pbenum.dart | 115 ----- .../proto/output/graphic/paint.pbjson.dart | 113 ----- .../proto/output/graphic/paint.pbserver.dart | 13 - .../proto/output/graphic/path.pb.dart | 420 ------------------ .../proto/output/graphic/path.pbenum.dart | 35 -- .../proto/output/graphic/path.pbjson.dart | 125 ------ .../proto/output/graphic/path.pbserver.dart | 13 - .../lib/src/serialization/proto/protos.dart | 4 - .../proto/schema/catrobat_image.proto | 12 - .../command/graphic/draw_path_command.proto | 9 - .../proto/schema/graphic/paint.proto | 34 -- .../proto/schema/graphic/path.proto | 27 -- .../proto_serializer_with_versioning.dart | 22 - .../serializer/catrobat_image_serializer.dart | 78 ---- .../graphic/draw_path_command_serializer.dart | 48 -- .../serializer/graphic/paint_serializer.dart | 68 --- .../serializer/graphic/path_serializer.dart | 81 ---- .../src/serialization/version_serializer.dart | 27 -- .../usecase/load_image_from_file_manager.dart | 32 +- .../src/usecase/save_as_catrobat_image.dart | 10 +- packages/io_library/pubspec.yaml | 3 + .../draw_path_command_serializer_test.dart | 60 +++ .../converter/paint_converter_test.dart | 90 ++++ .../converter/path_action_converter_test.dart | 47 ++ ...th_with_action_history_converter_test.dart | 43 ++ .../image/catrobat_image_serializer_test.dart | 55 +++ .../serialization/paint_serializer_test.dart | 53 --- .../utils/dummy_command_factory.dart | 63 +++ .../utils/dummy_paint_factory.dart | 39 ++ .../utils/dummy_path_factory.dart | 14 + .../utils/dummy_version_strategy.dart | 17 + .../l10n/lib/src/l10n/app_localizations.dart | 33 +- .../tools/lib/src/brush_tool/brush_tool.dart | 1 - .../src/brush_tool/brush_tool_provider.dart | 3 +- .../brush_tool/brush_tool_state_provider.dart | 2 +- .../src/eraser_tool/eraser_tool_provider.dart | 3 +- .../tools/lib/src/hand_tool/hand_tool.dart | 1 - .../test/unit/brush_tool_state_test.dart | 4 +- packages/tools/test/unit/brush_tool_test.dart | 1 - .../test/unit/brush_tool_test.mocks.dart | 63 ++- .../tools/test/unit/hand_tool_test.mocks.dart | 3 +- pubspec.lock | 130 +++--- pubspec.yaml | 2 - 135 files changed, 1802 insertions(+), 2830 deletions(-) delete mode 100755 generate_protos.sh delete mode 100644 packages/colorpicker/.gitignore delete mode 100644 packages/colorpicker/CHANGELOG.md delete mode 100644 packages/colorpicker/LICENSE delete mode 100644 packages/colorpicker/README.md create mode 100644 packages/colorpicker/lib/src/colorpicker.dart rename packages/colorpicker/lib/{ => src}/constants/colors.dart (100%) rename packages/colorpicker/lib/{ => src}/widgets/color_compare.dart (85%) rename packages/colorpicker/lib/{ => src}/widgets/slider.dart (86%) rename packages/colorpicker/lib/{ => src}/widgets/slider_indicator.dart (100%) delete mode 100644 packages/colorpicker/test/colorpicker_test.dart rename packages/{component_library/lib/src/models => command/lib/graphic_factory}/graphic_factory.dart (94%) rename packages/{component_library/lib/src => command/lib/graphic_factory}/graphic_factory_provider.dart (77%) rename packages/{component_library/lib/src => command/lib/graphic_factory}/graphic_factory_provider.g.dart (100%) delete mode 100644 packages/command/lib/src/command.dart rename packages/command/lib/src/{ => command_factory}/command_factory.dart (80%) rename packages/command/lib/src/{ => command_factory}/command_factory_provider.dart (100%) rename packages/command/lib/src/{ => command_factory}/command_factory_provider.g.dart (100%) create mode 100644 packages/command/lib/src/command_implementation/command.dart create mode 100644 packages/command/lib/src/command_implementation/graphic/draw_path_command.dart create mode 100644 packages/command/lib/src/command_implementation/graphic/draw_path_command.g.dart rename packages/command/lib/src/{ => command_implementation/graphic}/graphic_command.dart (75%) rename packages/command/lib/src/{ => command_manager}/command_manager.dart (100%) rename packages/command/lib/src/{ => command_manager}/command_manager_provider.dart (100%) rename packages/command/lib/src/{ => command_manager}/command_manager_provider.g.dart (100%) rename packages/command/lib/src/{manager => command_manager}/sync_command_manager.dart (100%) delete mode 100644 packages/command/lib/src/graphic/draw_path_command.dart create mode 100644 packages/command/lib/utils/path_with_action_history.dart delete mode 100644 packages/component_library/lib/src/models/path_with_action_history.dart create mode 100644 packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart create mode 100644 packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar_items.dart rename packages/features/workspace_screen/lib/src/components/{bottom_brush_tool_options.dart => bottom_bar/tool_options/stroke_cap_tool_option.dart} (90%) create mode 100644 packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_tool_options.dart rename packages/features/workspace_screen/lib/src/components/{top_brush_tool_options.dart => bottom_bar/tool_options/stroke_width_tool_option.dart} (90%) create mode 100644 packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/tool_option.dart create mode 100644 packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/tool_options.dart rename packages/features/workspace_screen/lib/src/components/{ => bottom_bar/tools}/tool_button.dart (100%) rename packages/features/workspace_screen/lib/src/components/{ => bottom_bar/tools}/tools_bottom_sheet.dart (87%) delete mode 100644 packages/features/workspace_screen/lib/src/components/bottom_nav_bar.dart rename packages/features/workspace_screen/lib/src/components/{ => drawing_surface}/canvas_painter.dart (100%) rename packages/features/workspace_screen/lib/src/components/{ => drawing_surface}/checkerboard_pattern.dart (100%) rename packages/features/workspace_screen/lib/src/components/{ => drawing_surface}/command_painter.dart (100%) rename packages/features/workspace_screen/lib/src/components/{ => drawing_surface}/drawing_canvas.dart (100%) rename packages/features/workspace_screen/lib/src/components/{ => drawing_surface}/exit_fullscreen_button.dart (100%) delete mode 100644 packages/features/workspace_screen/lib/src/components/tool_options.dart rename packages/features/workspace_screen/lib/src/components/{ => top_bar}/overflow_menu.dart (100%) rename packages/features/workspace_screen/lib/src/components/{ => top_bar}/top_app_bar.dart (100%) create mode 100644 packages/features/workspace_screen/lib/src/states/tool_options_visibility_state_provider.dart create mode 100644 packages/features/workspace_screen/lib/src/states/tool_options_visibility_state_provider.g.dart delete mode 100644 packages/io_library/lib/serialization.dart create mode 100644 packages/io_library/lib/src/json_serialization/converter/paint_converter.dart create mode 100644 packages/io_library/lib/src/json_serialization/converter/path_action_converter.dart create mode 100644 packages/io_library/lib/src/json_serialization/converter/path_with_action_history_converter.dart create mode 100644 packages/io_library/lib/src/json_serialization/versioning/serializer_version.dart create mode 100644 packages/io_library/lib/src/json_serialization/versioning/version_strategy.dart create mode 100644 packages/io_library/lib/src/models/catrobat_image.g.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/catrobat_image.pb.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbenum.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbjson.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbserver.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pb.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbenum.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbjson.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbserver.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pb.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbenum.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbjson.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbserver.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/paint.pb.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbenum.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbjson.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbserver.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/path.pb.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/path.pbenum.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/path.pbjson.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/output/graphic/path.pbserver.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/protos.dart delete mode 100644 packages/io_library/lib/src/serialization/proto/schema/catrobat_image.proto delete mode 100644 packages/io_library/lib/src/serialization/proto/schema/command/graphic/draw_path_command.proto delete mode 100644 packages/io_library/lib/src/serialization/proto/schema/graphic/paint.proto delete mode 100644 packages/io_library/lib/src/serialization/proto/schema/graphic/path.proto delete mode 100644 packages/io_library/lib/src/serialization/proto_serializer_with_versioning.dart delete mode 100644 packages/io_library/lib/src/serialization/serializer/catrobat_image_serializer.dart delete mode 100644 packages/io_library/lib/src/serialization/serializer/command/graphic/draw_path_command_serializer.dart delete mode 100644 packages/io_library/lib/src/serialization/serializer/graphic/paint_serializer.dart delete mode 100644 packages/io_library/lib/src/serialization/serializer/graphic/path_serializer.dart delete mode 100644 packages/io_library/lib/src/serialization/version_serializer.dart create mode 100644 packages/io_library/test/unit/serialization/command/draw_path_command_serializer_test.dart create mode 100644 packages/io_library/test/unit/serialization/converter/paint_converter_test.dart create mode 100644 packages/io_library/test/unit/serialization/converter/path_action_converter_test.dart create mode 100644 packages/io_library/test/unit/serialization/converter/path_with_action_history_converter_test.dart create mode 100644 packages/io_library/test/unit/serialization/image/catrobat_image_serializer_test.dart delete mode 100644 packages/io_library/test/unit/serialization/paint_serializer_test.dart create mode 100644 packages/io_library/test/unit/serialization/utils/dummy_command_factory.dart create mode 100644 packages/io_library/test/unit/serialization/utils/dummy_paint_factory.dart create mode 100644 packages/io_library/test/unit/serialization/utils/dummy_path_factory.dart create mode 100644 packages/io_library/test/unit/serialization/utils/dummy_version_strategy.dart diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4d3fe53b..b522c6d9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,10 +7,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Install Protoc - uses: arduino/setup-protoc@v2 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - uses: subosito/flutter-action@v2.10.0 with: flutter-version: "3.10.5" diff --git a/Makefile b/Makefile index 516b0a8d..528b93e2 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: run pods-clean get clean build languages lint format test watch -FLUTTER := fvm flutter -DART := fvm dart +FLUTTER := flutter +DART := dart run: $(FLUTTER) run diff --git a/generate_protos.sh b/generate_protos.sh deleted file mode 100755 index bcdcea6a..00000000 --- a/generate_protos.sh +++ /dev/null @@ -1,3 +0,0 @@ -cd packages/io_library/lib/src/serialization/proto || exit -mkdir -p output -protoc --dart_out=output --proto_path=schema $(find schema -iname "*.proto") google/protobuf/any.proto diff --git a/melos.yaml b/melos.yaml index 1a3b743c..eb95a60a 100644 --- a/melos.yaml +++ b/melos.yaml @@ -1,6 +1,6 @@ name: Paintroid-Flutter repository: https://github.com/Catrobat/Paintroid-Flutter -sdkPath: .fvm/flutter_sdk +sdkPath: auto packages: - packages/* diff --git a/packages/colorpicker/.gitignore b/packages/colorpicker/.gitignore deleted file mode 100644 index ac5aa989..00000000 --- a/packages/colorpicker/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ -migrate_working_dir/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. -/pubspec.lock -**/doc/api/ -.dart_tool/ -build/ diff --git a/packages/colorpicker/CHANGELOG.md b/packages/colorpicker/CHANGELOG.md deleted file mode 100644 index 41cc7d81..00000000 --- a/packages/colorpicker/CHANGELOG.md +++ /dev/null @@ -1,3 +0,0 @@ -## 0.0.1 - -* TODO: Describe initial release. diff --git a/packages/colorpicker/LICENSE b/packages/colorpicker/LICENSE deleted file mode 100644 index ba75c69f..00000000 --- a/packages/colorpicker/LICENSE +++ /dev/null @@ -1 +0,0 @@ -TODO: Add your license here. diff --git a/packages/colorpicker/README.md b/packages/colorpicker/README.md deleted file mode 100644 index 02fe8eca..00000000 --- a/packages/colorpicker/README.md +++ /dev/null @@ -1,39 +0,0 @@ - - -TODO: Put a short description of the package here that helps potential users -know whether this package might be useful for them. - -## Features - -TODO: List what your package can do. Maybe include images, gifs, or videos. - -## Getting started - -TODO: List prerequisites and provide or point to information on how to -start using the package. - -## Usage - -TODO: Include short and useful examples for package users. Add longer examples -to `/example` folder. - -```dart -const like = 'sample'; -``` - -## Additional information - -TODO: Tell users more about the package: where to find more information, how to -contribute to the package, how to file issues, what response they can expect -from the package authors, and more. diff --git a/packages/colorpicker/analysis_options.yaml b/packages/colorpicker/analysis_options.yaml index a5744c1c..1ee68bd9 100644 --- a/packages/colorpicker/analysis_options.yaml +++ b/packages/colorpicker/analysis_options.yaml @@ -1,4 +1,23 @@ include: package:flutter_lints/flutter.yaml +linter: + rules: + always_use_package_imports: true + avoid_relative_lib_imports: true + prefer_relative_imports: false + prefer_single_quotes: true + avoid_void_async: true + constant_identifier_names: false -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options +analyzer: + errors: + missing_enum_constant_in_switch: error + exhaustive_cases: error + unused_element: error + type_annotate_public_apis: error + missing_required_param: error + invalid_use_of_protected_member: error + unused_import: error + + exclude: + - lib/src/**.pb*.dart + - lib/src/data/*.g.dart diff --git a/packages/colorpicker/lib/colorpicker.dart b/packages/colorpicker/lib/colorpicker.dart index 09a335b3..d140aafb 100644 --- a/packages/colorpicker/lib/colorpicker.dart +++ b/packages/colorpicker/lib/colorpicker.dart @@ -1,116 +1,7 @@ library colorpicker; -import 'package:colorpicker/constants/colors.dart'; -import 'package:colorpicker/widgets/color_compare.dart'; -import 'package:colorpicker/widgets/slider.dart'; -import 'package:flutter/material.dart'; - -class ColorPicker extends StatefulWidget { - const ColorPicker({ - super.key, - required this.currentColor, - required this.onColorChanged, - }); - - final Color currentColor; - final void Function(Color) onColorChanged; - - @override - State createState() => _ColorPickerState(); -} - -class _ColorPickerState extends State { - final colors = DisplayColors.colors; - Color newColor = Colors.black; - double opacity = 1.0; - - void callback(Color color, double op) { - setState(() { - opacity = op; - }); - } - - @override - void initState() { - super.initState(); - newColor = widget.currentColor; - } - - @override - Widget build(BuildContext context) { - return Container( - margin: const EdgeInsets.all(26), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(16), - ), - child: Column( - children: [ - ColorCompare( - currentColor: widget.currentColor, - newColor: newColor.withOpacity(opacity), - ), - const SizedBox( - height: 10, - ), - GridView.count( - childAspectRatio: 1.4, - crossAxisCount: 4, - crossAxisSpacing: 2.0, - mainAxisSpacing: 2.0, - shrinkWrap: true, - children: List.generate( - colors.length + 1, - (index) { - if (index == colors.length) { - return Container( - decoration: const BoxDecoration( - image: DecorationImage( - image: AssetImage('assets/img/checkerboard.png'), - fit: BoxFit.contain, - repeat: ImageRepeat.repeat, - ), - ), - ); - } - return GestureDetector( - onTap: () { - setState(() { - newColor = colors[index]; - }); - }, - child: Container( - decoration: BoxDecoration( - color: colors[index], - ), - ), - ); - }, - ), - ), - const SizedBox( - height: 30, - ), - OpacitySlider( - gradientColor: newColor, - callback: callback, - ), - const Spacer(), - Row( - children: [ - const Spacer(), - TextButton(onPressed: (){ - Navigator.pop(context); - }, child: const Text('CANCEL')), - const SizedBox(width: 10,), - TextButton(onPressed: (){ - widget.onColorChanged(newColor.withOpacity(opacity)); - Navigator.pop(context); - }, child: const Text('APPLY')), - ], - ) - ], - ), - ); - } -} +export 'src/colorpicker.dart'; +export 'src/constants/colors.dart'; +export 'src/widgets/color_compare.dart'; +export 'src/widgets/slider.dart'; +export 'src/widgets/slider_indicator.dart'; diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart new file mode 100644 index 00000000..ae98a6a6 --- /dev/null +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -0,0 +1,123 @@ +import 'package:colorpicker/src/constants/colors.dart'; +import 'package:colorpicker/src/widgets/color_compare.dart'; +import 'package:colorpicker/src/widgets/slider.dart'; +import 'package:flutter/material.dart'; + +class ColorPicker extends StatefulWidget { + const ColorPicker({ + super.key, + required this.currentColor, + required this.onColorChanged, + }); + + final Color currentColor; + final void Function(Color) onColorChanged; + + @override + State createState() => _ColorPickerState(); +} + +class _ColorPickerState extends State { + final colors = DisplayColors.colors; + Color newColor = Colors.black; + double opacity = 1.0; + + void callback(Color color, double op) { + setState(() { + opacity = op; + }); + } + + @override + void initState() { + super.initState(); + newColor = widget.currentColor; + } + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.all(26.0), + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(16.0), + ), + child: Column( + children: [ + ColorCompare( + currentColor: widget.currentColor, + newColor: newColor.withOpacity(opacity), + ), + const SizedBox( + height: 10.0, + ), + GridView.count( + childAspectRatio: 1.4, + crossAxisCount: 4, + crossAxisSpacing: 2.0, + mainAxisSpacing: 2.0, + shrinkWrap: true, + children: List.generate( + colors.length + 1, + (index) { + if (index == colors.length) { + return Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage( + 'packages/component_library/assets/img/checkerboard.png', + ), + fit: BoxFit.contain, + repeat: ImageRepeat.repeat, + ), + ), + ); + } + return GestureDetector( + onTap: () { + setState(() { + newColor = colors[index]; + }); + }, + child: Container( + decoration: BoxDecoration( + color: colors[index], + ), + ), + ); + }, + ), + ), + const SizedBox( + height: 30.0, + ), + OpacitySlider( + gradientColor: newColor, + callback: callback, + ), + const Spacer(), + Row( + children: [ + const Spacer(), + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Text('CANCEL'), + ), + const SizedBox( + width: 10.0, + ), + TextButton( + onPressed: () { + widget.onColorChanged(newColor.withOpacity(opacity)); + Navigator.pop(context); + }, + child: const Text('APPLY')), + ], + ) + ], + ), + ); + } +} diff --git a/packages/colorpicker/lib/constants/colors.dart b/packages/colorpicker/lib/src/constants/colors.dart similarity index 100% rename from packages/colorpicker/lib/constants/colors.dart rename to packages/colorpicker/lib/src/constants/colors.dart diff --git a/packages/colorpicker/lib/widgets/color_compare.dart b/packages/colorpicker/lib/src/widgets/color_compare.dart similarity index 85% rename from packages/colorpicker/lib/widgets/color_compare.dart rename to packages/colorpicker/lib/src/widgets/color_compare.dart index c1b5bce2..1e6a630c 100644 --- a/packages/colorpicker/lib/widgets/color_compare.dart +++ b/packages/colorpicker/lib/src/widgets/color_compare.dart @@ -18,8 +18,8 @@ class _ColorCompareState extends State { @override Widget build(BuildContext context) { return SizedBox( - width: 130, - height: 70, + width: 130.0, + height: 70.0, child: Row( children: [ Expanded( @@ -59,11 +59,12 @@ class ColorDesc extends StatelessWidget { color: color, ), ), - const SizedBox(width: 8), - Text(desc, style: const TextStyle( - color: Color.fromARGB(255, 149, 149, 149) - ),), + const SizedBox(width: 8.0), + Text( + desc, + style: const TextStyle(color: Color.fromARGB(255, 149, 149, 149)), + ), ], ); } -} \ No newline at end of file +} diff --git a/packages/colorpicker/lib/widgets/slider.dart b/packages/colorpicker/lib/src/widgets/slider.dart similarity index 86% rename from packages/colorpicker/lib/widgets/slider.dart rename to packages/colorpicker/lib/src/widgets/slider.dart index 39db2e2a..01fcc88f 100644 --- a/packages/colorpicker/lib/widgets/slider.dart +++ b/packages/colorpicker/lib/src/widgets/slider.dart @@ -1,4 +1,4 @@ -import 'package:colorpicker/widgets/slider_indicator.dart'; +import 'package:colorpicker/src/widgets/slider_indicator.dart'; import 'package:flutter/material.dart'; class OpacitySlider extends StatefulWidget { @@ -16,12 +16,12 @@ class OpacitySlider extends StatefulWidget { } class _OpacitySliderState extends State { - double _sliderPosition = 0; - double _positionFraction = 0; + double _sliderPosition = 0.0; + double _positionFraction = 0.0; void _handleColorChange(double position, double widgetWidth) { - if (position < 0) { - position = 0; + if (position < 0.0) { + position = 0.0; } if (position > widgetWidth) { position = widgetWidth; @@ -40,11 +40,13 @@ class _OpacitySliderState extends State { Widget build(BuildContext context) { double widgetWidth = MediaQuery.of(context).size.width - 52; return Container( - height: 25, + height: 25.0, width: widgetWidth, decoration: const BoxDecoration( image: DecorationImage( - image: AssetImage('assets/img/checkerboard.png'), + image: AssetImage( + 'packages/component_library/assets/img/checkerboard.png', + ), fit: BoxFit.fitHeight, repeat: ImageRepeat.repeat, ), diff --git a/packages/colorpicker/lib/widgets/slider_indicator.dart b/packages/colorpicker/lib/src/widgets/slider_indicator.dart similarity index 100% rename from packages/colorpicker/lib/widgets/slider_indicator.dart rename to packages/colorpicker/lib/src/widgets/slider_indicator.dart diff --git a/packages/colorpicker/pubspec.yaml b/packages/colorpicker/pubspec.yaml index f15352f0..45838616 100644 --- a/packages/colorpicker/pubspec.yaml +++ b/packages/colorpicker/pubspec.yaml @@ -1,7 +1,7 @@ name: colorpicker description: "A new Flutter package project." version: 0.0.1 -homepage: +publish_to: "none" environment: sdk: ">=2.17.0 <3.0.0" @@ -20,30 +20,4 @@ dev_dependencies: flutter: uses-material-design: true assets: - - assets/img/ - # - # For details regarding assets in packages, see - # https://flutter.dev/assets-and-images/#from-packages - # - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware - - # To add custom fonts to your package, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts in packages, see - # https://flutter.dev/custom-fonts/#from-packages + - ../component_library/assets/img/ diff --git a/packages/colorpicker/test/colorpicker_test.dart b/packages/colorpicker/test/colorpicker_test.dart deleted file mode 100644 index 72bdd0b2..00000000 --- a/packages/colorpicker/test/colorpicker_test.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; - -void main() { - test('test colorpicker', () { - - }); -} diff --git a/packages/command/lib/command.dart b/packages/command/lib/command.dart index e6dc05e4..098170f7 100644 --- a/packages/command/lib/command.dart +++ b/packages/command/lib/command.dart @@ -1,9 +1,10 @@ library command; -export 'src/graphic/draw_path_command.dart'; -export 'src/manager/sync_command_manager.dart'; - -export 'src/command_factory.dart'; -export 'src/command_manager.dart'; -export 'src/command.dart'; -export 'src/graphic_command.dart'; +export 'graphic_factory/graphic_factory.dart'; +export 'src/command_factory/command_factory.dart'; +export 'src/command_implementation/command.dart'; +export 'src/command_implementation/graphic/draw_path_command.dart'; +export 'src/command_implementation/graphic/graphic_command.dart'; +export 'src/command_manager/command_manager.dart'; +export 'src/command_manager/sync_command_manager.dart'; +export 'utils/path_with_action_history.dart'; diff --git a/packages/command/lib/command_providers.dart b/packages/command/lib/command_providers.dart index f94e8ec9..aeb71f8d 100644 --- a/packages/command/lib/command_providers.dart +++ b/packages/command/lib/command_providers.dart @@ -1,4 +1,5 @@ library command; -export 'src/command_factory_provider.dart'; -export 'src/command_manager_provider.dart'; +export 'graphic_factory/graphic_factory_provider.dart'; +export 'src/command_factory/command_factory_provider.dart'; +export 'src/command_manager/command_manager_provider.dart'; diff --git a/packages/component_library/lib/src/models/graphic_factory.dart b/packages/command/lib/graphic_factory/graphic_factory.dart similarity index 94% rename from packages/component_library/lib/src/models/graphic_factory.dart rename to packages/command/lib/graphic_factory/graphic_factory.dart index 8c421094..d1ddb975 100644 --- a/packages/component_library/lib/src/models/graphic_factory.dart +++ b/packages/command/lib/graphic_factory/graphic_factory.dart @@ -1,6 +1,6 @@ import 'dart:ui'; -import 'package:component_library/component_library.dart'; +import 'package:command/command.dart'; class GraphicFactory { const GraphicFactory(); diff --git a/packages/component_library/lib/src/graphic_factory_provider.dart b/packages/command/lib/graphic_factory/graphic_factory_provider.dart similarity index 77% rename from packages/component_library/lib/src/graphic_factory_provider.dart rename to packages/command/lib/graphic_factory/graphic_factory_provider.dart index 1d56fee7..887ee7bb 100644 --- a/packages/component_library/lib/src/graphic_factory_provider.dart +++ b/packages/command/lib/graphic_factory/graphic_factory_provider.dart @@ -1,4 +1,4 @@ -import 'package:component_library/component_library.dart'; +import 'package:command/graphic_factory/graphic_factory.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'graphic_factory_provider.g.dart'; diff --git a/packages/component_library/lib/src/graphic_factory_provider.g.dart b/packages/command/lib/graphic_factory/graphic_factory_provider.g.dart similarity index 100% rename from packages/component_library/lib/src/graphic_factory_provider.g.dart rename to packages/command/lib/graphic_factory/graphic_factory_provider.g.dart diff --git a/packages/command/lib/src/command.dart b/packages/command/lib/src/command.dart deleted file mode 100644 index 555fd20a..00000000 --- a/packages/command/lib/src/command.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:equatable/equatable.dart'; - -abstract class Command with EquatableMixin { - const Command(); -} diff --git a/packages/command/lib/src/command_factory.dart b/packages/command/lib/src/command_factory/command_factory.dart similarity index 80% rename from packages/command/lib/src/command_factory.dart rename to packages/command/lib/src/command_factory/command_factory.dart index 2953b28c..328bce11 100644 --- a/packages/command/lib/src/command_factory.dart +++ b/packages/command/lib/src/command_factory/command_factory.dart @@ -1,7 +1,6 @@ import 'dart:ui'; import 'package:command/command.dart'; -import 'package:component_library/component_library.dart'; class CommandFactory { const CommandFactory(); diff --git a/packages/command/lib/src/command_factory_provider.dart b/packages/command/lib/src/command_factory/command_factory_provider.dart similarity index 100% rename from packages/command/lib/src/command_factory_provider.dart rename to packages/command/lib/src/command_factory/command_factory_provider.dart diff --git a/packages/command/lib/src/command_factory_provider.g.dart b/packages/command/lib/src/command_factory/command_factory_provider.g.dart similarity index 100% rename from packages/command/lib/src/command_factory_provider.g.dart rename to packages/command/lib/src/command_factory/command_factory_provider.g.dart diff --git a/packages/command/lib/src/command_implementation/command.dart b/packages/command/lib/src/command_implementation/command.dart new file mode 100644 index 00000000..e5377362 --- /dev/null +++ b/packages/command/lib/src/command_implementation/command.dart @@ -0,0 +1,19 @@ +import 'package:command/command.dart'; +import 'package:equatable/equatable.dart'; +import 'package:io_library/io_library.dart'; + +abstract class Command with EquatableMixin { + const Command(); + + Map toJson(); + + factory Command.fromJson(Map json) { + String type = json['type'] as String; + switch (type) { + case SerializerType.DRAW_PATH_COMMAND: + return DrawPathCommand.fromJson(json); + default: + return DrawPathCommand.fromJson(json); + } + } +} diff --git a/packages/command/lib/src/command_implementation/graphic/draw_path_command.dart b/packages/command/lib/src/command_implementation/graphic/draw_path_command.dart new file mode 100644 index 00000000..9b715d4c --- /dev/null +++ b/packages/command/lib/src/command_implementation/graphic/draw_path_command.dart @@ -0,0 +1,51 @@ +import 'dart:ui'; + +import 'package:command/command.dart'; +import 'package:flutter/widgets.dart'; +import 'package:io_library/io_library.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'draw_path_command.g.dart'; + +@JsonSerializable() +class DrawPathCommand extends GraphicCommand { + final String type; + final int version; + + DrawPathCommand( + this.path, + super.paint, { + this.type = SerializerType.DRAW_PATH_COMMAND, + int? version, + }) : version = version ?? + VersionStrategyManager.strategy.getDrawPathCommandVersion(); + + @PathWithActionHistoryConverter() + final PathWithActionHistory path; + + @override + void call(Canvas canvas) { + canvas.drawPath(path, paint); + } + + @override + List get props => [paint, path, type]; + + @override + Map toJson() => _$DrawPathCommandToJson(this); + + factory DrawPathCommand.fromJson(Map json) { + int version = json['version'] as int; + + switch (version) { + case Version.v1: + return _$DrawPathCommandFromJson(json); + case Version.v2: + // For different versions of DrawPathCommand the deserialization + // has to be implemented manually. + // Autogenerated code can only be used for one version + default: + return _$DrawPathCommandFromJson(json); + } + } +} diff --git a/packages/command/lib/src/command_implementation/graphic/draw_path_command.g.dart b/packages/command/lib/src/command_implementation/graphic/draw_path_command.g.dart new file mode 100644 index 00000000..5d76772c --- /dev/null +++ b/packages/command/lib/src/command_implementation/graphic/draw_path_command.g.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'draw_path_command.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +DrawPathCommand _$DrawPathCommandFromJson(Map json) => + DrawPathCommand( + const PathWithActionHistoryConverter() + .fromJson(json['path'] as Map), + const PaintConverter().fromJson(json['paint'] as Map), + type: json['type'] as String? ?? SerializerType.DRAW_PATH_COMMAND, + version: json['version'] as int?, + ); + +Map _$DrawPathCommandToJson(DrawPathCommand instance) => + { + 'paint': const PaintConverter().toJson(instance.paint), + 'type': instance.type, + 'version': instance.version, + 'path': const PathWithActionHistoryConverter().toJson(instance.path), + }; diff --git a/packages/command/lib/src/graphic_command.dart b/packages/command/lib/src/command_implementation/graphic/graphic_command.dart similarity index 75% rename from packages/command/lib/src/graphic_command.dart rename to packages/command/lib/src/command_implementation/graphic/graphic_command.dart index 7f251477..20108abc 100644 --- a/packages/command/lib/src/graphic_command.dart +++ b/packages/command/lib/src/command_implementation/graphic/graphic_command.dart @@ -1,10 +1,12 @@ import 'dart:ui'; import 'package:command/command.dart'; +import 'package:io_library/io_library.dart'; abstract class GraphicCommand extends Command { const GraphicCommand(this.paint); + @PaintConverter() final Paint paint; void call(Canvas canvas); diff --git a/packages/command/lib/src/command_manager.dart b/packages/command/lib/src/command_manager/command_manager.dart similarity index 100% rename from packages/command/lib/src/command_manager.dart rename to packages/command/lib/src/command_manager/command_manager.dart diff --git a/packages/command/lib/src/command_manager_provider.dart b/packages/command/lib/src/command_manager/command_manager_provider.dart similarity index 100% rename from packages/command/lib/src/command_manager_provider.dart rename to packages/command/lib/src/command_manager/command_manager_provider.dart diff --git a/packages/command/lib/src/command_manager_provider.g.dart b/packages/command/lib/src/command_manager/command_manager_provider.g.dart similarity index 100% rename from packages/command/lib/src/command_manager_provider.g.dart rename to packages/command/lib/src/command_manager/command_manager_provider.g.dart diff --git a/packages/command/lib/src/manager/sync_command_manager.dart b/packages/command/lib/src/command_manager/sync_command_manager.dart similarity index 100% rename from packages/command/lib/src/manager/sync_command_manager.dart rename to packages/command/lib/src/command_manager/sync_command_manager.dart diff --git a/packages/command/lib/src/graphic/draw_path_command.dart b/packages/command/lib/src/graphic/draw_path_command.dart deleted file mode 100644 index 45cfd96b..00000000 --- a/packages/command/lib/src/graphic/draw_path_command.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'dart:ui'; -import 'package:command/command.dart'; -import 'package:component_library/component_library.dart'; -import 'package:flutter/widgets.dart'; - -class DrawPathCommand extends GraphicCommand { - const DrawPathCommand(this.path, super.paint); - - final PathWithActionHistory path; - - @override - void call(Canvas canvas) { - canvas.drawPath(path, paint); - } - - @override - List get props => [paint, path]; -} diff --git a/packages/command/lib/utils/path_with_action_history.dart b/packages/command/lib/utils/path_with_action_history.dart new file mode 100644 index 00000000..9fa50909 --- /dev/null +++ b/packages/command/lib/utils/path_with_action_history.dart @@ -0,0 +1,236 @@ +import 'dart:typed_data'; +import 'dart:ui'; + +import 'package:collection/collection.dart'; +import 'package:io_library/io_library.dart'; + +class PathWithActionHistory implements Path { + PathWithActionHistory(); + final _path = Path(); + + @PathActionConverter() + final actions = []; + + @override + void moveTo(double x, double y) { + actions.add(MoveToAction(x, y)); + _path.moveTo(x, y); + } + + @override + void lineTo(double x, double y) { + actions.add(LineToAction(x, y)); + _path.lineTo(x, y); + } + + @override + void close() { + actions.add(const CloseAction()); + _path.close(); + } + + Map toJson() { + return const PathWithActionHistoryConverter().toJson(this); + } + + factory PathWithActionHistory.fromJson(Map json) { + return const PathWithActionHistoryConverter().fromJson(json); + } + + @override + bool operator ==(Object other) { + if (other is PathWithActionHistory) { + return const ListEquality().equals(actions, other.actions); + } + return false; + } + + @override + int get hashCode => const ListEquality().hash(actions); + + @override + PathFillType get fillType => _path.fillType; + + @override + set fillType(PathFillType value) => _path.fillType = value; + + @override + void addArc(Rect oval, double startAngle, double sweepAngle) { + // TODO: implement addArc + } + + @override + void addOval(Rect oval) { + // TODO: implement addOval + } + + @override + void addPath(Path path, Offset offset, {Float64List? matrix4}) { + // TODO: implement addPath + } + + @override + void addPolygon(List points, bool close) { + // TODO: implement addPolygon + } + + @override + void addRRect(RRect rrect) { + // TODO: implement addRRect + } + + @override + void addRect(Rect rect) { + // TODO: implement addRect + } + + @override + void arcTo( + Rect rect, double startAngle, double sweepAngle, bool forceMoveTo) { + // TODO: implement arcTo + } + + @override + void arcToPoint(Offset arcEnd, + {Radius radius = Radius.zero, + double rotation = 0.0, + bool largeArc = false, + bool clockwise = true}) { + // TODO: implement arcToPoint + } + + @override + PathMetrics computeMetrics({bool forceClosed = false}) { + // TODO: implement computeMetrics + throw UnimplementedError(); + } + + @override + void conicTo(double x1, double y1, double x2, double y2, double w) { + // TODO: implement conicTo + } + + @override + bool contains(Offset point) { + // TODO: implement contains + throw UnimplementedError(); + } + + @override + void cubicTo( + double x1, double y1, double x2, double y2, double x3, double y3) { + // TODO: implement cubicTo + } + + @override + void extendWithPath(Path path, Offset offset, {Float64List? matrix4}) { + // TODO: implement extendWithPath + } + + @override + Rect getBounds() { + // TODO: implement getBounds + throw UnimplementedError(); + } + + @override + void quadraticBezierTo(double x1, double y1, double x2, double y2) { + // TODO: implement quadraticBezierTo + } + + @override + void relativeArcToPoint(Offset arcEndDelta, + {Radius radius = Radius.zero, + double rotation = 0.0, + bool largeArc = false, + bool clockwise = true}) { + // TODO: implement relativeArcToPoint + } + + @override + void relativeConicTo(double x1, double y1, double x2, double y2, double w) { + // TODO: implement relativeConicTo + } + + @override + void relativeCubicTo( + double x1, double y1, double x2, double y2, double x3, double y3) { + // TODO: implement relativeCubicTo + } + + @override + void relativeLineTo(double dx, double dy) { + // TODO: implement relativeLineTo + } + + @override + void relativeMoveTo(double dx, double dy) { + // TODO: implement relativeMoveTo + } + + @override + void relativeQuadraticBezierTo(double x1, double y1, double x2, double y2) { + // TODO: implement relativeQuadraticBezierTo + } + + @override + void reset() { + // TODO: implement reset + } + + @override + Path shift(Offset offset) { + // TODO: implement shift + throw UnimplementedError(); + } + + @override + Path transform(Float64List matrix4) { + // TODO: implement transform + throw UnimplementedError(); + } +} + +abstract class PathAction { + const PathAction(); +} + +class MoveToAction extends PathAction { + final double x; + final double y; + + const MoveToAction(this.x, this.y); + + @override + bool operator ==(Object other) { + if (other is MoveToAction) { + return x == other.x && y == other.y; + } + return false; + } + + @override + int get hashCode => Object.hash(x, y); +} + +class LineToAction extends PathAction { + final double x; + final double y; + + const LineToAction(this.x, this.y); + + @override + bool operator ==(Object other) { + if (other is LineToAction) { + return x == other.x && y == other.y; + } + return false; + } + + @override + int get hashCode => Object.hash(x, y); +} + +class CloseAction extends PathAction { + const CloseAction(); +} diff --git a/packages/command/pubspec.yaml b/packages/command/pubspec.yaml index bc3e81f7..04fd7856 100644 --- a/packages/command/pubspec.yaml +++ b/packages/command/pubspec.yaml @@ -14,10 +14,15 @@ dependencies: flutter_riverpod: ^2.3.6 riverpod_annotation: ^2.1.1 equatable: ^2.0.3 + json_annotation: ^4.8.1 + collection: ^1.17.1 + # Internal packages component_library: path: ../component_library + io_library: + path: ../io_library dev_dependencies: flutter_test: @@ -31,6 +36,7 @@ dev_dependencies: riverpod_lint: ^1.3.2 build_runner: ^2.2.0 freezed: ^2.4.1 + json_serializable: ^6.7.1 flutter: uses-material-design: true diff --git a/packages/command/test/unit/command_factory_test.dart b/packages/command/test/unit/command_factory_test.dart index dd97df80..b8af3440 100644 --- a/packages/command/test/unit/command_factory_test.dart +++ b/packages/command/test/unit/command_factory_test.dart @@ -1,8 +1,7 @@ import 'dart:ui'; -import 'package:flutter_test/flutter_test.dart'; import 'package:command/command.dart'; -import 'package:component_library/component_library.dart'; +import 'package:flutter_test/flutter_test.dart'; void main() { late PathWithActionHistory testPath; diff --git a/packages/command/test/unit/draw_path_command_test.dart b/packages/command/test/unit/draw_path_command_test.dart index bfe43a4d..4d34c156 100644 --- a/packages/command/test/unit/draw_path_command_test.dart +++ b/packages/command/test/unit/draw_path_command_test.dart @@ -1,7 +1,6 @@ import 'dart:ui'; import 'package:command/command.dart'; -import 'package:component_library/component_library.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; diff --git a/packages/component_library/lib/component_library.dart b/packages/component_library/lib/component_library.dart index ee32f582..f3c31da0 100644 --- a/packages/component_library/lib/component_library.dart +++ b/packages/component_library/lib/component_library.dart @@ -1,20 +1,13 @@ library component_library; -export 'src/components/imgs.dart'; -export 'src/components/icon_svg.dart'; export 'src/components/bottom_nav_bar_icon.dart'; export 'src/components/custom_action_chip.dart'; export 'src/components/icon_button_with_label.dart'; +export 'src/components/icon_svg.dart'; +export 'src/components/imgs.dart'; export 'src/components/loading_overlay.dart'; export 'src/components/pop_menu_button.dart'; - -export 'src/models/graphic_factory.dart'; -export 'src/models/path_with_action_history.dart'; - export 'src/theme/color_schemes.dart'; export 'src/theme/styles.dart'; - export 'src/utils/open_url.dart'; export 'src/utils/toast_utils.dart'; - -export 'src/graphic_factory_provider.dart'; diff --git a/packages/component_library/lib/src/models/path_with_action_history.dart b/packages/component_library/lib/src/models/path_with_action_history.dart deleted file mode 100644 index 75bffb9b..00000000 --- a/packages/component_library/lib/src/models/path_with_action_history.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'dart:ui'; - -class PathWithActionHistory extends Path { - final actions = []; - - @override - void moveTo(double x, double y) { - actions.add(MoveToAction(x, y)); - super.moveTo(x, y); - } - - @override - void lineTo(double x, double y) { - actions.add(LineToAction(x, y)); - super.lineTo(x, y); - } - - @override - void close() { - actions.add(const CloseAction()); - super.close(); - } -} - -abstract class PathAction { - const PathAction(); -} - -class MoveToAction extends PathAction { - final double x; - final double y; - - const MoveToAction(this.x, this.y); -} - -class LineToAction extends PathAction { - final double x; - final double y; - - const LineToAction(this.x, this.y); -} - -class CloseAction extends PathAction { - const CloseAction(); -} diff --git a/packages/component_library/pubspec.yaml b/packages/component_library/pubspec.yaml index 6889f556..15a11017 100644 --- a/packages/component_library/pubspec.yaml +++ b/packages/component_library/pubspec.yaml @@ -20,6 +20,8 @@ dependencies: toast: ^0.3.0 logging: ^1.0.2 + collection: ^1.17.1 + dev_dependencies: flutter_test: sdk: flutter diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart b/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart new file mode 100644 index 00000000..8fb743fc --- /dev/null +++ b/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart @@ -0,0 +1,112 @@ +import 'package:colorpicker/colorpicker.dart'; +import 'package:component_library/component_library.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:l10n/l10n.dart'; +import 'package:tools/tools.dart'; +import 'package:workspace_screen/workspace_screen.dart'; + +class BottomNavBar extends ConsumerWidget { + static const height = 64.0; + + const BottomNavBar({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final localizations = AppLocalizations.of(context); + final currentToolData = getCurrentToolData(ref); + + return NavigationBarTheme( + data: WidgetThemes.bottomNavBarThemeData, + child: NavigationBar( + height: height, + onDestinationSelected: (index) => + _onNavigationItemSelected(index, context, ref), + destinations: [ + NavigationDestination( + label: localizations.tools, + icon: const BottomBarIcon(asset: 'assets/svg/ic_tools.svg'), + ), + NavigationDestination( + label: currentToolData.name, + icon: BottomBarIcon(asset: currentToolData.svgAssetPath), + ), + NavigationDestination( + label: localizations.color, + icon: Icon( + Icons.check_box_outline_blank, + size: 24, + color: Theme.of(context).colorScheme.onSurface, + ), + ), + NavigationDestination( + label: localizations.layers, + icon: const BottomBarIcon(asset: 'assets/svg/ic_layers.svg'), + ), + ], + ), + ); + } + + ToolData getCurrentToolData(WidgetRef ref) { + final ToolType currentToolType = ref.watch( + toolBoxStateProvider.select((value) => value.currentToolType), + ); + + final currentToolData = ToolData.allToolsData.firstWhere( + (toolData) => toolData.type == currentToolType, + orElse: () => ToolData.BRUSH, + ); + return currentToolData; + } +} + +void _onNavigationItemSelected(int index, BuildContext context, WidgetRef ref) { + BottomNavBarItem item = BottomNavBarItem.values[index]; + switch (item) { + case BottomNavBarItem.TOOLS: + _showToolBottomSheet(context); + break; + case BottomNavBarItem.TOOL_OPTIONS: + _handleToolOptionsVisibility(ref); + break; + case BottomNavBarItem.COLOR: + _showColorPicker(context); + break; + default: + return; + } +} + +void _showToolBottomSheet(BuildContext context) { + showModalBottomSheet( + context: context, + builder: (BuildContext context) => const SizedBox( + height: 270, + child: ToolsBottomSheet(), + ), + ); +} + +void _handleToolOptionsVisibility(WidgetRef ref) { + ref.read(toolOptionsVisibilityStateProvider.notifier).toggleVisibility(); +} + +void _showColorPicker(BuildContext context) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + builder: (BuildContext context) => Container( + height: MediaQuery.of(context).size.height * 0.7, + alignment: Alignment.center, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + ), + child: ColorPicker( + currentColor: Colors.black, + onColorChanged: (color) {}, + ), + ), + ); +} diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar_items.dart b/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar_items.dart new file mode 100644 index 00000000..e5f91e2b --- /dev/null +++ b/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar_items.dart @@ -0,0 +1,6 @@ +enum BottomNavBarItem { + TOOLS, + TOOL_OPTIONS, + COLOR, + LAYERS, +} diff --git a/packages/features/workspace_screen/lib/src/components/bottom_brush_tool_options.dart b/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_cap_tool_option.dart similarity index 90% rename from packages/features/workspace_screen/lib/src/components/bottom_brush_tool_options.dart rename to packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_cap_tool_option.dart index eb2b7142..6b1abb05 100644 --- a/packages/features/workspace_screen/lib/src/components/bottom_brush_tool_options.dart +++ b/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_cap_tool_option.dart @@ -3,16 +3,15 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:tools/tools.dart'; -class BottomBrushToolOptions extends ConsumerStatefulWidget { - const BottomBrushToolOptions({super.key}); +class StrokeCapToolOption extends ConsumerStatefulWidget { + const StrokeCapToolOption({super.key}); @override - ConsumerState createState() => - _BottomBrushToolOptionsState(); + ConsumerState createState() => + _StrokeCapToolOptionState(); } -class _BottomBrushToolOptionsState - extends ConsumerState { +class _StrokeCapToolOptionState extends ConsumerState { Color _roundChipBackgroundColor = Colors.blue; Color _squareChipBackgroundColor = Colors.white; diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_tool_options.dart b/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_tool_options.dart new file mode 100644 index 00000000..7d751026 --- /dev/null +++ b/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_tool_options.dart @@ -0,0 +1,14 @@ +import 'package:flutter/cupertino.dart'; +import 'package:workspace_screen/workspace_screen.dart'; + +class StrokeToolOptions extends StatelessWidget { + const StrokeToolOptions({super.key}); + @override + Widget build(BuildContext context) { + return const Column(children: [ + StrokeWidthToolOption(), + Spacer(), + StrokeCapToolOption(), + ]); + } +} diff --git a/packages/features/workspace_screen/lib/src/components/top_brush_tool_options.dart b/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_width_tool_option.dart similarity index 90% rename from packages/features/workspace_screen/lib/src/components/top_brush_tool_options.dart rename to packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_width_tool_option.dart index 22356f36..cce4c39f 100644 --- a/packages/features/workspace_screen/lib/src/components/top_brush_tool_options.dart +++ b/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_width_tool_option.dart @@ -4,14 +4,15 @@ import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:tools/tools.dart'; -class TopBrushToolOptions extends ConsumerStatefulWidget { - const TopBrushToolOptions({super.key}); +class StrokeWidthToolOption extends ConsumerStatefulWidget { + const StrokeWidthToolOption({super.key}); @override - ConsumerState createState() => _NumberTextFieldState(); + ConsumerState createState() => + _StrokeWidthToolOptionState(); } -class _NumberTextFieldState extends ConsumerState { +class _StrokeWidthToolOptionState extends ConsumerState { late final TextEditingController _strokeWidthTextController; void _onChangedTextField(String value) { diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/tool_option.dart b/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/tool_option.dart new file mode 100644 index 00000000..cf627f0b --- /dev/null +++ b/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/tool_option.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; + +class ToolOption extends StatelessWidget { + final bool isIgnoring; + final double opacity; + final Widget child; + final Duration duration; + + const ToolOption({ + Key? key, + required this.isIgnoring, + required this.opacity, + required this.child, + this.duration = const Duration(milliseconds: 300), + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return IgnorePointer( + ignoring: isIgnoring, + child: AnimatedOpacity( + opacity: opacity, + duration: duration, + child: child, + ), + ); + } +} diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/tool_options.dart b/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/tool_options.dart new file mode 100644 index 00000000..b50e3f7f --- /dev/null +++ b/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/tool_options.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:tools/tools.dart'; +import 'package:workspace_screen/workspace_screen.dart'; + +class ToolOptions extends ConsumerWidget { + const ToolOptions({super.key}); + final maxOpacity = 1.0; + final minOpacity = 0.0; + + @override + Widget build(BuildContext context, WidgetRef ref) { + bool visible = ref.watch(toolOptionsVisibilityStateProvider); + final currentToolType = ref.watch( + toolBoxStateProvider.select((value) => value.currentToolType), + ); + + return Padding( + padding: const EdgeInsets.all(8), + child: ToolOption( + isIgnoring: !visible, + opacity: visible ? maxOpacity : minOpacity, + child: switch (currentToolType) { + ToolType.BRUSH => const StrokeToolOptions(), + ToolType.ERASER => const StrokeToolOptions(), + _ => Container(), + }), + ); + } +} diff --git a/packages/features/workspace_screen/lib/src/components/tool_button.dart b/packages/features/workspace_screen/lib/src/components/bottom_bar/tools/tool_button.dart similarity index 100% rename from packages/features/workspace_screen/lib/src/components/tool_button.dart rename to packages/features/workspace_screen/lib/src/components/bottom_bar/tools/tool_button.dart diff --git a/packages/features/workspace_screen/lib/src/components/tools_bottom_sheet.dart b/packages/features/workspace_screen/lib/src/components/bottom_bar/tools/tools_bottom_sheet.dart similarity index 87% rename from packages/features/workspace_screen/lib/src/components/tools_bottom_sheet.dart rename to packages/features/workspace_screen/lib/src/components/bottom_bar/tools/tools_bottom_sheet.dart index 638f6be8..3a402b19 100644 --- a/packages/features/workspace_screen/lib/src/components/tools_bottom_sheet.dart +++ b/packages/features/workspace_screen/lib/src/components/bottom_bar/tools/tools_bottom_sheet.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:tools/tools.dart'; +import 'package:workspace_screen/src/components/bottom_bar/tools/tool_button.dart'; import 'package:workspace_screen/workspace_screen.dart'; class ToolsBottomSheet extends StatelessWidget { diff --git a/packages/features/workspace_screen/lib/src/components/bottom_nav_bar.dart b/packages/features/workspace_screen/lib/src/components/bottom_nav_bar.dart deleted file mode 100644 index 313e27b8..00000000 --- a/packages/features/workspace_screen/lib/src/components/bottom_nav_bar.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'package:colorpicker/colorpicker.dart'; -import 'package:component_library/component_library.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:l10n/l10n.dart'; -import 'package:tools/tools.dart'; -import 'package:workspace_screen/workspace_screen.dart'; - -class BottomNavBar extends StatelessWidget { - static const height = 64.0; - - const BottomNavBar({Key? key}) : super(key: key); - - void _onNavigationItemSelected(int index, BuildContext context) { - if (index == 0) { - showModalBottomSheet( - context: context, - builder: (BuildContext context) => const SizedBox( - height: 270, - child: ToolsBottomSheet(), - ), - ); - } - if (index == 2) { - showModalBottomSheet( - context: context, - isScrollControlled: true, - builder: (BuildContext context) => Container( - height: MediaQuery.of(context).size.height * 0.7, - alignment: Alignment.center, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(16), - ), - child: ColorPicker( - currentColor: Colors.black, - onColorChanged: (color) {}, - ), - ), - ); - } - } - - @override - Widget build(BuildContext context) { - final localizations = AppLocalizations.of(context); - return NavigationBarTheme( - data: WidgetThemes.bottomNavBarThemeData, - child: NavigationBar( - height: height, - onDestinationSelected: (index) => - _onNavigationItemSelected(index, context), - destinations: [ - NavigationDestination( - label: localizations.tools, - icon: const BottomBarIcon(asset: 'assets/svg/ic_tools.svg'), - ), - Consumer( - builder: (BuildContext context, WidgetRef ref, Widget? child) { - final ToolType currentToolType = ref.watch( - toolBoxStateProvider.select((value) => value.currentToolType), - ); - - final currentToolData = ToolData.allToolsData.firstWhere( - (toolData) => toolData.type == currentToolType, - orElse: () => ToolData.BRUSH, - ); - - return NavigationDestination( - label: currentToolData.name, - icon: BottomBarIcon(asset: currentToolData.svgAssetPath), - ); - }, - ), - NavigationDestination( - label: localizations.color, - icon: Icon( - Icons.check_box_outline_blank, - size: 24, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - NavigationDestination( - label: localizations.layers, - icon: const BottomBarIcon(asset: 'assets/svg/ic_layers.svg'), - ), - ], - ), - ); - } -} diff --git a/packages/features/workspace_screen/lib/src/components/canvas_painter.dart b/packages/features/workspace_screen/lib/src/components/drawing_surface/canvas_painter.dart similarity index 100% rename from packages/features/workspace_screen/lib/src/components/canvas_painter.dart rename to packages/features/workspace_screen/lib/src/components/drawing_surface/canvas_painter.dart diff --git a/packages/features/workspace_screen/lib/src/components/checkerboard_pattern.dart b/packages/features/workspace_screen/lib/src/components/drawing_surface/checkerboard_pattern.dart similarity index 100% rename from packages/features/workspace_screen/lib/src/components/checkerboard_pattern.dart rename to packages/features/workspace_screen/lib/src/components/drawing_surface/checkerboard_pattern.dart diff --git a/packages/features/workspace_screen/lib/src/components/command_painter.dart b/packages/features/workspace_screen/lib/src/components/drawing_surface/command_painter.dart similarity index 100% rename from packages/features/workspace_screen/lib/src/components/command_painter.dart rename to packages/features/workspace_screen/lib/src/components/drawing_surface/command_painter.dart diff --git a/packages/features/workspace_screen/lib/src/components/drawing_canvas.dart b/packages/features/workspace_screen/lib/src/components/drawing_surface/drawing_canvas.dart similarity index 100% rename from packages/features/workspace_screen/lib/src/components/drawing_canvas.dart rename to packages/features/workspace_screen/lib/src/components/drawing_surface/drawing_canvas.dart diff --git a/packages/features/workspace_screen/lib/src/components/exit_fullscreen_button.dart b/packages/features/workspace_screen/lib/src/components/drawing_surface/exit_fullscreen_button.dart similarity index 100% rename from packages/features/workspace_screen/lib/src/components/exit_fullscreen_button.dart rename to packages/features/workspace_screen/lib/src/components/drawing_surface/exit_fullscreen_button.dart diff --git a/packages/features/workspace_screen/lib/src/components/tool_options.dart b/packages/features/workspace_screen/lib/src/components/tool_options.dart deleted file mode 100644 index f46147a1..00000000 --- a/packages/features/workspace_screen/lib/src/components/tool_options.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:workspace_screen/workspace_screen.dart'; - -class ToolOptions extends StatelessWidget { - const ToolOptions({super.key}); - - @override - Widget build(BuildContext context) { - return const Padding( - padding: EdgeInsets.all(8), - child: Column( - children: [ - TopBrushToolOptions(), - Spacer(), - BottomBrushToolOptions(), - ], - ), - ); - } -} diff --git a/packages/features/workspace_screen/lib/src/components/overflow_menu.dart b/packages/features/workspace_screen/lib/src/components/top_bar/overflow_menu.dart similarity index 100% rename from packages/features/workspace_screen/lib/src/components/overflow_menu.dart rename to packages/features/workspace_screen/lib/src/components/top_bar/overflow_menu.dart diff --git a/packages/features/workspace_screen/lib/src/components/top_app_bar.dart b/packages/features/workspace_screen/lib/src/components/top_bar/top_app_bar.dart similarity index 100% rename from packages/features/workspace_screen/lib/src/components/top_app_bar.dart rename to packages/features/workspace_screen/lib/src/components/top_bar/top_app_bar.dart diff --git a/packages/features/workspace_screen/lib/src/states/canvas_state_data.dart b/packages/features/workspace_screen/lib/src/states/canvas_state_data.dart index 31c66e55..ac45268a 100644 --- a/packages/features/workspace_screen/lib/src/states/canvas_state_data.dart +++ b/packages/features/workspace_screen/lib/src/states/canvas_state_data.dart @@ -1,7 +1,6 @@ import 'dart:ui' as ui; import 'package:command/command.dart'; -import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; diff --git a/packages/features/workspace_screen/lib/src/states/canvas_state_provider.dart b/packages/features/workspace_screen/lib/src/states/canvas_state_provider.dart index 5faa5ad1..8e13c3c3 100644 --- a/packages/features/workspace_screen/lib/src/states/canvas_state_provider.dart +++ b/packages/features/workspace_screen/lib/src/states/canvas_state_provider.dart @@ -2,10 +2,8 @@ import 'dart:ui'; import 'package:command/command.dart'; import 'package:command/command_providers.dart'; -import 'package:component_library/component_library.dart'; import 'package:flutter/painting.dart'; import 'package:flutter/widgets.dart' as widgets; - import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:workspace_screen/src/service/device_service.dart'; import 'package:workspace_screen/src/states/canvas_state_data.dart'; diff --git a/packages/features/workspace_screen/lib/src/states/tool_options_visibility_state_provider.dart b/packages/features/workspace_screen/lib/src/states/tool_options_visibility_state_provider.dart new file mode 100644 index 00000000..60b650ed --- /dev/null +++ b/packages/features/workspace_screen/lib/src/states/tool_options_visibility_state_provider.dart @@ -0,0 +1,15 @@ +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +part 'tool_options_visibility_state_provider.g.dart'; + +@riverpod +class ToolOptionsVisibilityState extends _$ToolOptionsVisibilityState { + void toggleVisibility() { + state = !state; + } + + @override + bool build() { + return true; + } +} diff --git a/packages/features/workspace_screen/lib/src/states/tool_options_visibility_state_provider.g.dart b/packages/features/workspace_screen/lib/src/states/tool_options_visibility_state_provider.g.dart new file mode 100644 index 00000000..ebe6c0e7 --- /dev/null +++ b/packages/features/workspace_screen/lib/src/states/tool_options_visibility_state_provider.g.dart @@ -0,0 +1,27 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'tool_options_visibility_state_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$toolOptionsVisibilityStateHash() => + r'affb976d863865ff27bb7683bae487b4337cea8f'; + +/// See also [ToolOptionsVisibilityState]. +@ProviderFor(ToolOptionsVisibilityState) +final toolOptionsVisibilityStateProvider = + AutoDisposeNotifierProvider.internal( + ToolOptionsVisibilityState.new, + name: r'toolOptionsVisibilityStateProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$toolOptionsVisibilityStateHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef _$ToolOptionsVisibilityState = AutoDisposeNotifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/packages/features/workspace_screen/lib/src/usecase/render_image_for_export.dart b/packages/features/workspace_screen/lib/src/usecase/render_image_for_export.dart index da842b8f..f27fe205 100644 --- a/packages/features/workspace_screen/lib/src/usecase/render_image_for_export.dart +++ b/packages/features/workspace_screen/lib/src/usecase/render_image_for_export.dart @@ -2,7 +2,6 @@ import 'dart:ui'; import 'package:command/command.dart'; import 'package:command/command_providers.dart'; -import 'package:component_library/component_library.dart'; import 'package:flutter/painting.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:workspace_screen/workspace_screen.dart'; diff --git a/packages/features/workspace_screen/lib/workspace_screen.dart b/packages/features/workspace_screen/lib/workspace_screen.dart index 73242770..23ebc9e6 100644 --- a/packages/features/workspace_screen/lib/workspace_screen.dart +++ b/packages/features/workspace_screen/lib/workspace_screen.dart @@ -1,28 +1,27 @@ library workspace_screen; -export 'src/components/bottom_brush_tool_options.dart'; -export 'src/components/bottom_nav_bar.dart'; -export 'src/components/canvas_painter.dart'; -export 'src/components/checkerboard_pattern.dart'; -export 'src/components/command_painter.dart'; -export 'src/components/drawing_canvas.dart'; -export 'src/components/exit_fullscreen_button.dart'; -export 'src/components/overflow_menu.dart'; -export 'src/components/tool_button.dart'; -export 'src/components/tool_options.dart'; -export 'src/components/tools_bottom_sheet.dart'; -export 'src/components/top_app_bar.dart'; -export 'src/components/top_brush_tool_options.dart'; - +export 'src/components/bottom_bar/bottom_nav_bar.dart'; +export 'src/components/bottom_bar/bottom_nav_bar_items.dart'; +export 'src/components/bottom_bar/tool_options/stroke_cap_tool_option.dart'; +export 'src/components/bottom_bar/tool_options/stroke_tool_options.dart'; +export 'src/components/bottom_bar/tool_options/stroke_width_tool_option.dart'; +export 'src/components/bottom_bar/tool_options/tool_option.dart'; +export 'src/components/bottom_bar/tool_options/tool_options.dart'; +export 'src/components/bottom_bar/tools/tool_button.dart'; +export 'src/components/bottom_bar/tools/tools_bottom_sheet.dart'; +export 'src/components/drawing_surface/canvas_painter.dart'; +export 'src/components/drawing_surface/checkerboard_pattern.dart'; +export 'src/components/drawing_surface/command_painter.dart'; +export 'src/components/drawing_surface/drawing_canvas.dart'; +export 'src/components/drawing_surface/exit_fullscreen_button.dart'; +export 'src/components/top_bar/overflow_menu.dart'; +export 'src/components/top_bar/top_app_bar.dart'; export 'src/models/image_with_pixel_info.dart'; - export 'src/service/device_service.dart'; - export 'src/states/canvas_dirty_state.dart'; export 'src/states/canvas_state_data.dart'; export 'src/states/canvas_state_provider.dart'; +export 'src/states/tool_options_visibility_state_provider.dart'; export 'src/states/workspace_state_notifier.dart'; - export 'src/usecase/render_image_for_export.dart'; - export 'src/workspace_screen.dart'; diff --git a/packages/features/workspace_screen/test/unit/render_image_for_export_test.dart b/packages/features/workspace_screen/test/unit/render_image_for_export_test.dart index d7c92bec..e1c8e4ff 100644 --- a/packages/features/workspace_screen/test/unit/render_image_for_export_test.dart +++ b/packages/features/workspace_screen/test/unit/render_image_for_export_test.dart @@ -1,13 +1,12 @@ import 'dart:ui'; +import 'package:command/command.dart'; import 'package:command/command_providers.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:workspace_screen/workspace_screen.dart'; -import 'package:command/command.dart'; -import 'package:component_library/component_library.dart'; import 'render_image_for_export_test.mocks.dart'; diff --git a/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart b/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart index 14f1d25c..328f5e33 100644 --- a/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart +++ b/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart @@ -1,42 +1,162 @@ import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:l10n/l10n.dart'; import 'package:tools/tools.dart'; import 'package:workspace_screen/workspace_screen.dart'; -import 'package:flutter_localizations/flutter_localizations.dart'; import 'bottom_nav_bar_interactions.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + const VISIBLE = 1.0; + const INVISIBLE = 0.0; + + late Widget sut; - testWidgets( - 'Select eraser and brush tool and verify NavigationBarItem changes', - (WidgetTester tester) async { - const eraserToolData = ToolData.ERASER; - const brushToolData = ToolData.BRUSH; - - await tester.pumpWidget( - const ProviderScope( - child: MaterialApp( - home: WorkspaceScreen(), - localizationsDelegates: [ - AppLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - ], - ), + setUp(() { + sut = const ProviderScope( + child: MaterialApp( + home: WorkspaceScreen(), + localizationsDelegates: [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + ], ), ); + }); + + group('BottomNavBarItem.TOOLS', () { + testWidgets( + 'Select eraser and brush tool and verify NavigationBarItem changes', + (WidgetTester tester) async { + const eraserToolData = ToolData.ERASER; + const brushToolData = ToolData.BRUSH; + + await tester.pumpWidget(sut); + + final bottomNavBarInteractions = BottomNavBarInteractions(tester); + await bottomNavBarInteractions + .selectTool(eraserToolData) + .then((_) => _.checkActiveToolIconAndLabel(eraserToolData)); + + await bottomNavBarInteractions + .selectTool(brushToolData) + .then((_) => _.checkActiveToolIconAndLabel(brushToolData)); + }); + }); + + group('BottomNavBarItem.CURRENT_TOOL', () { + testWidgets('test if width tool-option is visible when starting app', + (WidgetTester tester) async { + await tester.pumpWidget(sut); + + final bottomNavBarInteractions = BottomNavBarInteractions(tester); + + final animatedOpacity = bottomNavBarInteractions + .getAnimatedOpacityFinder(StrokeWidthToolOption); + + var animatedOpacityWidget = + tester.widget(animatedOpacity); + expect(animatedOpacityWidget.opacity, equals(VISIBLE)); + }); + + testWidgets('test if width tool-option is invisible after clicking once', + (WidgetTester tester) async { + await tester.pumpWidget(sut); + + final bottomNavBarInteractions = BottomNavBarInteractions(tester); + + final animatedOpacity = bottomNavBarInteractions + .getAnimatedOpacityFinder(StrokeWidthToolOption); + + var animatedOpacityWidget = + tester.widget(animatedOpacity); + expect(animatedOpacityWidget.opacity, equals(VISIBLE)); + + await bottomNavBarInteractions.clickCurrentTool(); + + animatedOpacityWidget = tester.widget(animatedOpacity); + expect(animatedOpacityWidget.opacity, equals(INVISIBLE)); + }); + + testWidgets('test if width tool-option is visible after clicking twice', + (WidgetTester tester) async { + await tester.pumpWidget(sut); + + final bottomNavBarInteractions = BottomNavBarInteractions(tester); + final animatedOpacity = bottomNavBarInteractions + .getAnimatedOpacityFinder(StrokeWidthToolOption); + + var animatedOpacityWidget = + tester.widget(animatedOpacity); + expect(animatedOpacityWidget.opacity, equals(VISIBLE)); + + await bottomNavBarInteractions.clickCurrentTool(); + + animatedOpacityWidget = tester.widget(animatedOpacity); + expect(animatedOpacityWidget.opacity, equals(INVISIBLE)); + + await bottomNavBarInteractions.clickCurrentTool(); + + animatedOpacityWidget = tester.widget(animatedOpacity); + expect(animatedOpacityWidget.opacity, equals(VISIBLE)); + }); + + testWidgets('test if cap tool-option is visible when starting app', + (WidgetTester tester) async { + await tester.pumpWidget(sut); + + final bottomNavBarInteractions = BottomNavBarInteractions(tester); + final animatedOpacity = bottomNavBarInteractions + .getAnimatedOpacityFinder(StrokeCapToolOption); + + var animatedOpacityWidget = + tester.widget(animatedOpacity); + expect(animatedOpacityWidget.opacity, equals(VISIBLE)); + }); + + testWidgets('test if cap tool-option is invisible after clicking once', + (WidgetTester tester) async { + await tester.pumpWidget(sut); + + final bottomNavBarInteractions = BottomNavBarInteractions(tester); + final animatedOpacity = bottomNavBarInteractions + .getAnimatedOpacityFinder(StrokeCapToolOption); + + var animatedOpacityWidget = + tester.widget(animatedOpacity); + expect(animatedOpacityWidget.opacity, equals(VISIBLE)); + + await bottomNavBarInteractions.clickCurrentTool(); + + animatedOpacityWidget = tester.widget(animatedOpacity); + expect(animatedOpacityWidget.opacity, equals(INVISIBLE)); + }); + + testWidgets('test if cap tool-option is visible after clicking twice', + (WidgetTester tester) async { + await tester.pumpWidget(sut); + + final bottomNavBarInteractions = BottomNavBarInteractions(tester); + final animatedOpacity = bottomNavBarInteractions + .getAnimatedOpacityFinder(StrokeCapToolOption); + + var animatedOpacityWidget = + tester.widget(animatedOpacity); + expect(animatedOpacityWidget.opacity, equals(VISIBLE)); + + await bottomNavBarInteractions.clickCurrentTool(); + + animatedOpacityWidget = tester.widget(animatedOpacity); + expect(animatedOpacityWidget.opacity, equals(INVISIBLE)); - final bottomNavBarInteractions = BottomNavBarInteractions(tester); - await bottomNavBarInteractions - .selectTool(eraserToolData) - .then((_) => _.checkActiveToolIconAndLabel(eraserToolData)); + await bottomNavBarInteractions.clickCurrentTool(); - await bottomNavBarInteractions - .selectTool(brushToolData) - .then((_) => _.checkActiveToolIconAndLabel(brushToolData)); + animatedOpacityWidget = tester.widget(animatedOpacity); + expect(animatedOpacityWidget.opacity, equals(VISIBLE)); + }); }); } diff --git a/packages/features/workspace_screen/test/widget/bottom_nav_bar_interactions.dart b/packages/features/workspace_screen/test/widget/bottom_nav_bar_interactions.dart index d1306061..8b9f3c5a 100644 --- a/packages/features/workspace_screen/test/widget/bottom_nav_bar_interactions.dart +++ b/packages/features/workspace_screen/test/widget/bottom_nav_bar_interactions.dart @@ -17,6 +17,14 @@ class BottomNavBarInteractions { return this; } + Future clickCurrentTool() async { + final firstNavDestination = find.byType(NavigationDestination).at(1); + expect(firstNavDestination, findsOneWidget); + await _tester.tap(firstNavDestination); + await _tester.pumpAndSettle(); + return this; + } + Future selectTool(ToolData toolData) async { await openBottomToolSheet(); @@ -53,4 +61,14 @@ class BottomNavBarInteractions { matching: find.byType(IconButton), ); } + + Finder getAnimatedOpacityFinder(Type type) { + final child = find.byType(type); + final animatedOpacityFinder = find.ancestor( + of: child, + matching: find.byType(AnimatedOpacity), + ); + expect(animatedOpacityFinder, findsOneWidget); + return animatedOpacityFinder; + } } diff --git a/packages/io_library/lib/io_library.dart b/packages/io_library/lib/io_library.dart index acd0a174..beda5731 100644 --- a/packages/io_library/lib/io_library.dart +++ b/packages/io_library/lib/io_library.dart @@ -2,29 +2,23 @@ library io_library; export 'src/enums/image_format.dart'; export 'src/enums/image_location.dart'; - export 'src/failure/load_image_failure.dart'; export 'src/failure/save_image_failure.dart'; - +export 'src/io_handler.dart'; +export 'src/json_serialization/converter/paint_converter.dart'; +export 'src/json_serialization/converter/path_action_converter.dart'; +export 'src/json_serialization/converter/path_with_action_history_converter.dart'; +export 'src/json_serialization/versioning/serializer_version.dart'; +export 'src/json_serialization/versioning/version_strategy.dart'; export 'src/models/catrobat_image.dart'; export 'src/models/failure.dart'; export 'src/models/image_from_file.dart'; export 'src/models/image_meta_data.dart'; export 'src/models/loggable_mixin.dart'; - -export 'src/serialization/proto/protos.dart'; -export 'src/serialization/serializer/command/graphic/draw_path_command_serializer.dart'; -export 'src/serialization/serializer/graphic/paint_serializer.dart'; -export 'src/serialization/serializer/graphic/path_serializer.dart'; -export 'src/serialization/serializer/catrobat_image_serializer.dart'; -export 'src/serialization/proto_serializer_with_versioning.dart'; -export 'src/serialization/version_serializer.dart'; - export 'src/service/file_service.dart'; export 'src/service/image_service.dart'; export 'src/service/permission_service.dart'; export 'src/service/photo_library_service.dart'; - export 'src/ui/about_dialog.dart'; export 'src/ui/delete_project_dialog.dart'; export 'src/ui/discard_changes_dialog.dart'; @@ -34,10 +28,7 @@ export 'src/ui/load_image_dialog.dart'; export 'src/ui/overwrite_dialog.dart'; export 'src/ui/project_details_dialog.dart'; export 'src/ui/save_image_dialog.dart'; - export 'src/usecase/load_image_from_file_manager.dart'; export 'src/usecase/load_image_from_photo_library.dart'; export 'src/usecase/save_as_catrobat_image.dart'; export 'src/usecase/save_as_raster_image.dart'; - -export 'src/io_handler.dart'; diff --git a/packages/io_library/lib/serialization.dart b/packages/io_library/lib/serialization.dart deleted file mode 100644 index 7009b8be..00000000 --- a/packages/io_library/lib/serialization.dart +++ /dev/null @@ -1,10 +0,0 @@ -export 'src/serialization/proto/output/catrobat_image.pb.dart'; -export 'src/serialization/proto/output/command/graphic/draw_path_command.pb.dart'; -export 'src/serialization/proto/output/google/protobuf/any.pb.dart'; -export 'src/serialization/proto/output/graphic/paint.pb.dart'; -export 'src/serialization/proto/output/graphic/path.pb.dart'; -export 'src/serialization/proto_serializer_with_versioning.dart'; -export 'src/serialization/serializer/command/graphic/draw_path_command_serializer.dart'; -export 'src/serialization/serializer/graphic/paint_serializer.dart'; -export 'src/serialization/serializer/graphic/path_serializer.dart'; -export 'src/serialization/version_serializer.dart'; diff --git a/packages/io_library/lib/src/io_handler.dart b/packages/io_library/lib/src/io_handler.dart index 0713e174..72c0a782 100644 --- a/packages/io_library/lib/src/io_handler.dart +++ b/packages/io_library/lib/src/io_handler.dart @@ -1,4 +1,6 @@ +import 'dart:convert'; import 'dart:io'; +import 'dart:typed_data'; import 'package:command/command_providers.dart'; import 'package:component_library/component_library.dart'; @@ -201,8 +203,19 @@ class IOHandler { final canvasState = ref.read(canvasStateProvider); final imgWidth = canvasState.size.width.toInt(); final imgHeight = canvasState.size.height.toInt(); - final catrobatImage = CatrobatImage( - commands, imgWidth, imgHeight, canvasState.backgroundImage); + Uint8List? backgroundImageData; + final backgroundImage = canvasState.backgroundImage; + if (backgroundImage != null) { + final result = + await ref.read(IImageService.provider).exportAsPng(backgroundImage); + backgroundImageData = + result.unwrapOrElse((failure) => throw failure.message); + } + + final String backgroundImageAsString = + backgroundImageData != null ? base64Encode(backgroundImageData) : ''; + final catrobatImage = + CatrobatImage(commands, imgWidth, imgHeight, backgroundImageAsString); final saveAsCatrobatImage = ref.read(SaveAsCatrobatImage.provider); final result = await saveAsCatrobatImage(imageData, catrobatImage, isAProject); diff --git a/packages/io_library/lib/src/json_serialization/converter/paint_converter.dart b/packages/io_library/lib/src/json_serialization/converter/paint_converter.dart new file mode 100644 index 00000000..902a4c0c --- /dev/null +++ b/packages/io_library/lib/src/json_serialization/converter/paint_converter.dart @@ -0,0 +1,50 @@ +import 'dart:ui'; + +import 'package:io_library/io_library.dart'; +import 'package:json_annotation/json_annotation.dart'; + +class PaintConverter implements JsonConverter> { + const PaintConverter(); + + @override + Paint fromJson(Map json) { + Paint paint = Paint(); + + int version = json['version'] as int; + if (version >= Version.v1) { + paint.color = Color(json['color']); + paint.strokeWidth = json['strokeWidth']; + paint.strokeCap = StrokeCap.values[json['strokeCap']]; + paint.isAntiAlias = json['isAntiAlias']; + paint.style = PaintingStyle.values[json['style']]; + paint.strokeJoin = StrokeJoin.values[json['strokeJoin']]; + paint.blendMode = BlendMode.values[json['blendMode']]; + } + if (version >= Version.v2) { + // paint.newAttribute = json['newAttribute']; + } + return paint; + } + + // Never remove attributes, it will cause errors in older versions!! + // Only add new attributes at the end of the map and increase the version number. + @override + Map toJson(Paint paint) { + Map json = {}; + if (SerializerVersion.PAINT_VERSION >= Version.v1) { + json['version'] = SerializerVersion.PAINT_VERSION; + json['color'] = paint.color.value; + json['strokeWidth'] = paint.strokeWidth; + json['strokeCap'] = paint.strokeCap.index; + json['isAntiAlias'] = paint.isAntiAlias; + json['style'] = paint.style.index; + json['strokeJoin'] = paint.strokeJoin.index; + json['blendMode'] = paint.blendMode.index; + } + if (SerializerVersion.PAINT_VERSION >= Version.v2) { + // json['newAttribute'] = paint.newAttribute; + } + + return json; + } +} diff --git a/packages/io_library/lib/src/json_serialization/converter/path_action_converter.dart b/packages/io_library/lib/src/json_serialization/converter/path_action_converter.dart new file mode 100644 index 00000000..d1dd5dd9 --- /dev/null +++ b/packages/io_library/lib/src/json_serialization/converter/path_action_converter.dart @@ -0,0 +1,44 @@ +import 'package:command/command.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:io_library/io_library.dart'; + +class PathActionConverter + implements JsonConverter> { + const PathActionConverter(); + + @override + PathAction fromJson(Map json) { + switch (json['type'] as String) { + case SerializerType.MOVE_TO_ACTION: + return MoveToAction(json['x'] as double, json['y'] as double); + case SerializerType.LINE_TO_ACTION: + return LineToAction(json['x'] as double, json['y'] as double); + case SerializerType.CLOSE_ACTION: + return const CloseAction(); + default: + return const CloseAction(); + } + } + + @override + Map toJson(PathAction action) { + switch (action.runtimeType) { + case MoveToAction: + action as MoveToAction; + return { + 'type': SerializerType.MOVE_TO_ACTION, + 'x': action.x, + 'y': action.y, + }; + case LineToAction: + action as LineToAction; + return { + 'type': SerializerType.LINE_TO_ACTION, + 'x': action.x, + 'y': action.y, + }; + default: + return {'type': SerializerType.CLOSE_ACTION}; + } + } +} diff --git a/packages/io_library/lib/src/json_serialization/converter/path_with_action_history_converter.dart b/packages/io_library/lib/src/json_serialization/converter/path_with_action_history_converter.dart new file mode 100644 index 00000000..0edb3902 --- /dev/null +++ b/packages/io_library/lib/src/json_serialization/converter/path_with_action_history_converter.dart @@ -0,0 +1,34 @@ +import 'package:command/command.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:io_library/io_library.dart'; + +class PathWithActionHistoryConverter + implements JsonConverter> { + const PathWithActionHistoryConverter(); + + @override + PathWithActionHistory fromJson(Map json) { + var pathWithActionHistory = PathWithActionHistory(); + var actionsJson = json['actions'] as List; + for (var actionJson in actionsJson) { + var action = const PathActionConverter() + .fromJson(actionJson as Map); + + if (action is MoveToAction) { + pathWithActionHistory.moveTo(action.x, action.y); + } else if (action is LineToAction) { + pathWithActionHistory.lineTo(action.x, action.y); + } else if (action is CloseAction) { + pathWithActionHistory.close(); + } + } + return pathWithActionHistory; + } + + @override + Map toJson(PathWithActionHistory pathWithActionHistory) => { + 'actions': pathWithActionHistory.actions + .map((action) => const PathActionConverter().toJson(action)) + .toList(), + }; +} diff --git a/packages/io_library/lib/src/json_serialization/versioning/serializer_version.dart b/packages/io_library/lib/src/json_serialization/versioning/serializer_version.dart new file mode 100644 index 00000000..bb592105 --- /dev/null +++ b/packages/io_library/lib/src/json_serialization/versioning/serializer_version.dart @@ -0,0 +1,19 @@ +class SerializerVersion { + static const int PAINT_VERSION = Version.v1; + static const int CATROBAT_IMAGE_VERSION = Version.v1; + static const int DRAW_PATH_COMMAND_VERSION = Version.v1; +} + +class Version { + static const int v1 = 1; + static const int v2 = 2; + static const int v3 = 3; +// ... +} + +class SerializerType { + static const String DRAW_PATH_COMMAND = 'DrawPathCommand'; + static const String MOVE_TO_ACTION = 'MoveToAction'; + static const String LINE_TO_ACTION = 'LineToAction'; + static const String CLOSE_ACTION = 'CloseAction'; +} diff --git a/packages/io_library/lib/src/json_serialization/versioning/version_strategy.dart b/packages/io_library/lib/src/json_serialization/versioning/version_strategy.dart new file mode 100644 index 00000000..0f4ca73f --- /dev/null +++ b/packages/io_library/lib/src/json_serialization/versioning/version_strategy.dart @@ -0,0 +1,25 @@ +import 'package:io_library/io_library.dart'; + +abstract class IVersionStrategy { + int getCatrobatImageVersion(); + int getDrawPathCommandVersion(); +} + +class ProductionVersionStrategy implements IVersionStrategy { + @override + int getCatrobatImageVersion() => SerializerVersion.CATROBAT_IMAGE_VERSION; + + @override + int getDrawPathCommandVersion() => + SerializerVersion.DRAW_PATH_COMMAND_VERSION; +} + +class VersionStrategyManager { + static IVersionStrategy _strategy = ProductionVersionStrategy(); + + static void setStrategy(IVersionStrategy strategy) { + _strategy = strategy; + } + + static IVersionStrategy get strategy => _strategy; +} diff --git a/packages/io_library/lib/src/models/catrobat_image.dart b/packages/io_library/lib/src/models/catrobat_image.dart index 99b28a3a..49eb9c04 100644 --- a/packages/io_library/lib/src/models/catrobat_image.dart +++ b/packages/io_library/lib/src/models/catrobat_image.dart @@ -1,22 +1,57 @@ -import 'dart:ui'; +import 'dart:convert'; +import 'dart:typed_data'; import 'package:command/command.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:io_library/io_library.dart'; -class CatrobatImage { - static const magicValue = 'CATROBAT'; - static const latestVersion = 1; +part 'catrobat_image.g.dart'; +@JsonSerializable() +class CatrobatImage { + final String magicValue; final int version; final int width; final int height; final Iterable commands; - final Image? backgroundImage; + final String backgroundImage; - const CatrobatImage( + CatrobatImage( this.commands, this.width, this.height, this.backgroundImage, { - this.version = latestVersion, - }); + int? version, + this.magicValue = 'CATROBAT', + }) : version = version ?? + VersionStrategyManager.strategy.getCatrobatImageVersion(); + + Uint8List toBytes() { + Map jsonMap = toJson(); + String jsonString = json.encode(jsonMap); + return utf8.encode(jsonString) as Uint8List; + } + + static CatrobatImage fromBytes(Uint8List bytes) { + String jsonString = utf8.decode(bytes); + Map jsonMap = json.decode(jsonString); + return CatrobatImage.fromJson(jsonMap); + } + + Map toJson() => _$CatrobatImageToJson(this); + + factory CatrobatImage.fromJson(Map json) { + int version = json['version'] as int; + + switch (version) { + case Version.v1: + return _$CatrobatImageFromJson(json); + case Version.v2: + // For different versions of CatrobatImage the deserialization + // has to be implemented manually. + // Autogenerated code can only be used for one version + default: + return _$CatrobatImageFromJson(json); + } + } } diff --git a/packages/io_library/lib/src/models/catrobat_image.g.dart b/packages/io_library/lib/src/models/catrobat_image.g.dart new file mode 100644 index 00000000..9d900f86 --- /dev/null +++ b/packages/io_library/lib/src/models/catrobat_image.g.dart @@ -0,0 +1,28 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'catrobat_image.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +CatrobatImage _$CatrobatImageFromJson(Map json) => + CatrobatImage( + (json['commands'] as List) + .map((e) => Command.fromJson(e as Map)), + json['width'] as int, + json['height'] as int, + json['backgroundImage'] as String, + version: json['version'] as int?, + magicValue: json['magicValue'] as String? ?? 'CATROBAT', + ); + +Map _$CatrobatImageToJson(CatrobatImage instance) => + { + 'magicValue': instance.magicValue, + 'version': instance.version, + 'width': instance.width, + 'height': instance.height, + 'commands': instance.commands.toList(), + 'backgroundImage': instance.backgroundImage, + }; diff --git a/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pb.dart b/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pb.dart deleted file mode 100644 index d6f0e1d3..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pb.dart +++ /dev/null @@ -1,161 +0,0 @@ -// -// Generated code. Do not modify. -// source: catrobat_image.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -import 'dart:core' as $core; - -import 'package:protobuf/protobuf.dart' as $pb; - -import 'google/protobuf/any.pb.dart' as $2; - -class SerializableCatrobatImage extends $pb.GeneratedMessage { - factory SerializableCatrobatImage({ - $core.String? magicValue, - $core.int? version, - $core.int? width, - $core.int? height, - $core.Iterable<$2.Any>? commands, - $core.List<$core.int>? backgroundImage, - }) { - final $result = create(); - if (magicValue != null) { - $result.magicValue = magicValue; - } - if (version != null) { - $result.version = version; - } - if (width != null) { - $result.width = width; - } - if (height != null) { - $result.height = height; - } - if (commands != null) { - $result.commands.addAll(commands); - } - if (backgroundImage != null) { - $result.backgroundImage = backgroundImage; - } - return $result; - } - SerializableCatrobatImage._() : super(); - factory SerializableCatrobatImage.fromBuffer($core.List<$core.int> i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromBuffer(i, r); - factory SerializableCatrobatImage.fromJson($core.String i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromJson(i, r); - - static final $pb.BuilderInfo _i = $pb.BuilderInfo( - _omitMessageNames ? '' : 'SerializableCatrobatImage', - createEmptyInstance: create) - ..aOS(1, _omitFieldNames ? '' : 'magicValue', protoName: 'magicValue') - ..a<$core.int>(2, _omitFieldNames ? '' : 'version', $pb.PbFieldType.O3) - ..a<$core.int>(3, _omitFieldNames ? '' : 'width', $pb.PbFieldType.OU3) - ..a<$core.int>(4, _omitFieldNames ? '' : 'height', $pb.PbFieldType.OU3) - ..pc<$2.Any>(5, _omitFieldNames ? '' : 'commands', $pb.PbFieldType.PM, - subBuilder: $2.Any.create) - ..a<$core.List<$core.int>>( - 6, _omitFieldNames ? '' : 'backgroundImage', $pb.PbFieldType.OY, - protoName: 'backgroundImage') - ..hasRequiredFields = false; - - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - SerializableCatrobatImage clone() => - SerializableCatrobatImage()..mergeFromMessage(this); - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - SerializableCatrobatImage copyWith( - void Function(SerializableCatrobatImage) updates) => - super.copyWith((message) => updates(message as SerializableCatrobatImage)) - as SerializableCatrobatImage; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static SerializableCatrobatImage create() => SerializableCatrobatImage._(); - SerializableCatrobatImage createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') - static SerializableCatrobatImage getDefault() => _defaultInstance ??= - $pb.GeneratedMessage.$_defaultFor(create); - static SerializableCatrobatImage? _defaultInstance; - - @$pb.TagNumber(1) - $core.String get magicValue => $_getSZ(0); - @$pb.TagNumber(1) - set magicValue($core.String v) { - $_setString(0, v); - } - - @$pb.TagNumber(1) - $core.bool hasMagicValue() => $_has(0); - @$pb.TagNumber(1) - void clearMagicValue() => clearField(1); - - @$pb.TagNumber(2) - $core.int get version => $_getIZ(1); - @$pb.TagNumber(2) - set version($core.int v) { - $_setSignedInt32(1, v); - } - - @$pb.TagNumber(2) - $core.bool hasVersion() => $_has(1); - @$pb.TagNumber(2) - void clearVersion() => clearField(2); - - @$pb.TagNumber(3) - $core.int get width => $_getIZ(2); - @$pb.TagNumber(3) - set width($core.int v) { - $_setUnsignedInt32(2, v); - } - - @$pb.TagNumber(3) - $core.bool hasWidth() => $_has(2); - @$pb.TagNumber(3) - void clearWidth() => clearField(3); - - @$pb.TagNumber(4) - $core.int get height => $_getIZ(3); - @$pb.TagNumber(4) - set height($core.int v) { - $_setUnsignedInt32(3, v); - } - - @$pb.TagNumber(4) - $core.bool hasHeight() => $_has(3); - @$pb.TagNumber(4) - void clearHeight() => clearField(4); - - @$pb.TagNumber(5) - $core.List<$2.Any> get commands => $_getList(4); - - @$pb.TagNumber(6) - $core.List<$core.int> get backgroundImage => $_getN(5); - @$pb.TagNumber(6) - set backgroundImage($core.List<$core.int> v) { - $_setBytes(5, v); - } - - @$pb.TagNumber(6) - $core.bool hasBackgroundImage() => $_has(5); - @$pb.TagNumber(6) - void clearBackgroundImage() => clearField(6); -} - -const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); -const _omitMessageNames = - $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbenum.dart b/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbenum.dart deleted file mode 100644 index 9cf6956b..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbenum.dart +++ /dev/null @@ -1,10 +0,0 @@ -// -// Generated code. Do not modify. -// source: catrobat_image.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import diff --git a/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbjson.dart b/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbjson.dart deleted file mode 100644 index 13afd26d..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbjson.dart +++ /dev/null @@ -1,42 +0,0 @@ -// -// Generated code. Do not modify. -// source: catrobat_image.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -import 'dart:convert' as $convert; -import 'dart:core' as $core; -import 'dart:typed_data' as $typed_data; - -@$core.Deprecated('Use serializableCatrobatImageDescriptor instead') -const SerializableCatrobatImage$json = { - '1': 'SerializableCatrobatImage', - '2': [ - {'1': 'magicValue', '3': 1, '4': 1, '5': 9, '10': 'magicValue'}, - {'1': 'version', '3': 2, '4': 1, '5': 5, '10': 'version'}, - {'1': 'width', '3': 3, '4': 1, '5': 13, '10': 'width'}, - {'1': 'height', '3': 4, '4': 1, '5': 13, '10': 'height'}, - { - '1': 'commands', - '3': 5, - '4': 3, - '5': 11, - '6': '.google.protobuf.Any', - '10': 'commands' - }, - {'1': 'backgroundImage', '3': 6, '4': 1, '5': 12, '10': 'backgroundImage'}, - ], -}; - -/// Descriptor for `SerializableCatrobatImage`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List serializableCatrobatImageDescriptor = $convert.base64Decode( - 'ChlTZXJpYWxpemFibGVDYXRyb2JhdEltYWdlEh4KCm1hZ2ljVmFsdWUYASABKAlSCm1hZ2ljVm' - 'FsdWUSGAoHdmVyc2lvbhgCIAEoBVIHdmVyc2lvbhIUCgV3aWR0aBgDIAEoDVIFd2lkdGgSFgoG' - 'aGVpZ2h0GAQgASgNUgZoZWlnaHQSMAoIY29tbWFuZHMYBSADKAsyFC5nb29nbGUucHJvdG9idW' - 'YuQW55Ughjb21tYW5kcxIoCg9iYWNrZ3JvdW5kSW1hZ2UYBiABKAxSD2JhY2tncm91bmRJbWFn' - 'ZQ=='); diff --git a/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbserver.dart b/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbserver.dart deleted file mode 100644 index 3971a739..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/catrobat_image.pbserver.dart +++ /dev/null @@ -1,13 +0,0 @@ -// -// Generated code. Do not modify. -// source: catrobat_image.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names -// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -export 'catrobat_image.pb.dart'; diff --git a/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pb.dart b/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pb.dart deleted file mode 100644 index 6311b5fc..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pb.dart +++ /dev/null @@ -1,108 +0,0 @@ -// -// Generated code. Do not modify. -// source: command/graphic/draw_path_command.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -import 'dart:core' as $core; - -import 'package:protobuf/protobuf.dart' as $pb; - -import '../../graphic/paint.pb.dart' as $0; -import '../../graphic/path.pb.dart' as $1; - -class SerializableDrawPathCommand extends $pb.GeneratedMessage { - factory SerializableDrawPathCommand({ - $0.SerializablePaint? paint, - $1.SerializablePath? path, - }) { - final $result = create(); - if (paint != null) { - $result.paint = paint; - } - if (path != null) { - $result.path = path; - } - return $result; - } - SerializableDrawPathCommand._() : super(); - factory SerializableDrawPathCommand.fromBuffer($core.List<$core.int> i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromBuffer(i, r); - factory SerializableDrawPathCommand.fromJson($core.String i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromJson(i, r); - - static final $pb.BuilderInfo _i = $pb.BuilderInfo( - _omitMessageNames ? '' : 'SerializableDrawPathCommand', - createEmptyInstance: create) - ..aOM<$0.SerializablePaint>(1, _omitFieldNames ? '' : 'paint', - subBuilder: $0.SerializablePaint.create) - ..aOM<$1.SerializablePath>(2, _omitFieldNames ? '' : 'path', - subBuilder: $1.SerializablePath.create) - ..hasRequiredFields = false; - - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - SerializableDrawPathCommand clone() => - SerializableDrawPathCommand()..mergeFromMessage(this); - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - SerializableDrawPathCommand copyWith( - void Function(SerializableDrawPathCommand) updates) => - super.copyWith( - (message) => updates(message as SerializableDrawPathCommand)) - as SerializableDrawPathCommand; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static SerializableDrawPathCommand create() => - SerializableDrawPathCommand._(); - SerializableDrawPathCommand createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') - static SerializableDrawPathCommand getDefault() => _defaultInstance ??= - $pb.GeneratedMessage.$_defaultFor(create); - static SerializableDrawPathCommand? _defaultInstance; - - @$pb.TagNumber(1) - $0.SerializablePaint get paint => $_getN(0); - @$pb.TagNumber(1) - set paint($0.SerializablePaint v) { - setField(1, v); - } - - @$pb.TagNumber(1) - $core.bool hasPaint() => $_has(0); - @$pb.TagNumber(1) - void clearPaint() => clearField(1); - @$pb.TagNumber(1) - $0.SerializablePaint ensurePaint() => $_ensure(0); - - @$pb.TagNumber(2) - $1.SerializablePath get path => $_getN(1); - @$pb.TagNumber(2) - set path($1.SerializablePath v) { - setField(2, v); - } - - @$pb.TagNumber(2) - $core.bool hasPath() => $_has(1); - @$pb.TagNumber(2) - void clearPath() => clearField(2); - @$pb.TagNumber(2) - $1.SerializablePath ensurePath() => $_ensure(1); -} - -const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); -const _omitMessageNames = - $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbenum.dart b/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbenum.dart deleted file mode 100644 index dbe32309..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbenum.dart +++ /dev/null @@ -1,10 +0,0 @@ -// -// Generated code. Do not modify. -// source: command/graphic/draw_path_command.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import diff --git a/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbjson.dart b/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbjson.dart deleted file mode 100644 index 3ff6d2c5..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbjson.dart +++ /dev/null @@ -1,43 +0,0 @@ -// -// Generated code. Do not modify. -// source: command/graphic/draw_path_command.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -import 'dart:convert' as $convert; -import 'dart:core' as $core; -import 'dart:typed_data' as $typed_data; - -@$core.Deprecated('Use serializableDrawPathCommandDescriptor instead') -const SerializableDrawPathCommand$json = { - '1': 'SerializableDrawPathCommand', - '2': [ - { - '1': 'paint', - '3': 1, - '4': 1, - '5': 11, - '6': '.SerializablePaint', - '10': 'paint' - }, - { - '1': 'path', - '3': 2, - '4': 1, - '5': 11, - '6': '.SerializablePath', - '10': 'path' - }, - ], -}; - -/// Descriptor for `SerializableDrawPathCommand`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List serializableDrawPathCommandDescriptor = - $convert.base64Decode( - 'ChtTZXJpYWxpemFibGVEcmF3UGF0aENvbW1hbmQSKAoFcGFpbnQYASABKAsyEi5TZXJpYWxpem' - 'FibGVQYWludFIFcGFpbnQSJQoEcGF0aBgCIAEoCzIRLlNlcmlhbGl6YWJsZVBhdGhSBHBhdGg='); diff --git a/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbserver.dart b/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbserver.dart deleted file mode 100644 index 5dc7a54f..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/command/graphic/draw_path_command.pbserver.dart +++ /dev/null @@ -1,13 +0,0 @@ -// -// Generated code. Do not modify. -// source: command/graphic/draw_path_command.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names -// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -export 'draw_path_command.pb.dart'; diff --git a/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pb.dart b/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pb.dart deleted file mode 100644 index 9f9d4c72..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pb.dart +++ /dev/null @@ -1,224 +0,0 @@ -// -// Generated code. Do not modify. -// source: google/protobuf/any.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -import 'dart:core' as $core; - -import 'package:protobuf/protobuf.dart' as $pb; -import 'package:protobuf/src/protobuf/mixins/well_known.dart' as $mixin; - -/// `Any` contains an arbitrary serialized protocol buffer message along with a -/// URL that describes the type of the serialized message. -/// -/// Protobuf library provides support to pack/unpack Any values in the form -/// of utility functions or additional generated methods of the Any type. -/// -/// Example 1: Pack and unpack a message in C++. -/// -/// Foo foo = ...; -/// Any any; -/// any.PackFrom(foo); -/// ... -/// if (any.UnpackTo(&foo)) { -/// ... -/// } -/// -/// Example 2: Pack and unpack a message in Java. -/// -/// Foo foo = ...; -/// Any any = Any.pack(foo); -/// ... -/// if (any.is(Foo.class)) { -/// foo = any.unpack(Foo.class); -/// } -/// // or ... -/// if (any.isSameTypeAs(Foo.getDefaultInstance())) { -/// foo = any.unpack(Foo.getDefaultInstance()); -/// } -/// -/// Example 3: Pack and unpack a message in Python. -/// -/// foo = Foo(...) -/// any = Any() -/// any.Pack(foo) -/// ... -/// if any.Is(Foo.DESCRIPTOR): -/// any.Unpack(foo) -/// ... -/// -/// Example 4: Pack and unpack a message in Go -/// -/// foo := &pb.Foo{...} -/// any, err := anypb.New(foo) -/// if err != nil { -/// ... -/// } -/// ... -/// foo := &pb.Foo{} -/// if err := any.UnmarshalTo(foo); err != nil { -/// ... -/// } -/// -/// The pack methods provided by protobuf library will by default use -/// 'type.googleapis.com/full.type.name' as the type URL and the unpack -/// methods only use the fully qualified type name after the last '/' -/// in the type URL, for example "foo.bar.com/x/y.z" will yield type -/// name "y.z". -/// -/// JSON -/// ==== -/// The JSON representation of an `Any` value uses the regular -/// representation of the deserialized, embedded message, with an -/// additional field `@type` which contains the type URL. Example: -/// -/// package google.profile; -/// message Person { -/// string first_name = 1; -/// string last_name = 2; -/// } -/// -/// { -/// "@type": "type.googleapis.com/google.profile.Person", -/// "firstName": , -/// "lastName": -/// } -/// -/// If the embedded message type is well-known and has a custom JSON -/// representation, that representation will be embedded adding a field -/// `value` which holds the custom JSON in addition to the `@type` -/// field. Example (for message [google.protobuf.Duration][]): -/// -/// { -/// "@type": "type.googleapis.com/google.protobuf.Duration", -/// "value": "1.212s" -/// } -class Any extends $pb.GeneratedMessage with $mixin.AnyMixin { - factory Any({ - $core.String? typeUrl, - $core.List<$core.int>? value, - }) { - final $result = create(); - if (typeUrl != null) { - $result.typeUrl = typeUrl; - } - if (value != null) { - $result.value = value; - } - return $result; - } - Any._() : super(); - factory Any.fromBuffer($core.List<$core.int> i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromBuffer(i, r); - factory Any.fromJson($core.String i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromJson(i, r); - - static final $pb.BuilderInfo _i = $pb.BuilderInfo( - _omitMessageNames ? '' : 'Any', - package: - const $pb.PackageName(_omitMessageNames ? '' : 'google.protobuf'), - createEmptyInstance: create, - toProto3Json: $mixin.AnyMixin.toProto3JsonHelper, - fromProto3Json: $mixin.AnyMixin.fromProto3JsonHelper) - ..aOS(1, _omitFieldNames ? '' : 'typeUrl') - ..a<$core.List<$core.int>>( - 2, _omitFieldNames ? '' : 'value', $pb.PbFieldType.OY) - ..hasRequiredFields = false; - - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - Any clone() => Any()..mergeFromMessage(this); - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - Any copyWith(void Function(Any) updates) => - super.copyWith((message) => updates(message as Any)) as Any; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static Any create() => Any._(); - Any createEmptyInstance() => create(); - static $pb.PbList createRepeated() => $pb.PbList(); - @$core.pragma('dart2js:noInline') - static Any getDefault() => - _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); - static Any? _defaultInstance; - - /// A URL/resource name that uniquely identifies the type of the serialized - /// protocol buffer message. This string must contain at least - /// one "/" character. The last segment of the URL's path must represent - /// the fully qualified name of the type (as in - /// `path/google.protobuf.Duration`). The name should be in a canonical form - /// (e.g., leading "." is not accepted). - /// - /// In practice, teams usually precompile into the binary all types that they - /// expect it to use in the context of Any. However, for URLs which use the - /// scheme `http`, `https`, or no scheme, one can optionally set up a type - /// server that maps type URLs to message definitions as follows: - /// - /// * If no scheme is provided, `https` is assumed. - /// * An HTTP GET on the URL must yield a [google.protobuf.Type][] - /// value in binary format, or produce an error. - /// * Applications are allowed to cache lookup results based on the - /// URL, or have them precompiled into a binary to avoid any - /// lookup. Therefore, binary compatibility needs to be preserved - /// on changes to types. (Use versioned type names to manage - /// breaking changes.) - /// - /// Note: this functionality is not currently available in the official - /// protobuf release, and it is not used for type URLs beginning with - /// type.googleapis.com. As of May 2023, there are no widely used type server - /// implementations and no plans to implement one. - /// - /// Schemes other than `http`, `https` (or the empty scheme) might be - /// used with implementation specific semantics. - @$pb.TagNumber(1) - $core.String get typeUrl => $_getSZ(0); - @$pb.TagNumber(1) - set typeUrl($core.String v) { - $_setString(0, v); - } - - @$pb.TagNumber(1) - $core.bool hasTypeUrl() => $_has(0); - @$pb.TagNumber(1) - void clearTypeUrl() => clearField(1); - - /// Must be a valid serialized protocol buffer of the above specified type. - @$pb.TagNumber(2) - $core.List<$core.int> get value => $_getN(1); - @$pb.TagNumber(2) - set value($core.List<$core.int> v) { - $_setBytes(1, v); - } - - @$pb.TagNumber(2) - $core.bool hasValue() => $_has(1); - @$pb.TagNumber(2) - void clearValue() => clearField(2); - - /// Creates a new [Any] encoding [message]. - /// - /// The [typeUrl] will be [typeUrlPrefix]/`fullName` where `fullName` is - /// the fully qualified name of the type of [message]. - static Any pack($pb.GeneratedMessage message, - {$core.String typeUrlPrefix = 'type.googleapis.com'}) { - final result = create(); - $mixin.AnyMixin.packIntoAny(result, message, typeUrlPrefix: typeUrlPrefix); - return result; - } -} - -const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); -const _omitMessageNames = - $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbenum.dart b/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbenum.dart deleted file mode 100644 index 3744f124..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbenum.dart +++ /dev/null @@ -1,10 +0,0 @@ -// -// Generated code. Do not modify. -// source: google/protobuf/any.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import diff --git a/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbjson.dart b/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbjson.dart deleted file mode 100644 index eafbc6bd..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbjson.dart +++ /dev/null @@ -1,27 +0,0 @@ -// -// Generated code. Do not modify. -// source: google/protobuf/any.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -import 'dart:convert' as $convert; -import 'dart:core' as $core; -import 'dart:typed_data' as $typed_data; - -@$core.Deprecated('Use anyDescriptor instead') -const Any$json = { - '1': 'Any', - '2': [ - {'1': 'type_url', '3': 1, '4': 1, '5': 9, '10': 'typeUrl'}, - {'1': 'value', '3': 2, '4': 1, '5': 12, '10': 'value'}, - ], -}; - -/// Descriptor for `Any`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List anyDescriptor = $convert.base64Decode( - 'CgNBbnkSGQoIdHlwZV91cmwYASABKAlSB3R5cGVVcmwSFAoFdmFsdWUYAiABKAxSBXZhbHVl'); diff --git a/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbserver.dart b/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbserver.dart deleted file mode 100644 index 227b7b2c..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/google/protobuf/any.pbserver.dart +++ /dev/null @@ -1,13 +0,0 @@ -// -// Generated code. Do not modify. -// source: google/protobuf/any.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names -// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -export 'any.pb.dart'; diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pb.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pb.dart deleted file mode 100644 index 7598857a..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pb.dart +++ /dev/null @@ -1,187 +0,0 @@ -// -// Generated code. Do not modify. -// source: graphic/paint.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -import 'dart:core' as $core; - -import 'package:protobuf/protobuf.dart' as $pb; - -import 'paint.pbenum.dart'; - -export 'paint.pbenum.dart'; - -class SerializablePaint extends $pb.GeneratedMessage { - factory SerializablePaint({ - $core.int? color, - $core.double? strokeWidth, - SerializablePaint_StrokeCap? cap, - SerializablePaint_PaintingStyle? style, - SerializablePaint_BlendMode? blendMode, - SerializablePaint_StrokeJoin? strokeJoin, - }) { - final $result = create(); - if (color != null) { - $result.color = color; - } - if (strokeWidth != null) { - $result.strokeWidth = strokeWidth; - } - if (cap != null) { - $result.cap = cap; - } - if (style != null) { - $result.style = style; - } - if (blendMode != null) { - $result.blendMode = blendMode; - } - if (strokeJoin != null) { - $result.strokeJoin = strokeJoin; - } - return $result; - } - SerializablePaint._() : super(); - factory SerializablePaint.fromBuffer($core.List<$core.int> i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromBuffer(i, r); - factory SerializablePaint.fromJson($core.String i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromJson(i, r); - - static final $pb.BuilderInfo _i = $pb.BuilderInfo( - _omitMessageNames ? '' : 'SerializablePaint', - createEmptyInstance: create) - ..a<$core.int>(1, _omitFieldNames ? '' : 'color', $pb.PbFieldType.OU3) - ..a<$core.double>( - 2, _omitFieldNames ? '' : 'strokeWidth', $pb.PbFieldType.OF, - protoName: 'strokeWidth') - ..e( - 3, _omitFieldNames ? '' : 'cap', $pb.PbFieldType.OE, - defaultOrMaker: SerializablePaint_StrokeCap.STROKE_CAP_ROUND, - valueOf: SerializablePaint_StrokeCap.valueOf, - enumValues: SerializablePaint_StrokeCap.values) - ..e( - 4, _omitFieldNames ? '' : 'style', $pb.PbFieldType.OE, - defaultOrMaker: SerializablePaint_PaintingStyle.PAINTING_STYLE_FILL, - valueOf: SerializablePaint_PaintingStyle.valueOf, - enumValues: SerializablePaint_PaintingStyle.values) - ..e( - 5, _omitFieldNames ? '' : 'blendMode', $pb.PbFieldType.OE, - protoName: 'blendMode', - defaultOrMaker: SerializablePaint_BlendMode.BLEND_MODE_SCR_OVER, - valueOf: SerializablePaint_BlendMode.valueOf, - enumValues: SerializablePaint_BlendMode.values) - ..e( - 6, _omitFieldNames ? '' : 'strokeJoin', $pb.PbFieldType.OE, - protoName: 'strokeJoin', - defaultOrMaker: SerializablePaint_StrokeJoin.STROKE_JOIN_MITER, - valueOf: SerializablePaint_StrokeJoin.valueOf, - enumValues: SerializablePaint_StrokeJoin.values) - ..hasRequiredFields = false; - - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - SerializablePaint clone() => SerializablePaint()..mergeFromMessage(this); - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - SerializablePaint copyWith(void Function(SerializablePaint) updates) => - super.copyWith((message) => updates(message as SerializablePaint)) - as SerializablePaint; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static SerializablePaint create() => SerializablePaint._(); - SerializablePaint createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') - static SerializablePaint getDefault() => _defaultInstance ??= - $pb.GeneratedMessage.$_defaultFor(create); - static SerializablePaint? _defaultInstance; - - @$pb.TagNumber(1) - $core.int get color => $_getIZ(0); - @$pb.TagNumber(1) - set color($core.int v) { - $_setUnsignedInt32(0, v); - } - - @$pb.TagNumber(1) - $core.bool hasColor() => $_has(0); - @$pb.TagNumber(1) - void clearColor() => clearField(1); - - @$pb.TagNumber(2) - $core.double get strokeWidth => $_getN(1); - @$pb.TagNumber(2) - set strokeWidth($core.double v) { - $_setFloat(1, v); - } - - @$pb.TagNumber(2) - $core.bool hasStrokeWidth() => $_has(1); - @$pb.TagNumber(2) - void clearStrokeWidth() => clearField(2); - - @$pb.TagNumber(3) - SerializablePaint_StrokeCap get cap => $_getN(2); - @$pb.TagNumber(3) - set cap(SerializablePaint_StrokeCap v) { - setField(3, v); - } - - @$pb.TagNumber(3) - $core.bool hasCap() => $_has(2); - @$pb.TagNumber(3) - void clearCap() => clearField(3); - - @$pb.TagNumber(4) - SerializablePaint_PaintingStyle get style => $_getN(3); - @$pb.TagNumber(4) - set style(SerializablePaint_PaintingStyle v) { - setField(4, v); - } - - @$pb.TagNumber(4) - $core.bool hasStyle() => $_has(3); - @$pb.TagNumber(4) - void clearStyle() => clearField(4); - - @$pb.TagNumber(5) - SerializablePaint_BlendMode get blendMode => $_getN(4); - @$pb.TagNumber(5) - set blendMode(SerializablePaint_BlendMode v) { - setField(5, v); - } - - @$pb.TagNumber(5) - $core.bool hasBlendMode() => $_has(4); - @$pb.TagNumber(5) - void clearBlendMode() => clearField(5); - - @$pb.TagNumber(6) - SerializablePaint_StrokeJoin get strokeJoin => $_getN(5); - @$pb.TagNumber(6) - set strokeJoin(SerializablePaint_StrokeJoin v) { - setField(6, v); - } - - @$pb.TagNumber(6) - $core.bool hasStrokeJoin() => $_has(5); - @$pb.TagNumber(6) - void clearStrokeJoin() => clearField(6); -} - -const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); -const _omitMessageNames = - $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbenum.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbenum.dart deleted file mode 100644 index fd71611c..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbenum.dart +++ /dev/null @@ -1,115 +0,0 @@ -// -// Generated code. Do not modify. -// source: graphic/paint.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -import 'dart:core' as $core; - -import 'package:protobuf/protobuf.dart' as $pb; - -class SerializablePaint_StrokeCap extends $pb.ProtobufEnum { - static const SerializablePaint_StrokeCap STROKE_CAP_ROUND = - SerializablePaint_StrokeCap._( - 0, _omitEnumNames ? '' : 'STROKE_CAP_ROUND'); - static const SerializablePaint_StrokeCap STROKE_CAP_BUTT = - SerializablePaint_StrokeCap._(1, _omitEnumNames ? '' : 'STROKE_CAP_BUTT'); - static const SerializablePaint_StrokeCap STROKE_CAP_SQUARE = - SerializablePaint_StrokeCap._( - 2, _omitEnumNames ? '' : 'STROKE_CAP_SQUARE'); - - static const $core.List values = - [ - STROKE_CAP_ROUND, - STROKE_CAP_BUTT, - STROKE_CAP_SQUARE, - ]; - - static final $core.Map<$core.int, SerializablePaint_StrokeCap> _byValue = - $pb.ProtobufEnum.initByValue(values); - static SerializablePaint_StrokeCap? valueOf($core.int value) => - _byValue[value]; - - const SerializablePaint_StrokeCap._($core.int v, $core.String n) - : super(v, n); -} - -class SerializablePaint_PaintingStyle extends $pb.ProtobufEnum { - static const SerializablePaint_PaintingStyle PAINTING_STYLE_FILL = - SerializablePaint_PaintingStyle._( - 0, _omitEnumNames ? '' : 'PAINTING_STYLE_FILL'); - static const SerializablePaint_PaintingStyle PAINTING_STYLE_STROKE = - SerializablePaint_PaintingStyle._( - 1, _omitEnumNames ? '' : 'PAINTING_STYLE_STROKE'); - - static const $core.List values = - [ - PAINTING_STYLE_FILL, - PAINTING_STYLE_STROKE, - ]; - - static final $core.Map<$core.int, SerializablePaint_PaintingStyle> _byValue = - $pb.ProtobufEnum.initByValue(values); - static SerializablePaint_PaintingStyle? valueOf($core.int value) => - _byValue[value]; - - const SerializablePaint_PaintingStyle._($core.int v, $core.String n) - : super(v, n); -} - -class SerializablePaint_BlendMode extends $pb.ProtobufEnum { - static const SerializablePaint_BlendMode BLEND_MODE_SCR_OVER = - SerializablePaint_BlendMode._( - 0, _omitEnumNames ? '' : 'BLEND_MODE_SCR_OVER'); - static const SerializablePaint_BlendMode BLEND_MODE_CLEAR = - SerializablePaint_BlendMode._( - 1, _omitEnumNames ? '' : 'BLEND_MODE_CLEAR'); - - static const $core.List values = - [ - BLEND_MODE_SCR_OVER, - BLEND_MODE_CLEAR, - ]; - - static final $core.Map<$core.int, SerializablePaint_BlendMode> _byValue = - $pb.ProtobufEnum.initByValue(values); - static SerializablePaint_BlendMode? valueOf($core.int value) => - _byValue[value]; - - const SerializablePaint_BlendMode._($core.int v, $core.String n) - : super(v, n); -} - -class SerializablePaint_StrokeJoin extends $pb.ProtobufEnum { - static const SerializablePaint_StrokeJoin STROKE_JOIN_MITER = - SerializablePaint_StrokeJoin._( - 0, _omitEnumNames ? '' : 'STROKE_JOIN_MITER'); - static const SerializablePaint_StrokeJoin STROKE_JOIN_ROUND = - SerializablePaint_StrokeJoin._( - 1, _omitEnumNames ? '' : 'STROKE_JOIN_ROUND'); - static const SerializablePaint_StrokeJoin STROKE_JOIN_BEVEL = - SerializablePaint_StrokeJoin._( - 2, _omitEnumNames ? '' : 'STROKE_JOIN_BEVEL'); - - static const $core.List values = - [ - STROKE_JOIN_MITER, - STROKE_JOIN_ROUND, - STROKE_JOIN_BEVEL, - ]; - - static final $core.Map<$core.int, SerializablePaint_StrokeJoin> _byValue = - $pb.ProtobufEnum.initByValue(values); - static SerializablePaint_StrokeJoin? valueOf($core.int value) => - _byValue[value]; - - const SerializablePaint_StrokeJoin._($core.int v, $core.String n) - : super(v, n); -} - -const _omitEnumNames = $core.bool.fromEnvironment('protobuf.omit_enum_names'); diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbjson.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbjson.dart deleted file mode 100644 index 98ae48cc..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbjson.dart +++ /dev/null @@ -1,113 +0,0 @@ -// -// Generated code. Do not modify. -// source: graphic/paint.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -import 'dart:convert' as $convert; -import 'dart:core' as $core; -import 'dart:typed_data' as $typed_data; - -@$core.Deprecated('Use serializablePaintDescriptor instead') -const SerializablePaint$json = { - '1': 'SerializablePaint', - '2': [ - {'1': 'color', '3': 1, '4': 1, '5': 13, '10': 'color'}, - {'1': 'strokeWidth', '3': 2, '4': 1, '5': 2, '10': 'strokeWidth'}, - { - '1': 'cap', - '3': 3, - '4': 1, - '5': 14, - '6': '.SerializablePaint.StrokeCap', - '10': 'cap' - }, - { - '1': 'style', - '3': 4, - '4': 1, - '5': 14, - '6': '.SerializablePaint.PaintingStyle', - '10': 'style' - }, - { - '1': 'blendMode', - '3': 5, - '4': 1, - '5': 14, - '6': '.SerializablePaint.BlendMode', - '10': 'blendMode' - }, - { - '1': 'strokeJoin', - '3': 6, - '4': 1, - '5': 14, - '6': '.SerializablePaint.StrokeJoin', - '10': 'strokeJoin' - }, - ], - '4': [ - SerializablePaint_StrokeCap$json, - SerializablePaint_PaintingStyle$json, - SerializablePaint_BlendMode$json, - SerializablePaint_StrokeJoin$json - ], -}; - -@$core.Deprecated('Use serializablePaintDescriptor instead') -const SerializablePaint_StrokeCap$json = { - '1': 'StrokeCap', - '2': [ - {'1': 'STROKE_CAP_ROUND', '2': 0}, - {'1': 'STROKE_CAP_BUTT', '2': 1}, - {'1': 'STROKE_CAP_SQUARE', '2': 2}, - ], -}; - -@$core.Deprecated('Use serializablePaintDescriptor instead') -const SerializablePaint_PaintingStyle$json = { - '1': 'PaintingStyle', - '2': [ - {'1': 'PAINTING_STYLE_FILL', '2': 0}, - {'1': 'PAINTING_STYLE_STROKE', '2': 1}, - ], -}; - -@$core.Deprecated('Use serializablePaintDescriptor instead') -const SerializablePaint_BlendMode$json = { - '1': 'BlendMode', - '2': [ - {'1': 'BLEND_MODE_SCR_OVER', '2': 0}, - {'1': 'BLEND_MODE_CLEAR', '2': 1}, - ], -}; - -@$core.Deprecated('Use serializablePaintDescriptor instead') -const SerializablePaint_StrokeJoin$json = { - '1': 'StrokeJoin', - '2': [ - {'1': 'STROKE_JOIN_MITER', '2': 0}, - {'1': 'STROKE_JOIN_ROUND', '2': 1}, - {'1': 'STROKE_JOIN_BEVEL', '2': 2}, - ], -}; - -/// Descriptor for `SerializablePaint`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List serializablePaintDescriptor = $convert.base64Decode( - 'ChFTZXJpYWxpemFibGVQYWludBIUCgVjb2xvchgBIAEoDVIFY29sb3ISIAoLc3Ryb2tlV2lkdG' - 'gYAiABKAJSC3N0cm9rZVdpZHRoEi4KA2NhcBgDIAEoDjIcLlNlcmlhbGl6YWJsZVBhaW50LlN0' - 'cm9rZUNhcFIDY2FwEjYKBXN0eWxlGAQgASgOMiAuU2VyaWFsaXphYmxlUGFpbnQuUGFpbnRpbm' - 'dTdHlsZVIFc3R5bGUSOgoJYmxlbmRNb2RlGAUgASgOMhwuU2VyaWFsaXphYmxlUGFpbnQuQmxl' - 'bmRNb2RlUglibGVuZE1vZGUSPQoKc3Ryb2tlSm9pbhgGIAEoDjIdLlNlcmlhbGl6YWJsZVBhaW' - '50LlN0cm9rZUpvaW5SCnN0cm9rZUpvaW4iTQoJU3Ryb2tlQ2FwEhQKEFNUUk9LRV9DQVBfUk9V' - 'TkQQABITCg9TVFJPS0VfQ0FQX0JVVFQQARIVChFTVFJPS0VfQ0FQX1NRVUFSRRACIkMKDVBhaW' - '50aW5nU3R5bGUSFwoTUEFJTlRJTkdfU1RZTEVfRklMTBAAEhkKFVBBSU5USU5HX1NUWUxFX1NU' - 'Uk9LRRABIjoKCUJsZW5kTW9kZRIXChNCTEVORF9NT0RFX1NDUl9PVkVSEAASFAoQQkxFTkRfTU' - '9ERV9DTEVBUhABIlEKClN0cm9rZUpvaW4SFQoRU1RST0tFX0pPSU5fTUlURVIQABIVChFTVFJP' - 'S0VfSk9JTl9ST1VORBABEhUKEVNUUk9LRV9KT0lOX0JFVkVMEAI='); diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbserver.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbserver.dart deleted file mode 100644 index 4b9c3196..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/graphic/paint.pbserver.dart +++ /dev/null @@ -1,13 +0,0 @@ -// -// Generated code. Do not modify. -// source: graphic/paint.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names -// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -export 'paint.pb.dart'; diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/path.pb.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/path.pb.dart deleted file mode 100644 index 1e21d472..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/graphic/path.pb.dart +++ /dev/null @@ -1,420 +0,0 @@ -// -// Generated code. Do not modify. -// source: graphic/path.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -import 'dart:core' as $core; - -import 'package:protobuf/protobuf.dart' as $pb; - -import 'path.pbenum.dart'; - -export 'path.pbenum.dart'; - -class SerializablePath_Action_MoveTo extends $pb.GeneratedMessage { - factory SerializablePath_Action_MoveTo({ - $core.double? x, - $core.double? y, - }) { - final $result = create(); - if (x != null) { - $result.x = x; - } - if (y != null) { - $result.y = y; - } - return $result; - } - SerializablePath_Action_MoveTo._() : super(); - factory SerializablePath_Action_MoveTo.fromBuffer($core.List<$core.int> i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromBuffer(i, r); - factory SerializablePath_Action_MoveTo.fromJson($core.String i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromJson(i, r); - - static final $pb.BuilderInfo _i = $pb.BuilderInfo( - _omitMessageNames ? '' : 'SerializablePath.Action.MoveTo', - createEmptyInstance: create) - ..a<$core.double>(1, _omitFieldNames ? '' : 'x', $pb.PbFieldType.OD) - ..a<$core.double>(2, _omitFieldNames ? '' : 'y', $pb.PbFieldType.OD) - ..hasRequiredFields = false; - - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - SerializablePath_Action_MoveTo clone() => - SerializablePath_Action_MoveTo()..mergeFromMessage(this); - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - SerializablePath_Action_MoveTo copyWith( - void Function(SerializablePath_Action_MoveTo) updates) => - super.copyWith( - (message) => updates(message as SerializablePath_Action_MoveTo)) - as SerializablePath_Action_MoveTo; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static SerializablePath_Action_MoveTo create() => - SerializablePath_Action_MoveTo._(); - SerializablePath_Action_MoveTo createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') - static SerializablePath_Action_MoveTo getDefault() => _defaultInstance ??= - $pb.GeneratedMessage.$_defaultFor(create); - static SerializablePath_Action_MoveTo? _defaultInstance; - - @$pb.TagNumber(1) - $core.double get x => $_getN(0); - @$pb.TagNumber(1) - set x($core.double v) { - $_setDouble(0, v); - } - - @$pb.TagNumber(1) - $core.bool hasX() => $_has(0); - @$pb.TagNumber(1) - void clearX() => clearField(1); - - @$pb.TagNumber(2) - $core.double get y => $_getN(1); - @$pb.TagNumber(2) - set y($core.double v) { - $_setDouble(1, v); - } - - @$pb.TagNumber(2) - $core.bool hasY() => $_has(1); - @$pb.TagNumber(2) - void clearY() => clearField(2); -} - -class SerializablePath_Action_LineTo extends $pb.GeneratedMessage { - factory SerializablePath_Action_LineTo({ - $core.double? x, - $core.double? y, - }) { - final $result = create(); - if (x != null) { - $result.x = x; - } - if (y != null) { - $result.y = y; - } - return $result; - } - SerializablePath_Action_LineTo._() : super(); - factory SerializablePath_Action_LineTo.fromBuffer($core.List<$core.int> i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromBuffer(i, r); - factory SerializablePath_Action_LineTo.fromJson($core.String i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromJson(i, r); - - static final $pb.BuilderInfo _i = $pb.BuilderInfo( - _omitMessageNames ? '' : 'SerializablePath.Action.LineTo', - createEmptyInstance: create) - ..a<$core.double>(1, _omitFieldNames ? '' : 'x', $pb.PbFieldType.OD) - ..a<$core.double>(2, _omitFieldNames ? '' : 'y', $pb.PbFieldType.OD) - ..hasRequiredFields = false; - - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - SerializablePath_Action_LineTo clone() => - SerializablePath_Action_LineTo()..mergeFromMessage(this); - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - SerializablePath_Action_LineTo copyWith( - void Function(SerializablePath_Action_LineTo) updates) => - super.copyWith( - (message) => updates(message as SerializablePath_Action_LineTo)) - as SerializablePath_Action_LineTo; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static SerializablePath_Action_LineTo create() => - SerializablePath_Action_LineTo._(); - SerializablePath_Action_LineTo createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') - static SerializablePath_Action_LineTo getDefault() => _defaultInstance ??= - $pb.GeneratedMessage.$_defaultFor(create); - static SerializablePath_Action_LineTo? _defaultInstance; - - @$pb.TagNumber(1) - $core.double get x => $_getN(0); - @$pb.TagNumber(1) - set x($core.double v) { - $_setDouble(0, v); - } - - @$pb.TagNumber(1) - $core.bool hasX() => $_has(0); - @$pb.TagNumber(1) - void clearX() => clearField(1); - - @$pb.TagNumber(2) - $core.double get y => $_getN(1); - @$pb.TagNumber(2) - set y($core.double v) { - $_setDouble(1, v); - } - - @$pb.TagNumber(2) - $core.bool hasY() => $_has(1); - @$pb.TagNumber(2) - void clearY() => clearField(2); -} - -class SerializablePath_Action_Close extends $pb.GeneratedMessage { - factory SerializablePath_Action_Close() => create(); - SerializablePath_Action_Close._() : super(); - factory SerializablePath_Action_Close.fromBuffer($core.List<$core.int> i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromBuffer(i, r); - factory SerializablePath_Action_Close.fromJson($core.String i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromJson(i, r); - - static final $pb.BuilderInfo _i = $pb.BuilderInfo( - _omitMessageNames ? '' : 'SerializablePath.Action.Close', - createEmptyInstance: create) - ..hasRequiredFields = false; - - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - SerializablePath_Action_Close clone() => - SerializablePath_Action_Close()..mergeFromMessage(this); - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - SerializablePath_Action_Close copyWith( - void Function(SerializablePath_Action_Close) updates) => - super.copyWith( - (message) => updates(message as SerializablePath_Action_Close)) - as SerializablePath_Action_Close; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static SerializablePath_Action_Close create() => - SerializablePath_Action_Close._(); - SerializablePath_Action_Close createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') - static SerializablePath_Action_Close getDefault() => _defaultInstance ??= - $pb.GeneratedMessage.$_defaultFor(create); - static SerializablePath_Action_Close? _defaultInstance; -} - -enum SerializablePath_Action_Action { moveTo, lineTo, close, notSet } - -class SerializablePath_Action extends $pb.GeneratedMessage { - factory SerializablePath_Action({ - SerializablePath_Action_MoveTo? moveTo, - SerializablePath_Action_LineTo? lineTo, - SerializablePath_Action_Close? close, - }) { - final $result = create(); - if (moveTo != null) { - $result.moveTo = moveTo; - } - if (lineTo != null) { - $result.lineTo = lineTo; - } - if (close != null) { - $result.close = close; - } - return $result; - } - SerializablePath_Action._() : super(); - factory SerializablePath_Action.fromBuffer($core.List<$core.int> i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromBuffer(i, r); - factory SerializablePath_Action.fromJson($core.String i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromJson(i, r); - - static const $core.Map<$core.int, SerializablePath_Action_Action> - _SerializablePath_Action_ActionByTag = { - 1: SerializablePath_Action_Action.moveTo, - 2: SerializablePath_Action_Action.lineTo, - 3: SerializablePath_Action_Action.close, - 0: SerializablePath_Action_Action.notSet - }; - static final $pb.BuilderInfo _i = $pb.BuilderInfo( - _omitMessageNames ? '' : 'SerializablePath.Action', - createEmptyInstance: create) - ..oo(0, [1, 2, 3]) - ..aOM(1, _omitFieldNames ? '' : 'moveTo', - subBuilder: SerializablePath_Action_MoveTo.create) - ..aOM(2, _omitFieldNames ? '' : 'lineTo', - subBuilder: SerializablePath_Action_LineTo.create) - ..aOM(3, _omitFieldNames ? '' : 'close', - subBuilder: SerializablePath_Action_Close.create) - ..hasRequiredFields = false; - - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - SerializablePath_Action clone() => - SerializablePath_Action()..mergeFromMessage(this); - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - SerializablePath_Action copyWith( - void Function(SerializablePath_Action) updates) => - super.copyWith((message) => updates(message as SerializablePath_Action)) - as SerializablePath_Action; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static SerializablePath_Action create() => SerializablePath_Action._(); - SerializablePath_Action createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') - static SerializablePath_Action getDefault() => _defaultInstance ??= - $pb.GeneratedMessage.$_defaultFor(create); - static SerializablePath_Action? _defaultInstance; - - SerializablePath_Action_Action whichAction() => - _SerializablePath_Action_ActionByTag[$_whichOneof(0)]!; - void clearAction() => clearField($_whichOneof(0)); - - @$pb.TagNumber(1) - SerializablePath_Action_MoveTo get moveTo => $_getN(0); - @$pb.TagNumber(1) - set moveTo(SerializablePath_Action_MoveTo v) { - setField(1, v); - } - - @$pb.TagNumber(1) - $core.bool hasMoveTo() => $_has(0); - @$pb.TagNumber(1) - void clearMoveTo() => clearField(1); - @$pb.TagNumber(1) - SerializablePath_Action_MoveTo ensureMoveTo() => $_ensure(0); - - @$pb.TagNumber(2) - SerializablePath_Action_LineTo get lineTo => $_getN(1); - @$pb.TagNumber(2) - set lineTo(SerializablePath_Action_LineTo v) { - setField(2, v); - } - - @$pb.TagNumber(2) - $core.bool hasLineTo() => $_has(1); - @$pb.TagNumber(2) - void clearLineTo() => clearField(2); - @$pb.TagNumber(2) - SerializablePath_Action_LineTo ensureLineTo() => $_ensure(1); - - @$pb.TagNumber(3) - SerializablePath_Action_Close get close => $_getN(2); - @$pb.TagNumber(3) - set close(SerializablePath_Action_Close v) { - setField(3, v); - } - - @$pb.TagNumber(3) - $core.bool hasClose() => $_has(2); - @$pb.TagNumber(3) - void clearClose() => clearField(3); - @$pb.TagNumber(3) - SerializablePath_Action_Close ensureClose() => $_ensure(2); -} - -class SerializablePath extends $pb.GeneratedMessage { - factory SerializablePath({ - $core.Iterable? actions, - SerializablePath_FillType? fillType, - }) { - final $result = create(); - if (actions != null) { - $result.actions.addAll(actions); - } - if (fillType != null) { - $result.fillType = fillType; - } - return $result; - } - SerializablePath._() : super(); - factory SerializablePath.fromBuffer($core.List<$core.int> i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromBuffer(i, r); - factory SerializablePath.fromJson($core.String i, - [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => - create()..mergeFromJson(i, r); - - static final $pb.BuilderInfo _i = $pb.BuilderInfo( - _omitMessageNames ? '' : 'SerializablePath', - createEmptyInstance: create) - ..pc( - 1, _omitFieldNames ? '' : 'actions', $pb.PbFieldType.PM, - subBuilder: SerializablePath_Action.create) - ..e( - 2, _omitFieldNames ? '' : 'fillType', $pb.PbFieldType.OE, - defaultOrMaker: SerializablePath_FillType.NON_ZERO, - valueOf: SerializablePath_FillType.valueOf, - enumValues: SerializablePath_FillType.values) - ..hasRequiredFields = false; - - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' - 'Will be removed in next major version') - SerializablePath clone() => SerializablePath()..mergeFromMessage(this); - @$core.Deprecated('Using this can add significant overhead to your binary. ' - 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' - 'Will be removed in next major version') - SerializablePath copyWith(void Function(SerializablePath) updates) => - super.copyWith((message) => updates(message as SerializablePath)) - as SerializablePath; - - $pb.BuilderInfo get info_ => _i; - - @$core.pragma('dart2js:noInline') - static SerializablePath create() => SerializablePath._(); - SerializablePath createEmptyInstance() => create(); - static $pb.PbList createRepeated() => - $pb.PbList(); - @$core.pragma('dart2js:noInline') - static SerializablePath getDefault() => _defaultInstance ??= - $pb.GeneratedMessage.$_defaultFor(create); - static SerializablePath? _defaultInstance; - - @$pb.TagNumber(1) - $core.List get actions => $_getList(0); - - @$pb.TagNumber(2) - SerializablePath_FillType get fillType => $_getN(1); - @$pb.TagNumber(2) - set fillType(SerializablePath_FillType v) { - setField(2, v); - } - - @$pb.TagNumber(2) - $core.bool hasFillType() => $_has(1); - @$pb.TagNumber(2) - void clearFillType() => clearField(2); -} - -const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); -const _omitMessageNames = - $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbenum.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbenum.dart deleted file mode 100644 index a942740d..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbenum.dart +++ /dev/null @@ -1,35 +0,0 @@ -// -// Generated code. Do not modify. -// source: graphic/path.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -import 'dart:core' as $core; - -import 'package:protobuf/protobuf.dart' as $pb; - -class SerializablePath_FillType extends $pb.ProtobufEnum { - static const SerializablePath_FillType NON_ZERO = - SerializablePath_FillType._(0, _omitEnumNames ? '' : 'NON_ZERO'); - static const SerializablePath_FillType EVEN_ODD = - SerializablePath_FillType._(1, _omitEnumNames ? '' : 'EVEN_ODD'); - - static const $core.List values = - [ - NON_ZERO, - EVEN_ODD, - ]; - - static final $core.Map<$core.int, SerializablePath_FillType> _byValue = - $pb.ProtobufEnum.initByValue(values); - static SerializablePath_FillType? valueOf($core.int value) => _byValue[value]; - - const SerializablePath_FillType._($core.int v, $core.String n) : super(v, n); -} - -const _omitEnumNames = $core.bool.fromEnvironment('protobuf.omit_enum_names'); diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbjson.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbjson.dart deleted file mode 100644 index f209b2c4..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbjson.dart +++ /dev/null @@ -1,125 +0,0 @@ -// -// Generated code. Do not modify. -// source: graphic/path.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -import 'dart:convert' as $convert; -import 'dart:core' as $core; -import 'dart:typed_data' as $typed_data; - -@$core.Deprecated('Use serializablePathDescriptor instead') -const SerializablePath$json = { - '1': 'SerializablePath', - '2': [ - { - '1': 'actions', - '3': 1, - '4': 3, - '5': 11, - '6': '.SerializablePath.Action', - '10': 'actions' - }, - { - '1': 'fill_type', - '3': 2, - '4': 1, - '5': 14, - '6': '.SerializablePath.FillType', - '10': 'fillType' - }, - ], - '3': [SerializablePath_Action$json], - '4': [SerializablePath_FillType$json], -}; - -@$core.Deprecated('Use serializablePathDescriptor instead') -const SerializablePath_Action$json = { - '1': 'Action', - '2': [ - { - '1': 'move_to', - '3': 1, - '4': 1, - '5': 11, - '6': '.SerializablePath.Action.MoveTo', - '9': 0, - '10': 'moveTo' - }, - { - '1': 'line_to', - '3': 2, - '4': 1, - '5': 11, - '6': '.SerializablePath.Action.LineTo', - '9': 0, - '10': 'lineTo' - }, - { - '1': 'close', - '3': 3, - '4': 1, - '5': 11, - '6': '.SerializablePath.Action.Close', - '9': 0, - '10': 'close' - }, - ], - '3': [ - SerializablePath_Action_MoveTo$json, - SerializablePath_Action_LineTo$json, - SerializablePath_Action_Close$json - ], - '8': [ - {'1': 'action'}, - ], -}; - -@$core.Deprecated('Use serializablePathDescriptor instead') -const SerializablePath_Action_MoveTo$json = { - '1': 'MoveTo', - '2': [ - {'1': 'x', '3': 1, '4': 1, '5': 1, '10': 'x'}, - {'1': 'y', '3': 2, '4': 1, '5': 1, '10': 'y'}, - ], -}; - -@$core.Deprecated('Use serializablePathDescriptor instead') -const SerializablePath_Action_LineTo$json = { - '1': 'LineTo', - '2': [ - {'1': 'x', '3': 1, '4': 1, '5': 1, '10': 'x'}, - {'1': 'y', '3': 2, '4': 1, '5': 1, '10': 'y'}, - ], -}; - -@$core.Deprecated('Use serializablePathDescriptor instead') -const SerializablePath_Action_Close$json = { - '1': 'Close', -}; - -@$core.Deprecated('Use serializablePathDescriptor instead') -const SerializablePath_FillType$json = { - '1': 'FillType', - '2': [ - {'1': 'NON_ZERO', '2': 0}, - {'1': 'EVEN_ODD', '2': 1}, - ], -}; - -/// Descriptor for `SerializablePath`. Decode as a `google.protobuf.DescriptorProto`. -final $typed_data.Uint8List serializablePathDescriptor = $convert.base64Decode( - 'ChBTZXJpYWxpemFibGVQYXRoEjIKB2FjdGlvbnMYASADKAsyGC5TZXJpYWxpemFibGVQYXRoLk' - 'FjdGlvblIHYWN0aW9ucxI3CglmaWxsX3R5cGUYAiABKA4yGi5TZXJpYWxpemFibGVQYXRoLkZp' - 'bGxUeXBlUghmaWxsVHlwZRqXAgoGQWN0aW9uEjoKB21vdmVfdG8YASABKAsyHy5TZXJpYWxpem' - 'FibGVQYXRoLkFjdGlvbi5Nb3ZlVG9IAFIGbW92ZVRvEjoKB2xpbmVfdG8YAiABKAsyHy5TZXJp' - 'YWxpemFibGVQYXRoLkFjdGlvbi5MaW5lVG9IAFIGbGluZVRvEjYKBWNsb3NlGAMgASgLMh4uU2' - 'VyaWFsaXphYmxlUGF0aC5BY3Rpb24uQ2xvc2VIAFIFY2xvc2UaJAoGTW92ZVRvEgwKAXgYASAB' - 'KAFSAXgSDAoBeRgCIAEoAVIBeRokCgZMaW5lVG8SDAoBeBgBIAEoAVIBeBIMCgF5GAIgASgBUg' - 'F5GgcKBUNsb3NlQggKBmFjdGlvbiImCghGaWxsVHlwZRIMCghOT05fWkVSTxAAEgwKCEVWRU5f' - 'T0REEAE='); diff --git a/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbserver.dart b/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbserver.dart deleted file mode 100644 index a406ef5d..00000000 --- a/packages/io_library/lib/src/serialization/proto/output/graphic/path.pbserver.dart +++ /dev/null @@ -1,13 +0,0 @@ -// -// Generated code. Do not modify. -// source: graphic/path.proto -// -// @dart = 2.12 - -// ignore_for_file: annotate_overrides, camel_case_types, comment_references -// ignore_for_file: constant_identifier_names -// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes -// ignore_for_file: non_constant_identifier_names, prefer_final_fields -// ignore_for_file: unnecessary_import, unnecessary_this, unused_import - -export 'path.pb.dart'; diff --git a/packages/io_library/lib/src/serialization/proto/protos.dart b/packages/io_library/lib/src/serialization/proto/protos.dart deleted file mode 100644 index a180b981..00000000 --- a/packages/io_library/lib/src/serialization/proto/protos.dart +++ /dev/null @@ -1,4 +0,0 @@ -export 'output/command/graphic/draw_path_command.pb.dart'; -export 'output/google/protobuf/any.pb.dart'; -export 'output/graphic/paint.pb.dart'; -export 'output/graphic/path.pb.dart'; diff --git a/packages/io_library/lib/src/serialization/proto/schema/catrobat_image.proto b/packages/io_library/lib/src/serialization/proto/schema/catrobat_image.proto deleted file mode 100644 index 5ac819af..00000000 --- a/packages/io_library/lib/src/serialization/proto/schema/catrobat_image.proto +++ /dev/null @@ -1,12 +0,0 @@ -syntax = "proto3"; - -import "google/protobuf/any.proto"; - -message SerializableCatrobatImage { - string magicValue = 1; - int32 version = 2; - uint32 width = 3; - uint32 height = 4; - repeated google.protobuf.Any commands = 5; - bytes backgroundImage = 6; -} \ No newline at end of file diff --git a/packages/io_library/lib/src/serialization/proto/schema/command/graphic/draw_path_command.proto b/packages/io_library/lib/src/serialization/proto/schema/command/graphic/draw_path_command.proto deleted file mode 100644 index 84b8781b..00000000 --- a/packages/io_library/lib/src/serialization/proto/schema/command/graphic/draw_path_command.proto +++ /dev/null @@ -1,9 +0,0 @@ -syntax = 'proto3'; - -import 'graphic/paint.proto'; -import 'graphic/path.proto'; - -message SerializableDrawPathCommand { - SerializablePaint paint = 1; - SerializablePath path = 2; -} \ No newline at end of file diff --git a/packages/io_library/lib/src/serialization/proto/schema/graphic/paint.proto b/packages/io_library/lib/src/serialization/proto/schema/graphic/paint.proto deleted file mode 100644 index d9a40ceb..00000000 --- a/packages/io_library/lib/src/serialization/proto/schema/graphic/paint.proto +++ /dev/null @@ -1,34 +0,0 @@ -syntax = 'proto3'; - -message SerializablePaint { - uint32 color = 1; - - float strokeWidth = 2; - - enum StrokeCap { - STROKE_CAP_ROUND = 0; - STROKE_CAP_BUTT = 1; - STROKE_CAP_SQUARE = 2; - } - StrokeCap cap = 3; - - enum PaintingStyle { - PAINTING_STYLE_FILL = 0; - PAINTING_STYLE_STROKE = 1; - } - PaintingStyle style = 4; - - enum BlendMode { - BLEND_MODE_SCR_OVER = 0; - BLEND_MODE_CLEAR = 1; - } - BlendMode blendMode = 5; - - enum StrokeJoin { - STROKE_JOIN_MITER = 0; - STROKE_JOIN_ROUND = 1; - STROKE_JOIN_BEVEL = 2; - } - StrokeJoin strokeJoin = 6; - -} \ No newline at end of file diff --git a/packages/io_library/lib/src/serialization/proto/schema/graphic/path.proto b/packages/io_library/lib/src/serialization/proto/schema/graphic/path.proto deleted file mode 100644 index 8fa45480..00000000 --- a/packages/io_library/lib/src/serialization/proto/schema/graphic/path.proto +++ /dev/null @@ -1,27 +0,0 @@ -syntax = "proto3"; - -message SerializablePath { - message Action { - message MoveTo { - double x = 1; - double y = 2; - } - message LineTo { - double x = 1; - double y = 2; - } - message Close {} - - oneof action { - MoveTo move_to = 1; - LineTo line_to = 2; - Close close = 3; - } - } - repeated Action actions = 1; - enum FillType { - NON_ZERO = 0; - EVEN_ODD = 1; - } - FillType fill_type = 2; -} \ No newline at end of file diff --git a/packages/io_library/lib/src/serialization/proto_serializer_with_versioning.dart b/packages/io_library/lib/src/serialization/proto_serializer_with_versioning.dart deleted file mode 100644 index 808b1026..00000000 --- a/packages/io_library/lib/src/serialization/proto_serializer_with_versioning.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:io_library/io_library.dart'; -import 'package:protobuf/protobuf.dart' show GeneratedMessage; - -abstract class ProtoSerializerWithVersioning - extends VersionSerializer { - const ProtoSerializerWithVersioning(super.version); - - static const urlPrefix = 'org.catrobat.paintroid'; - - @protected - SERIALIZABLE Function(Uint8List binary) get fromBytesToSerializable; - - @nonVirtual - Future fromBytes(Uint8List binary) => - deserialize(fromBytesToSerializable(binary)); - - @nonVirtual - Future toBytes(T object) async => - (await serializeWithLatestVersion(object)).writeToBuffer(); -} diff --git a/packages/io_library/lib/src/serialization/serializer/catrobat_image_serializer.dart b/packages/io_library/lib/src/serialization/serializer/catrobat_image_serializer.dart deleted file mode 100644 index a2aa999f..00000000 --- a/packages/io_library/lib/src/serialization/serializer/catrobat_image_serializer.dart +++ /dev/null @@ -1,78 +0,0 @@ -import 'dart:typed_data'; -import 'dart:ui'; - -import 'package:command/command.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart' show Provider; -import 'package:io_library/io_library.dart'; -import 'package:io_library/serialization.dart'; - -class CatrobatImageSerializer extends ProtoSerializerWithVersioning< - CatrobatImage, SerializableCatrobatImage> { - final DrawPathCommandSerializer _drawPathCommandSerializer; - final IImageService _imageService; - - const CatrobatImageSerializer( - super.version, this._imageService, this._drawPathCommandSerializer); - - static final provider = Provider.family( - (ref, int ver) => CatrobatImageSerializer( - ver, - ref.watch(IImageService.provider), - ref.watch(DrawPathCommandSerializer.provider(ver)), - ), - ); - - @override - Future serializeWithLatestVersion( - CatrobatImage object) async { - Uint8List? backgroundImageData; - if (object.backgroundImage != null) { - final result = await _imageService.exportAsPng(object.backgroundImage!); - backgroundImageData = - result.unwrapOrElse((failure) => throw failure.message); - } - return SerializableCatrobatImage() - ..magicValue = CatrobatImage.magicValue - ..version = CatrobatImage.latestVersion - ..width = object.width - ..height = object.height - ..backgroundImage = - (backgroundImageData != null) ? backgroundImageData : Uint8List(0) - ..commands.addAll(await Future.wait(object.commands.map((command) async { - if (command is DrawPathCommand) { - return Any.pack( - await _drawPathCommandSerializer - .serializeWithLatestVersion(command), - typeUrlPrefix: ProtoSerializerWithVersioning.urlPrefix, - ); - } else { - throw 'Invalid command type'; - } - }))); - } - - @override - Future deserializeWithLatestVersion( - SerializableCatrobatImage data) async { - final commands = []; - for (final cmd in data.commands) { - if (cmd.canUnpackInto(SerializableDrawPathCommand.getDefault())) { - final unpacked = cmd.unpackInto(SerializableDrawPathCommand()); - commands.add(await _drawPathCommandSerializer.deserialize(unpacked)); - } else { - throw 'Invalid command type'; - } - } - Image? image; - if (data.hasBackgroundImage()) { - final result = - await _imageService.import(Uint8List.fromList(data.backgroundImage)); - image = result.unwrapOrElse((failure) => throw failure.message); - } - return CatrobatImage(commands, data.width, data.height, image, - version: data.version); - } - - @override - final fromBytesToSerializable = SerializableCatrobatImage.fromBuffer; -} diff --git a/packages/io_library/lib/src/serialization/serializer/command/graphic/draw_path_command_serializer.dart b/packages/io_library/lib/src/serialization/serializer/command/graphic/draw_path_command_serializer.dart deleted file mode 100644 index 41f05511..00000000 --- a/packages/io_library/lib/src/serialization/serializer/command/graphic/draw_path_command_serializer.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:command/command.dart'; -import 'package:command/command_providers.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; - -class DrawPathCommandSerializer extends ProtoSerializerWithVersioning< - DrawPathCommand, SerializableDrawPathCommand> { - final PathSerializer _pathSerializer; - final PaintSerializer _paintSerializer; - final CommandFactory _commandFactory; - - const DrawPathCommandSerializer( - super.version, - this._pathSerializer, - this._paintSerializer, - this._commandFactory, - ); - - static final provider = Provider.family( - (ref, int ver) => DrawPathCommandSerializer( - ver, - ref.watch(PathSerializer.provider(ver)), - ref.watch(PaintSerializer.provider(ver)), - ref.watch(commandFactoryProvider)), - ); - - @override - final fromBytesToSerializable = SerializableDrawPathCommand.fromBuffer; - - @override - Future deserializeWithLatestVersion( - SerializableDrawPathCommand data) async { - final path = await _pathSerializer.deserialize(data.path); - final paint = await _paintSerializer.deserialize(data.paint); - return _commandFactory.createDrawPathCommand(path, paint); - } - - @override - Future serializeWithLatestVersion( - DrawPathCommand object) async { - final sPaint = - await _paintSerializer.serializeWithLatestVersion(object.paint); - final sPath = await _pathSerializer.serializeWithLatestVersion(object.path); - return SerializableDrawPathCommand() - ..paint = sPaint - ..path = sPath; - } -} diff --git a/packages/io_library/lib/src/serialization/serializer/graphic/paint_serializer.dart b/packages/io_library/lib/src/serialization/serializer/graphic/paint_serializer.dart deleted file mode 100644 index 96124bf9..00000000 --- a/packages/io_library/lib/src/serialization/serializer/graphic/paint_serializer.dart +++ /dev/null @@ -1,68 +0,0 @@ -import 'dart:ui'; - -import 'package:component_library/component_library.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; - -class PaintSerializer - extends ProtoSerializerWithVersioning { - final GraphicFactory _graphicFactory; - - static final _capMap = { - SerializablePaint_StrokeCap.STROKE_CAP_BUTT: StrokeCap.butt, - SerializablePaint_StrokeCap.STROKE_CAP_ROUND: StrokeCap.round, - SerializablePaint_StrokeCap.STROKE_CAP_SQUARE: StrokeCap.square, - }; - - static final _styleMap = { - SerializablePaint_PaintingStyle.PAINTING_STYLE_FILL: PaintingStyle.fill, - SerializablePaint_PaintingStyle.PAINTING_STYLE_STROKE: PaintingStyle.stroke, - }; - - static final _blendModeMap = { - SerializablePaint_BlendMode.BLEND_MODE_SCR_OVER: BlendMode.srcOver, - SerializablePaint_BlendMode.BLEND_MODE_CLEAR: BlendMode.clear, - }; - - static final _strokeJoinMap = { - SerializablePaint_StrokeJoin.STROKE_JOIN_MITER: StrokeJoin.miter, - SerializablePaint_StrokeJoin.STROKE_JOIN_ROUND: StrokeJoin.round, - SerializablePaint_StrokeJoin.STROKE_JOIN_BEVEL: StrokeJoin.bevel, - }; - - const PaintSerializer(super.version, this._graphicFactory); - - static final provider = Provider.family( - (ref, int ver) => PaintSerializer(ver, ref.watch(graphicFactoryProvider)), - ); - - @override - final fromBytesToSerializable = SerializablePaint.fromBuffer; - - @override - Future deserializeWithLatestVersion(SerializablePaint data) async { - return _graphicFactory.createPaint() - ..color = Color(data.color) - ..strokeWidth = data.strokeWidth - ..strokeCap = _capMap[data.cap] ?? StrokeCap.butt - ..style = _styleMap[data.style] ?? PaintingStyle.fill - ..blendMode = _blendModeMap[data.blendMode] ?? BlendMode.srcOver - ..strokeJoin = _strokeJoinMap[data.strokeJoin] ?? StrokeJoin.miter; - } - - @override - Future serializeWithLatestVersion(Paint object) async { - final serializable = SerializablePaint() - ..color = object.color.value - ..strokeWidth = object.strokeWidth - ..cap = _capMap.entries.firstWhere((e) => e.value == object.strokeCap).key - ..style = _styleMap.entries.firstWhere((e) => e.value == object.style).key - ..blendMode = _blendModeMap.entries - .firstWhere((e) => e.value == object.blendMode) - .key - ..strokeJoin = _strokeJoinMap.entries - .firstWhere((e) => e.value == object.strokeJoin) - .key; - return serializable; - } -} diff --git a/packages/io_library/lib/src/serialization/serializer/graphic/path_serializer.dart b/packages/io_library/lib/src/serialization/serializer/graphic/path_serializer.dart deleted file mode 100644 index 9c45db4a..00000000 --- a/packages/io_library/lib/src/serialization/serializer/graphic/path_serializer.dart +++ /dev/null @@ -1,81 +0,0 @@ -import 'dart:ui'; - -import 'package:component_library/component_library.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; - -class PathSerializer extends ProtoSerializerWithVersioning< - PathWithActionHistory, SerializablePath> with LoggableMixin { - final GraphicFactory _graphicFactory; - - PathSerializer(super.version, this._graphicFactory); - - static final provider = Provider.family( - (ref, int ver) => PathSerializer(ver, ref.watch(graphicFactoryProvider)), - ); - - @override - Future deserializeWithLatestVersion( - SerializablePath data) async { - final path = _graphicFactory.createPathWithActionHistory(); - switch (data.fillType) { - case SerializablePath_FillType.EVEN_ODD: - path.fillType = PathFillType.evenOdd; - break; - case SerializablePath_FillType.NON_ZERO: - path.fillType = PathFillType.nonZero; - break; - } - for (var i = 0; i < data.actions.length; i++) { - final action = data.actions[i]; - if (action.hasMoveTo()) { - path.moveTo(action.moveTo.x, action.moveTo.y); - } else if (action.hasLineTo()) { - path.lineTo(action.lineTo.x, action.lineTo.y); - } else if (action.hasClose()) { - path.close(); - } else { - logger.severe('No Path Action was set at index $i.'); - } - } - return path; - } - - @override - final fromBytesToSerializable = SerializablePath.fromBuffer; - - @override - Future serializeWithLatestVersion( - PathWithActionHistory object) async { - final serializablePath = SerializablePath(); - switch (object.fillType) { - case PathFillType.nonZero: - serializablePath.fillType = SerializablePath_FillType.NON_ZERO; - break; - case PathFillType.evenOdd: - serializablePath.fillType = SerializablePath_FillType.EVEN_ODD; - break; - } - for (final action in object.actions) { - late final SerializablePath_Action serializableAction; - if (action is MoveToAction) { - final moveTo = SerializablePath_Action_MoveTo() - ..x = action.x - ..y = action.y; - serializableAction = SerializablePath_Action()..moveTo = moveTo; - } else if (action is LineToAction) { - final lineTo = SerializablePath_Action_LineTo() - ..x = action.x - ..y = action.y; - serializableAction = SerializablePath_Action()..lineTo = lineTo; - } else if (action is CloseAction) { - final close = SerializablePath_Action_Close(); - serializableAction = SerializablePath_Action()..close = close; - } else { - logger.severe('Path Action serialization was not handled for $action'); - } - serializablePath.actions.add(serializableAction); - } - return serializablePath; - } -} diff --git a/packages/io_library/lib/src/serialization/version_serializer.dart b/packages/io_library/lib/src/serialization/version_serializer.dart deleted file mode 100644 index 5fd5b1f5..00000000 --- a/packages/io_library/lib/src/serialization/version_serializer.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/foundation.dart'; - -abstract class VersionSerializer { - final int version; - - static const v1 = 1; - - const VersionSerializer(this.version); - - Future serializeWithLatestVersion(FROM object); - - @nonVirtual - Future deserialize(TO data) { - switch (version) { - case v1: - return deserializeV1(data); - default: - throw 'Invalid version'; - } - } - - @protected - Future deserializeV1(TO data) => deserializeWithLatestVersion(data); - - @protected - Future deserializeWithLatestVersion(TO data); -} diff --git a/packages/io_library/lib/src/usecase/load_image_from_file_manager.dart b/packages/io_library/lib/src/usecase/load_image_from_file_manager.dart index 53a96d9f..aaa4d2fd 100644 --- a/packages/io_library/lib/src/usecase/load_image_from_file_manager.dart +++ b/packages/io_library/lib/src/usecase/load_image_from_file_manager.dart @@ -1,4 +1,7 @@ +import 'dart:convert'; import 'dart:io'; +import 'dart:typed_data'; +import 'dart:ui'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:io_library/io_library.dart'; @@ -16,19 +19,16 @@ class LoadImageFromFileManager with LoggableMixin { final IFileService fileService; final IImageService imageService; final IPermissionService permissionService; - final CatrobatImageSerializer catrobatImageSerializer; - LoadImageFromFileManager(this.fileService, this.imageService, - this.permissionService, this.catrobatImageSerializer); + LoadImageFromFileManager( + this.fileService, this.imageService, this.permissionService); static final provider = Provider((ref) { final imageService = ref.watch(IImageService.provider); final fileService = ref.watch(IFileService.provider); final permissionService = ref.watch(IPermissionService.provider); - const ver = CatrobatImage.latestVersion; - final serializer = ref.watch(CatrobatImageSerializer.provider(ver)); return LoadImageFromFileManager( - fileService, imageService, permissionService, serializer); + fileService, imageService, permissionService); }); Future> call( @@ -50,11 +50,13 @@ class LoadImageFromFileManager with LoggableMixin { .import(await file.readAsBytes()) .map((img) => ImageFromFile.rasterImage(img)); case 'catrobat-image': - final image = await catrobatImageSerializer - .fromBytes(await file.readAsBytes()); + Uint8List bytes = await file.readAsBytes(); + CatrobatImage catrobatImage = CatrobatImage.fromBytes(bytes); + Image? backgroundImage = + await rebuildBackgroundImage(catrobatImage); return Result.ok(ImageFromFile.catrobatImage( - image, - backgroundImage: image.backgroundImage, + catrobatImage, + backgroundImage: backgroundImage, )); default: return const Result.err(LoadImageFailure.invalidImage); @@ -68,4 +70,14 @@ class LoadImageFromFileManager with LoggableMixin { } }); } + + Future rebuildBackgroundImage(CatrobatImage catrobatImage) async { + if (catrobatImage.backgroundImage.isNotEmpty) { + final backgroundImageData = base64Decode(catrobatImage.backgroundImage); + final result = + await imageService.import(Uint8List.fromList(backgroundImageData)); + return result.unwrapOrElse((failure) => throw failure.message); + } + return null; + } } diff --git a/packages/io_library/lib/src/usecase/save_as_catrobat_image.dart b/packages/io_library/lib/src/usecase/save_as_catrobat_image.dart index ba7b9cc4..c97deb6a 100644 --- a/packages/io_library/lib/src/usecase/save_as_catrobat_image.dart +++ b/packages/io_library/lib/src/usecase/save_as_catrobat_image.dart @@ -7,17 +7,13 @@ import 'package:oxidized/oxidized.dart'; class SaveAsCatrobatImage with LoggableMixin { final IFileService _fileService; final IPermissionService permissionService; - final CatrobatImageSerializer _catrobatImageSerializer; - SaveAsCatrobatImage( - this._fileService, this.permissionService, this._catrobatImageSerializer); + SaveAsCatrobatImage(this._fileService, this.permissionService); static final provider = Provider((ref) { final fileService = ref.watch(IFileService.provider); final permissionService = ref.watch(IPermissionService.provider); - const ver = CatrobatImage.latestVersion; - final serializer = ref.watch(CatrobatImageSerializer.provider(ver)); - return SaveAsCatrobatImage(fileService, permissionService, serializer); + return SaveAsCatrobatImage(fileService, permissionService); }); Future> call( @@ -27,7 +23,7 @@ class SaveAsCatrobatImage with LoggableMixin { } final nameWithExt = '${data.name}.${data.format.extension}'; try { - final bytes = await _catrobatImageSerializer.toBytes(image); + final bytes = image.toBytes(); if (isAProject) { return _fileService.saveToApplicationDirectory(nameWithExt, bytes); } diff --git a/packages/io_library/pubspec.yaml b/packages/io_library/pubspec.yaml index cda4d8dd..33e1fe2b 100644 --- a/packages/io_library/pubspec.yaml +++ b/packages/io_library/pubspec.yaml @@ -26,6 +26,7 @@ dependencies: filesize: ^2.0.1 oxidized: ^5.2.0 intl: ^0.18.0 + json_annotation: ^4.8.1 # Internal packages: component_library: @@ -37,6 +38,7 @@ dependencies: workspace_screen: path: ../features/workspace_screen + dev_dependencies: flutter_test: sdk: flutter @@ -49,6 +51,7 @@ dev_dependencies: riverpod_lint: ^1.3.2 build_runner: ^2.2.0 freezed: ^2.4.1 + json_serializable: ^6.7.1 flutter: uses-material-design: true diff --git a/packages/io_library/test/unit/serialization/command/draw_path_command_serializer_test.dart b/packages/io_library/test/unit/serialization/command/draw_path_command_serializer_test.dart new file mode 100644 index 00000000..e4e86ea9 --- /dev/null +++ b/packages/io_library/test/unit/serialization/command/draw_path_command_serializer_test.dart @@ -0,0 +1,60 @@ +import 'package:command/command.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:io_library/io_library.dart'; + +import '../utils/dummy_command_factory.dart'; +import '../utils/dummy_paint_factory.dart'; +import '../utils/dummy_path_factory.dart'; + +void main() { + group('Version 1', () { + test('Test DrawPathCommand serialization with one path', () { + PathWithActionHistory originalPath = + DummyPathFactory.createPathWithActionHistory(1); + Paint originalPaint = DummyPaintFactory.createPaint(version: Version.v1); + DrawPathCommand command = DummyCommandFactory.createDrawPathCommand( + originalPath, + originalPaint, + version: Version.v1, + ); + + var json = command.toJson(); + DrawPathCommand deserializedCommand = DrawPathCommand.fromJson(json); + + expect(command.version, equals(deserializedCommand.version)); + expect( + DummyPaintFactory.comparePaint( + originalPaint, + deserializedCommand.paint, + version: Version.v1, + ), + isTrue); + expect(originalPath, equals(deserializedCommand.path)); + }); + + test('Test DrawPathCommand serialization with multiple paths', () { + PathWithActionHistory originalPath = + DummyPathFactory.createPathWithActionHistory(5); + Paint originalPaint = DummyPaintFactory.createPaint(version: Version.v1); + DrawPathCommand command = DummyCommandFactory.createDrawPathCommand( + originalPath, + originalPaint, + version: Version.v1, + ); + + var json = command.toJson(); + DrawPathCommand deserializedCommand = DrawPathCommand.fromJson(json); + + expect(command.version, equals(deserializedCommand.version)); + expect( + DummyPaintFactory.comparePaint( + originalPaint, + deserializedCommand.paint, + version: Version.v1, + ), + isTrue); + expect(originalPath, equals(deserializedCommand.path)); + }); + }); +} diff --git a/packages/io_library/test/unit/serialization/converter/paint_converter_test.dart b/packages/io_library/test/unit/serialization/converter/paint_converter_test.dart new file mode 100644 index 00000000..1be43995 --- /dev/null +++ b/packages/io_library/test/unit/serialization/converter/paint_converter_test.dart @@ -0,0 +1,90 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:io_library/io_library.dart'; + +import '../utils/dummy_paint_factory.dart'; + +void main() { + PaintConverter converter = const PaintConverter(); + + group('Version 1', () { + test('Basic Paint', () { + Paint originalPaint = Paint() + ..color = Colors.blue + ..strokeWidth = 5.0 + ..strokeCap = StrokeCap.round + ..isAntiAlias = true + ..style = PaintingStyle.fill + ..strokeJoin = StrokeJoin.bevel + ..blendMode = BlendMode.clear; + + var json = converter.toJson(originalPaint); + + Paint deserializedPaint = converter.fromJson(json); + + expect( + DummyPaintFactory.comparePaint( + deserializedPaint, + originalPaint, + version: Version.v1, + ), + isTrue); + }); + + test('Basic Paint', () { + Paint originalPaint = Paint() + ..color = Colors.yellow + ..strokeWidth = 2.5 + ..strokeCap = StrokeCap.butt + ..isAntiAlias = true + ..style = PaintingStyle.stroke + ..strokeJoin = StrokeJoin.miter + ..blendMode = BlendMode.srcOver; + + var json = converter.toJson(originalPaint); + + Paint deserializedPaint = converter.fromJson(json); + + expect( + DummyPaintFactory.comparePaint( + deserializedPaint, + originalPaint, + version: Version.v1, + ), + isTrue); + }); + + test('Basic Paint', () { + Paint originalPaint = Paint() + ..color = Colors.green + ..strokeWidth = 3.0 + ..strokeCap = StrokeCap.square + ..isAntiAlias = false + ..style = PaintingStyle.stroke + ..strokeJoin = StrokeJoin.round + ..blendMode = BlendMode.srcIn; + + var json = converter.toJson(originalPaint); + + Paint deserializedPaint = converter.fromJson(json); + + expect( + DummyPaintFactory.comparePaint( + deserializedPaint, + originalPaint, + version: Version.v1, + ), + isTrue); + }); + + test('Custom Color', () { + Paint originalPaint = Paint()..color = Colors.red; + + var json = converter.toJson(originalPaint); + + Paint deserializedPaint = converter.fromJson(json); + + expect(deserializedPaint.color, equals(originalPaint.color)); + }); + }); +} diff --git a/packages/io_library/test/unit/serialization/converter/path_action_converter_test.dart b/packages/io_library/test/unit/serialization/converter/path_action_converter_test.dart new file mode 100644 index 00000000..4fd6e0ee --- /dev/null +++ b/packages/io_library/test/unit/serialization/converter/path_action_converter_test.dart @@ -0,0 +1,47 @@ +import 'package:command/command.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:io_library/io_library.dart'; + +void main() { + const PathActionConverter converter = PathActionConverter(); + + test('Test converter for MoveToAction', () { + double xExpected = 1.0; + double yExpected = 2.0; + + MoveToAction moveToAction = MoveToAction(xExpected, yExpected); + + var json = converter.toJson(moveToAction); + + PathAction deserializedMoveToAction = converter.fromJson(json); + + expect(deserializedMoveToAction, isA()); + deserializedMoveToAction as MoveToAction; + expect(moveToAction, equals(deserializedMoveToAction)); + }); + + test('Test converter for LineToAction', () { + double xExpected = 1.0; + double yExpected = 2.0; + + LineToAction lineToAction = LineToAction(xExpected, yExpected); + + var json = converter.toJson(lineToAction); + + PathAction deserializedLineToAction = converter.fromJson(json); + + expect(deserializedLineToAction, isA()); + deserializedLineToAction as LineToAction; + expect(lineToAction, equals(deserializedLineToAction)); + }); + + test('Test converter for CloseAction', () { + CloseAction closeAction = const CloseAction(); + + var json = converter.toJson(closeAction); + + PathAction deserializedCloseAction = converter.fromJson(json); + + expect(deserializedCloseAction, isA()); + }); +} diff --git a/packages/io_library/test/unit/serialization/converter/path_with_action_history_converter_test.dart b/packages/io_library/test/unit/serialization/converter/path_with_action_history_converter_test.dart new file mode 100644 index 00000000..1167e2be --- /dev/null +++ b/packages/io_library/test/unit/serialization/converter/path_with_action_history_converter_test.dart @@ -0,0 +1,43 @@ +import 'package:command/command.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:io_library/io_library.dart'; + +import '../utils/dummy_path_factory.dart'; + +void main() { + const PathWithActionHistoryConverter converter = + PathWithActionHistoryConverter(); + + test('Test converter for PathWithActionHistory with one path', () { + PathWithActionHistory path = + DummyPathFactory.createPathWithActionHistory(1); + + var json = converter.toJson(path); + + PathWithActionHistory deserializedPath = converter.fromJson(json); + + expect(path, equals(deserializedPath)); + }); + + test('Test converter for PathWithActionHistory with two paths', () { + PathWithActionHistory path = + DummyPathFactory.createPathWithActionHistory(2); + + var json = converter.toJson(path); + + PathWithActionHistory deserializedPath = converter.fromJson(json); + + expect(path, equals(deserializedPath)); + }); + + test('Test converter for PathWithActionHistory with multiple paths', () { + PathWithActionHistory path = + DummyPathFactory.createPathWithActionHistory(10); + + var json = converter.toJson(path); + + PathWithActionHistory deserializedPath = converter.fromJson(json); + + expect(path, equals(deserializedPath)); + }); +} diff --git a/packages/io_library/test/unit/serialization/image/catrobat_image_serializer_test.dart b/packages/io_library/test/unit/serialization/image/catrobat_image_serializer_test.dart new file mode 100644 index 00000000..10b0cbbd --- /dev/null +++ b/packages/io_library/test/unit/serialization/image/catrobat_image_serializer_test.dart @@ -0,0 +1,55 @@ +import 'dart:typed_data'; + +import 'package:command/command.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:io_library/io_library.dart'; + +import '../utils/dummy_command_factory.dart'; +import '../utils/dummy_version_strategy.dart'; + +void main() { + group('Version 1', () { + test('Test CatrobatImage serialization with 1 path', () { + Iterable commands = + DummyCommandFactory.createCommandList(1, version: Version.v1); + VersionStrategyManager.setStrategy( + DummyVersionStrategy(catrobatImageVersion: Version.v1)); + CatrobatImage originalImage = CatrobatImage(commands, 100, 200, ''); + + Uint8List bytes = originalImage.toBytes(); + CatrobatImage deserializedImage = CatrobatImage.fromBytes(bytes); + + expect( + DummyCommandFactory.compareCommandLists( + commands, deserializedImage.commands), + isTrue); + expect(originalImage.width, equals(deserializedImage.width)); + expect(originalImage.height, equals(deserializedImage.height)); + expect(originalImage.backgroundImage, + equals(deserializedImage.backgroundImage)); + expect(Version.v1, equals(deserializedImage.version)); + expect(originalImage.magicValue, equals(deserializedImage.magicValue)); + }); + + test('Test CatrobatImage serialization with multiple paths', () { + Iterable commands = DummyCommandFactory.createCommandList(5); + VersionStrategyManager.setStrategy( + DummyVersionStrategy(catrobatImageVersion: Version.v1)); + CatrobatImage originalImage = CatrobatImage(commands, 100, 200, ''); + + Uint8List bytes = originalImage.toBytes(); + CatrobatImage deserializedImage = CatrobatImage.fromBytes(bytes); + + expect( + DummyCommandFactory.compareCommandLists( + commands, deserializedImage.commands), + isTrue); + expect(originalImage.width, equals(deserializedImage.width)); + expect(originalImage.height, equals(deserializedImage.height)); + expect(originalImage.backgroundImage, + equals(deserializedImage.backgroundImage)); + expect(Version.v1, equals(deserializedImage.version)); + expect(originalImage.magicValue, equals(deserializedImage.magicValue)); + }); + }); +} diff --git a/packages/io_library/test/unit/serialization/paint_serializer_test.dart b/packages/io_library/test/unit/serialization/paint_serializer_test.dart deleted file mode 100644 index 40015ca9..00000000 --- a/packages/io_library/test/unit/serialization/paint_serializer_test.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:component_library/component_library.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:io_library/io_library.dart'; - -void main() { - final mockGraphicFactory = MockGraphicFactory(); - final paintSerializer = PaintSerializer(1, mockGraphicFactory); - - group('PaintSerializer', () { - test( - 'serialize and deserialize with a Paint object having all default values', - () async { - final paint = Paint(); - - final serialized = - await paintSerializer.serializeWithLatestVersion(paint); - final deserialized = - await paintSerializer.deserializeWithLatestVersion(serialized); - - expect(deserialized.color, Colors.black); - expect(deserialized.strokeWidth, 0.0); - expect(deserialized.blendMode, BlendMode.srcOver); - expect(deserialized.strokeCap, StrokeCap.butt); - expect(deserialized.strokeJoin, StrokeJoin.miter); - expect(deserialized.style, PaintingStyle.fill); - }); - - test('serialize and deserialize with different values', () async { - final paint = Paint() - ..blendMode = BlendMode.srcOver - ..color = Colors.red - ..strokeCap = StrokeCap.round - ..strokeJoin = StrokeJoin.round - ..strokeWidth = 25.0 - ..style = PaintingStyle.stroke; - - final serialized = - await paintSerializer.serializeWithLatestVersion(paint); - final deserialized = - await paintSerializer.deserializeWithLatestVersion(serialized); - - expect(deserialized.blendMode, paint.blendMode); - expect(deserialized.color, paint.color); - expect(deserialized.strokeCap, paint.strokeCap); - expect(deserialized.strokeJoin, paint.strokeJoin); - expect(deserialized.strokeWidth, paint.strokeWidth); - expect(deserialized.style, paint.style); - }); - }); -} - -class MockGraphicFactory extends GraphicFactory {} diff --git a/packages/io_library/test/unit/serialization/utils/dummy_command_factory.dart b/packages/io_library/test/unit/serialization/utils/dummy_command_factory.dart new file mode 100644 index 00000000..2812ce77 --- /dev/null +++ b/packages/io_library/test/unit/serialization/utils/dummy_command_factory.dart @@ -0,0 +1,63 @@ +import 'dart:ui'; + +import 'package:command/command.dart'; +import 'package:io_library/io_library.dart'; + +import 'dummy_paint_factory.dart'; +import 'dummy_path_factory.dart'; +import 'dummy_version_strategy.dart'; + +class DummyCommandFactory { + static Iterable createCommandList(int numberOfCommands, + {int version = Version.v1}) { + CommandFactory commandFactory = const CommandFactory(); + VersionStrategyManager.setStrategy( + DummyVersionStrategy(drawPathCommandVersion: version)); + List commands = []; + for (int i = 0; i < numberOfCommands; i++) { + PathWithActionHistory originalPath = + DummyPathFactory.createPathWithActionHistory(i * numberOfCommands); + Paint originalPaint = DummyPaintFactory.createPaint(); + DrawPathCommand command = + commandFactory.createDrawPathCommand(originalPath, originalPaint); + commands.add(command); + } + return commands; + } + + static DrawPathCommand createDrawPathCommand( + PathWithActionHistory path, Paint paint, + {int version = Version.v1}) { + CommandFactory commandFactory = const CommandFactory(); + VersionStrategyManager.setStrategy( + DummyVersionStrategy(drawPathCommandVersion: version)); + return commandFactory.createDrawPathCommand(path, paint); + } + + static bool compareCommandLists( + Iterable commands1, Iterable commands2) { + if (commands1.length != commands2.length) { + return false; + } + var iterator1 = commands1.iterator; + var iterator2 = commands2.iterator; + + while (iterator1.moveNext() && iterator2.moveNext()) { + if (!areCommandsEqual(iterator1.current, iterator2.current)) { + return false; + } + } + return true; + } + + static bool areCommandsEqual(Command command1, Command command2) { + if (command1 is DrawPathCommand && command2 is DrawPathCommand) { + return command1.path == command2.path && + DummyPaintFactory.comparePaint( + command1.paint, + command2.paint, + ); + } + return false; + } +} diff --git a/packages/io_library/test/unit/serialization/utils/dummy_paint_factory.dart b/packages/io_library/test/unit/serialization/utils/dummy_paint_factory.dart new file mode 100644 index 00000000..dc53ffa4 --- /dev/null +++ b/packages/io_library/test/unit/serialization/utils/dummy_paint_factory.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; +import 'package:io_library/io_library.dart'; + +class DummyPaintFactory { + static Paint createPaint({int version = Version.v1}) { + Paint paint = Paint(); + if (version >= Version.v1) { + paint.color = Colors.blue; + paint.strokeWidth = 5.0; + paint.strokeCap = StrokeCap.round; + paint.isAntiAlias = true; + paint.style = PaintingStyle.fill; + paint.strokeJoin = StrokeJoin.bevel; + paint.blendMode = BlendMode.clear; + } + if (version >= Version.v2) { + // paint.newAttribute = newAttribute; + } + return paint; + } + + static bool comparePaint(Paint paint1, Paint paint2, + {int version = Version.v1}) { + bool result = true; + if (version >= Version.v1) { + result = paint1.color == paint2.color && + paint1.strokeWidth == paint2.strokeWidth && + paint1.strokeCap == paint2.strokeCap && + paint1.isAntiAlias == paint2.isAntiAlias && + paint1.style == paint2.style && + paint1.strokeJoin == paint2.strokeJoin && + paint1.blendMode == paint2.blendMode; + } + if (version >= Version.v2) { + // result = result && paint1.newAttribute == paint2.newAttribute; + } + return result; + } +} diff --git a/packages/io_library/test/unit/serialization/utils/dummy_path_factory.dart b/packages/io_library/test/unit/serialization/utils/dummy_path_factory.dart new file mode 100644 index 00000000..2f19f5bb --- /dev/null +++ b/packages/io_library/test/unit/serialization/utils/dummy_path_factory.dart @@ -0,0 +1,14 @@ +import 'package:command/command.dart'; + +class DummyPathFactory { + static PathWithActionHistory createPathWithActionHistory( + int numberOfActions) { + PathWithActionHistory pathWithActionHistory = PathWithActionHistory(); + for (int i = 0; i < numberOfActions; i++) { + pathWithActionHistory.moveTo(i.toDouble(), i.toDouble() + 1); + pathWithActionHistory.lineTo(i.toDouble() + 2, i.toDouble() + 3); + } + pathWithActionHistory.close(); + return pathWithActionHistory; + } +} diff --git a/packages/io_library/test/unit/serialization/utils/dummy_version_strategy.dart b/packages/io_library/test/unit/serialization/utils/dummy_version_strategy.dart new file mode 100644 index 00000000..b0ca626f --- /dev/null +++ b/packages/io_library/test/unit/serialization/utils/dummy_version_strategy.dart @@ -0,0 +1,17 @@ +import 'package:io_library/io_library.dart'; + +class DummyVersionStrategy implements IVersionStrategy { + final int drawPathCommandVersion; + final int catrobatImageVersion; + + DummyVersionStrategy( + {this.drawPathCommandVersion = + SerializerVersion.DRAW_PATH_COMMAND_VERSION, + this.catrobatImageVersion = SerializerVersion.CATROBAT_IMAGE_VERSION}); + + @override + int getCatrobatImageVersion() => catrobatImageVersion; + + @override + int getDrawPathCommandVersion() => drawPathCommandVersion; +} diff --git a/packages/l10n/lib/src/l10n/app_localizations.dart b/packages/l10n/lib/src/l10n/app_localizations.dart index 86fb2fbb..1fecd5db 100644 --- a/packages/l10n/lib/src/l10n/app_localizations.dart +++ b/packages/l10n/lib/src/l10n/app_localizations.dart @@ -59,8 +59,7 @@ import 'app_localizations_en.dart'; /// be consistent with the languages listed in the AppLocalizations.supportedLocales /// property. abstract class AppLocalizations { - AppLocalizations(String locale) - : localeName = intl.Intl.canonicalizedLocale(locale.toString()); + AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString()); final String localeName; @@ -68,8 +67,7 @@ abstract class AppLocalizations { return Localizations.of(context, AppLocalizations)!; } - static const LocalizationsDelegate delegate = - _AppLocalizationsDelegate(); + static const LocalizationsDelegate delegate = _AppLocalizationsDelegate(); /// A list of this localizations delegate along with the default localizations /// delegates. @@ -81,8 +79,7 @@ abstract class AppLocalizations { /// Additional delegates can be added by appending to this list in /// MaterialApp. This list does not have to be used at all if a custom list /// of delegates is preferred or required. - static const List> localizationsDelegates = - >[ + static const List> localizationsDelegates = >[ delegate, GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, @@ -90,7 +87,9 @@ abstract class AppLocalizations { ]; /// A list of this localizations delegate's supported locales. - static const List supportedLocales = [Locale('en')]; + static const List supportedLocales = [ + Locale('en') + ]; /// No description provided for @fullscreen. /// @@ -147,8 +146,7 @@ abstract class AppLocalizations { String get layers; } -class _AppLocalizationsDelegate - extends LocalizationsDelegate { +class _AppLocalizationsDelegate extends LocalizationsDelegate { const _AppLocalizationsDelegate(); @override @@ -157,23 +155,24 @@ class _AppLocalizationsDelegate } @override - bool isSupported(Locale locale) => - ['en'].contains(locale.languageCode); + bool isSupported(Locale locale) => ['en'].contains(locale.languageCode); @override bool shouldReload(_AppLocalizationsDelegate old) => false; } AppLocalizations lookupAppLocalizations(Locale locale) { + + // Lookup logic when only language code is specified. switch (locale.languageCode) { - case 'en': - return AppLocalizationsEn(); + case 'en': return AppLocalizationsEn(); } throw FlutterError( - 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' - 'an issue with the localizations generation tool. Please file an issue ' - 'on GitHub with a reproducible sample app and the gen-l10n configuration ' - 'that was used.'); + 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.' + ); } diff --git a/packages/tools/lib/src/brush_tool/brush_tool.dart b/packages/tools/lib/src/brush_tool/brush_tool.dart index 440a683e..65379ac2 100644 --- a/packages/tools/lib/src/brush_tool/brush_tool.dart +++ b/packages/tools/lib/src/brush_tool/brush_tool.dart @@ -1,7 +1,6 @@ import 'dart:ui'; import 'package:command/command.dart'; -import 'package:component_library/component_library.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/foundation.dart'; import 'package:tools/tools.dart'; diff --git a/packages/tools/lib/src/brush_tool/brush_tool_provider.dart b/packages/tools/lib/src/brush_tool/brush_tool_provider.dart index 863f528a..66d9b048 100644 --- a/packages/tools/lib/src/brush_tool/brush_tool_provider.dart +++ b/packages/tools/lib/src/brush_tool/brush_tool_provider.dart @@ -1,7 +1,6 @@ -import 'package:component_library/component_library.dart'; +import 'package:command/command_providers.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:tools/tools.dart'; -import 'package:command/command_providers.dart'; part 'brush_tool_provider.g.dart'; diff --git a/packages/tools/lib/src/brush_tool/brush_tool_state_provider.dart b/packages/tools/lib/src/brush_tool/brush_tool_state_provider.dart index 228146d5..52921062 100644 --- a/packages/tools/lib/src/brush_tool/brush_tool_state_provider.dart +++ b/packages/tools/lib/src/brush_tool/brush_tool_state_provider.dart @@ -1,6 +1,6 @@ import 'dart:ui'; -import 'package:component_library/component_library.dart'; +import 'package:command/graphic_factory/graphic_factory_provider.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:tools/tools.dart'; diff --git a/packages/tools/lib/src/eraser_tool/eraser_tool_provider.dart b/packages/tools/lib/src/eraser_tool/eraser_tool_provider.dart index 9d6221ab..5b28e24c 100644 --- a/packages/tools/lib/src/eraser_tool/eraser_tool_provider.dart +++ b/packages/tools/lib/src/eraser_tool/eraser_tool_provider.dart @@ -1,7 +1,6 @@ -import 'package:component_library/component_library.dart'; +import 'package:command/command_providers.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:tools/tools.dart'; -import 'package:command/command_providers.dart'; part 'eraser_tool_provider.g.dart'; diff --git a/packages/tools/lib/src/hand_tool/hand_tool.dart b/packages/tools/lib/src/hand_tool/hand_tool.dart index ad845b39..b130941b 100644 --- a/packages/tools/lib/src/hand_tool/hand_tool.dart +++ b/packages/tools/lib/src/hand_tool/hand_tool.dart @@ -1,7 +1,6 @@ import 'dart:ui'; import 'package:command/command.dart'; -import 'package:component_library/component_library.dart'; import 'package:equatable/equatable.dart'; import 'package:tools/tools.dart'; diff --git a/packages/tools/test/unit/brush_tool_state_test.dart b/packages/tools/test/unit/brush_tool_state_test.dart index 8a61393f..0f48b5c6 100644 --- a/packages/tools/test/unit/brush_tool_state_test.dart +++ b/packages/tools/test/unit/brush_tool_state_test.dart @@ -1,5 +1,5 @@ -import 'package:component_library/component_library.dart'; -import 'package:flutter/material.dart'; // needed for Paint, Color, etc. +import 'package:command/graphic_factory/graphic_factory.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; diff --git a/packages/tools/test/unit/brush_tool_test.dart b/packages/tools/test/unit/brush_tool_test.dart index a3dfb462..06a21b60 100644 --- a/packages/tools/test/unit/brush_tool_test.dart +++ b/packages/tools/test/unit/brush_tool_test.dart @@ -1,7 +1,6 @@ import 'dart:ui'; import 'package:command/command.dart'; -import 'package:component_library/component_library.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; diff --git a/packages/tools/test/unit/brush_tool_test.mocks.dart b/packages/tools/test/unit/brush_tool_test.mocks.dart index 25e8e73a..381528e4 100644 --- a/packages/tools/test/unit/brush_tool_test.mocks.dart +++ b/packages/tools/test/unit/brush_tool_test.mocks.dart @@ -3,11 +3,10 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:typed_data' as _i5; +import 'dart:typed_data' as _i4; import 'dart:ui' as _i2; -import 'package:command/command.dart' as _i4; -import 'package:component_library/component_library.dart' as _i3; +import 'package:command/command.dart' as _i3; import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: type=lint @@ -83,7 +82,7 @@ class _FakePaint_5 extends _i1.SmartFake implements _i2.Paint { } class _FakeDrawPathCommand_6 extends _i1.SmartFake - implements _i4.DrawPathCommand { + implements _i3.DrawPathCommand { _FakeDrawPathCommand_6( Object parent, Invocation parentInvocation, @@ -185,6 +184,15 @@ class MockPathWithActionHistory extends _i1.Mock returnValueForMissingStub: null, ); + @override + Map toJson() => (super.noSuchMethod( + Invocation.method( + #toJson, + [], + ), + returnValue: {}, + ) as Map); + @override void relativeMoveTo( double? dx, @@ -478,7 +486,7 @@ class MockPathWithActionHistory extends _i1.Mock void addPath( _i2.Path? path, _i2.Offset? offset, { - _i5.Float64List? matrix4, + _i4.Float64List? matrix4, }) => super.noSuchMethod( Invocation.method( @@ -496,7 +504,7 @@ class MockPathWithActionHistory extends _i1.Mock void extendWithPath( _i2.Path? path, _i2.Offset? offset, { - _i5.Float64List? matrix4, + _i4.Float64List? matrix4, }) => super.noSuchMethod( Invocation.method( @@ -544,7 +552,7 @@ class MockPathWithActionHistory extends _i1.Mock ) as _i2.Path); @override - _i2.Path transform(_i5.Float64List? matrix4) => (super.noSuchMethod( + _i2.Path transform(_i4.Float64List? matrix4) => (super.noSuchMethod( Invocation.method( #transform, [matrix4], @@ -852,11 +860,23 @@ class MockOffset extends _i1.Mock implements _i2.Offset { /// A class which mocks [DrawPathCommand]. /// /// See the documentation for Mockito's code generation for more information. -class MockDrawPathCommand extends _i1.Mock implements _i4.DrawPathCommand { +class MockDrawPathCommand extends _i1.Mock implements _i3.DrawPathCommand { MockDrawPathCommand() { _i1.throwOnMissingStub(this); } + @override + String get type => (super.noSuchMethod( + Invocation.getter(#type), + returnValue: '', + ) as String); + + @override + int get version => (super.noSuchMethod( + Invocation.getter(#version), + returnValue: 0, + ) as int); + @override _i3.PathWithActionHistory get path => (super.noSuchMethod( Invocation.getter(#path), @@ -889,21 +909,30 @@ class MockDrawPathCommand extends _i1.Mock implements _i4.DrawPathCommand { ), returnValueForMissingStub: null, ); + + @override + Map toJson() => (super.noSuchMethod( + Invocation.method( + #toJson, + [], + ), + returnValue: {}, + ) as Map); } /// A class which mocks [CommandManager]. /// /// See the documentation for Mockito's code generation for more information. -class MockCommandManager extends _i1.Mock implements _i4.CommandManager { +class MockCommandManager extends _i1.Mock implements _i3.CommandManager { MockCommandManager() { _i1.throwOnMissingStub(this); } @override - Iterable<_i4.Command> get history => (super.noSuchMethod( + Iterable<_i3.Command> get history => (super.noSuchMethod( Invocation.getter(#history), - returnValue: <_i4.Command>[], - ) as Iterable<_i4.Command>); + returnValue: <_i3.Command>[], + ) as Iterable<_i3.Command>); @override int get count => (super.noSuchMethod( @@ -912,7 +941,7 @@ class MockCommandManager extends _i1.Mock implements _i4.CommandManager { ) as int); @override - void addGraphicCommand(_i4.GraphicCommand? command) => super.noSuchMethod( + void addGraphicCommand(_i3.GraphicCommand? command) => super.noSuchMethod( Invocation.method( #addGraphicCommand, [command], @@ -948,7 +977,7 @@ class MockCommandManager extends _i1.Mock implements _i4.CommandManager { ); @override - void clearHistory({Iterable<_i4.Command>? newCommands}) => super.noSuchMethod( + void clearHistory({Iterable<_i3.Command>? newCommands}) => super.noSuchMethod( Invocation.method( #clearHistory, [], @@ -961,13 +990,13 @@ class MockCommandManager extends _i1.Mock implements _i4.CommandManager { /// A class which mocks [CommandFactory]. /// /// See the documentation for Mockito's code generation for more information. -class MockCommandFactory extends _i1.Mock implements _i4.CommandFactory { +class MockCommandFactory extends _i1.Mock implements _i3.CommandFactory { MockCommandFactory() { _i1.throwOnMissingStub(this); } @override - _i4.DrawPathCommand createDrawPathCommand( + _i3.DrawPathCommand createDrawPathCommand( _i3.PathWithActionHistory? path, _i2.Paint? paint, ) => @@ -989,7 +1018,7 @@ class MockCommandFactory extends _i1.Mock implements _i4.CommandFactory { ], ), ), - ) as _i4.DrawPathCommand); + ) as _i3.DrawPathCommand); } /// A class which mocks [GraphicFactory]. diff --git a/packages/tools/test/unit/hand_tool_test.mocks.dart b/packages/tools/test/unit/hand_tool_test.mocks.dart index 52c43e50..7fc51b53 100644 --- a/packages/tools/test/unit/hand_tool_test.mocks.dart +++ b/packages/tools/test/unit/hand_tool_test.mocks.dart @@ -6,7 +6,6 @@ import 'dart:ui' as _i2; import 'package:command/command.dart' as _i3; -import 'package:component_library/component_library.dart' as _i4; import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: type=lint @@ -316,7 +315,7 @@ class MockCommandFactory extends _i1.Mock implements _i3.CommandFactory { @override _i3.DrawPathCommand createDrawPathCommand( - _i4.PathWithActionHistory? path, + _i3.PathWithActionHistory? path, _i2.Paint? paint, ) => (super.noSuchMethod( diff --git a/pubspec.lock b/pubspec.lock index af8a521b..7fc77ab1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: archive - sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d" + sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b" url: "https://pub.dev" source: hosted - version: "3.4.10" + version: "3.4.9" args: dependency: transitive description: @@ -101,10 +101,10 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "581bacf68f89ec8792f5e5a0b2c4decd1c948e97ce659dc783688c8a88fbec21" + sha256: "67d591d602906ef9201caf93452495ad1812bea2074f04e25dbd7c133785821b" url: "https://pub.dev" source: hosted - version: "2.4.8" + version: "2.4.7" build_runner_core: dependency: transitive description: @@ -189,10 +189,10 @@ packages: dependency: transitive description: name: code_builder - sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 + sha256: feee43a5c05e7b3199bb375a86430b8ada1b04104f2923d0e03cc01ca87b6d84 url: "https://pub.dev" source: hosted - version: "4.10.0" + version: "4.9.0" collection: dependency: transitive description: @@ -202,7 +202,7 @@ packages: source: hosted version: "1.18.0" colorpicker: - dependency: "direct main" + dependency: transitive description: path: "packages/colorpicker" relative: true @@ -242,10 +242,10 @@ packages: dependency: transitive description: name: cross_file - sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e + sha256: "2f9d2cbccb76127ba28528cb3ae2c2326a122446a83de5a056aaa3880d3882c5" url: "https://pub.dev" source: hosted - version: "0.3.3+8" + version: "0.3.3+7" crypto: dependency: transitive description: @@ -369,10 +369,10 @@ packages: dependency: transitive description: name: file_selector_platform_interface - sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b + sha256: "0aa47a725c346825a2bd396343ce63ac00bda6eff2fbc43eabe99737dede8262" url: "https://pub.dev" source: hosted - version: "2.6.2" + version: "2.6.1" file_selector_windows: dependency: transitive description: @@ -551,10 +551,10 @@ packages: dependency: transitive description: name: http - sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba + sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.1.0" http_multi_server: dependency: transitive description: @@ -591,10 +591,10 @@ packages: dependency: transitive description: name: image_picker_android - sha256: "39f2bfe497e495450c81abcd44b62f56c2a36a37a175da7d137b4454977b51b1" + sha256: ecdc963d2aa67af5195e723a40580f802d4392e31457a12a562b3e2bd6a396fe url: "https://pub.dev" source: hosted - version: "0.8.9+3" + version: "0.8.9+1" image_picker_for_web: dependency: transitive description: @@ -607,10 +607,10 @@ packages: dependency: transitive description: name: image_picker_ios - sha256: fadafce49e8569257a0cad56d24438a6fa1f0cbd7ee0af9b631f7492818a4ca3 + sha256: eac0a62104fa12feed213596df0321f57ce5a572562f72a68c4ff81e9e4caacf url: "https://pub.dev" source: hosted - version: "0.8.9+1" + version: "0.8.9" image_picker_linux: dependency: transitive description: @@ -631,10 +631,10 @@ packages: dependency: transitive description: name: image_picker_platform_interface - sha256: fa4e815e6fcada50e35718727d83ba1c92f1edf95c0b4436554cec301b56233b + sha256: ed9b00e63977c93b0d2d2b343685bed9c324534ba5abafbb3dfbd6a780b1b514 url: "https://pub.dev" source: hosted - version: "2.9.3" + version: "2.9.1" image_picker_windows: dependency: transitive description: @@ -777,10 +777,10 @@ packages: dependency: "direct dev" description: name: mockito - sha256: "6841eed20a7befac0ce07df8116c8b8233ed1f4486a7647c7fc5a02ae6163917" + sha256: "7d5b53bcd556c1bc7ffbe4e4d5a19c3e112b7e925e9e172dd7c6ad0630812616" url: "https://pub.dev" source: hosted - version: "5.4.4" + version: "5.4.2" mustache_template: dependency: transitive description: @@ -856,10 +856,10 @@ packages: dependency: transitive description: name: path_provider - sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b + sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" path_provider_android: dependency: transitive description: @@ -872,10 +872,10 @@ packages: dependency: transitive description: name: path_provider_foundation - sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" + sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.1" path_provider_linux: dependency: transitive description: @@ -888,10 +888,10 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" path_provider_windows: dependency: transitive description: @@ -944,10 +944,10 @@ packages: dependency: transitive description: name: petitparser - sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 url: "https://pub.dev" source: hosted - version: "6.0.2" + version: "5.4.0" platform: dependency: transitive description: @@ -960,18 +960,18 @@ packages: dependency: transitive description: name: plugin_platform_interface - sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 url: "https://pub.dev" source: hosted - version: "2.1.8" + version: "2.1.7" pointycastle: dependency: transitive description: name: pointycastle - sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" + sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" url: "https://pub.dev" source: hosted - version: "3.7.4" + version: "3.7.3" pool: dependency: transitive description: @@ -1112,10 +1112,10 @@ packages: dependency: transitive description: name: shared_preferences_foundation - sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c" + sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7" url: "https://pub.dev" source: hosted - version: "2.3.5" + version: "2.3.4" shared_preferences_linux: dependency: transitive description: @@ -1128,18 +1128,18 @@ packages: dependency: transitive description: name: shared_preferences_platform_interface - sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" + sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.1" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21" + sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.2.1" shared_preferences_windows: dependency: transitive description: @@ -1205,26 +1205,26 @@ packages: dependency: transitive description: name: sqflite_common - sha256: "76db4d324c8cbb16ca5b60ad2f3d25cec953107c93ae65aafa480d3e6fb69f14" + sha256: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6 url: "https://pub.dev" source: hosted - version: "2.5.2-1" + version: "2.5.0+2" sqflite_common_ffi: dependency: transitive description: name: sqflite_common_ffi - sha256: d0e3f0d04fdf668e57db8db1df758f56c4193cb429092c708e7bfcc6ab04b27e + sha256: "35d2fce1e971707c227cc4775cc017d5eafe06c2654c3435ebd5c3ad6c170f5f" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.0+4" sqlite3: dependency: transitive description: name: sqlite3 - sha256: c4a4c5a4b2a32e2d0f6837b33d7c91a67903891a5b7dbe706cf4b1f6b0c798c5 + sha256: db65233e6b99e99b2548932f55a987961bc06d82a31a0665451fa0b4fff4c3fb url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.1.0" sqlparser: dependency: transitive description: @@ -1364,26 +1364,26 @@ packages: dependency: transitive description: name: url_launcher - sha256: d25bb0ca00432a5e1ee40e69c36c85863addf7cc45e433769d61bed3fe81fd96 + sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27" url: "https://pub.dev" source: hosted - version: "6.2.3" + version: "6.1.14" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "507dc655b1d9cb5ebc756032eb785f114e415f91557b73bf60b7e201dfedeb2f" + sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def" url: "https://pub.dev" source: hosted - version: "6.2.2" + version: "6.2.0" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03" + sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3 url: "https://pub.dev" source: hosted - version: "6.2.4" + version: "6.2.1" url_launcher_linux: dependency: transitive description: @@ -1404,18 +1404,18 @@ packages: dependency: transitive description: name: url_launcher_platform_interface - sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f + sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.2.0" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b + sha256: ba140138558fcc3eead51a1c42e92a9fb074a1b1149ed3c73e66035b2ccd94f2 url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.0.19" url_launcher_windows: dependency: transitive description: @@ -1484,18 +1484,18 @@ packages: dependency: transitive description: name: win32 - sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8" + sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" url: "https://pub.dev" source: hosted - version: "5.2.0" + version: "5.0.9" win32_registry: dependency: transitive description: name: win32_registry - sha256: "41fd8a189940d8696b1b810efb9abcf60827b6cbfab90b0c43e8439e3a39d85a" + sha256: e4506d60b7244251bc59df15656a3093501c37fb5af02105a944d73eb95be4c9 url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.1" workspace_screen: dependency: "direct main" description: @@ -1507,18 +1507,18 @@ packages: dependency: transitive description: name: xdg_directories - sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d + sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.3" xml: dependency: transitive description: name: xml - sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" url: "https://pub.dev" source: hosted - version: "6.5.0" + version: "6.3.0" yaml: dependency: transitive description: @@ -1536,5 +1536,5 @@ packages: source: hosted version: "2.1.1" sdks: - dart: ">=3.2.0 <4.0.0" - flutter: ">=3.16.0" + dart: ">=3.2.0-194.0.dev <4.0.0" + flutter: ">=3.10.0" diff --git a/pubspec.yaml b/pubspec.yaml index 82c8b039..5a441042 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -40,8 +40,6 @@ dependencies: path: ./packages/features/landing_page_screen onboarding_screen: path: ./packages/features/onboarding_screen - colorpicker: - path: ./packages/colorpicker dev_dependencies: flutter_test: From c90bdd657352b6ff2ba5d5e730d43c15654a1a4d Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Mon, 19 Feb 2024 02:32:59 +0530 Subject: [PATCH 08/39] fix minor issues --- .../colorpicker/assets/img/checkerboard.png | Bin 103386 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/colorpicker/assets/img/checkerboard.png diff --git a/packages/colorpicker/assets/img/checkerboard.png b/packages/colorpicker/assets/img/checkerboard.png deleted file mode 100644 index ecc4202152720c6c84ef5dfe5314bad3f1e885a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 103386 zcmeHQe{56b8t&;LL@8~#9kFETKlPa9?_A0a;#(=DhWfe{4Lg~OXFq(Y z<&mj5yc|S>SB)me~1PN~gd zjJhYeyw#B^-jgkzrS8ZoJKFdE*Qgyt3Vj-SICp5T^wynZ_hh3+)Uh*_Z7cca*cs{=u|d=Hko$dgUllu}!ow@o?^u+aZISPg z)899!7l*5euP$4sef^?kZNb{Movc^8{-?OB4)n>(540z$)UP^8pWLQHnVN~ckw?`X z(%W1TF1_*(+#1{(L=B>b#RH9gXkxCxTq7Y3K!%144aqZ-XJxrZFCDP1!IG1V0W3Lz z1^}p0AQS*Kz|bgk5AY`7O(4%eo>3G)y$1Cfl+s9n6;)1DIZ=QvK#@>@1~&k-4bV2g zr~%mt7#etJHc$jX5d?b^?9Dvo7sOg{p22wr4-Gst@X)|R0}l;6G#jK(ETm7(P^CdI z2*DsV2B77HmJ>2tD4?N$Cfa;O%lVfD>zZbI0RT@!4*@M(Ko5ax2Xvk2yn)UeXo`ZS zC~6xY=sM9#=&CUQT_<#%&~-xBiQZ@&IB95GhmL|AIBCGpfT00H%lB^uCk>o5aMHj@ z11AlfG;q=!;H2^3q@jsDn%L800Gu>%(tZ^uZGY|dOQ)aMzM!b1I{nc>=K<>pr+L7* zVNE<$yyK|07@ccv3sx-;`t6E~hv+}dl;_&W)hk2Tw^uRbD4H8DHp``5H6<4^>%ZfNdO6#`Qn|K% z52G1?3`AI8;$33np==iPO1j6z(agg9O0sr;FzYJw#&~t-p3T(9!n>u!nBGCkEKk{A z%b^e%`*fyziRxY<`dNP2(=#3=Lg-vN{%=0$SC87q(;GQ^*uZGpmsf^r=O_nDRDNEcnVYbKOp~_OYZaM=`qdpY>z*I<=L4hu(DC(SGZrRc?v1=r ziD$?(9igZP%usvJ70nSvx$rHT8B2*R_IBP7#o3+G9ZUw6dK`)9#@wwpyGy!iEk$eHwb%gBGDyFTPIq(9$P zV{*>xd@eiiqnhbAQkTsC!~F5x_II>F5qqBHk{S0m#p-0nps!IIobi4$82Edd+pIm@+sMy?9|`Q~Rmwylk+ z(iXMD772cRcs3@O;T?}Zqm8JDyny;z(L?3aJ1(GW*p2om~l9yYDm=-G#9B_ z&cD%$H4fG|SmOX3061`MBnsdFP&J@xK-GY%0geV74LJHbtmEAOS+8xT7XT^Ep{7Hs zmq^=?wjpgp+J>|ZX&cfuq;1z>+J;oETBTDWRYR(VR1K*bQZ=M%NY#+4AyorY8cbiqh@S&?*Y8qR?ZFv~r~b0hAk1Za}#KgW7Tr1Lp1hk%On9)>c5mNQ&YK0czX|3ORwsHp#ga&V*qHtt`F3#ilv_!K%P;r0fvSpCzhO8a;iwVt#$KNU>%m6SaM>? zi6tjWY0VB6$uqrr0NDuzXjD1%W(kE@Jt%^xaw2&~@{Hse$up8?B+mi|r2xoIViaU2 zqbA~!psz7a54nLn19{#Xc~mXI(8LAM(II_;U=Sh>&^CJQUm|&iQh;wp^89-fr~k`T z^WID^0L|Ne7C33(q=AzLP8v9AKn8#e02xr)_|Uir1RW4`K+sVV_d(F18Tz5DhO!!v zf!`Z405m{ra|DttNVXu^f@BMxz&OwVpaDPwY@$EKqp@&dn_RSa02%-^KjsG~al(Lv_{>j|fMz_?*eJXO5os9<0e zuD`V{ShYOpw=4E)qW>^co_F7{idANJIB+tNUazRc2#lLuaCtV_gus77fz`;Oe8Q)g zQBCETu`%+Mbc+vXd0-zog1RGN-(KzD@nW-F+Er6>A+!EFeyCS5c#~`E_b}?2RS!g1 zU*cWDFH|-QdL_M0@6pV{yc0<6{$SQs=8f^{&OMu{kA-(ji80;r!z@qPUt6q!ml^wX zrh7@w{Dh@VR6^&{KkvOVM>$xsvh@q)Vvz6hJY!#*)mxX-_A~4tJSgEo2@lE})q@hg zlW|_P;)3rad?%Tq_MR)6Mi9P}@STM3Bzz}tG~dahQ?9Rbz6_>%- z0%vPu3W0;balILxI;LC($1s(5wD$bqU81HVL>dN(0VD>H7*HAuNDLq`fW!b2gRiCL zL-U{WB}!R^JD8?f>F)6GXi&9bA(~{iji`_{jWz-YfrG$7;Gq8iv^fy9fhis5z?248 z4a@-)KvBm591S=caI~gnw=`3Fk*-C~a!vY9KzbTXXnxjXLmkI1wjgj2I0&3Rt)X+6 z0wO&_rs)Xfgn&8@>NxZaB5ZM-Lf{~9)bwJREcEC-V3$X_=SQSUt>w-cfqrtJ0E#*e z>Nu$5ppJ9h)N#T$O{NWon>N(ft!Pj>c7yN<-kQ!j08lWu8m)1Wwjpgp+IFL*ZJ8f0 zp5{8tTt{QJ>BtLw*DZ~b$+cP>DT^2PrG)5_yK|MJY(e|eYiiOjwkBJr0P20vt@pv*e(0>wjint<|OSVQs9%qB{S}CiZuh3YmJSju0^>Tt&c5z Z^4%{Q{=Rh883XyR{^3=1{SSFM{s$oSe3k$J From 6d2e8030ac7dab823874e0c48a5022d29d6ded68 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Wed, 21 Feb 2024 17:06:35 +0530 Subject: [PATCH 09/39] refactoring and minor fixes --- Makefile | 4 +- melos.yaml | 2 +- packages/colorpicker/lib/colorpicker.dart | 6 +- packages/colorpicker/lib/src/colorpicker.dart | 4 +- .../color_compare.dart | 0 .../src/{widgets => components}/slider.dart | 4 +- .../slider_indicator.dart | 0 packages/colorpicker/pubspec.yaml | 2 + .../lib/utils/path_with_action_history.dart | 155 +++++++++++++++++- .../l10n/lib/src/l10n/app_localizations.dart | 35 ++-- 10 files changed, 180 insertions(+), 32 deletions(-) rename packages/colorpicker/lib/src/{widgets => components}/color_compare.dart (100%) rename packages/colorpicker/lib/src/{widgets => components}/slider.dart (94%) rename packages/colorpicker/lib/src/{widgets => components}/slider_indicator.dart (100%) diff --git a/Makefile b/Makefile index 528b93e2..516b0a8d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: run pods-clean get clean build languages lint format test watch -FLUTTER := flutter -DART := dart +FLUTTER := fvm flutter +DART := fvm dart run: $(FLUTTER) run diff --git a/melos.yaml b/melos.yaml index eb95a60a..1a3b743c 100644 --- a/melos.yaml +++ b/melos.yaml @@ -1,6 +1,6 @@ name: Paintroid-Flutter repository: https://github.com/Catrobat/Paintroid-Flutter -sdkPath: auto +sdkPath: .fvm/flutter_sdk packages: - packages/* diff --git a/packages/colorpicker/lib/colorpicker.dart b/packages/colorpicker/lib/colorpicker.dart index d140aafb..e3a7266b 100644 --- a/packages/colorpicker/lib/colorpicker.dart +++ b/packages/colorpicker/lib/colorpicker.dart @@ -2,6 +2,6 @@ library colorpicker; export 'src/colorpicker.dart'; export 'src/constants/colors.dart'; -export 'src/widgets/color_compare.dart'; -export 'src/widgets/slider.dart'; -export 'src/widgets/slider_indicator.dart'; +export 'src/components/color_compare.dart'; +export 'src/components/slider.dart'; +export 'src/components/slider_indicator.dart'; diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index ae98a6a6..a7f08d3e 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -1,6 +1,6 @@ import 'package:colorpicker/src/constants/colors.dart'; -import 'package:colorpicker/src/widgets/color_compare.dart'; -import 'package:colorpicker/src/widgets/slider.dart'; +import 'package:colorpicker/src/components/color_compare.dart'; +import 'package:colorpicker/src/components/slider.dart'; import 'package:flutter/material.dart'; class ColorPicker extends StatefulWidget { diff --git a/packages/colorpicker/lib/src/widgets/color_compare.dart b/packages/colorpicker/lib/src/components/color_compare.dart similarity index 100% rename from packages/colorpicker/lib/src/widgets/color_compare.dart rename to packages/colorpicker/lib/src/components/color_compare.dart diff --git a/packages/colorpicker/lib/src/widgets/slider.dart b/packages/colorpicker/lib/src/components/slider.dart similarity index 94% rename from packages/colorpicker/lib/src/widgets/slider.dart rename to packages/colorpicker/lib/src/components/slider.dart index 01fcc88f..430d55fa 100644 --- a/packages/colorpicker/lib/src/widgets/slider.dart +++ b/packages/colorpicker/lib/src/components/slider.dart @@ -1,4 +1,4 @@ -import 'package:colorpicker/src/widgets/slider_indicator.dart'; +import 'package:colorpicker/src/components/slider_indicator.dart'; import 'package:flutter/material.dart'; class OpacitySlider extends StatefulWidget { @@ -38,7 +38,7 @@ class _OpacitySliderState extends State { @override Widget build(BuildContext context) { - double widgetWidth = MediaQuery.of(context).size.width - 52; + double widgetWidth = MediaQuery.of(context).size.width - 52.0; return Container( height: 25.0, width: widgetWidth, diff --git a/packages/colorpicker/lib/src/widgets/slider_indicator.dart b/packages/colorpicker/lib/src/components/slider_indicator.dart similarity index 100% rename from packages/colorpicker/lib/src/widgets/slider_indicator.dart rename to packages/colorpicker/lib/src/components/slider_indicator.dart diff --git a/packages/colorpicker/pubspec.yaml b/packages/colorpicker/pubspec.yaml index 45838616..a276f165 100644 --- a/packages/colorpicker/pubspec.yaml +++ b/packages/colorpicker/pubspec.yaml @@ -11,6 +11,8 @@ dependencies: flutter: sdk: flutter + component_library: + path: ../component_library dev_dependencies: flutter_test: sdk: flutter diff --git a/packages/command/lib/utils/path_with_action_history.dart b/packages/command/lib/utils/path_with_action_history.dart index 9d01f7ae..354f2d52 100644 --- a/packages/command/lib/utils/path_with_action_history.dart +++ b/packages/command/lib/utils/path_with_action_history.dart @@ -1,30 +1,33 @@ +import 'dart:typed_data'; import 'dart:ui'; import 'package:collection/collection.dart'; import 'package:io_library/io_library.dart'; -class PathWithActionHistory extends Path { +class PathWithActionHistory implements Path { PathWithActionHistory(); @PathActionConverter() final actions = []; + final _path = Path(); + @override void moveTo(double x, double y) { actions.add(MoveToAction(x, y)); - super.moveTo(x, y); + _path.moveTo(x, y); } @override void lineTo(double x, double y) { actions.add(LineToAction(x, y)); - super.lineTo(x, y); + _path.lineTo(x, y); } @override void close() { actions.add(const CloseAction()); - super.close(); + _path.close(); } Map toJson() { @@ -45,6 +48,148 @@ class PathWithActionHistory extends Path { @override int get hashCode => const ListEquality().hash(actions); + + @override + PathFillType get fillType => _path.fillType; + + @override + set fillType(PathFillType value) => _path.fillType = value; + + @override + void addArc(Rect oval, double startAngle, double sweepAngle) { + // TODO: implement addArc + } + + @override + void addOval(Rect oval) { + // TODO: implement addOval + } + + @override + void addPath(Path path, Offset offset, {Float64List? matrix4}) { + // TODO: implement addPath + } + + @override + void addPolygon(List points, bool close) { + // TODO: implement addPolygon + } + + @override + void addRRect(RRect rrect) { + // TODO: implement addRRect + } + + @override + void addRect(Rect rect) { + // TODO: implement addRect + } + + @override + void arcTo( + Rect rect, double startAngle, double sweepAngle, bool forceMoveTo) { + // TODO: implement arcTo + } + + @override + void arcToPoint(Offset arcEnd, + {Radius radius = Radius.zero, + double rotation = 0.0, + bool largeArc = false, + bool clockwise = true}) { + // TODO: implement arcToPoint + } + + @override + PathMetrics computeMetrics({bool forceClosed = false}) { + // TODO: implement computeMetrics + throw UnimplementedError(); + } + + @override + void conicTo(double x1, double y1, double x2, double y2, double w) { + // TODO: implement conicTo + } + + @override + bool contains(Offset point) { + // TODO: implement contains + throw UnimplementedError(); + } + + @override + void cubicTo( + double x1, double y1, double x2, double y2, double x3, double y3) { + // TODO: implement cubicTo + } + + @override + void extendWithPath(Path path, Offset offset, {Float64List? matrix4}) { + // TODO: implement extendWithPath + } + + @override + Rect getBounds() { + // TODO: implement getBounds + throw UnimplementedError(); + } + + @override + void quadraticBezierTo(double x1, double y1, double x2, double y2) { + // TODO: implement quadraticBezierTo + } + + @override + void relativeArcToPoint(Offset arcEndDelta, + {Radius radius = Radius.zero, + double rotation = 0.0, + bool largeArc = false, + bool clockwise = true}) { + // TODO: implement relativeArcToPoint + } + + @override + void relativeConicTo(double x1, double y1, double x2, double y2, double w) { + // TODO: implement relativeConicTo + } + + @override + void relativeCubicTo( + double x1, double y1, double x2, double y2, double x3, double y3) { + // TODO: implement relativeCubicTo + } + + @override + void relativeLineTo(double dx, double dy) { + // TODO: implement relativeLineTo + } + + @override + void relativeMoveTo(double dx, double dy) { + // TODO: implement relativeMoveTo + } + + @override + void relativeQuadraticBezierTo(double x1, double y1, double x2, double y2) { + // TODO: implement relativeQuadraticBezierTo + } + + @override + void reset() { + // TODO: implement reset + } + + @override + Path shift(Offset offset) { + // TODO: implement shift + throw UnimplementedError(); + } + + @override + Path transform(Float64List matrix4) { + // TODO: implement transform + throw UnimplementedError(); + } } abstract class PathAction { @@ -89,4 +234,4 @@ class LineToAction extends PathAction { class CloseAction extends PathAction { const CloseAction(); -} \ No newline at end of file +} diff --git a/packages/l10n/lib/src/l10n/app_localizations.dart b/packages/l10n/lib/src/l10n/app_localizations.dart index 1fecd5db..7825f1ae 100644 --- a/packages/l10n/lib/src/l10n/app_localizations.dart +++ b/packages/l10n/lib/src/l10n/app_localizations.dart @@ -59,7 +59,8 @@ import 'app_localizations_en.dart'; /// be consistent with the languages listed in the AppLocalizations.supportedLocales /// property. abstract class AppLocalizations { - AppLocalizations(String locale) : localeName = intl.Intl.canonicalizedLocale(locale.toString()); + AppLocalizations(String locale) + : localeName = intl.Intl.canonicalizedLocale(locale.toString()); final String localeName; @@ -67,7 +68,8 @@ abstract class AppLocalizations { return Localizations.of(context, AppLocalizations)!; } - static const LocalizationsDelegate delegate = _AppLocalizationsDelegate(); + static const LocalizationsDelegate delegate = + _AppLocalizationsDelegate(); /// A list of this localizations delegate along with the default localizations /// delegates. @@ -79,7 +81,8 @@ abstract class AppLocalizations { /// Additional delegates can be added by appending to this list in /// MaterialApp. This list does not have to be used at all if a custom list /// of delegates is preferred or required. - static const List> localizationsDelegates = >[ + static const List> localizationsDelegates = + >[ delegate, GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, @@ -87,9 +90,7 @@ abstract class AppLocalizations { ]; /// A list of this localizations delegate's supported locales. - static const List supportedLocales = [ - Locale('en') - ]; + static const List supportedLocales = [Locale('en')]; /// No description provided for @fullscreen. /// @@ -146,7 +147,8 @@ abstract class AppLocalizations { String get layers; } -class _AppLocalizationsDelegate extends LocalizationsDelegate { +class _AppLocalizationsDelegate + extends LocalizationsDelegate { const _AppLocalizationsDelegate(); @override @@ -155,24 +157,23 @@ class _AppLocalizationsDelegate extends LocalizationsDelegate } @override - bool isSupported(Locale locale) => ['en'].contains(locale.languageCode); + bool isSupported(Locale locale) => + ['en'].contains(locale.languageCode); @override bool shouldReload(_AppLocalizationsDelegate old) => false; } AppLocalizations lookupAppLocalizations(Locale locale) { - - // Lookup logic when only language code is specified. switch (locale.languageCode) { - case 'en': return AppLocalizationsEn(); + case 'en': + return AppLocalizationsEn(); } throw FlutterError( - 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' - 'an issue with the localizations generation tool. Please file an issue ' - 'on GitHub with a reproducible sample app and the gen-l10n configuration ' - 'that was used.' - ); -} + 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.'); +} \ No newline at end of file From c05f08f2bdf7343c36d0fbadb65adf8661c55941 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Wed, 21 Feb 2024 18:21:32 +0530 Subject: [PATCH 10/39] use checkerboardimg from component_library --- packages/colorpicker/lib/src/colorpicker.dart | 7 +++---- packages/colorpicker/lib/src/components/slider.dart | 7 +++---- packages/colorpicker/pubspec.yaml | 2 -- packages/component_library/lib/src/components/imgs.dart | 6 ++++++ 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index a7f08d3e..c7d66ea1 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -1,6 +1,7 @@ import 'package:colorpicker/src/constants/colors.dart'; import 'package:colorpicker/src/components/color_compare.dart'; import 'package:colorpicker/src/components/slider.dart'; +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; class ColorPicker extends StatefulWidget { @@ -62,11 +63,9 @@ class _ColorPickerState extends State { (index) { if (index == colors.length) { return Container( - decoration: const BoxDecoration( + decoration: BoxDecoration( image: DecorationImage( - image: AssetImage( - 'packages/component_library/assets/img/checkerboard.png', - ), + image: CheckerboardImg.getCheckerboardImgAsset(), fit: BoxFit.contain, repeat: ImageRepeat.repeat, ), diff --git a/packages/colorpicker/lib/src/components/slider.dart b/packages/colorpicker/lib/src/components/slider.dart index 430d55fa..65730729 100644 --- a/packages/colorpicker/lib/src/components/slider.dart +++ b/packages/colorpicker/lib/src/components/slider.dart @@ -1,4 +1,5 @@ import 'package:colorpicker/src/components/slider_indicator.dart'; +import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; class OpacitySlider extends StatefulWidget { @@ -42,11 +43,9 @@ class _OpacitySliderState extends State { return Container( height: 25.0, width: widgetWidth, - decoration: const BoxDecoration( + decoration: BoxDecoration( image: DecorationImage( - image: AssetImage( - 'packages/component_library/assets/img/checkerboard.png', - ), + image: CheckerboardImg.getCheckerboardImgAsset(), fit: BoxFit.fitHeight, repeat: ImageRepeat.repeat, ), diff --git a/packages/colorpicker/pubspec.yaml b/packages/colorpicker/pubspec.yaml index a276f165..e9108550 100644 --- a/packages/colorpicker/pubspec.yaml +++ b/packages/colorpicker/pubspec.yaml @@ -21,5 +21,3 @@ dev_dependencies: flutter: uses-material-design: true - assets: - - ../component_library/assets/img/ diff --git a/packages/component_library/lib/src/components/imgs.dart b/packages/component_library/lib/src/components/imgs.dart index 16421d92..aa22e4f4 100644 --- a/packages/component_library/lib/src/components/imgs.dart +++ b/packages/component_library/lib/src/components/imgs.dart @@ -3,6 +3,12 @@ import 'package:flutter/material.dart'; class CheckerboardImg extends StatelessWidget { const CheckerboardImg({Key? key}) : super(key: key); + static ImageProvider getCheckerboardImgAsset() { + return const AssetImage( + 'packages/component_library/assets/img/checkerboard.png', + ); + } + @override Widget build(BuildContext context) { return SizedBox( From 4596426ac66e134ff4ba66f0aeb0382d1f5534ef Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Wed, 21 Feb 2024 18:23:09 +0530 Subject: [PATCH 11/39] fix minor issues --- .../lib/utils/path_with_action_history.dart | 153 +----------------- 1 file changed, 4 insertions(+), 149 deletions(-) diff --git a/packages/command/lib/utils/path_with_action_history.dart b/packages/command/lib/utils/path_with_action_history.dart index 354f2d52..e5657dde 100644 --- a/packages/command/lib/utils/path_with_action_history.dart +++ b/packages/command/lib/utils/path_with_action_history.dart @@ -1,33 +1,30 @@ -import 'dart:typed_data'; import 'dart:ui'; import 'package:collection/collection.dart'; import 'package:io_library/io_library.dart'; -class PathWithActionHistory implements Path { +class PathWithActionHistory extends Path { PathWithActionHistory(); @PathActionConverter() final actions = []; - final _path = Path(); - @override void moveTo(double x, double y) { actions.add(MoveToAction(x, y)); - _path.moveTo(x, y); + super.moveTo(x, y); } @override void lineTo(double x, double y) { actions.add(LineToAction(x, y)); - _path.lineTo(x, y); + super.lineTo(x, y); } @override void close() { actions.add(const CloseAction()); - _path.close(); + super.close(); } Map toJson() { @@ -48,148 +45,6 @@ class PathWithActionHistory implements Path { @override int get hashCode => const ListEquality().hash(actions); - - @override - PathFillType get fillType => _path.fillType; - - @override - set fillType(PathFillType value) => _path.fillType = value; - - @override - void addArc(Rect oval, double startAngle, double sweepAngle) { - // TODO: implement addArc - } - - @override - void addOval(Rect oval) { - // TODO: implement addOval - } - - @override - void addPath(Path path, Offset offset, {Float64List? matrix4}) { - // TODO: implement addPath - } - - @override - void addPolygon(List points, bool close) { - // TODO: implement addPolygon - } - - @override - void addRRect(RRect rrect) { - // TODO: implement addRRect - } - - @override - void addRect(Rect rect) { - // TODO: implement addRect - } - - @override - void arcTo( - Rect rect, double startAngle, double sweepAngle, bool forceMoveTo) { - // TODO: implement arcTo - } - - @override - void arcToPoint(Offset arcEnd, - {Radius radius = Radius.zero, - double rotation = 0.0, - bool largeArc = false, - bool clockwise = true}) { - // TODO: implement arcToPoint - } - - @override - PathMetrics computeMetrics({bool forceClosed = false}) { - // TODO: implement computeMetrics - throw UnimplementedError(); - } - - @override - void conicTo(double x1, double y1, double x2, double y2, double w) { - // TODO: implement conicTo - } - - @override - bool contains(Offset point) { - // TODO: implement contains - throw UnimplementedError(); - } - - @override - void cubicTo( - double x1, double y1, double x2, double y2, double x3, double y3) { - // TODO: implement cubicTo - } - - @override - void extendWithPath(Path path, Offset offset, {Float64List? matrix4}) { - // TODO: implement extendWithPath - } - - @override - Rect getBounds() { - // TODO: implement getBounds - throw UnimplementedError(); - } - - @override - void quadraticBezierTo(double x1, double y1, double x2, double y2) { - // TODO: implement quadraticBezierTo - } - - @override - void relativeArcToPoint(Offset arcEndDelta, - {Radius radius = Radius.zero, - double rotation = 0.0, - bool largeArc = false, - bool clockwise = true}) { - // TODO: implement relativeArcToPoint - } - - @override - void relativeConicTo(double x1, double y1, double x2, double y2, double w) { - // TODO: implement relativeConicTo - } - - @override - void relativeCubicTo( - double x1, double y1, double x2, double y2, double x3, double y3) { - // TODO: implement relativeCubicTo - } - - @override - void relativeLineTo(double dx, double dy) { - // TODO: implement relativeLineTo - } - - @override - void relativeMoveTo(double dx, double dy) { - // TODO: implement relativeMoveTo - } - - @override - void relativeQuadraticBezierTo(double x1, double y1, double x2, double y2) { - // TODO: implement relativeQuadraticBezierTo - } - - @override - void reset() { - // TODO: implement reset - } - - @override - Path shift(Offset offset) { - // TODO: implement shift - throw UnimplementedError(); - } - - @override - Path transform(Float64List matrix4) { - // TODO: implement transform - throw UnimplementedError(); - } } abstract class PathAction { From 0c157326a7ff58fc7cca7f61e411facc032c78bb Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Wed, 21 Feb 2024 18:25:14 +0530 Subject: [PATCH 12/39] revert app_localizations file --- packages/l10n/lib/src/l10n/app_localizations.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/l10n/lib/src/l10n/app_localizations.dart b/packages/l10n/lib/src/l10n/app_localizations.dart index 7825f1ae..86fb2fbb 100644 --- a/packages/l10n/lib/src/l10n/app_localizations.dart +++ b/packages/l10n/lib/src/l10n/app_localizations.dart @@ -176,4 +176,4 @@ AppLocalizations lookupAppLocalizations(Locale locale) { 'an issue with the localizations generation tool. Please file an issue ' 'on GitHub with a reproducible sample app and the gen-l10n configuration ' 'that was used.'); -} \ No newline at end of file +} From f7526f501756a5ea8ede0a70ebff100b9a06cb8d Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Fri, 23 Feb 2024 23:18:20 +0530 Subject: [PATCH 13/39] add dynamic color change, separate colorpicker package --- .../colorpicker/assets/img/checkerboard.png | Bin 0 -> 103386 bytes packages/colorpicker/lib/src/colorpicker.dart | 4 +-- .../lib/src/components/slider.dart | 4 +-- packages/colorpicker/lib/utils/assets.dart | 7 ++++ packages/colorpicker/pubspec.yaml | 6 ++-- .../lib/src/components/imgs.dart | 6 ---- .../components/bottom_bar/bottom_nav_bar.dart | 34 +++++++++++------- 7 files changed, 37 insertions(+), 24 deletions(-) create mode 100644 packages/colorpicker/assets/img/checkerboard.png create mode 100644 packages/colorpicker/lib/utils/assets.dart diff --git a/packages/colorpicker/assets/img/checkerboard.png b/packages/colorpicker/assets/img/checkerboard.png new file mode 100644 index 0000000000000000000000000000000000000000..ecc4202152720c6c84ef5dfe5314bad3f1e885a9 GIT binary patch literal 103386 zcmeHQe{56b8t&;LL@8~#9kFETKlPa9?_A0a;#(=DhWfe{4Lg~OXFq(Y z<&mj5yc|S>SB)me~1PN~gd zjJhYeyw#B^-jgkzrS8ZoJKFdE*Qgyt3Vj-SICp5T^wynZ_hh3+)Uh*_Z7cca*cs{=u|d=Hko$dgUllu}!ow@o?^u+aZISPg z)899!7l*5euP$4sef^?kZNb{Movc^8{-?OB4)n>(540z$)UP^8pWLQHnVN~ckw?`X z(%W1TF1_*(+#1{(L=B>b#RH9gXkxCxTq7Y3K!%144aqZ-XJxrZFCDP1!IG1V0W3Lz z1^}p0AQS*Kz|bgk5AY`7O(4%eo>3G)y$1Cfl+s9n6;)1DIZ=QvK#@>@1~&k-4bV2g zr~%mt7#etJHc$jX5d?b^?9Dvo7sOg{p22wr4-Gst@X)|R0}l;6G#jK(ETm7(P^CdI z2*DsV2B77HmJ>2tD4?N$Cfa;O%lVfD>zZbI0RT@!4*@M(Ko5ax2Xvk2yn)UeXo`ZS zC~6xY=sM9#=&CUQT_<#%&~-xBiQZ@&IB95GhmL|AIBCGpfT00H%lB^uCk>o5aMHj@ z11AlfG;q=!;H2^3q@jsDn%L800Gu>%(tZ^uZGY|dOQ)aMzM!b1I{nc>=K<>pr+L7* zVNE<$yyK|07@ccv3sx-;`t6E~hv+}dl;_&W)hk2Tw^uRbD4H8DHp``5H6<4^>%ZfNdO6#`Qn|K% z52G1?3`AI8;$33np==iPO1j6z(agg9O0sr;FzYJw#&~t-p3T(9!n>u!nBGCkEKk{A z%b^e%`*fyziRxY<`dNP2(=#3=Lg-vN{%=0$SC87q(;GQ^*uZGpmsf^r=O_nDRDNEcnVYbKOp~_OYZaM=`qdpY>z*I<=L4hu(DC(SGZrRc?v1=r ziD$?(9igZP%usvJ70nSvx$rHT8B2*R_IBP7#o3+G9ZUw6dK`)9#@wwpyGy!iEk$eHwb%gBGDyFTPIq(9$P zV{*>xd@eiiqnhbAQkTsC!~F5x_II>F5qqBHk{S0m#p-0nps!IIobi4$82Edd+pIm@+sMy?9|`Q~Rmwylk+ z(iXMD772cRcs3@O;T?}Zqm8JDyny;z(L?3aJ1(GW*p2om~l9yYDm=-G#9B_ z&cD%$H4fG|SmOX3061`MBnsdFP&J@xK-GY%0geV74LJHbtmEAOS+8xT7XT^Ep{7Hs zmq^=?wjpgp+J>|ZX&cfuq;1z>+J;oETBTDWRYR(VR1K*bQZ=M%NY#+4AyorY8cbiqh@S&?*Y8qR?ZFv~r~b0hAk1Za}#KgW7Tr1Lp1hk%On9)>c5mNQ&YK0czX|3ORwsHp#ga&V*qHtt`F3#ilv_!K%P;r0fvSpCzhO8a;iwVt#$KNU>%m6SaM>? zi6tjWY0VB6$uqrr0NDuzXjD1%W(kE@Jt%^xaw2&~@{Hse$up8?B+mi|r2xoIViaU2 zqbA~!psz7a54nLn19{#Xc~mXI(8LAM(II_;U=Sh>&^CJQUm|&iQh;wp^89-fr~k`T z^WID^0L|Ne7C33(q=AzLP8v9AKn8#e02xr)_|Uir1RW4`K+sVV_d(F18Tz5DhO!!v zf!`Z405m{ra|DttNVXu^f@BMxz&OwVpaDPwY@$EKqp@&dn_RSa02%-^KjsG~al(Lv_{>j|fMz_?*eJXO5os9<0e zuD`V{ShYOpw=4E)qW>^co_F7{idANJIB+tNUazRc2#lLuaCtV_gus77fz`;Oe8Q)g zQBCETu`%+Mbc+vXd0-zog1RGN-(KzD@nW-F+Er6>A+!EFeyCS5c#~`E_b}?2RS!g1 zU*cWDFH|-QdL_M0@6pV{yc0<6{$SQs=8f^{&OMu{kA-(ji80;r!z@qPUt6q!ml^wX zrh7@w{Dh@VR6^&{KkvOVM>$xsvh@q)Vvz6hJY!#*)mxX-_A~4tJSgEo2@lE})q@hg zlW|_P;)3rad?%Tq_MR)6Mi9P}@STM3Bzz}tG~dahQ?9Rbz6_>%- z0%vPu3W0;balILxI;LC($1s(5wD$bqU81HVL>dN(0VD>H7*HAuNDLq`fW!b2gRiCL zL-U{WB}!R^JD8?f>F)6GXi&9bA(~{iji`_{jWz-YfrG$7;Gq8iv^fy9fhis5z?248 z4a@-)KvBm591S=caI~gnw=`3Fk*-C~a!vY9KzbTXXnxjXLmkI1wjgj2I0&3Rt)X+6 z0wO&_rs)Xfgn&8@>NxZaB5ZM-Lf{~9)bwJREcEC-V3$X_=SQSUt>w-cfqrtJ0E#*e z>Nu$5ppJ9h)N#T$O{NWon>N(ft!Pj>c7yN<-kQ!j08lWu8m)1Wwjpgp+IFL*ZJ8f0 zp5{8tTt{QJ>BtLw*DZ~b$+cP>DT^2PrG)5_yK|MJY(e|eYiiOjwkBJr0P20vt@pv*e(0>wjint<|OSVQs9%qB{S}CiZuh3YmJSju0^>Tt&c5z Z^4%{Q{=Rh883XyR{^3=1{SSFM{s$oSe3k$J literal 0 HcmV?d00001 diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index c7d66ea1..2532c3df 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -1,7 +1,7 @@ import 'package:colorpicker/src/constants/colors.dart'; import 'package:colorpicker/src/components/color_compare.dart'; import 'package:colorpicker/src/components/slider.dart'; -import 'package:component_library/component_library.dart'; +import 'package:colorpicker/utils/assets.dart'; import 'package:flutter/material.dart'; class ColorPicker extends StatefulWidget { @@ -65,7 +65,7 @@ class _ColorPickerState extends State { return Container( decoration: BoxDecoration( image: DecorationImage( - image: CheckerboardImg.getCheckerboardImgAsset(), + image: PackageAssets.getCheckerboardImgAsset(), fit: BoxFit.contain, repeat: ImageRepeat.repeat, ), diff --git a/packages/colorpicker/lib/src/components/slider.dart b/packages/colorpicker/lib/src/components/slider.dart index 65730729..a333e5e8 100644 --- a/packages/colorpicker/lib/src/components/slider.dart +++ b/packages/colorpicker/lib/src/components/slider.dart @@ -1,5 +1,5 @@ import 'package:colorpicker/src/components/slider_indicator.dart'; -import 'package:component_library/component_library.dart'; +import 'package:colorpicker/utils/assets.dart'; import 'package:flutter/material.dart'; class OpacitySlider extends StatefulWidget { @@ -45,7 +45,7 @@ class _OpacitySliderState extends State { width: widgetWidth, decoration: BoxDecoration( image: DecorationImage( - image: CheckerboardImg.getCheckerboardImgAsset(), + image: PackageAssets.getCheckerboardImgAsset(), fit: BoxFit.fitHeight, repeat: ImageRepeat.repeat, ), diff --git a/packages/colorpicker/lib/utils/assets.dart b/packages/colorpicker/lib/utils/assets.dart new file mode 100644 index 00000000..3b43835b --- /dev/null +++ b/packages/colorpicker/lib/utils/assets.dart @@ -0,0 +1,7 @@ +import 'package:flutter/material.dart'; + +class PackageAssets { + static ImageProvider getCheckerboardImgAsset() { + return const AssetImage('packages/colorpicker/assets/img/checkerboard.png'); + } +} diff --git a/packages/colorpicker/pubspec.yaml b/packages/colorpicker/pubspec.yaml index e9108550..dc106854 100644 --- a/packages/colorpicker/pubspec.yaml +++ b/packages/colorpicker/pubspec.yaml @@ -7,12 +7,11 @@ environment: sdk: ">=2.17.0 <3.0.0" flutter: ">=1.17.0" +# this package should be built separately and not depend on other app modules dependencies: flutter: sdk: flutter - component_library: - path: ../component_library dev_dependencies: flutter_test: sdk: flutter @@ -21,3 +20,6 @@ dev_dependencies: flutter: uses-material-design: true + + assets: + - assets/img/ \ No newline at end of file diff --git a/packages/component_library/lib/src/components/imgs.dart b/packages/component_library/lib/src/components/imgs.dart index aa22e4f4..16421d92 100644 --- a/packages/component_library/lib/src/components/imgs.dart +++ b/packages/component_library/lib/src/components/imgs.dart @@ -3,12 +3,6 @@ import 'package:flutter/material.dart'; class CheckerboardImg extends StatelessWidget { const CheckerboardImg({Key? key}) : super(key: key); - static ImageProvider getCheckerboardImgAsset() { - return const AssetImage( - 'packages/component_library/assets/img/checkerboard.png', - ); - } - @override Widget build(BuildContext context) { return SizedBox( diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart b/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart index fd8d9d18..0a6983b8 100644 --- a/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart +++ b/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart @@ -32,13 +32,21 @@ class BottomNavBar extends ConsumerWidget { icon: BottomBarIcon(asset: currentToolData.svgAssetPath), ), NavigationDestination( - label: localizations.color, - icon: Icon( - Icons.check_box_outline_blank, - size: 24, - color: Theme.of(context).colorScheme.onSurface, - ), - ), + label: localizations.color, + icon: InkWell( + child: Container( + height: 24.0, + width: 24.0, + decoration: BoxDecoration( + color: ref.watch(brushToolStateProvider).paint.color, + border: Border.all( + color: Colors.white, + width: 1.4, + ), + borderRadius: BorderRadius.circular(2.0), + ), + ), + )), NavigationDestination( label: localizations.layers, icon: const BottomBarIcon(asset: 'assets/svg/ic_layers.svg'), @@ -71,7 +79,7 @@ void _onNavigationItemSelected(int index, BuildContext context, WidgetRef ref) { _handleToolOptionsVisibility(ref); break; case BottomNavBarItem.COLOR: - _showColorPicker(context); + _showColorPicker(context, ref); break; default: return; @@ -92,7 +100,7 @@ void _handleToolOptionsVisibility(WidgetRef ref) { ref.read(toolOptionsVisibilityStateProvider.notifier).toggleVisibility(); } -void _showColorPicker(BuildContext context) { +void _showColorPicker(BuildContext context, WidgetRef ref) { showModalBottomSheet( context: context, isScrollControlled: true, @@ -104,9 +112,11 @@ void _showColorPicker(BuildContext context) { borderRadius: BorderRadius.circular(16), ), child: ColorPicker( - currentColor: Colors.black, - onColorChanged: (color) {}, + currentColor: ref.watch(brushToolStateProvider).paint.color, + onColorChanged: (newColor) { + ref.read(brushToolStateProvider.notifier).updateColor(newColor); + }, ), ), ); -} \ No newline at end of file +} From 37eac0127b253681cebd6c8284457cdcef69c01a Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Tue, 27 Feb 2024 22:30:41 +0530 Subject: [PATCH 14/39] use riverpod generator --- packages/colorpicker/lib/src/colorpicker.dart | 38 ++++++++--------- .../lib/src/components/slider.dart | 41 ++++++------------- .../lib/src/state/color_state.dart | 16 ++++++++ .../lib/src/state/color_state.g.dart | 27 ++++++++++++ .../src/state/position_fraction_state.dart | 15 +++++++ .../src/state/position_fraction_state.g.dart | 27 ++++++++++++ .../lib/src/state/slider_state.dart | 27 ++++++++++++ .../lib/src/state/slider_state.g.dart | 26 ++++++++++++ packages/colorpicker/pubspec.yaml | 4 ++ .../components/bottom_bar/bottom_nav_bar.dart | 3 +- 10 files changed, 174 insertions(+), 50 deletions(-) create mode 100644 packages/colorpicker/lib/src/state/color_state.dart create mode 100644 packages/colorpicker/lib/src/state/color_state.g.dart create mode 100644 packages/colorpicker/lib/src/state/position_fraction_state.dart create mode 100644 packages/colorpicker/lib/src/state/position_fraction_state.g.dart create mode 100644 packages/colorpicker/lib/src/state/slider_state.dart create mode 100644 packages/colorpicker/lib/src/state/slider_state.g.dart diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index 2532c3df..c957a515 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -1,10 +1,13 @@ import 'package:colorpicker/src/constants/colors.dart'; import 'package:colorpicker/src/components/color_compare.dart'; import 'package:colorpicker/src/components/slider.dart'; +import 'package:colorpicker/src/state/color_state.dart'; +import 'package:colorpicker/src/state/position_fraction_state.dart'; import 'package:colorpicker/utils/assets.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; -class ColorPicker extends StatefulWidget { +class ColorPicker extends ConsumerStatefulWidget { const ColorPicker({ super.key, required this.currentColor, @@ -15,28 +18,21 @@ class ColorPicker extends StatefulWidget { final void Function(Color) onColorChanged; @override - State createState() => _ColorPickerState(); + _ColorPickerState createState() => _ColorPickerState(); } -class _ColorPickerState extends State { +class _ColorPickerState extends ConsumerState { final colors = DisplayColors.colors; - Color newColor = Colors.black; - double opacity = 1.0; - - void callback(Color color, double op) { - setState(() { - opacity = op; - }); - } @override void initState() { super.initState(); - newColor = widget.currentColor; } @override Widget build(BuildContext context) { + final opacity = 1.0 - ref.watch(positionFractionNotifierProvider); + final newColor = ref.watch(colorStateNotifierProvider); return Container( margin: const EdgeInsets.all(26.0), alignment: Alignment.center, @@ -74,9 +70,9 @@ class _ColorPickerState extends State { } return GestureDetector( onTap: () { - setState(() { - newColor = colors[index]; - }); + ref.read(colorStateNotifierProvider.notifier).updateColor( + colors[index].withOpacity(opacity), + ); }, child: Container( decoration: BoxDecoration( @@ -92,7 +88,6 @@ class _ColorPickerState extends State { ), OpacitySlider( gradientColor: newColor, - callback: callback, ), const Spacer(), Row( @@ -108,11 +103,12 @@ class _ColorPickerState extends State { width: 10.0, ), TextButton( - onPressed: () { - widget.onColorChanged(newColor.withOpacity(opacity)); - Navigator.pop(context); - }, - child: const Text('APPLY')), + onPressed: () { + widget.onColorChanged(newColor.withOpacity(opacity)); + Navigator.pop(context); + }, + child: const Text('APPLY'), + ), ], ) ], diff --git a/packages/colorpicker/lib/src/components/slider.dart b/packages/colorpicker/lib/src/components/slider.dart index a333e5e8..2d838f00 100644 --- a/packages/colorpicker/lib/src/components/slider.dart +++ b/packages/colorpicker/lib/src/components/slider.dart @@ -1,44 +1,25 @@ import 'package:colorpicker/src/components/slider_indicator.dart'; +import 'package:colorpicker/src/state/slider_state.dart'; import 'package:colorpicker/utils/assets.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; -class OpacitySlider extends StatefulWidget { +class OpacitySlider extends ConsumerStatefulWidget { const OpacitySlider({ super.key, required this.gradientColor, - required this.callback, }); final Color gradientColor; - final Function(Color, double) callback; @override - State createState() => _OpacitySliderState(); + _OpacitySliderState createState() => _OpacitySliderState(); } -class _OpacitySliderState extends State { - double _sliderPosition = 0.0; - double _positionFraction = 0.0; - - void _handleColorChange(double position, double widgetWidth) { - if (position < 0.0) { - position = 0.0; - } - if (position > widgetWidth) { - position = widgetWidth; - } - setState(() { - _sliderPosition = position; - _positionFraction = _sliderPosition / widgetWidth; - widget.callback( - widget.gradientColor, - 1 - _positionFraction, - ); - }); - } - +class _OpacitySliderState extends ConsumerState { @override Widget build(BuildContext context) { + final positon = ref.watch(positionNotifierProvider); double widgetWidth = MediaQuery.of(context).size.width - 52.0; return Container( height: 25.0, @@ -54,12 +35,16 @@ class _OpacitySliderState extends State { onHorizontalDragStart: (DragStartDetails details) {}, onHorizontalDragUpdate: (DragUpdateDetails details) { double position = details.localPosition.dx; - _handleColorChange(position, widgetWidth); + ref + .read(positionNotifierProvider.notifier) + .updatePosition(position, widgetWidth); }, onHorizontalDragEnd: (DragEndDetails details) {}, onTapDown: (TapDownDetails details) { double position = details.localPosition.dx; - _handleColorChange(position, widgetWidth); + ref + .read(positionNotifierProvider.notifier) + .updatePosition(position, widgetWidth); }, child: Container( decoration: BoxDecoration( @@ -73,7 +58,7 @@ class _OpacitySliderState extends State { ), ), child: CustomPaint( - painter: SliderIndicatorPainter(_sliderPosition), + painter: SliderIndicatorPainter(positon), ), ), ), diff --git a/packages/colorpicker/lib/src/state/color_state.dart b/packages/colorpicker/lib/src/state/color_state.dart new file mode 100644 index 00000000..0010600b --- /dev/null +++ b/packages/colorpicker/lib/src/state/color_state.dart @@ -0,0 +1,16 @@ +import 'package:flutter/material.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +part 'color_state.g.dart'; + +@riverpod +class ColorStateNotifier extends _$ColorStateNotifier { + @override + Color build() { + return Colors.blue; + } + + void updateColor(Color newColor) { + state = newColor; + } +} diff --git a/packages/colorpicker/lib/src/state/color_state.g.dart b/packages/colorpicker/lib/src/state/color_state.g.dart new file mode 100644 index 00000000..60b4c781 --- /dev/null +++ b/packages/colorpicker/lib/src/state/color_state.g.dart @@ -0,0 +1,27 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'color_state.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$colorStateNotifierHash() => + r'7ab92b2d43fb0357fe1d0e1dbfb55ffbba72671e'; + +/// See also [ColorStateNotifier]. +@ProviderFor(ColorStateNotifier) +final colorStateNotifierProvider = + AutoDisposeNotifierProvider.internal( + ColorStateNotifier.new, + name: r'colorStateNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$colorStateNotifierHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef _$ColorStateNotifier = AutoDisposeNotifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/packages/colorpicker/lib/src/state/position_fraction_state.dart b/packages/colorpicker/lib/src/state/position_fraction_state.dart new file mode 100644 index 00000000..0b42b2e8 --- /dev/null +++ b/packages/colorpicker/lib/src/state/position_fraction_state.dart @@ -0,0 +1,15 @@ +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +part 'position_fraction_state.g.dart'; + +@riverpod +class PositionFractionNotifier extends _$PositionFractionNotifier { + @override + double build() { + return 0.0; + } + + void updateFraction(double newFraction) { + state = newFraction; + } +} diff --git a/packages/colorpicker/lib/src/state/position_fraction_state.g.dart b/packages/colorpicker/lib/src/state/position_fraction_state.g.dart new file mode 100644 index 00000000..781ac922 --- /dev/null +++ b/packages/colorpicker/lib/src/state/position_fraction_state.g.dart @@ -0,0 +1,27 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'position_fraction_state.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$positionFractionNotifierHash() => + r'5eac955e9e2919021effa7f62ea70ceead6a3cc7'; + +/// See also [PositionFractionNotifier]. +@ProviderFor(PositionFractionNotifier) +final positionFractionNotifierProvider = + AutoDisposeNotifierProvider.internal( + PositionFractionNotifier.new, + name: r'positionFractionNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$positionFractionNotifierHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef _$PositionFractionNotifier = AutoDisposeNotifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/packages/colorpicker/lib/src/state/slider_state.dart b/packages/colorpicker/lib/src/state/slider_state.dart new file mode 100644 index 00000000..7e5e8795 --- /dev/null +++ b/packages/colorpicker/lib/src/state/slider_state.dart @@ -0,0 +1,27 @@ +import 'package:colorpicker/src/state/position_fraction_state.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; +part 'slider_state.g.dart'; + +@riverpod +class PositionNotifier extends _$PositionNotifier { + @override + double build() { + return 0.0; + } + + void updatePosition( + double position, + double widgetWidth, + ) { + if (position < 0.0) { + position = 0.0; + } + if (position > widgetWidth) { + position = widgetWidth; + } + state = position; + ref.read(positionFractionNotifierProvider.notifier).updateFraction( + position / widgetWidth, + ); + } +} diff --git a/packages/colorpicker/lib/src/state/slider_state.g.dart b/packages/colorpicker/lib/src/state/slider_state.g.dart new file mode 100644 index 00000000..208b8c24 --- /dev/null +++ b/packages/colorpicker/lib/src/state/slider_state.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'slider_state.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$positionNotifierHash() => r'11b7d29187bbe63a99dae094d40cc6278e0f8a2e'; + +/// See also [PositionNotifier]. +@ProviderFor(PositionNotifier) +final positionNotifierProvider = + AutoDisposeNotifierProvider.internal( + PositionNotifier.new, + name: r'positionNotifierProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$positionNotifierHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef _$PositionNotifier = AutoDisposeNotifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/packages/colorpicker/pubspec.yaml b/packages/colorpicker/pubspec.yaml index dc106854..52d2201e 100644 --- a/packages/colorpicker/pubspec.yaml +++ b/packages/colorpicker/pubspec.yaml @@ -11,12 +11,16 @@ environment: dependencies: flutter: sdk: flutter + flutter_riverpod: ^2.3.6 + riverpod_annotation: ^2.1.1 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^2.0.0 build_runner: ^2.2.0 + riverpod_generator: ^2.2.3 + riverpod_lint: ^1.3.2 flutter: uses-material-design: true diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart b/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart index 0a6983b8..842d2e64 100644 --- a/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart +++ b/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart @@ -15,6 +15,7 @@ class BottomNavBar extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { final localizations = AppLocalizations.of(context); final currentToolData = getCurrentToolData(ref); + final currentPaint = ref.watch(brushToolStateProvider).paint; return NavigationBarTheme( data: WidgetThemes.bottomNavBarThemeData, @@ -38,7 +39,7 @@ class BottomNavBar extends ConsumerWidget { height: 24.0, width: 24.0, decoration: BoxDecoration( - color: ref.watch(brushToolStateProvider).paint.color, + color: currentPaint.color, border: Border.all( color: Colors.white, width: 1.4, From 10c8e5681f0e49459d0e20d642d622d1341e9c73 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Tue, 27 Feb 2024 22:40:18 +0530 Subject: [PATCH 15/39] fix lint errors --- packages/colorpicker/lib/src/colorpicker.dart | 2 +- packages/colorpicker/lib/src/components/slider.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index c957a515..78bc0fc4 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -18,7 +18,7 @@ class ColorPicker extends ConsumerStatefulWidget { final void Function(Color) onColorChanged; @override - _ColorPickerState createState() => _ColorPickerState(); + ConsumerState createState() => _ColorPickerState(); } class _ColorPickerState extends ConsumerState { diff --git a/packages/colorpicker/lib/src/components/slider.dart b/packages/colorpicker/lib/src/components/slider.dart index 2d838f00..ac1035cb 100644 --- a/packages/colorpicker/lib/src/components/slider.dart +++ b/packages/colorpicker/lib/src/components/slider.dart @@ -13,7 +13,7 @@ class OpacitySlider extends ConsumerStatefulWidget { final Color gradientColor; @override - _OpacitySliderState createState() => _OpacitySliderState(); + ConsumerState createState() => _OpacitySliderState(); } class _OpacitySliderState extends ConsumerState { From e9d9f7642208d7a4cdc6a2650e726cfbcb745905 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Wed, 28 Feb 2024 11:47:10 +0530 Subject: [PATCH 16/39] add tests --- packages/colorpicker/lib/src/colorpicker.dart | 140 +++++++++--------- .../test/unit/color_state_test.dart | 22 +++ .../unit/position_fraction_state_test.dart | 23 +++ .../test/unit/slider_state_test.dart | 25 ++++ .../bottom_control_navigation_bar_test.dart | 14 ++ .../widget/bottom_nav_bar_interactions.dart | 57 +++++++ 6 files changed, 213 insertions(+), 68 deletions(-) create mode 100644 packages/colorpicker/test/unit/color_state_test.dart create mode 100644 packages/colorpicker/test/unit/position_fraction_state_test.dart create mode 100644 packages/colorpicker/test/unit/slider_state_test.dart diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index 78bc0fc4..8c13edd7 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -39,79 +39,83 @@ class _ColorPickerState extends ConsumerState { decoration: BoxDecoration( borderRadius: BorderRadius.circular(16.0), ), - child: Column( - children: [ - ColorCompare( - currentColor: widget.currentColor, - newColor: newColor.withOpacity(opacity), - ), - const SizedBox( - height: 10.0, - ), - GridView.count( - childAspectRatio: 1.4, - crossAxisCount: 4, - crossAxisSpacing: 2.0, - mainAxisSpacing: 2.0, - shrinkWrap: true, - children: List.generate( - colors.length + 1, - (index) { - if (index == colors.length) { - return Container( - decoration: BoxDecoration( - image: DecorationImage( - image: PackageAssets.getCheckerboardImgAsset(), - fit: BoxFit.contain, - repeat: ImageRepeat.repeat, + child: SingleChildScrollView( + child: Column( + children: [ + ColorCompare( + currentColor: widget.currentColor, + newColor: newColor.withOpacity(opacity), + ), + const SizedBox( + height: 10.0, + ), + GridView.count( + childAspectRatio: 1.4, + crossAxisCount: 4, + crossAxisSpacing: 2.0, + mainAxisSpacing: 2.0, + shrinkWrap: true, + children: List.generate( + colors.length + 1, + (index) { + if (index == colors.length) { + return Container( + decoration: BoxDecoration( + image: DecorationImage( + image: PackageAssets.getCheckerboardImgAsset(), + fit: BoxFit.contain, + repeat: ImageRepeat.repeat, + ), + ), + ); + } + return GestureDetector( + onTap: () { + ref.read(colorStateNotifierProvider.notifier).updateColor( + colors[index].withOpacity(opacity), + ); + }, + child: Container( + decoration: BoxDecoration( + color: colors[index], ), ), ); - } - return GestureDetector( - onTap: () { - ref.read(colorStateNotifierProvider.notifier).updateColor( - colors[index].withOpacity(opacity), - ); - }, - child: Container( - decoration: BoxDecoration( - color: colors[index], - ), - ), - ); - }, - ), - ), - const SizedBox( - height: 30.0, - ), - OpacitySlider( - gradientColor: newColor, - ), - const Spacer(), - Row( - children: [ - const Spacer(), - TextButton( - onPressed: () { - Navigator.pop(context); }, - child: const Text('CANCEL'), ), - const SizedBox( - width: 10.0, - ), - TextButton( - onPressed: () { - widget.onColorChanged(newColor.withOpacity(opacity)); - Navigator.pop(context); - }, - child: const Text('APPLY'), - ), - ], - ) - ], + ), + const SizedBox( + height: 30.0, + ), + OpacitySlider( + gradientColor: newColor, + ), + const SizedBox( + height: 20.0, + ), + Row( + children: [ + const Spacer(), + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Text('CANCEL'), + ), + const SizedBox( + width: 10.0, + ), + TextButton( + onPressed: () { + widget.onColorChanged(newColor.withOpacity(opacity)); + Navigator.pop(context); + }, + child: const Text('APPLY'), + ), + ], + ) + ], + ), ), ); } diff --git a/packages/colorpicker/test/unit/color_state_test.dart b/packages/colorpicker/test/unit/color_state_test.dart new file mode 100644 index 00000000..f2f06021 --- /dev/null +++ b/packages/colorpicker/test/unit/color_state_test.dart @@ -0,0 +1,22 @@ +import 'package:colorpicker/src/state/color_state.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + late ProviderContainer container; + + setUp(() { + container = ProviderContainer(); + }); + + tearDown(() { + container.dispose(); + }); + + test('updateColor updates the color correctly', () { + Color newColor = Colors.blue.shade50; + container.read(colorStateNotifierProvider.notifier).updateColor(newColor); + expect(container.read(colorStateNotifierProvider), newColor); + }); +} diff --git a/packages/colorpicker/test/unit/position_fraction_state_test.dart b/packages/colorpicker/test/unit/position_fraction_state_test.dart new file mode 100644 index 00000000..bb2a6387 --- /dev/null +++ b/packages/colorpicker/test/unit/position_fraction_state_test.dart @@ -0,0 +1,23 @@ +import 'package:colorpicker/src/state/position_fraction_state.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + late ProviderContainer container; + + setUp(() { + container = ProviderContainer(); + }); + + tearDown(() { + container.dispose(); + }); + + test('updateFraction updates the fraction correctly', () { + double newFraction = 0.3; + container + .read(positionFractionNotifierProvider.notifier) + .updateFraction(newFraction); + expect(container.read(positionFractionNotifierProvider), newFraction); + }); +} diff --git a/packages/colorpicker/test/unit/slider_state_test.dart b/packages/colorpicker/test/unit/slider_state_test.dart new file mode 100644 index 00000000..6a8c6308 --- /dev/null +++ b/packages/colorpicker/test/unit/slider_state_test.dart @@ -0,0 +1,25 @@ +import 'package:colorpicker/src/state/slider_state.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + late ProviderContainer container; + + setUp(() { + container = ProviderContainer(); + }); + + tearDown(() { + container.dispose(); + }); + + test('updatePosition updates the position correctly', () { + double position = 30.0; + double widgetWidth = 100.0; + container.read(positionNotifierProvider.notifier).updatePosition( + position, + widgetWidth, + ); + expect(container.read(positionNotifierProvider), position); + }); +} diff --git a/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart b/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart index 328f5e33..9e6d2df1 100644 --- a/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart +++ b/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart @@ -159,4 +159,18 @@ void main() { expect(animatedOpacityWidget.opacity, equals(VISIBLE)); }); }); + + group('BottomNavBarItem.COLOR', () { + testWidgets('test if color changes on selection', + (WidgetTester tester) async { + const blueColor = Color(0xff0073cc); + + await tester.pumpWidget(sut); + + final bottomNavBarInteractions = BottomNavBarInteractions(tester); + await bottomNavBarInteractions + .selectColor(blueColor) + .then((_) => _.checkActiveColor(blueColor)); + }); + }); } diff --git a/packages/features/workspace_screen/test/widget/bottom_nav_bar_interactions.dart b/packages/features/workspace_screen/test/widget/bottom_nav_bar_interactions.dart index 8b9f3c5a..718cd99b 100644 --- a/packages/features/workspace_screen/test/widget/bottom_nav_bar_interactions.dart +++ b/packages/features/workspace_screen/test/widget/bottom_nav_bar_interactions.dart @@ -52,6 +52,63 @@ class BottomNavBarInteractions { return this; } + Future openColorPicker() async { + final thirdNavDestination = find.byType(NavigationDestination).at(2); + expect(thirdNavDestination, findsOneWidget); + await _tester.tap(thirdNavDestination); + await _tester.pumpAndSettle(); + expect(find.byType(ModalBarrier), findsWidgets); + return this; + } + + Future selectColor(Color color) async { + await openColorPicker(); + + final colorButton = _findButtonWithColor(color); + expect(colorButton, findsOneWidget); + + await _tester.tap(colorButton); + await _tester.pumpAndSettle(); + final applyButton = find.descendant( + of: find.byWidgetPredicate((Widget widget) => widget is Row), + matching: find.text('APPLY'), + ); + expect(applyButton, findsWidgets); + await _tester.dragUntilVisible( + applyButton, find.byType(SingleChildScrollView), const Offset(0, 50)); + await _tester.pumpAndSettle(); + await _tester.tap(applyButton); + await _tester.pumpAndSettle(); + return this; + } + + Future checkActiveColor(Color color) async { + final thirdNavDestination = find.byType(NavigationDestination).at(2); + final activeColor = find.descendant( + of: thirdNavDestination, + matching: find.byWidgetPredicate((Widget widget) => + widget is InkWell && + widget.child is Container && + (widget.child as Container).decoration is BoxDecoration && + ((widget.child as Container).decoration as BoxDecoration).color == + color)); + + expect(activeColor, findsOneWidget); + return this; + } + + Finder _findButtonWithColor(Color color) { + return find.descendant( + of: find.byWidgetPredicate((Widget widget) => + widget is GestureDetector && + widget.child is Container && + (widget.child as Container).decoration is BoxDecoration && + ((widget.child as Container).decoration as BoxDecoration).color == + color), + matching: find.byType(Container), + ); + } + Finder _findIconButtonWithLabel(String targetLabel) { return find.descendant( of: find.byWidgetPredicate( From 1272ceb7574a0dc03401496fdf20ab3650e14f93 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Wed, 28 Feb 2024 21:17:17 +0530 Subject: [PATCH 17/39] fix riverpod issues, remove redundancies --- packages/colorpicker/lib/colorpicker.dart | 2 +- packages/colorpicker/lib/src/colorpicker.dart | 9 +- .../lib/src/components/slider.dart | 93 +++++++++++++------ .../lib/src/components/slider_indicator.dart | 20 ---- .../lib/src/components/slider_shape.dart | 57 ++++++++++++ .../lib/src/state/color_state.dart | 2 +- .../lib/src/state/color_state.g.dart | 22 ++--- .../src/state/position_fraction_state.dart | 15 --- .../src/state/position_fraction_state.g.dart | 27 ------ ..._state.dart => slider_position_state.dart} | 8 +- ...te.g.dart => slider_position_state.g.dart} | 21 +++-- .../test/unit/color_state_test.dart | 4 +- .../unit/position_fraction_state_test.dart | 23 ----- .../test/unit/slider_state_test.dart | 6 +- 14 files changed, 155 insertions(+), 154 deletions(-) delete mode 100644 packages/colorpicker/lib/src/components/slider_indicator.dart create mode 100644 packages/colorpicker/lib/src/components/slider_shape.dart delete mode 100644 packages/colorpicker/lib/src/state/position_fraction_state.dart delete mode 100644 packages/colorpicker/lib/src/state/position_fraction_state.g.dart rename packages/colorpicker/lib/src/state/{slider_state.dart => slider_position_state.dart} (56%) rename packages/colorpicker/lib/src/state/{slider_state.g.dart => slider_position_state.g.dart} (50%) delete mode 100644 packages/colorpicker/test/unit/position_fraction_state_test.dart diff --git a/packages/colorpicker/lib/colorpicker.dart b/packages/colorpicker/lib/colorpicker.dart index e3a7266b..4b1abc69 100644 --- a/packages/colorpicker/lib/colorpicker.dart +++ b/packages/colorpicker/lib/colorpicker.dart @@ -4,4 +4,4 @@ export 'src/colorpicker.dart'; export 'src/constants/colors.dart'; export 'src/components/color_compare.dart'; export 'src/components/slider.dart'; -export 'src/components/slider_indicator.dart'; +export 'src/components/slider_shape.dart'; diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index 8c13edd7..bb21380d 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -2,7 +2,7 @@ import 'package:colorpicker/src/constants/colors.dart'; import 'package:colorpicker/src/components/color_compare.dart'; import 'package:colorpicker/src/components/slider.dart'; import 'package:colorpicker/src/state/color_state.dart'; -import 'package:colorpicker/src/state/position_fraction_state.dart'; +import 'package:colorpicker/src/state/slider_position_state.dart'; import 'package:colorpicker/utils/assets.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -31,8 +31,9 @@ class _ColorPickerState extends ConsumerState { @override Widget build(BuildContext context) { - final opacity = 1.0 - ref.watch(positionFractionNotifierProvider); - final newColor = ref.watch(colorStateNotifierProvider); + final widgetWidth = MediaQuery.of(context).size.width - 52.0; + final opacity = 1.0 - ref.watch(sliderPositionStateProvider) / widgetWidth; + final newColor = ref.watch(colorStateProvider); return Container( margin: const EdgeInsets.all(26.0), alignment: Alignment.center, @@ -71,7 +72,7 @@ class _ColorPickerState extends ConsumerState { } return GestureDetector( onTap: () { - ref.read(colorStateNotifierProvider.notifier).updateColor( + ref.read(colorStateProvider.notifier).updateColor( colors[index].withOpacity(opacity), ); }, diff --git a/packages/colorpicker/lib/src/components/slider.dart b/packages/colorpicker/lib/src/components/slider.dart index ac1035cb..ee31fdda 100644 --- a/packages/colorpicker/lib/src/components/slider.dart +++ b/packages/colorpicker/lib/src/components/slider.dart @@ -1,5 +1,5 @@ -import 'package:colorpicker/src/components/slider_indicator.dart'; -import 'package:colorpicker/src/state/slider_state.dart'; +import 'package:colorpicker/src/components/slider_shape.dart'; +import 'package:colorpicker/src/state/slider_position_state.dart'; import 'package:colorpicker/utils/assets.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -19,7 +19,7 @@ class OpacitySlider extends ConsumerStatefulWidget { class _OpacitySliderState extends ConsumerState { @override Widget build(BuildContext context) { - final positon = ref.watch(positionNotifierProvider); + final positon = ref.watch(sliderPositionStateProvider); double widgetWidth = MediaQuery.of(context).size.width - 52.0; return Container( height: 25.0, @@ -31,34 +31,67 @@ class _OpacitySliderState extends ConsumerState { repeat: ImageRepeat.repeat, ), ), - child: GestureDetector( - onHorizontalDragStart: (DragStartDetails details) {}, - onHorizontalDragUpdate: (DragUpdateDetails details) { - double position = details.localPosition.dx; - ref - .read(positionNotifierProvider.notifier) - .updatePosition(position, widgetWidth); - }, - onHorizontalDragEnd: (DragEndDetails details) {}, - onTapDown: (TapDownDetails details) { - double position = details.localPosition.dx; - ref - .read(positionNotifierProvider.notifier) - .updatePosition(position, widgetWidth); - }, - child: Container( - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - widget.gradientColor, - widget.gradientColor.withOpacity(0), - ], - begin: Alignment.centerLeft, - end: Alignment.centerRight, - ), + // child: GestureDetector( + // onHorizontalDragStart: (DragStartDetails details) {}, + // onHorizontalDragUpdate: (DragUpdateDetails details) { + // double position = details.localPosition.dx; + // ref + // .read(sliderPositionStateProvider.notifier) + // .updatePosition(position, widgetWidth); + // }, + // onHorizontalDragEnd: (DragEndDetails details) {}, + // onTapDown: (TapDownDetails details) { + // double position = details.localPosition.dx; + // ref + // .read(sliderPositionStateProvider.notifier) + // .updatePosition(position, widgetWidth); + // }, + // child: Container( + // decoration: BoxDecoration( + // gradient: LinearGradient( + // colors: [ + // widget.gradientColor.withOpacity(1.0), + // widget.gradientColor.withOpacity(0.0), + // ], + // begin: Alignment.centerLeft, + // end: Alignment.centerRight, + // ), + // ), + // child: CustomPaint( + // painter: SliderIndicatorPainter(positon), + // ), + // ), + // ), + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + widget.gradientColor.withOpacity(1.0), + widget.gradientColor.withOpacity(0.0), + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, ), - child: CustomPaint( - painter: SliderIndicatorPainter(positon), + ), + child: SliderTheme( + data: SliderTheme.of(context).copyWith( + trackHeight: 25.0, + trackShape: CustomTrackShape(), + thumbShape: SliderIndicatorShape(), + inactiveTrackColor: Colors.transparent, + activeTrackColor: Colors.transparent, + overlayColor: Colors.transparent, + ), + child: Slider( + min: 0.0, + max: 1.0, + value: positon / widgetWidth, + onChanged: (value) { + ref.read(sliderPositionStateProvider.notifier).updatePosition( + value * widgetWidth, + widgetWidth, + ); + }, ), ), ), diff --git a/packages/colorpicker/lib/src/components/slider_indicator.dart b/packages/colorpicker/lib/src/components/slider_indicator.dart deleted file mode 100644 index 35826baa..00000000 --- a/packages/colorpicker/lib/src/components/slider_indicator.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/material.dart'; - -class SliderIndicatorPainter extends CustomPainter { - final double position; - SliderIndicatorPainter(this.position); - @override - void paint(Canvas canvas, Size size) { - canvas.drawRect( - Offset(position, -1) & Size(6, size.height + 2), - Paint() - ..color = const Color.fromARGB(255, 62, 62, 62) - ..style = PaintingStyle.stroke - ..strokeWidth = 2); - } - - @override - bool shouldRepaint(SliderIndicatorPainter oldDelegate) { - return true; - } -} diff --git a/packages/colorpicker/lib/src/components/slider_shape.dart b/packages/colorpicker/lib/src/components/slider_shape.dart new file mode 100644 index 00000000..485b6557 --- /dev/null +++ b/packages/colorpicker/lib/src/components/slider_shape.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; + +class SliderIndicatorShape extends SliderComponentShape { + SliderIndicatorShape(); + + @override + Size getPreferredSize(bool isEnabled, bool isDiscrete) { + return const Size(5.0, 30.0); + } + + @override + void paint( + PaintingContext context, + Offset center, { + Animation? activationAnimation, + Animation? enableAnimation, + bool? isDiscrete, + TextPainter? labelPainter, + RenderBox? parentBox, + SliderThemeData? sliderTheme, + TextDirection? textDirection, + double? value, + double? textScaleFactor, + Size? sizeWithOverflow, + }) { + final Canvas canvas = context.canvas; + + canvas.drawRect( + Rect.fromCenter( + center: center, + width: 5.0, + height: 28.0, + ), + Paint() + ..color = const Color.fromARGB(255, 62, 62, 62) + ..style = PaintingStyle.stroke + ..strokeWidth = 2.0, + ); + } +} + +class CustomTrackShape extends RoundedRectSliderTrackShape { + @override + Rect getPreferredRect({ + required RenderBox parentBox, + Offset offset = Offset.zero, + required SliderThemeData sliderTheme, + bool isEnabled = false, + bool isDiscrete = false, + }) { + final double trackHeight = sliderTheme.trackHeight ?? 2.0; + final double trackWidth = parentBox.size.width; + final double trackTop = + offset.dy + (parentBox.size.height - trackHeight) / 2; + return Rect.fromLTWH(offset.dx, trackTop, trackWidth, trackHeight); + } +} diff --git a/packages/colorpicker/lib/src/state/color_state.dart b/packages/colorpicker/lib/src/state/color_state.dart index 0010600b..b1734204 100644 --- a/packages/colorpicker/lib/src/state/color_state.dart +++ b/packages/colorpicker/lib/src/state/color_state.dart @@ -4,7 +4,7 @@ import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'color_state.g.dart'; @riverpod -class ColorStateNotifier extends _$ColorStateNotifier { +class ColorState extends _$ColorState { @override Color build() { return Colors.blue; diff --git a/packages/colorpicker/lib/src/state/color_state.g.dart b/packages/colorpicker/lib/src/state/color_state.g.dart index 60b4c781..c486ed7b 100644 --- a/packages/colorpicker/lib/src/state/color_state.g.dart +++ b/packages/colorpicker/lib/src/state/color_state.g.dart @@ -6,22 +6,20 @@ part of 'color_state.dart'; // RiverpodGenerator // ************************************************************************** -String _$colorStateNotifierHash() => - r'7ab92b2d43fb0357fe1d0e1dbfb55ffbba72671e'; +String _$colorStateHash() => r'cfdfc3937c27a7d96c9b0f5b57e66a3697d1b5cd'; -/// See also [ColorStateNotifier]. -@ProviderFor(ColorStateNotifier) -final colorStateNotifierProvider = - AutoDisposeNotifierProvider.internal( - ColorStateNotifier.new, - name: r'colorStateNotifierProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$colorStateNotifierHash, +/// See also [ColorState]. +@ProviderFor(ColorState) +final colorStateProvider = + AutoDisposeNotifierProvider.internal( + ColorState.new, + name: r'colorStateProvider', + debugGetCreateSourceHash: + const bool.fromEnvironment('dart.vm.product') ? null : _$colorStateHash, dependencies: null, allTransitiveDependencies: null, ); -typedef _$ColorStateNotifier = AutoDisposeNotifier; +typedef _$ColorState = AutoDisposeNotifier; // ignore_for_file: type=lint // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/packages/colorpicker/lib/src/state/position_fraction_state.dart b/packages/colorpicker/lib/src/state/position_fraction_state.dart deleted file mode 100644 index 0b42b2e8..00000000 --- a/packages/colorpicker/lib/src/state/position_fraction_state.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -part 'position_fraction_state.g.dart'; - -@riverpod -class PositionFractionNotifier extends _$PositionFractionNotifier { - @override - double build() { - return 0.0; - } - - void updateFraction(double newFraction) { - state = newFraction; - } -} diff --git a/packages/colorpicker/lib/src/state/position_fraction_state.g.dart b/packages/colorpicker/lib/src/state/position_fraction_state.g.dart deleted file mode 100644 index 781ac922..00000000 --- a/packages/colorpicker/lib/src/state/position_fraction_state.g.dart +++ /dev/null @@ -1,27 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'position_fraction_state.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$positionFractionNotifierHash() => - r'5eac955e9e2919021effa7f62ea70ceead6a3cc7'; - -/// See also [PositionFractionNotifier]. -@ProviderFor(PositionFractionNotifier) -final positionFractionNotifierProvider = - AutoDisposeNotifierProvider.internal( - PositionFractionNotifier.new, - name: r'positionFractionNotifierProvider', - debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') - ? null - : _$positionFractionNotifierHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef _$PositionFractionNotifier = AutoDisposeNotifier; -// ignore_for_file: type=lint -// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/packages/colorpicker/lib/src/state/slider_state.dart b/packages/colorpicker/lib/src/state/slider_position_state.dart similarity index 56% rename from packages/colorpicker/lib/src/state/slider_state.dart rename to packages/colorpicker/lib/src/state/slider_position_state.dart index 7e5e8795..06add667 100644 --- a/packages/colorpicker/lib/src/state/slider_state.dart +++ b/packages/colorpicker/lib/src/state/slider_position_state.dart @@ -1,9 +1,8 @@ -import 'package:colorpicker/src/state/position_fraction_state.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; -part 'slider_state.g.dart'; +part 'slider_position_state.g.dart'; @riverpod -class PositionNotifier extends _$PositionNotifier { +class SliderPositionState extends _$SliderPositionState { @override double build() { return 0.0; @@ -20,8 +19,5 @@ class PositionNotifier extends _$PositionNotifier { position = widgetWidth; } state = position; - ref.read(positionFractionNotifierProvider.notifier).updateFraction( - position / widgetWidth, - ); } } diff --git a/packages/colorpicker/lib/src/state/slider_state.g.dart b/packages/colorpicker/lib/src/state/slider_position_state.g.dart similarity index 50% rename from packages/colorpicker/lib/src/state/slider_state.g.dart rename to packages/colorpicker/lib/src/state/slider_position_state.g.dart index 208b8c24..70a4c17b 100644 --- a/packages/colorpicker/lib/src/state/slider_state.g.dart +++ b/packages/colorpicker/lib/src/state/slider_position_state.g.dart @@ -1,26 +1,27 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'slider_state.dart'; +part of 'slider_position_state.dart'; // ************************************************************************** // RiverpodGenerator // ************************************************************************** -String _$positionNotifierHash() => r'11b7d29187bbe63a99dae094d40cc6278e0f8a2e'; +String _$sliderPositionStateHash() => + r'bc845178b65cd978c5438bc92706fc9880e5dcf6'; -/// See also [PositionNotifier]. -@ProviderFor(PositionNotifier) -final positionNotifierProvider = - AutoDisposeNotifierProvider.internal( - PositionNotifier.new, - name: r'positionNotifierProvider', +/// See also [SliderPositionState]. +@ProviderFor(SliderPositionState) +final sliderPositionStateProvider = + AutoDisposeNotifierProvider.internal( + SliderPositionState.new, + name: r'sliderPositionStateProvider', debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') ? null - : _$positionNotifierHash, + : _$sliderPositionStateHash, dependencies: null, allTransitiveDependencies: null, ); -typedef _$PositionNotifier = AutoDisposeNotifier; +typedef _$SliderPositionState = AutoDisposeNotifier; // ignore_for_file: type=lint // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/packages/colorpicker/test/unit/color_state_test.dart b/packages/colorpicker/test/unit/color_state_test.dart index f2f06021..fabe01f3 100644 --- a/packages/colorpicker/test/unit/color_state_test.dart +++ b/packages/colorpicker/test/unit/color_state_test.dart @@ -16,7 +16,7 @@ void main() { test('updateColor updates the color correctly', () { Color newColor = Colors.blue.shade50; - container.read(colorStateNotifierProvider.notifier).updateColor(newColor); - expect(container.read(colorStateNotifierProvider), newColor); + container.read(colorStateProvider.notifier).updateColor(newColor); + expect(container.read(colorStateProvider), newColor); }); } diff --git a/packages/colorpicker/test/unit/position_fraction_state_test.dart b/packages/colorpicker/test/unit/position_fraction_state_test.dart deleted file mode 100644 index bb2a6387..00000000 --- a/packages/colorpicker/test/unit/position_fraction_state_test.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:colorpicker/src/state/position_fraction_state.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - late ProviderContainer container; - - setUp(() { - container = ProviderContainer(); - }); - - tearDown(() { - container.dispose(); - }); - - test('updateFraction updates the fraction correctly', () { - double newFraction = 0.3; - container - .read(positionFractionNotifierProvider.notifier) - .updateFraction(newFraction); - expect(container.read(positionFractionNotifierProvider), newFraction); - }); -} diff --git a/packages/colorpicker/test/unit/slider_state_test.dart b/packages/colorpicker/test/unit/slider_state_test.dart index 6a8c6308..42ac3840 100644 --- a/packages/colorpicker/test/unit/slider_state_test.dart +++ b/packages/colorpicker/test/unit/slider_state_test.dart @@ -1,4 +1,4 @@ -import 'package:colorpicker/src/state/slider_state.dart'; +import 'package:colorpicker/src/state/slider_position_state.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -16,10 +16,10 @@ void main() { test('updatePosition updates the position correctly', () { double position = 30.0; double widgetWidth = 100.0; - container.read(positionNotifierProvider.notifier).updatePosition( + container.read(sliderPositionStateProvider.notifier).updatePosition( position, widgetWidth, ); - expect(container.read(positionNotifierProvider), position); + expect(container.read(sliderPositionStateProvider), position); }); } From 34235dc68d4df51fb3d476c59909bd4c0c15770e Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Wed, 6 Mar 2024 00:58:09 +0530 Subject: [PATCH 18/39] remove comments, capitalize text --- .../lib/src/components/slider.dart | 31 ------------------- .../bottom_control_navigation_bar_test.dart | 14 ++++----- 2 files changed, 7 insertions(+), 38 deletions(-) diff --git a/packages/colorpicker/lib/src/components/slider.dart b/packages/colorpicker/lib/src/components/slider.dart index ee31fdda..e42d74e9 100644 --- a/packages/colorpicker/lib/src/components/slider.dart +++ b/packages/colorpicker/lib/src/components/slider.dart @@ -31,37 +31,6 @@ class _OpacitySliderState extends ConsumerState { repeat: ImageRepeat.repeat, ), ), - // child: GestureDetector( - // onHorizontalDragStart: (DragStartDetails details) {}, - // onHorizontalDragUpdate: (DragUpdateDetails details) { - // double position = details.localPosition.dx; - // ref - // .read(sliderPositionStateProvider.notifier) - // .updatePosition(position, widgetWidth); - // }, - // onHorizontalDragEnd: (DragEndDetails details) {}, - // onTapDown: (TapDownDetails details) { - // double position = details.localPosition.dx; - // ref - // .read(sliderPositionStateProvider.notifier) - // .updatePosition(position, widgetWidth); - // }, - // child: Container( - // decoration: BoxDecoration( - // gradient: LinearGradient( - // colors: [ - // widget.gradientColor.withOpacity(1.0), - // widget.gradientColor.withOpacity(0.0), - // ], - // begin: Alignment.centerLeft, - // end: Alignment.centerRight, - // ), - // ), - // child: CustomPaint( - // painter: SliderIndicatorPainter(positon), - // ), - // ), - // ), child: Container( decoration: BoxDecoration( gradient: LinearGradient( diff --git a/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart b/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart index 9e6d2df1..6c0327b6 100644 --- a/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart +++ b/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart @@ -49,7 +49,7 @@ void main() { }); group('BottomNavBarItem.CURRENT_TOOL', () { - testWidgets('test if width tool-option is visible when starting app', + testWidgets('Test if width tool-option is visible when starting app', (WidgetTester tester) async { await tester.pumpWidget(sut); @@ -63,7 +63,7 @@ void main() { expect(animatedOpacityWidget.opacity, equals(VISIBLE)); }); - testWidgets('test if width tool-option is invisible after clicking once', + testWidgets('Test if width tool-option is invisible after clicking once', (WidgetTester tester) async { await tester.pumpWidget(sut); @@ -82,7 +82,7 @@ void main() { expect(animatedOpacityWidget.opacity, equals(INVISIBLE)); }); - testWidgets('test if width tool-option is visible after clicking twice', + testWidgets('Test if width tool-option is visible after clicking twice', (WidgetTester tester) async { await tester.pumpWidget(sut); @@ -105,7 +105,7 @@ void main() { expect(animatedOpacityWidget.opacity, equals(VISIBLE)); }); - testWidgets('test if cap tool-option is visible when starting app', + testWidgets('Test if cap tool-option is visible when starting app', (WidgetTester tester) async { await tester.pumpWidget(sut); @@ -118,7 +118,7 @@ void main() { expect(animatedOpacityWidget.opacity, equals(VISIBLE)); }); - testWidgets('test if cap tool-option is invisible after clicking once', + testWidgets('Test if cap tool-option is invisible after clicking once', (WidgetTester tester) async { await tester.pumpWidget(sut); @@ -136,7 +136,7 @@ void main() { expect(animatedOpacityWidget.opacity, equals(INVISIBLE)); }); - testWidgets('test if cap tool-option is visible after clicking twice', + testWidgets('Test if cap tool-option is visible after clicking twice', (WidgetTester tester) async { await tester.pumpWidget(sut); @@ -161,7 +161,7 @@ void main() { }); group('BottomNavBarItem.COLOR', () { - testWidgets('test if color changes on selection', + testWidgets('Test if color changes on selection', (WidgetTester tester) async { const blueColor = Color(0xff0073cc); From 7a430c20e30b05eb127794261c8ad7faec9c89ea Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Wed, 6 Mar 2024 17:29:41 +0530 Subject: [PATCH 19/39] convert stateful to stateless, rename widgets --- packages/colorpicker/lib/colorpicker.dart | 2 +- packages/colorpicker/lib/src/colorpicker.dart | 22 +++++-------------- ...lor_compare.dart => color_comparison.dart} | 21 +++++++----------- .../lib/src/components/slider.dart | 13 ++++------- .../lib/src/state/color_state.dart | 5 ++++- 5 files changed, 23 insertions(+), 40 deletions(-) rename packages/colorpicker/lib/src/components/{color_compare.dart => color_comparison.dart} (71%) diff --git a/packages/colorpicker/lib/colorpicker.dart b/packages/colorpicker/lib/colorpicker.dart index 4b1abc69..b3d6ede5 100644 --- a/packages/colorpicker/lib/colorpicker.dart +++ b/packages/colorpicker/lib/colorpicker.dart @@ -2,6 +2,6 @@ library colorpicker; export 'src/colorpicker.dart'; export 'src/constants/colors.dart'; -export 'src/components/color_compare.dart'; +export 'src/components/color_comparison.dart'; export 'src/components/slider.dart'; export 'src/components/slider_shape.dart'; diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index bb21380d..3a32bab1 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -1,5 +1,5 @@ import 'package:colorpicker/src/constants/colors.dart'; -import 'package:colorpicker/src/components/color_compare.dart'; +import 'package:colorpicker/src/components/color_comparison.dart'; import 'package:colorpicker/src/components/slider.dart'; import 'package:colorpicker/src/state/color_state.dart'; import 'package:colorpicker/src/state/slider_position_state.dart'; @@ -7,7 +7,7 @@ import 'package:colorpicker/utils/assets.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -class ColorPicker extends ConsumerStatefulWidget { +class ColorPicker extends ConsumerWidget { const ColorPicker({ super.key, required this.currentColor, @@ -17,20 +17,10 @@ class ColorPicker extends ConsumerStatefulWidget { final Color currentColor; final void Function(Color) onColorChanged; - @override - ConsumerState createState() => _ColorPickerState(); -} - -class _ColorPickerState extends ConsumerState { final colors = DisplayColors.colors; @override - void initState() { - super.initState(); - } - - @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { final widgetWidth = MediaQuery.of(context).size.width - 52.0; final opacity = 1.0 - ref.watch(sliderPositionStateProvider) / widgetWidth; final newColor = ref.watch(colorStateProvider); @@ -43,8 +33,8 @@ class _ColorPickerState extends ConsumerState { child: SingleChildScrollView( child: Column( children: [ - ColorCompare( - currentColor: widget.currentColor, + ColorComparison( + currentColor: currentColor, newColor: newColor.withOpacity(opacity), ), const SizedBox( @@ -108,7 +98,7 @@ class _ColorPickerState extends ConsumerState { ), TextButton( onPressed: () { - widget.onColorChanged(newColor.withOpacity(opacity)); + onColorChanged(newColor.withOpacity(opacity)); Navigator.pop(context); }, child: const Text('APPLY'), diff --git a/packages/colorpicker/lib/src/components/color_compare.dart b/packages/colorpicker/lib/src/components/color_comparison.dart similarity index 71% rename from packages/colorpicker/lib/src/components/color_compare.dart rename to packages/colorpicker/lib/src/components/color_comparison.dart index 1e6a630c..4b72ccea 100644 --- a/packages/colorpicker/lib/src/components/color_compare.dart +++ b/packages/colorpicker/lib/src/components/color_comparison.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; -class ColorCompare extends StatefulWidget { - const ColorCompare({ +class ColorComparison extends StatelessWidget { + const ColorComparison({ super.key, required this.currentColor, required this.newColor, @@ -10,11 +10,6 @@ class ColorCompare extends StatefulWidget { final Color currentColor; final Color newColor; - @override - State createState() => _ColorCompareState(); -} - -class _ColorCompareState extends State { @override Widget build(BuildContext context) { return SizedBox( @@ -23,14 +18,14 @@ class _ColorCompareState extends State { child: Row( children: [ Expanded( - child: ColorDesc( - color: widget.currentColor, + child: ColorDescription( + color: currentColor, desc: 'current', ), ), Expanded( - child: ColorDesc( - color: widget.newColor, + child: ColorDescription( + color: newColor, desc: 'new', ), ), @@ -40,8 +35,8 @@ class _ColorCompareState extends State { } } -class ColorDesc extends StatelessWidget { - const ColorDesc({ +class ColorDescription extends StatelessWidget { + const ColorDescription({ super.key, required this.color, required this.desc, diff --git a/packages/colorpicker/lib/src/components/slider.dart b/packages/colorpicker/lib/src/components/slider.dart index e42d74e9..48825d0c 100644 --- a/packages/colorpicker/lib/src/components/slider.dart +++ b/packages/colorpicker/lib/src/components/slider.dart @@ -4,7 +4,7 @@ import 'package:colorpicker/utils/assets.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -class OpacitySlider extends ConsumerStatefulWidget { +class OpacitySlider extends ConsumerWidget { const OpacitySlider({ super.key, required this.gradientColor, @@ -13,12 +13,7 @@ class OpacitySlider extends ConsumerStatefulWidget { final Color gradientColor; @override - ConsumerState createState() => _OpacitySliderState(); -} - -class _OpacitySliderState extends ConsumerState { - @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { final positon = ref.watch(sliderPositionStateProvider); double widgetWidth = MediaQuery.of(context).size.width - 52.0; return Container( @@ -35,8 +30,8 @@ class _OpacitySliderState extends ConsumerState { decoration: BoxDecoration( gradient: LinearGradient( colors: [ - widget.gradientColor.withOpacity(1.0), - widget.gradientColor.withOpacity(0.0), + gradientColor.withOpacity(1.0), + gradientColor.withOpacity(0.0), ], begin: Alignment.centerLeft, end: Alignment.centerRight, diff --git a/packages/colorpicker/lib/src/state/color_state.dart b/packages/colorpicker/lib/src/state/color_state.dart index b1734204..286557a5 100644 --- a/packages/colorpicker/lib/src/state/color_state.dart +++ b/packages/colorpicker/lib/src/state/color_state.dart @@ -1,13 +1,16 @@ import 'package:flutter/material.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:colorpicker/src/constants/colors.dart'; + part 'color_state.g.dart'; @riverpod class ColorState extends _$ColorState { + final colors = DisplayColors.colors; @override Color build() { - return Colors.blue; + return colors[0]; } void updateColor(Color newColor) { From 8a347b946141e32cd9b30bfd3be7692644ceb3a7 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Mon, 11 Mar 2024 00:30:39 +0530 Subject: [PATCH 20/39] address changes, remove slider position state provider --- .../colorpicker/assets/img/checkerboard.png | Bin 103386 -> 10096 bytes packages/colorpicker/lib/colorpicker.dart | 4 +- packages/colorpicker/lib/src/colorpicker.dart | 135 ++++++--------- .../src/components/checkerboard_square.dart | 19 +++ .../lib/src/components/color_comparison.dart | 23 ++- .../lib/src/components/color_square.dart | 28 ++++ .../{slider.dart => opacity_slider.dart} | 19 +-- ...shape.dart => slider_indicator_shape.dart} | 4 +- .../src/state/color_picker_state_data.dart | 13 ++ .../color_picker_state_data.freezed.dart | 155 ++++++++++++++++++ .../state/color_picker_state_provider.dart | 27 +++ ...art => color_picker_state_provider.g.dart} | 21 ++- .../lib/src/state/color_state.dart | 19 --- .../lib/src/state/color_state.g.dart | 25 --- .../lib/src/state/slider_position_state.dart | 23 --- packages/colorpicker/lib/utils/assets.dart | 4 +- packages/colorpicker/pubspec.yaml | 2 + .../test/unit/color_state_test.dart | 16 +- .../test/unit/slider_state_test.dart | 25 --- .../components/bottom_bar/bottom_nav_bar.dart | 10 +- pubspec.lock | 54 +++--- 21 files changed, 381 insertions(+), 245 deletions(-) create mode 100644 packages/colorpicker/lib/src/components/checkerboard_square.dart create mode 100644 packages/colorpicker/lib/src/components/color_square.dart rename packages/colorpicker/lib/src/components/{slider.dart => opacity_slider.dart} (73%) rename packages/colorpicker/lib/src/components/{slider_shape.dart => slider_indicator_shape.dart} (96%) create mode 100644 packages/colorpicker/lib/src/state/color_picker_state_data.dart create mode 100644 packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart create mode 100644 packages/colorpicker/lib/src/state/color_picker_state_provider.dart rename packages/colorpicker/lib/src/state/{slider_position_state.g.dart => color_picker_state_provider.g.dart} (50%) delete mode 100644 packages/colorpicker/lib/src/state/color_state.dart delete mode 100644 packages/colorpicker/lib/src/state/color_state.g.dart delete mode 100644 packages/colorpicker/lib/src/state/slider_position_state.dart delete mode 100644 packages/colorpicker/test/unit/slider_state_test.dart diff --git a/packages/colorpicker/assets/img/checkerboard.png b/packages/colorpicker/assets/img/checkerboard.png index ecc4202152720c6c84ef5dfe5314bad3f1e885a9..92f8909d5962f1ed4d9f3d6b7ac39262c86eaa7e 100644 GIT binary patch literal 10096 zcmb_>2Q*z>xAsEN1|9x}6ara>CdFFc7Gw0cJ&1Ws!)xy;(0992~Q3Q~XfZx~E8ZxDdoSdb$ zu9l*Ty28x>GR|FFxBJLY0C02n_R>|7r8P1(p+#Q?kN`3O1z-b2t!?jn$Y^V;|3&iO z+>Yl#GC}wi9T>Y+P^bpljO; zOc3;^UfYhp?eZJUZ@cRTqpvFmVqSx`wBx_nHveM(6&Hj6D7O69xBuJA+uk3{9{?0( z0pR+X{$~ICS^e!pApuhm0089jzkT;g0YKyk^r!yqv&jR1&L{wYFaGUgECvAlNC4<~ zW9#GP`#T0e4&KL+Mp0}b=@_oq$51I^9ST9Z1GZFtxOloEM90s3*VW?zB(6C>sNVVc zL&VE%-m9ytB|r{9MM1g#K}A7@prS(1u+Y)K3l|d$0}CG)3dP68$0Hzu!w3jT3GwiW zDTztR$S5c%pfD;LDsmb)IR*LE0Dz4F#&$wNq6e-9uQNeG0ZZ?}A}%Vw?DiP_l;s^A zjg)!bI;pdq_|rcA={Kj|Y~P9Fsk@ZOCwm(HeKTMAU9Z-<9G@j#L)5$A9zJWzv#~DM zrTCKU$CwjK^3R2u?EWB^Kgd_`)%=U!fs%%90-f&68@#kwHo$2+)j08;rfY~y-Aj#~ zoNP+9Y@Eu~+WRIW^?koK&t}{mzE;r*w~0D{Y)l9$PfYWT+`j@cP7ie-Dn6Yvs*ur} zen6jMXxzVp=k+qW{PD2nVeDt@hgcg}$MAJ5M@ibgz7o2CTQv-x?#)aFK0PctqDC?AJ53{SJ<$Wm(Ge#0 zXuAqUf=?WKUBmQmOzP)X`#U2+5?FIRZ-WgVOP~F%rM- zU_#DzF(WVcQHibq?z5U~&W?}C?53X4td>vr|3)(Po zfeC#0&y2IVevb9PwR^W}`S9?v=zT0Xf*Vxs{@*MfA+Uv+z`X$#9qd)Gk^gFAWE4~+ z2oy#vAjrp0K*Yer_*XY0L6FNk_Y(GT#GKB{g|^B^Jb31qgLNcqY)g|wBPLzceh&21 zaDGoaRP&uTJyAG`rV@NOLw=}h+eP{%LyEPinQvOLu>Z3V)31-_`q=@>XG~8O1=q8!=-h9cLPn31h9)u%M}%ik z^UK$duf;my|EwO#75iM?sVqFfR5Yy-Zr+!CCMTJ%E{1IC%zqs9O}*XFzVVN6*ii}t zC7B@s4KpO$5JT2oHX}|> z65Mfnicbn>z%H@=F*d5MfZPXqo-}M)KXxNdqPwN&ee#y{q>L8i{nlt|vcg-~pX5@` z6~YJlJ?_L2lD>+X845Ns2iQ zW1Ea7u|cj^mk$CY`cdX&HvS9IK~ z9h~U12Bdc?ZEpCVM{1xL4a_6bDAu@t^+TQx4L>MY;ln;6KpK4zst>ewMc` zvNfr7PJd8#M5x3_tGO{-O!Z-Am!yk~Qo`OLCD9J2Dr~1EE3eiKef2Dd&!C7Vh z{Wi&PJw&F4@hO>~nRhtVRvGuwf0WWLnG>rR^t19tE3Y$pqBZ&8IHQ{M*YhipF@%?) zPYtIU5%XPhlaSqT+i4-Ci?D$`ot1qt{qSRq290<0Gg$5(wxt-fzBOH&@mS;VXRAz$d)ZxGEhld~dnZ*P`AFXX6A|G-8g-|6OH z36ql!nNT$Ae=EVXDAVW6c^rS2aQDz}hU{?0dWvvKC8v!i+_turC!VfYYO{>mYNsfD zh4zDBcA&y7Oy4u{ZJaY_-YrbG^6^E|e*Rg0c`|ww3R=D@I3iYpop%&U<}VR_tyy9ve7>hT+Hqua5wUMmc)vVnG|GIttA(m?4) z?J=maxOb$sDx^!_j2(UjcwS2wl|5}>l$?Nqz1s{;3GGL@%JzYhmKdFoDRAtzppM~3 zZG}v}T~PVZpAQIQB}BCN5{|bn$8Z#Y6`=PaI+?3LWSY&sTvc+F>s9e+hcFFgsPW;aOi-!wVEuwZ_ z-_Ze@_{q7AfIaFJ4aQ=ESr9J zZoJsq?t4t5iOrA`7twTn#363z`vg1R%s587MbzJ9X66bwtlu?W?A4?@a8+Mjp;t6~jG=Du@GyW3w43+}cp*=-^`ZIw<*${KUu_I8)AVVbzL zAly=6T8ZArF0(#Uzmj_pZrKHQ^FIE1`0(5Vq@49ZsMxA79D*D`|{o>V(BSy%nf@GT8lUj(Kia#;qGfql#Rr&H24V$%RjJr@OEyk}?-S9fH&(?K%SHLGLjO}O+ zzBa@^6zW#=_sh(a{2+O%!PZUogB-6IHz7%;^W57Gl?R%^rDU%(BodQKddqlQUUMdd zqv=otNWdkst?d?l@C~1$gpawm6coQ% zU!4)VoVT{0>ax88hB8;|g*C2#H`{wBSAe0leXcRO2z3>WPv%MhtJU5!Dc9>bQL1Hi zEBo<*eLc>)BrBY{jPk z@W}?)0a2Tk2)(qh=A2&&lDhACh4VxBCn6tK7ES9ppTk3lgoFwGVh)mojh%Z&H#^r+ zt(V&=e5#kKy6ZhrS08W*8~YhRlD78@%iP;3yg%zY2Wp*>6x8Q_ZfY-HQ#MKJnRS~I zR7&+eaY6W`?r6;4co4UxGOC_~p6r79d|btF^j()*I~{TRewJ2kEB2K;%(u!S%q03j zY@lZT*MV{KH~07%DctJrnorcl4UvSjR;bfTYz8ej}GSi+VIJo)c9pB7DKYa3^j8 zkisjufjHJvdK#1W_zDwW1IpfhI5#G55%ME_Iu}2=v0=S0xlo^EOx`=`=^QM9Jh`#y znvfth&?02#^1b(%#y!l@YaicpcgW7=)!f`=@|&5-jYs2EwjRdhPieMxM<9<7dd@Yk zUM!4X(m!Uq2d9{j%5xZyL})qHv|S`h#pM^oiN8F(0#yHt==$D>uFARGXtE6;rJ~0;!%M0fmR`nv*X!n>N^W8~&nknvF zbHKCQzb+&kfBy(NDeL^z&JA~i+`R|k^VU^@s%x#C!oGTmhs>ENmrK~(KUW<8x$bWl zc9`cqa8)$+YB)nqeN2*CX5Dg=gS)vWilQ-y<>+5XPVxu$LQlhs}OD}X>NvojHQ^YQCeYZ~XOHvPrmVVc1SjloABe}zySOv%hjh* zP<3_Qf@@f_Xl0?{);s5p(HHt2z$G~QsVnvI;j!0^o);~;b2%L&xrl8iRj+M6_PE&$ z?3a|Yg{zuCL3g^pEF;x^BhdmcPtVSeSKFz4s&{_#RmL6^J^v9t>$6$(ALX_H%e`A! zHTe8KdgAPRwl}kKqL@|9X>EU2ZyN9*zziM)kRho5^707@fD+J^d^_Ni(Xpm&?)MD) znD!rkwo1{t-0OULf1N`!KkpSm#P2zTsa$7u(Cl_4mCY(P+ z2`{a5A7oW&Cpg2&toqn-hnqs_;Amf*OaA!mwXsN`<6R+x&9>cU1)F$LqJCC2 z+!N#CRvBWoPf&Z}cy{E{RkHditNdX1%@&9 z*N!pK7&F_Sr`J3vih8`^x6&sd#K3*|mTM1XE)t`m6N57?YU+wj{17n}UOY=wK1Q^1 zMY?<$Q#=Puf1guufTm86#EEBL18WH8#e!7E6Ieg>V880AC-`L-tB=jm8tKZkFL>vS zx?QS9dbaCQN>6AStUiy!6gzeXTDSKK{l^d;wGufpb+JyfQtCp6+$J>#dp$1eThB&z zj6}Z=L0#Q@seiy;U^r>K|Bm918Y=LDVQMJWuMf>8Y!x-{8-pe-hF|YzY_e3$gxid& zm_YY_R!@=Kv(;f_m07Dd_{cDsu!v^|i)XZIx7{A7qH4VV`K&sE2rXbgGF%WY{+^F0 z(SvFq1E3}8Euk;gK%qfLJbbqFn9Rg`*0JkryZGWtZ7_ws*T=RH8jBw-vs(A+hcaS1 zd|w(^xN0t88mThoi9-tOqoAy1a7IJIk_8NS*sP&fYbGj`j|i8sDU*L_h(N`WL)7G# zB9|Jbj5d8-mK}$v0>-^7z-GV@IYOR5pxSsWo=}vo#F_(B0g402w`OYS(pnj*4(J|15nke5-bL25TJaNBm@4RF{JzhLFDCj~{ zNnS_FrGI*2F64P=v3^uf`O_wLe#PJLp~O-OnThY5Qp=W*CoXx+c69B~xPhd^TMe^^ zq+J)T=#oaILY*3k_4X>f%FC@;xy29|TR91T=_woz%#z%ErzQd_hvrPNjeh9$cT!yQ zM0GJ5!wQAr)X^D_VPFSJK@#gBB(bzrv-KO&cLO4~jK+p_6j2DFoEt>2et0&2a~33H z8l{+X1I20dk?f!$e<%?ON>giAYN;m%@ItjY)2!l!Fz3d0-}~J+i49^d0?WQ8k9OVX zq;OlhJr<=>o&>yeVd?c!2mb}oyyM-m&vUCQ2hlXpcY z$sN8lu-T}6OubXtD4DPv+#d0mQwI%Pp^U!9rL78zYAtb`+VcD|oKP0b zdJs_MFVo0(aZMeE6KKyXc_w%sfBO$UqaW2i{PM62g@65W~Xhz=l zer+dO+TpYNxcjJS?oK|UBkZH}w~8dThtA|JaX?I*GS3b+4{C$#HB$m}m-!9%n!D3)nZLLS`@~n+1F)F@(gb74mDl+9(`Dj;T({ zl(YYT(F(ACE)`mbZ~t|vUd~fTl4BtIFt!}!l+Xt-4%SOZbBE(#jn7+@4zngRPFR0o z-hP3>!DIXY`^5k=9VDg<0~6@?I?Aaja9ZV*u-@t_2FOtjEmB@3@zK*a9VL{3{R5C# z#OGAf<79I;9Wl4_S<$x~ikF~L$#UQuJrKc^4!{QKL@?QCxv9fbn=-0tTTU9!0z0Ys z+jeVH?5AAT$c69`xCZ~FcHkDk(O0zlkKIPTRQaF(_kq%}aR9n$m?}odna#=f)ve*O zgtO2#dT4fWR0$NwilnuQEU!mWl`dz+M3$z*biptoz);hcor;rHPDg8!)inevxS5O) zg^JL~c2q8mNTzB!Cus;9Ei%>(bI#@E=a9gOz+sk!;TvW;O`kYjiPX%jP&Q?dna;)h zGu0cu%zt5i4xSrWpx|2rG^F1LhreDRfaeB2oo_PMo@ult2hAV*!>0f9-~c^!Qo?NO z#?{&mA-n%*b+E6`e$v8zz(t9NV91$UN|&fLb0#Rq*^5FZVz4VoCF1pc3j5LBpa0IJ zQ*%#NZmYz+WKp}My9zH54I4gElFd48E{l#-GOTe7Ou8#fUN9F7bQw2+WD-by<}<@> zrqM_$YhzGR(@cKuv#ye!y=}`(^Ko@-Q`Cy0H;bvEGG^^%HC839e@hwE7)m6Bc46o7 z>x)jwEa|pDqwd)W@l5ZZTfSXOX;16lPNZfUb62Of&0jRL__R%9`b%9V&SoP(RD*7O(`<88 zBuI&@#^bzC*SoN=g8+U~(%Rm_&DIT^d5Y$#z}w8ip~i;v2K z)z(WWnP)x;Nmcx^pY)3$Jo}j=8jyooL)oiDT;6q|tU0Nt^4+}Rl^Ys9;hGRLKHqD% z9G1@2mj3DobrFWcToTcYubJ3%$`Vv;x!^*f%>lbjTi+<0YA41Mv&n^N!-}6ubO7-P zZT+^gcZ|)uY0*t{mkJ81TpM>uA&sHMY-S(R=OWoVVz~=3kQ6T!O$h)(2r*P zgYazbI~kcXlwh;n&4?NF%+JAp`mtk@RiuDOanp?}wmXA2o-pjrt?d3qUROG=A4^t; zPQE$@OB?o0&~8{`7PppLV#T&%TZ2VESAkU|M4=1@W6REJwm=grjdvuoZ%0!7q~iSv zE6Oy$zPUVgmc2GJh-k@W{9vG6orIHcVXL|+9)VlHdHn9jWCb>i)wGW5aUNkPmf(&T z8v9%OyYh2*$Q8pLYS!e!Yr+Oj(UBcQnG@BuSvBv1P5+(N&)F$Enwm|3u-0IKi$)Cp zVCs88dWHOh#NZy9Ef;4sVn3SXlo4t3vCULmqHg62Z-U0&Zu1AwkZ91WFAA#_)N3GG z4(=h@mfb?}C2tVerb&**ozIwy;!rnCslMR(;63N`NPs3e%&Ay#YGKDlN`s~`>cUn`H;Fpi_FxJc@TC;E)ueL;^hlWlZ4SKs zwRZ$-Xp%#9cD8X}vnH=KpKTStpwd8*c`zeIb?~G7)Bmoxi(qj#s#N;N-9uc@e(4;y zh)D2740dabf?{f_mazPYVJ9RmmXFiy2@6}fXwZ1!I~M%dbs=sVzZdIqI`@juf#B43ml=XF#mWN-rf>Z)*_dIB{nm)bU7q$ z+g4T6c=Xe*Jfh|U)tZPt8+27-^h>0Ux^~YqgWUBLoGC1u@DJrh5_!tRV(AwSp0CDD zWutNTO-I*RHINO_+lvD~XL`mo#JnfJ0@k$f?;gj=>gzXrF}+k?bC|2mDFI*Pva~To zE}BJG9X?O&p8RHG3AOS}k7|Be3SoCU7Ldo+B zYc4twr8vH)oKkg3*{reV zV#%F*U3HzyD42xNDLVEPA&2o#9}b!Ktd+T*T!SY!<{LDa}*g#|YEuBXmDdH$N!=?KOaF)OC)eD8qR_dH75WDrT6x)cmx zRnZ<0W#0F(+mgkO&T!ZVCio!1c}XdqefI=w`f1V&z9Q~vkgy}^X;5k7hY+fNYpWtu z#=)%Dro=2y^@ug&V8>TeRruOe4LK|coK!*iknaZEo7W{6F3x;V5}ZM(uzA>oQhH&R zM*d=|qt4}G2-~_Xj^_v#RZbX;oK9tk$%?+^Y?Ve)U28+i`jYRY<2t=Oq)9t9=_#=kUd%qJj?A?k4L^ zVY$H^=~1ATI(wOOkR$pYM{Q@*Y-7`mx!mi3(lCAfh)!HogJsk=hpr9WV`FE*J(jP- ztms2_qzA>HOtSLNA*kX1Yf@-9BrLsHAD7?I1_RGDzqIz5F^05CqU>@_cPxEXyh9%3 zPFth{rDzKg&LDxGdOVCAd!}wrR>UI}Ri+HWU=~Jbud1ZmUg2p%2$iR7;vQH8LUDCv zQI}0IGM$c|?%6mA4-^WLBgJ9FWpZN`B)iLSq2dP>)i;<>-BngZd7}fwmB(YN&?Yv! q^UIeaL{qaLc`)Q=k?P87%S+alls;k)ibVW7yU4#KG~Umz-u*vkK16u{ literal 103386 zcmeHQe{56b8t&;LL@8~#9kFETKlPa9?_A0a;#(=DhWfe{4Lg~OXFq(Y z<&mj5yc|S>SB)me~1PN~gd zjJhYeyw#B^-jgkzrS8ZoJKFdE*Qgyt3Vj-SICp5T^wynZ_hh3+)Uh*_Z7cca*cs{=u|d=Hko$dgUllu}!ow@o?^u+aZISPg z)899!7l*5euP$4sef^?kZNb{Movc^8{-?OB4)n>(540z$)UP^8pWLQHnVN~ckw?`X z(%W1TF1_*(+#1{(L=B>b#RH9gXkxCxTq7Y3K!%144aqZ-XJxrZFCDP1!IG1V0W3Lz z1^}p0AQS*Kz|bgk5AY`7O(4%eo>3G)y$1Cfl+s9n6;)1DIZ=QvK#@>@1~&k-4bV2g zr~%mt7#etJHc$jX5d?b^?9Dvo7sOg{p22wr4-Gst@X)|R0}l;6G#jK(ETm7(P^CdI z2*DsV2B77HmJ>2tD4?N$Cfa;O%lVfD>zZbI0RT@!4*@M(Ko5ax2Xvk2yn)UeXo`ZS zC~6xY=sM9#=&CUQT_<#%&~-xBiQZ@&IB95GhmL|AIBCGpfT00H%lB^uCk>o5aMHj@ z11AlfG;q=!;H2^3q@jsDn%L800Gu>%(tZ^uZGY|dOQ)aMzM!b1I{nc>=K<>pr+L7* zVNE<$yyK|07@ccv3sx-;`t6E~hv+}dl;_&W)hk2Tw^uRbD4H8DHp``5H6<4^>%ZfNdO6#`Qn|K% z52G1?3`AI8;$33np==iPO1j6z(agg9O0sr;FzYJw#&~t-p3T(9!n>u!nBGCkEKk{A z%b^e%`*fyziRxY<`dNP2(=#3=Lg-vN{%=0$SC87q(;GQ^*uZGpmsf^r=O_nDRDNEcnVYbKOp~_OYZaM=`qdpY>z*I<=L4hu(DC(SGZrRc?v1=r ziD$?(9igZP%usvJ70nSvx$rHT8B2*R_IBP7#o3+G9ZUw6dK`)9#@wwpyGy!iEk$eHwb%gBGDyFTPIq(9$P zV{*>xd@eiiqnhbAQkTsC!~F5x_II>F5qqBHk{S0m#p-0nps!IIobi4$82Edd+pIm@+sMy?9|`Q~Rmwylk+ z(iXMD772cRcs3@O;T?}Zqm8JDyny;z(L?3aJ1(GW*p2om~l9yYDm=-G#9B_ z&cD%$H4fG|SmOX3061`MBnsdFP&J@xK-GY%0geV74LJHbtmEAOS+8xT7XT^Ep{7Hs zmq^=?wjpgp+J>|ZX&cfuq;1z>+J;oETBTDWRYR(VR1K*bQZ=M%NY#+4AyorY8cbiqh@S&?*Y8qR?ZFv~r~b0hAk1Za}#KgW7Tr1Lp1hk%On9)>c5mNQ&YK0czX|3ORwsHp#ga&V*qHtt`F3#ilv_!K%P;r0fvSpCzhO8a;iwVt#$KNU>%m6SaM>? zi6tjWY0VB6$uqrr0NDuzXjD1%W(kE@Jt%^xaw2&~@{Hse$up8?B+mi|r2xoIViaU2 zqbA~!psz7a54nLn19{#Xc~mXI(8LAM(II_;U=Sh>&^CJQUm|&iQh;wp^89-fr~k`T z^WID^0L|Ne7C33(q=AzLP8v9AKn8#e02xr)_|Uir1RW4`K+sVV_d(F18Tz5DhO!!v zf!`Z405m{ra|DttNVXu^f@BMxz&OwVpaDPwY@$EKqp@&dn_RSa02%-^KjsG~al(Lv_{>j|fMz_?*eJXO5os9<0e zuD`V{ShYOpw=4E)qW>^co_F7{idANJIB+tNUazRc2#lLuaCtV_gus77fz`;Oe8Q)g zQBCETu`%+Mbc+vXd0-zog1RGN-(KzD@nW-F+Er6>A+!EFeyCS5c#~`E_b}?2RS!g1 zU*cWDFH|-QdL_M0@6pV{yc0<6{$SQs=8f^{&OMu{kA-(ji80;r!z@qPUt6q!ml^wX zrh7@w{Dh@VR6^&{KkvOVM>$xsvh@q)Vvz6hJY!#*)mxX-_A~4tJSgEo2@lE})q@hg zlW|_P;)3rad?%Tq_MR)6Mi9P}@STM3Bzz}tG~dahQ?9Rbz6_>%- z0%vPu3W0;balILxI;LC($1s(5wD$bqU81HVL>dN(0VD>H7*HAuNDLq`fW!b2gRiCL zL-U{WB}!R^JD8?f>F)6GXi&9bA(~{iji`_{jWz-YfrG$7;Gq8iv^fy9fhis5z?248 z4a@-)KvBm591S=caI~gnw=`3Fk*-C~a!vY9KzbTXXnxjXLmkI1wjgj2I0&3Rt)X+6 z0wO&_rs)Xfgn&8@>NxZaB5ZM-Lf{~9)bwJREcEC-V3$X_=SQSUt>w-cfqrtJ0E#*e z>Nu$5ppJ9h)N#T$O{NWon>N(ft!Pj>c7yN<-kQ!j08lWu8m)1Wwjpgp+IFL*ZJ8f0 zp5{8tTt{QJ>BtLw*DZ~b$+cP>DT^2PrG)5_yK|MJY(e|eYiiOjwkBJr0P20vt@pv*e(0>wjint<|OSVQs9%qB{S}CiZuh3YmJSju0^>Tt&c5z Z^4%{Q{=Rh883XyR{^3=1{SSFM{s$oSe3k$J diff --git a/packages/colorpicker/lib/colorpicker.dart b/packages/colorpicker/lib/colorpicker.dart index b3d6ede5..88950ae5 100644 --- a/packages/colorpicker/lib/colorpicker.dart +++ b/packages/colorpicker/lib/colorpicker.dart @@ -3,5 +3,5 @@ library colorpicker; export 'src/colorpicker.dart'; export 'src/constants/colors.dart'; export 'src/components/color_comparison.dart'; -export 'src/components/slider.dart'; -export 'src/components/slider_shape.dart'; +export 'src/components/opacity_slider.dart'; +export 'src/components/slider_indicator_shape.dart'; diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index 3a32bab1..d2853241 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -1,9 +1,9 @@ +import 'package:colorpicker/src/components/checkerboard_square.dart'; +import 'package:colorpicker/src/components/color_square.dart'; import 'package:colorpicker/src/constants/colors.dart'; import 'package:colorpicker/src/components/color_comparison.dart'; -import 'package:colorpicker/src/components/slider.dart'; -import 'package:colorpicker/src/state/color_state.dart'; -import 'package:colorpicker/src/state/slider_position_state.dart'; -import 'package:colorpicker/utils/assets.dart'; +import 'package:colorpicker/src/components/opacity_slider.dart'; +import 'package:colorpicker/src/state/color_picker_state_provider.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -21,92 +21,65 @@ class ColorPicker extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final widgetWidth = MediaQuery.of(context).size.width - 52.0; - final opacity = 1.0 - ref.watch(sliderPositionStateProvider) / widgetWidth; - final newColor = ref.watch(colorStateProvider); + final colorPickerStateData = ref.watch(colorPickerStateProvider); return Container( margin: const EdgeInsets.all(26.0), alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(16.0), ), - child: SingleChildScrollView( - child: Column( - children: [ - ColorComparison( - currentColor: currentColor, - newColor: newColor.withOpacity(opacity), - ), - const SizedBox( - height: 10.0, - ), - GridView.count( - childAspectRatio: 1.4, - crossAxisCount: 4, - crossAxisSpacing: 2.0, - mainAxisSpacing: 2.0, - shrinkWrap: true, - children: List.generate( - colors.length + 1, - (index) { - if (index == colors.length) { - return Container( - decoration: BoxDecoration( - image: DecorationImage( - image: PackageAssets.getCheckerboardImgAsset(), - fit: BoxFit.contain, - repeat: ImageRepeat.repeat, - ), - ), - ); - } - return GestureDetector( - onTap: () { - ref.read(colorStateProvider.notifier).updateColor( - colors[index].withOpacity(opacity), - ); - }, - child: Container( - decoration: BoxDecoration( - color: colors[index], - ), - ), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ColorComparison( + currentColor: currentColor, + newColor: colorPickerStateData.currentColor + .withOpacity(colorPickerStateData.currentOpacity), + ), + GridView.count( + childAspectRatio: 1.4, + crossAxisCount: 4, + crossAxisSpacing: 2.0, + mainAxisSpacing: 2.0, + shrinkWrap: true, + children: List.generate( + colors.length + 1, + (index) { + if (index == colors.length) { + return const CheckerboardSquare(); + } else { + return ColorSquare( + color: colors[index], + opacity: colorPickerStateData.currentOpacity, ); + } + }, + ), + ), + OpacitySlider( + gradientColor: colorPickerStateData.currentColor, + ), + Row( + children: [ + const Spacer(), + TextButton( + onPressed: () { + Navigator.pop(context); }, + child: const Text('CANCEL'), ), - ), - const SizedBox( - height: 30.0, - ), - OpacitySlider( - gradientColor: newColor, - ), - const SizedBox( - height: 20.0, - ), - Row( - children: [ - const Spacer(), - TextButton( - onPressed: () { - Navigator.pop(context); - }, - child: const Text('CANCEL'), - ), - const SizedBox( - width: 10.0, - ), - TextButton( - onPressed: () { - onColorChanged(newColor.withOpacity(opacity)); - Navigator.pop(context); - }, - child: const Text('APPLY'), - ), - ], - ) - ], - ), + const SizedBox(width: 10.0), + TextButton( + onPressed: () { + onColorChanged(colorPickerStateData.currentColor + .withOpacity(colorPickerStateData.currentOpacity)); + Navigator.pop(context); + }, + child: const Text('APPLY'), + ), + ], + ) + ], ), ); } diff --git a/packages/colorpicker/lib/src/components/checkerboard_square.dart b/packages/colorpicker/lib/src/components/checkerboard_square.dart new file mode 100644 index 00000000..0f23d44d --- /dev/null +++ b/packages/colorpicker/lib/src/components/checkerboard_square.dart @@ -0,0 +1,19 @@ +import 'package:colorpicker/utils/assets.dart'; +import 'package:flutter/material.dart'; + +class CheckerboardSquare extends StatelessWidget { + const CheckerboardSquare({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + image: DecorationImage( + image: PackageAssets.getCheckerboardImgAsset(), + fit: BoxFit.contain, + repeat: ImageRepeat.repeat, + ), + ), + ); + } +} diff --git a/packages/colorpicker/lib/src/components/color_comparison.dart b/packages/colorpicker/lib/src/components/color_comparison.dart index 4b72ccea..e7f33438 100644 --- a/packages/colorpicker/lib/src/components/color_comparison.dart +++ b/packages/colorpicker/lib/src/components/color_comparison.dart @@ -1,3 +1,4 @@ +import 'package:colorpicker/utils/assets.dart'; import 'package:flutter/material.dart'; class ColorComparison extends StatelessWidget { @@ -20,13 +21,13 @@ class ColorComparison extends StatelessWidget { Expanded( child: ColorDescription( color: currentColor, - desc: 'current', + description: 'current', ), ), Expanded( child: ColorDescription( color: newColor, - desc: 'new', + description: 'new', ), ), ], @@ -39,11 +40,11 @@ class ColorDescription extends StatelessWidget { const ColorDescription({ super.key, required this.color, - required this.desc, + required this.description, }); final Color color; - final String desc; + final String description; @override Widget build(BuildContext context) { @@ -51,12 +52,22 @@ class ColorDescription extends StatelessWidget { children: [ Expanded( child: Container( - color: color, + decoration: BoxDecoration( + image: DecorationImage( + image: PackageAssets.getCheckerboardImgAsset(), + repeat: ImageRepeat.repeat, + ), + ), + child: Container( + decoration: BoxDecoration( + color: color, + ), + ), ), ), const SizedBox(width: 8.0), Text( - desc, + description, style: const TextStyle(color: Color.fromARGB(255, 149, 149, 149)), ), ], diff --git a/packages/colorpicker/lib/src/components/color_square.dart b/packages/colorpicker/lib/src/components/color_square.dart new file mode 100644 index 00000000..8ef8bf95 --- /dev/null +++ b/packages/colorpicker/lib/src/components/color_square.dart @@ -0,0 +1,28 @@ +import 'package:colorpicker/src/state/color_picker_state_provider.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class ColorSquare extends ConsumerWidget { + const ColorSquare({ + super.key, + required this.color, + required this.opacity, + }); + + final Color color; + final double opacity; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return GestureDetector( + onTap: () { + ref.read(colorPickerStateProvider.notifier).updateColor(color); + }, + child: Container( + decoration: BoxDecoration( + color: color, + ), + ), + ); + } +} diff --git a/packages/colorpicker/lib/src/components/slider.dart b/packages/colorpicker/lib/src/components/opacity_slider.dart similarity index 73% rename from packages/colorpicker/lib/src/components/slider.dart rename to packages/colorpicker/lib/src/components/opacity_slider.dart index 48825d0c..27064f1b 100644 --- a/packages/colorpicker/lib/src/components/slider.dart +++ b/packages/colorpicker/lib/src/components/opacity_slider.dart @@ -1,5 +1,5 @@ -import 'package:colorpicker/src/components/slider_shape.dart'; -import 'package:colorpicker/src/state/slider_position_state.dart'; +import 'package:colorpicker/src/components/slider_indicator_shape.dart'; +import 'package:colorpicker/src/state/color_picker_state_provider.dart'; import 'package:colorpicker/utils/assets.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -14,11 +14,9 @@ class OpacitySlider extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final positon = ref.watch(sliderPositionStateProvider); - double widgetWidth = MediaQuery.of(context).size.width - 52.0; + final colorPickerStateData = ref.watch(colorPickerStateProvider); return Container( height: 25.0, - width: widgetWidth, decoration: BoxDecoration( image: DecorationImage( image: PackageAssets.getCheckerboardImgAsset(), @@ -49,12 +47,11 @@ class OpacitySlider extends ConsumerWidget { child: Slider( min: 0.0, max: 1.0, - value: positon / widgetWidth, - onChanged: (value) { - ref.read(sliderPositionStateProvider.notifier).updatePosition( - value * widgetWidth, - widgetWidth, - ); + value: 1.0 - colorPickerStateData.currentOpacity, + onChanged: (position) { + ref + .read(colorPickerStateProvider.notifier) + .updateOpacity(1.0 - position); }, ), ), diff --git a/packages/colorpicker/lib/src/components/slider_shape.dart b/packages/colorpicker/lib/src/components/slider_indicator_shape.dart similarity index 96% rename from packages/colorpicker/lib/src/components/slider_shape.dart rename to packages/colorpicker/lib/src/components/slider_indicator_shape.dart index 485b6557..4cf110be 100644 --- a/packages/colorpicker/lib/src/components/slider_shape.dart +++ b/packages/colorpicker/lib/src/components/slider_indicator_shape.dart @@ -5,7 +5,7 @@ class SliderIndicatorShape extends SliderComponentShape { @override Size getPreferredSize(bool isEnabled, bool isDiscrete) { - return const Size(5.0, 30.0); + return const Size(5.0, 26.0); } @override @@ -29,7 +29,7 @@ class SliderIndicatorShape extends SliderComponentShape { Rect.fromCenter( center: center, width: 5.0, - height: 28.0, + height: 26.0, ), Paint() ..color = const Color.fromARGB(255, 62, 62, 62) diff --git a/packages/colorpicker/lib/src/state/color_picker_state_data.dart b/packages/colorpicker/lib/src/state/color_picker_state_data.dart new file mode 100644 index 00000000..0410d1a9 --- /dev/null +++ b/packages/colorpicker/lib/src/state/color_picker_state_data.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'color_picker_state_data.freezed.dart'; + +@immutable +@freezed +class ColorPickerStateData with _$ColorPickerStateData { + const factory ColorPickerStateData({ + required Color currentColor, + required double currentOpacity, + }) = _ColorPickerStateData; +} diff --git a/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart b/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart new file mode 100644 index 00000000..c217e94e --- /dev/null +++ b/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart @@ -0,0 +1,155 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'color_picker_state_data.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + +/// @nodoc +mixin _$ColorPickerStateData { + Color get currentColor => throw _privateConstructorUsedError; + double get currentOpacity => throw _privateConstructorUsedError; + + @JsonKey(ignore: true) + $ColorPickerStateDataCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ColorPickerStateDataCopyWith<$Res> { + factory $ColorPickerStateDataCopyWith(ColorPickerStateData value, + $Res Function(ColorPickerStateData) then) = + _$ColorPickerStateDataCopyWithImpl<$Res, ColorPickerStateData>; + @useResult + $Res call({Color currentColor, double currentOpacity}); +} + +/// @nodoc +class _$ColorPickerStateDataCopyWithImpl<$Res, + $Val extends ColorPickerStateData> + implements $ColorPickerStateDataCopyWith<$Res> { + _$ColorPickerStateDataCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? currentColor = null, + Object? currentOpacity = null, + }) { + return _then(_value.copyWith( + currentColor: null == currentColor + ? _value.currentColor + : currentColor // ignore: cast_nullable_to_non_nullable + as Color, + currentOpacity: null == currentOpacity + ? _value.currentOpacity + : currentOpacity // ignore: cast_nullable_to_non_nullable + as double, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$_ColorPickerStateDataCopyWith<$Res> + implements $ColorPickerStateDataCopyWith<$Res> { + factory _$$_ColorPickerStateDataCopyWith(_$_ColorPickerStateData value, + $Res Function(_$_ColorPickerStateData) then) = + __$$_ColorPickerStateDataCopyWithImpl<$Res>; + @override + @useResult + $Res call({Color currentColor, double currentOpacity}); +} + +/// @nodoc +class __$$_ColorPickerStateDataCopyWithImpl<$Res> + extends _$ColorPickerStateDataCopyWithImpl<$Res, _$_ColorPickerStateData> + implements _$$_ColorPickerStateDataCopyWith<$Res> { + __$$_ColorPickerStateDataCopyWithImpl(_$_ColorPickerStateData _value, + $Res Function(_$_ColorPickerStateData) _then) + : super(_value, _then); + + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? currentColor = null, + Object? currentOpacity = null, + }) { + return _then(_$_ColorPickerStateData( + currentColor: null == currentColor + ? _value.currentColor + : currentColor // ignore: cast_nullable_to_non_nullable + as Color, + currentOpacity: null == currentOpacity + ? _value.currentOpacity + : currentOpacity // ignore: cast_nullable_to_non_nullable + as double, + )); + } +} + +/// @nodoc + +class _$_ColorPickerStateData implements _ColorPickerStateData { + const _$_ColorPickerStateData( + {required this.currentColor, required this.currentOpacity}); + + @override + final Color currentColor; + @override + final double currentOpacity; + + @override + String toString() { + return 'ColorPickerStateData(currentColor: $currentColor, currentOpacity: $currentOpacity)'; + } + + @override + bool operator ==(dynamic other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$_ColorPickerStateData && + (identical(other.currentColor, currentColor) || + other.currentColor == currentColor) && + (identical(other.currentOpacity, currentOpacity) || + other.currentOpacity == currentOpacity)); + } + + @override + int get hashCode => Object.hash(runtimeType, currentColor, currentOpacity); + + @JsonKey(ignore: true) + @override + @pragma('vm:prefer-inline') + _$$_ColorPickerStateDataCopyWith<_$_ColorPickerStateData> get copyWith => + __$$_ColorPickerStateDataCopyWithImpl<_$_ColorPickerStateData>( + this, _$identity); +} + +abstract class _ColorPickerStateData implements ColorPickerStateData { + const factory _ColorPickerStateData( + {required final Color currentColor, + required final double currentOpacity}) = _$_ColorPickerStateData; + + @override + Color get currentColor; + @override + double get currentOpacity; + @override + @JsonKey(ignore: true) + _$$_ColorPickerStateDataCopyWith<_$_ColorPickerStateData> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/packages/colorpicker/lib/src/state/color_picker_state_provider.dart b/packages/colorpicker/lib/src/state/color_picker_state_provider.dart new file mode 100644 index 00000000..32deda4f --- /dev/null +++ b/packages/colorpicker/lib/src/state/color_picker_state_provider.dart @@ -0,0 +1,27 @@ +import 'package:colorpicker/src/state/color_picker_state_data.dart'; +import 'package:flutter/material.dart'; +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +import 'package:colorpicker/src/constants/colors.dart'; + +part 'color_picker_state_provider.g.dart'; + +@riverpod +class ColorPickerState extends _$ColorPickerState { + final colors = DisplayColors.colors; + @override + ColorPickerStateData build() { + return ColorPickerStateData( + currentColor: colors[0], + currentOpacity: 1.0, + ); + } + + void updateColor(Color newColor) { + state = state.copyWith(currentColor: newColor); + } + + void updateOpacity(double newOpacity) { + state = state.copyWith(currentOpacity: newOpacity); + } +} diff --git a/packages/colorpicker/lib/src/state/slider_position_state.g.dart b/packages/colorpicker/lib/src/state/color_picker_state_provider.g.dart similarity index 50% rename from packages/colorpicker/lib/src/state/slider_position_state.g.dart rename to packages/colorpicker/lib/src/state/color_picker_state_provider.g.dart index 70a4c17b..522ae199 100644 --- a/packages/colorpicker/lib/src/state/slider_position_state.g.dart +++ b/packages/colorpicker/lib/src/state/color_picker_state_provider.g.dart @@ -1,27 +1,26 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'slider_position_state.dart'; +part of 'color_picker_state_provider.dart'; // ************************************************************************** // RiverpodGenerator // ************************************************************************** -String _$sliderPositionStateHash() => - r'bc845178b65cd978c5438bc92706fc9880e5dcf6'; +String _$colorPickerStateHash() => r'383e6e54ba4cd4c039beda38499e4fc4cf8deb74'; -/// See also [SliderPositionState]. -@ProviderFor(SliderPositionState) -final sliderPositionStateProvider = - AutoDisposeNotifierProvider.internal( - SliderPositionState.new, - name: r'sliderPositionStateProvider', +/// See also [ColorPickerState]. +@ProviderFor(ColorPickerState) +final colorPickerStateProvider = AutoDisposeNotifierProvider.internal( + ColorPickerState.new, + name: r'colorPickerStateProvider', debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') ? null - : _$sliderPositionStateHash, + : _$colorPickerStateHash, dependencies: null, allTransitiveDependencies: null, ); -typedef _$SliderPositionState = AutoDisposeNotifier; +typedef _$ColorPickerState = AutoDisposeNotifier; // ignore_for_file: type=lint // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/packages/colorpicker/lib/src/state/color_state.dart b/packages/colorpicker/lib/src/state/color_state.dart deleted file mode 100644 index 286557a5..00000000 --- a/packages/colorpicker/lib/src/state/color_state.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -import 'package:colorpicker/src/constants/colors.dart'; - -part 'color_state.g.dart'; - -@riverpod -class ColorState extends _$ColorState { - final colors = DisplayColors.colors; - @override - Color build() { - return colors[0]; - } - - void updateColor(Color newColor) { - state = newColor; - } -} diff --git a/packages/colorpicker/lib/src/state/color_state.g.dart b/packages/colorpicker/lib/src/state/color_state.g.dart deleted file mode 100644 index c486ed7b..00000000 --- a/packages/colorpicker/lib/src/state/color_state.g.dart +++ /dev/null @@ -1,25 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'color_state.dart'; - -// ************************************************************************** -// RiverpodGenerator -// ************************************************************************** - -String _$colorStateHash() => r'cfdfc3937c27a7d96c9b0f5b57e66a3697d1b5cd'; - -/// See also [ColorState]. -@ProviderFor(ColorState) -final colorStateProvider = - AutoDisposeNotifierProvider.internal( - ColorState.new, - name: r'colorStateProvider', - debugGetCreateSourceHash: - const bool.fromEnvironment('dart.vm.product') ? null : _$colorStateHash, - dependencies: null, - allTransitiveDependencies: null, -); - -typedef _$ColorState = AutoDisposeNotifier; -// ignore_for_file: type=lint -// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member diff --git a/packages/colorpicker/lib/src/state/slider_position_state.dart b/packages/colorpicker/lib/src/state/slider_position_state.dart deleted file mode 100644 index 06add667..00000000 --- a/packages/colorpicker/lib/src/state/slider_position_state.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:riverpod_annotation/riverpod_annotation.dart'; -part 'slider_position_state.g.dart'; - -@riverpod -class SliderPositionState extends _$SliderPositionState { - @override - double build() { - return 0.0; - } - - void updatePosition( - double position, - double widgetWidth, - ) { - if (position < 0.0) { - position = 0.0; - } - if (position > widgetWidth) { - position = widgetWidth; - } - state = position; - } -} diff --git a/packages/colorpicker/lib/utils/assets.dart b/packages/colorpicker/lib/utils/assets.dart index 3b43835b..ec419224 100644 --- a/packages/colorpicker/lib/utils/assets.dart +++ b/packages/colorpicker/lib/utils/assets.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; class PackageAssets { static ImageProvider getCheckerboardImgAsset() { - return const AssetImage('packages/colorpicker/assets/img/checkerboard.png'); + return const AssetImage( + 'packages/colorpicker/assets/img/checkerboard.png', + ); } } diff --git a/packages/colorpicker/pubspec.yaml b/packages/colorpicker/pubspec.yaml index 52d2201e..fa1b8386 100644 --- a/packages/colorpicker/pubspec.yaml +++ b/packages/colorpicker/pubspec.yaml @@ -13,6 +13,7 @@ dependencies: sdk: flutter flutter_riverpod: ^2.3.6 riverpod_annotation: ^2.1.1 + freezed_annotation: ^2.4.1 dev_dependencies: flutter_test: @@ -21,6 +22,7 @@ dev_dependencies: build_runner: ^2.2.0 riverpod_generator: ^2.2.3 riverpod_lint: ^1.3.2 + freezed: ^2.4.1 flutter: uses-material-design: true diff --git a/packages/colorpicker/test/unit/color_state_test.dart b/packages/colorpicker/test/unit/color_state_test.dart index fabe01f3..59eaa29a 100644 --- a/packages/colorpicker/test/unit/color_state_test.dart +++ b/packages/colorpicker/test/unit/color_state_test.dart @@ -1,4 +1,4 @@ -import 'package:colorpicker/src/state/color_state.dart'; +import 'package:colorpicker/src/state/color_picker_state_provider.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -15,8 +15,16 @@ void main() { }); test('updateColor updates the color correctly', () { - Color newColor = Colors.blue.shade50; - container.read(colorStateProvider.notifier).updateColor(newColor); - expect(container.read(colorStateProvider), newColor); + final state = container.read(colorPickerStateProvider.notifier); + const newColor = Colors.red; + state.updateColor(newColor); + expect(container.read(colorPickerStateProvider).currentColor, newColor); + }); + + test('updateOpacity updates the opacity correctly', () { + final state = container.read(colorPickerStateProvider.notifier); + const newOpacity = 0.5; + state.updateOpacity(newOpacity); + expect(container.read(colorPickerStateProvider).currentOpacity, newOpacity); }); } diff --git a/packages/colorpicker/test/unit/slider_state_test.dart b/packages/colorpicker/test/unit/slider_state_test.dart deleted file mode 100644 index 42ac3840..00000000 --- a/packages/colorpicker/test/unit/slider_state_test.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:colorpicker/src/state/slider_position_state.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - late ProviderContainer container; - - setUp(() { - container = ProviderContainer(); - }); - - tearDown(() { - container.dispose(); - }); - - test('updatePosition updates the position correctly', () { - double position = 30.0; - double widgetWidth = 100.0; - container.read(sliderPositionStateProvider.notifier).updatePosition( - position, - widgetWidth, - ); - expect(container.read(sliderPositionStateProvider), position); - }); -} diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart b/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart index 842d2e64..7b754afa 100644 --- a/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart +++ b/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart @@ -108,10 +108,12 @@ void _showColorPicker(BuildContext context, WidgetRef ref) { builder: (BuildContext context) => Container( height: MediaQuery.of(context).size.height * 0.7, alignment: Alignment.center, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(16), - ), + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(16.0), + topRight: Radius.circular(16.0), + )), child: ColorPicker( currentColor: ref.watch(brushToolStateProvider).paint.color, onColorChanged: (newColor) { diff --git a/pubspec.lock b/pubspec.lock index 7fc77ab1..c758aeac 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -197,10 +197,10 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.17.1" colorpicker: dependency: transitive description: @@ -652,10 +652,10 @@ packages: dependency: "direct main" description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.18.0" io: dependency: transitive description: @@ -737,18 +737,18 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.15" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.2.0" melos: dependency: "direct main" description: @@ -761,10 +761,10 @@ packages: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.9.1" mime: dependency: transitive description: @@ -952,10 +952,10 @@ packages: dependency: transitive description: name: platform - sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 + sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.0" plugin_platform_interface: dependency: transitive description: @@ -1189,10 +1189,10 @@ packages: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.9.1" sqflite: dependency: transitive description: @@ -1237,10 +1237,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.11.0" state_notifier: dependency: transitive description: @@ -1253,10 +1253,10 @@ packages: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" stream_transform: dependency: transitive description: @@ -1309,10 +1309,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.5.1" timing: dependency: transitive description: @@ -1444,10 +1444,10 @@ packages: dependency: transitive description: name: vm_service - sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583 + sha256: f6deed8ed625c52864792459709183da231ebf66ff0cf09e69b573227c377efe url: "https://pub.dev" source: hosted - version: "11.10.0" + version: "11.3.0" watcher: dependency: transitive description: @@ -1456,14 +1456,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" - web: - dependency: transitive - description: - name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 - url: "https://pub.dev" - source: hosted - version: "0.3.0" web_socket_channel: dependency: transitive description: @@ -1536,5 +1528,5 @@ packages: source: hosted version: "2.1.1" sdks: - dart: ">=3.2.0-194.0.dev <4.0.0" + dart: ">=3.0.5 <4.0.0" flutter: ">=3.10.0" From 749274afbd2fdd36edc9c9e7eb3e9a5f965713fa Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Mon, 11 Mar 2024 00:42:31 +0530 Subject: [PATCH 21/39] fix minor issues --- packages/colorpicker/lib/src/colorpicker.dart | 103 +++++++++--------- 1 file changed, 54 insertions(+), 49 deletions(-) diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index d2853241..9f7ebd56 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -28,58 +28,63 @@ class ColorPicker extends ConsumerWidget { decoration: BoxDecoration( borderRadius: BorderRadius.circular(16.0), ), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - ColorComparison( - currentColor: currentColor, - newColor: colorPickerStateData.currentColor - .withOpacity(colorPickerStateData.currentOpacity), - ), - GridView.count( - childAspectRatio: 1.4, - crossAxisCount: 4, - crossAxisSpacing: 2.0, - mainAxisSpacing: 2.0, - shrinkWrap: true, - children: List.generate( - colors.length + 1, - (index) { - if (index == colors.length) { - return const CheckerboardSquare(); - } else { - return ColorSquare( - color: colors[index], - opacity: colorPickerStateData.currentOpacity, - ); - } - }, + child: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ColorComparison( + currentColor: currentColor, + newColor: colorPickerStateData.currentColor + .withOpacity(colorPickerStateData.currentOpacity), ), - ), - OpacitySlider( - gradientColor: colorPickerStateData.currentColor, - ), - Row( - children: [ - const Spacer(), - TextButton( - onPressed: () { - Navigator.pop(context); + const SizedBox(height: 10.0), + GridView.count( + childAspectRatio: 1.4, + crossAxisCount: 4, + crossAxisSpacing: 2.0, + mainAxisSpacing: 2.0, + shrinkWrap: true, + children: List.generate( + colors.length + 1, + (index) { + if (index == colors.length) { + return const CheckerboardSquare(); + } else { + return ColorSquare( + color: colors[index], + opacity: colorPickerStateData.currentOpacity, + ); + } }, - child: const Text('CANCEL'), ), - const SizedBox(width: 10.0), - TextButton( - onPressed: () { - onColorChanged(colorPickerStateData.currentColor - .withOpacity(colorPickerStateData.currentOpacity)); - Navigator.pop(context); - }, - child: const Text('APPLY'), - ), - ], - ) - ], + ), + const SizedBox(height: 20.0), + OpacitySlider( + gradientColor: colorPickerStateData.currentColor, + ), + const SizedBox(height: 20.0), + Row( + children: [ + const Spacer(), + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Text('CANCEL'), + ), + const SizedBox(width: 10.0), + TextButton( + onPressed: () { + onColorChanged(colorPickerStateData.currentColor + .withOpacity(colorPickerStateData.currentOpacity)); + Navigator.pop(context); + }, + child: const Text('APPLY'), + ), + ], + ) + ], + ), ), ); } From e8a6e030a7d545ebd4fc72b6c70533aca772a6c6 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Mon, 11 Mar 2024 20:03:11 +0530 Subject: [PATCH 22/39] debug test error --- packages/colorpicker/lib/src/colorpicker.dart | 103 +++++++++--------- 1 file changed, 49 insertions(+), 54 deletions(-) diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index 9f7ebd56..d2853241 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -28,63 +28,58 @@ class ColorPicker extends ConsumerWidget { decoration: BoxDecoration( borderRadius: BorderRadius.circular(16.0), ), - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - ColorComparison( - currentColor: currentColor, - newColor: colorPickerStateData.currentColor - .withOpacity(colorPickerStateData.currentOpacity), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ColorComparison( + currentColor: currentColor, + newColor: colorPickerStateData.currentColor + .withOpacity(colorPickerStateData.currentOpacity), + ), + GridView.count( + childAspectRatio: 1.4, + crossAxisCount: 4, + crossAxisSpacing: 2.0, + mainAxisSpacing: 2.0, + shrinkWrap: true, + children: List.generate( + colors.length + 1, + (index) { + if (index == colors.length) { + return const CheckerboardSquare(); + } else { + return ColorSquare( + color: colors[index], + opacity: colorPickerStateData.currentOpacity, + ); + } + }, ), - const SizedBox(height: 10.0), - GridView.count( - childAspectRatio: 1.4, - crossAxisCount: 4, - crossAxisSpacing: 2.0, - mainAxisSpacing: 2.0, - shrinkWrap: true, - children: List.generate( - colors.length + 1, - (index) { - if (index == colors.length) { - return const CheckerboardSquare(); - } else { - return ColorSquare( - color: colors[index], - opacity: colorPickerStateData.currentOpacity, - ); - } + ), + OpacitySlider( + gradientColor: colorPickerStateData.currentColor, + ), + Row( + children: [ + const Spacer(), + TextButton( + onPressed: () { + Navigator.pop(context); }, + child: const Text('CANCEL'), ), - ), - const SizedBox(height: 20.0), - OpacitySlider( - gradientColor: colorPickerStateData.currentColor, - ), - const SizedBox(height: 20.0), - Row( - children: [ - const Spacer(), - TextButton( - onPressed: () { - Navigator.pop(context); - }, - child: const Text('CANCEL'), - ), - const SizedBox(width: 10.0), - TextButton( - onPressed: () { - onColorChanged(colorPickerStateData.currentColor - .withOpacity(colorPickerStateData.currentOpacity)); - Navigator.pop(context); - }, - child: const Text('APPLY'), - ), - ], - ) - ], - ), + const SizedBox(width: 10.0), + TextButton( + onPressed: () { + onColorChanged(colorPickerStateData.currentColor + .withOpacity(colorPickerStateData.currentOpacity)); + Navigator.pop(context); + }, + child: const Text('APPLY'), + ), + ], + ) + ], ), ); } From 06972ecfd4b71599f3f7237aae1731859a56b0b4 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Fri, 29 Mar 2024 22:10:04 +0530 Subject: [PATCH 23/39] Revert "debug test error" This reverts commit e8a6e030a7d545ebd4fc72b6c70533aca772a6c6. --- packages/colorpicker/lib/src/colorpicker.dart | 103 +++++++++--------- 1 file changed, 54 insertions(+), 49 deletions(-) diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index d2853241..9f7ebd56 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -28,58 +28,63 @@ class ColorPicker extends ConsumerWidget { decoration: BoxDecoration( borderRadius: BorderRadius.circular(16.0), ), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - ColorComparison( - currentColor: currentColor, - newColor: colorPickerStateData.currentColor - .withOpacity(colorPickerStateData.currentOpacity), - ), - GridView.count( - childAspectRatio: 1.4, - crossAxisCount: 4, - crossAxisSpacing: 2.0, - mainAxisSpacing: 2.0, - shrinkWrap: true, - children: List.generate( - colors.length + 1, - (index) { - if (index == colors.length) { - return const CheckerboardSquare(); - } else { - return ColorSquare( - color: colors[index], - opacity: colorPickerStateData.currentOpacity, - ); - } - }, + child: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ColorComparison( + currentColor: currentColor, + newColor: colorPickerStateData.currentColor + .withOpacity(colorPickerStateData.currentOpacity), ), - ), - OpacitySlider( - gradientColor: colorPickerStateData.currentColor, - ), - Row( - children: [ - const Spacer(), - TextButton( - onPressed: () { - Navigator.pop(context); + const SizedBox(height: 10.0), + GridView.count( + childAspectRatio: 1.4, + crossAxisCount: 4, + crossAxisSpacing: 2.0, + mainAxisSpacing: 2.0, + shrinkWrap: true, + children: List.generate( + colors.length + 1, + (index) { + if (index == colors.length) { + return const CheckerboardSquare(); + } else { + return ColorSquare( + color: colors[index], + opacity: colorPickerStateData.currentOpacity, + ); + } }, - child: const Text('CANCEL'), ), - const SizedBox(width: 10.0), - TextButton( - onPressed: () { - onColorChanged(colorPickerStateData.currentColor - .withOpacity(colorPickerStateData.currentOpacity)); - Navigator.pop(context); - }, - child: const Text('APPLY'), - ), - ], - ) - ], + ), + const SizedBox(height: 20.0), + OpacitySlider( + gradientColor: colorPickerStateData.currentColor, + ), + const SizedBox(height: 20.0), + Row( + children: [ + const Spacer(), + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Text('CANCEL'), + ), + const SizedBox(width: 10.0), + TextButton( + onPressed: () { + onColorChanged(colorPickerStateData.currentColor + .withOpacity(colorPickerStateData.currentOpacity)); + Navigator.pop(context); + }, + child: const Text('APPLY'), + ), + ], + ) + ], + ), ), ); } From f17b9fd98a43c9b160520330d22a199fc9f27b2f Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Mon, 11 Mar 2024 20:03:11 +0530 Subject: [PATCH 24/39] debug test error --- packages/colorpicker/lib/src/colorpicker.dart | 103 +++++++++--------- 1 file changed, 49 insertions(+), 54 deletions(-) diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index 9f7ebd56..d2853241 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -28,63 +28,58 @@ class ColorPicker extends ConsumerWidget { decoration: BoxDecoration( borderRadius: BorderRadius.circular(16.0), ), - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - ColorComparison( - currentColor: currentColor, - newColor: colorPickerStateData.currentColor - .withOpacity(colorPickerStateData.currentOpacity), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ColorComparison( + currentColor: currentColor, + newColor: colorPickerStateData.currentColor + .withOpacity(colorPickerStateData.currentOpacity), + ), + GridView.count( + childAspectRatio: 1.4, + crossAxisCount: 4, + crossAxisSpacing: 2.0, + mainAxisSpacing: 2.0, + shrinkWrap: true, + children: List.generate( + colors.length + 1, + (index) { + if (index == colors.length) { + return const CheckerboardSquare(); + } else { + return ColorSquare( + color: colors[index], + opacity: colorPickerStateData.currentOpacity, + ); + } + }, ), - const SizedBox(height: 10.0), - GridView.count( - childAspectRatio: 1.4, - crossAxisCount: 4, - crossAxisSpacing: 2.0, - mainAxisSpacing: 2.0, - shrinkWrap: true, - children: List.generate( - colors.length + 1, - (index) { - if (index == colors.length) { - return const CheckerboardSquare(); - } else { - return ColorSquare( - color: colors[index], - opacity: colorPickerStateData.currentOpacity, - ); - } + ), + OpacitySlider( + gradientColor: colorPickerStateData.currentColor, + ), + Row( + children: [ + const Spacer(), + TextButton( + onPressed: () { + Navigator.pop(context); }, + child: const Text('CANCEL'), ), - ), - const SizedBox(height: 20.0), - OpacitySlider( - gradientColor: colorPickerStateData.currentColor, - ), - const SizedBox(height: 20.0), - Row( - children: [ - const Spacer(), - TextButton( - onPressed: () { - Navigator.pop(context); - }, - child: const Text('CANCEL'), - ), - const SizedBox(width: 10.0), - TextButton( - onPressed: () { - onColorChanged(colorPickerStateData.currentColor - .withOpacity(colorPickerStateData.currentOpacity)); - Navigator.pop(context); - }, - child: const Text('APPLY'), - ), - ], - ) - ], - ), + const SizedBox(width: 10.0), + TextButton( + onPressed: () { + onColorChanged(colorPickerStateData.currentColor + .withOpacity(colorPickerStateData.currentOpacity)); + Navigator.pop(context); + }, + child: const Text('APPLY'), + ), + ], + ) + ], ), ); } From 9b1ba2ec8669cb140d1df3bc059e9f2e570d7f18 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Sat, 6 Apr 2024 21:17:37 +0530 Subject: [PATCH 25/39] fix test error --- packages/colorpicker/lib/src/colorpicker.dart | 103 +++++++++--------- pubspec.lock | 54 +++++---- 2 files changed, 85 insertions(+), 72 deletions(-) diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index d2853241..9f7ebd56 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -28,58 +28,63 @@ class ColorPicker extends ConsumerWidget { decoration: BoxDecoration( borderRadius: BorderRadius.circular(16.0), ), - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - ColorComparison( - currentColor: currentColor, - newColor: colorPickerStateData.currentColor - .withOpacity(colorPickerStateData.currentOpacity), - ), - GridView.count( - childAspectRatio: 1.4, - crossAxisCount: 4, - crossAxisSpacing: 2.0, - mainAxisSpacing: 2.0, - shrinkWrap: true, - children: List.generate( - colors.length + 1, - (index) { - if (index == colors.length) { - return const CheckerboardSquare(); - } else { - return ColorSquare( - color: colors[index], - opacity: colorPickerStateData.currentOpacity, - ); - } - }, + child: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + ColorComparison( + currentColor: currentColor, + newColor: colorPickerStateData.currentColor + .withOpacity(colorPickerStateData.currentOpacity), ), - ), - OpacitySlider( - gradientColor: colorPickerStateData.currentColor, - ), - Row( - children: [ - const Spacer(), - TextButton( - onPressed: () { - Navigator.pop(context); + const SizedBox(height: 10.0), + GridView.count( + childAspectRatio: 1.4, + crossAxisCount: 4, + crossAxisSpacing: 2.0, + mainAxisSpacing: 2.0, + shrinkWrap: true, + children: List.generate( + colors.length + 1, + (index) { + if (index == colors.length) { + return const CheckerboardSquare(); + } else { + return ColorSquare( + color: colors[index], + opacity: colorPickerStateData.currentOpacity, + ); + } }, - child: const Text('CANCEL'), ), - const SizedBox(width: 10.0), - TextButton( - onPressed: () { - onColorChanged(colorPickerStateData.currentColor - .withOpacity(colorPickerStateData.currentOpacity)); - Navigator.pop(context); - }, - child: const Text('APPLY'), - ), - ], - ) - ], + ), + const SizedBox(height: 20.0), + OpacitySlider( + gradientColor: colorPickerStateData.currentColor, + ), + const SizedBox(height: 20.0), + Row( + children: [ + const Spacer(), + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Text('CANCEL'), + ), + const SizedBox(width: 10.0), + TextButton( + onPressed: () { + onColorChanged(colorPickerStateData.currentColor + .withOpacity(colorPickerStateData.currentOpacity)); + Navigator.pop(context); + }, + child: const Text('APPLY'), + ), + ], + ) + ], + ), ), ); } diff --git a/pubspec.lock b/pubspec.lock index c758aeac..7fc77ab1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -197,10 +197,10 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.18.0" colorpicker: dependency: transitive description: @@ -652,10 +652,10 @@ packages: dependency: "direct main" description: name: intl - sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6 + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" url: "https://pub.dev" source: hosted - version: "0.18.0" + version: "0.18.1" io: dependency: transitive description: @@ -737,18 +737,18 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.5.0" melos: dependency: "direct main" description: @@ -761,10 +761,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" mime: dependency: transitive description: @@ -952,10 +952,10 @@ packages: dependency: transitive description: name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.2" plugin_platform_interface: dependency: transitive description: @@ -1189,10 +1189,10 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" sqflite: dependency: transitive description: @@ -1237,10 +1237,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" state_notifier: dependency: transitive description: @@ -1253,10 +1253,10 @@ packages: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" stream_transform: dependency: transitive description: @@ -1309,10 +1309,10 @@ packages: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.6.1" timing: dependency: transitive description: @@ -1444,10 +1444,10 @@ packages: dependency: transitive description: name: vm_service - sha256: f6deed8ed625c52864792459709183da231ebf66ff0cf09e69b573227c377efe + sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583 url: "https://pub.dev" source: hosted - version: "11.3.0" + version: "11.10.0" watcher: dependency: transitive description: @@ -1456,6 +1456,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + url: "https://pub.dev" + source: hosted + version: "0.3.0" web_socket_channel: dependency: transitive description: @@ -1528,5 +1536,5 @@ packages: source: hosted version: "2.1.1" sdks: - dart: ">=3.0.5 <4.0.0" + dart: ">=3.2.0-194.0.dev <4.0.0" flutter: ">=3.10.0" From 48bd9deb193aaeed09e2d39616a13eb890e01218 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Sat, 18 May 2024 17:31:48 +0530 Subject: [PATCH 26/39] resolve conflicts --- .fvmrc | 3 + .github/pull_request_template.md | 9 +- .github/workflows/main.yml | 29 +- .github/workflows/update_app_identifiers.sh | 60 +++ .gitignore | 5 +- Makefile | 68 ++- README.md | 8 +- analysis_options.yaml | 2 +- android/app/build.gradle | 20 +- android/build.gradle | 13 - android/settings.gradle | 30 +- .../assets => assets}/img/checkerboard.png | Bin .../img/pocketpaint_intro_landscape.png | Bin .../img/pocketpaint_intro_portrait.png | Bin .../img/pocketpaint_logo_small.png | Bin .../lang}/app_translations_en.arb | 0 .../assets => assets}/svg/ic_brush.svg | 0 .../assets => assets}/svg/ic_clipboard.svg | 0 .../assets => assets}/svg/ic_clipping.svg | 0 .../assets => assets}/svg/ic_cursor.svg | 0 .../assets => assets}/svg/ic_edit_circle.svg | 0 .../assets => assets}/svg/ic_eraser.svg | 0 .../assets => assets}/svg/ic_fill.svg | 0 .../assets => assets}/svg/ic_hand.svg | 0 .../assets => assets}/svg/ic_import.svg | 0 .../assets => assets}/svg/ic_layers.svg | 0 .../assets => assets}/svg/ic_line.svg | 0 .../assets => assets}/svg/ic_pipette.svg | 0 .../assets => assets}/svg/ic_shapes.svg | 0 .../assets => assets}/svg/ic_smudge.svg | 0 .../assets => assets}/svg/ic_spray_can.svg | 0 .../assets => assets}/svg/ic_stamp.svg | 0 .../assets => assets}/svg/ic_text.svg | 0 .../assets => assets}/svg/ic_tools.svg | 0 .../assets => assets}/svg/ic_transform.svg | 0 .../assets => assets}/svg/ic_watercolor.svg | 0 ios/Flutter/AppFrameworkInfo.plist | 2 +- ios/Podfile | 2 +- ios/Podfile.lock | 25 +- ios/Runner.xcodeproj/project.pbxproj | 8 +- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- lib/app.dart | 77 +++ .../command_factory/command_factory.dart | 14 + .../command_factory_provider.dart | 7 +- .../command_factory_provider.g.dart | 2 +- .../command_implementation/command.dart | 7 +- .../graphic/draw_path_command.dart | 16 +- .../graphic/draw_path_command.g.dart | 2 +- .../graphic/graphic_command.dart | 15 + .../command_manager/command_manager.dart | 5 +- .../command_manager_provider.dart | 8 +- .../command_manager_provider.g.dart | 2 +- .../command_manager/sync_command_manager.dart | 6 +- .../core/commands}/command_painter.dart | 5 +- .../graphic_factory/graphic_factory.dart | 4 +- .../graphic_factory_provider.dart | 7 +- .../graphic_factory_provider.g.dart | 2 +- .../commands}/path_with_action_history.dart | 20 +- .../core/database}/project_dao.dart | 5 +- .../core/database}/project_database.dart | 13 +- .../core/database}/project_database.g.dart | 0 .../src => lib/core}/enums/image_format.dart | 0 .../core}/enums/image_location.dart | 0 .../src => lib/core}/enums/tool_types.dart | 0 .../converter/paint_converter.dart | 6 +- .../converter/path_action_converter.dart | 11 +- .../path_with_action_history_converter.dart | 7 +- .../versioning/serializer_version.dart | 0 .../versioning/version_strategy.dart | 5 +- .../core/localization}/app_localizations.dart | 7 +- .../localization}/app_localizations_en.dart | 6 +- .../core}/models/catrobat_image.dart | 11 +- .../core}/models/catrobat_image.g.dart | 6 +- .../core/models/database}/project.dart | 1 + .../core}/models/image_from_file.dart | 4 +- .../core}/models/image_meta_data.dart | 3 +- .../core}/models/image_with_pixel_info.dart | 2 + .../core}/models/loggable_mixin.dart | 1 + .../object/canvas_dirty_notifier.dart | 7 +- .../providers/object}/device_service.dart | 4 + .../core/providers/object}/file_service.dart | 10 +- .../core/providers/object}/image_service.dart | 11 +- .../core/providers/object}/io_handler.dart | 40 +- .../object}/load_image_from_file_manager.dart | 14 +- .../load_image_from_photo_library.dart | 10 +- .../providers/object}/permission_service.dart | 6 +- .../object}/photo_library_service.dart | 10 +- .../object}/render_image_for_export.dart | 14 +- .../object}/save_as_catrobat_image.dart | 12 +- .../object}/save_as_raster_image.dart | 11 +- .../object/tools/brush_tool_provider.dart | 23 + .../object/tools}/brush_tool_provider.g.dart | 4 +- .../object/tools/eraser_tool_provider.dart | 21 + .../object/tools}/eraser_tool_provider.g.dart | 4 +- .../object/tools/hand_tool_provider.dart | 21 + .../object/tools}/hand_tool_provider.g.dart | 4 +- .../providers/state}/canvas_state_data.dart | 9 +- .../state}/canvas_state_data.freezed.dart | 39 +- .../state}/canvas_state_provider.dart | 15 +- .../state}/canvas_state_provider.g.dart | 2 +- ...ool_options_visibility_state_provider.dart | 1 + ...l_options_visibility_state_provider.g.dart | 2 +- .../tools/brush}/brush_tool_state_data.dart | 3 + .../brush}/brush_tool_state_data.freezed.dart | 38 +- .../brush}/brush_tool_state_provider.dart | 9 +- .../brush}/brush_tool_state_provider.g.dart | 2 +- .../tools}/toolbox/toolbox_state_data.dart | 6 +- .../toolbox/toolbox_state_data.freezed.dart | 39 +- .../toolbox/toolbox_state_provider.dart | 12 +- .../toolbox/toolbox_state_provider.g.dart | 2 +- .../providers/state}/workspace_state.dart | 11 +- .../state/workspace_state_notifier.dart | 48 ++ .../tools/implementation}/brush_tool.dart | 22 +- .../tools/implementation/eraser_tool.dart | 15 + .../core/tools/implementation}/hand_tool.dart | 15 +- .../lib/src => lib/core/tools}/tool.dart | 8 +- .../lib/src => lib/core/tools}/tool_data.dart | 5 +- .../core}/utils/date_time_converter.dart | 1 + .../models => lib/core/utils}/failure.dart | 0 .../core/utils}/load_image_failure.dart | 3 +- .../lib/src => lib/core}/utils/open_url.dart | 1 + .../core/utils}/save_image_failure.dart | 3 +- lib/main.dart | 11 +- lib/pocket_paint_app.dart | 66 --- .../components/custom_action_button.dart | 12 +- .../components/image_preview.dart | 13 +- .../components/main_overflow_menu.dart | 23 +- .../components/project_list_tile.dart | 12 +- .../components/project_overflow_menu.dart | 31 +- .../ui/pages/landing_page}/landing_page.dart | 61 ++- .../components/bottom_nav_bar_container.dart | 13 +- .../components/onboarding_page_app_bar.dart | 4 +- .../onboarding_page_bottom_nav_bar.dart | 16 +- .../onboarding_page/onboarding_page.dart | 36 +- .../onboarding_page}/screens/screen1.dart | 19 +- .../onboarding_page}/screens/screen2.dart | 72 ++- .../onboarding_page}/screens/screen3.dart | 109 ++-- .../onboarding_page}/screens/screen4.dart | 18 +- .../onboarding_page}/screens/screen5.dart | 18 +- .../components/bottom_bar/bottom_nav_bar.dart | 57 +- .../bottom_bar/bottom_nav_bar_items.dart | 0 .../tool_options/stroke_cap_tool_option.dart | 20 +- .../tool_options/stroke_tool_options.dart | 8 +- .../stroke_width_tool_option.dart | 13 +- .../bottom_bar/tool_options/tool_option.dart | 5 +- .../bottom_bar/tool_options/tool_options.dart | 12 +- .../bottom_bar/tools/tool_button.dart | 51 ++ .../bottom_bar/tools/tools_bottom_sheet.dart | 17 +- .../drawing_surface/canvas_painter.dart | 14 +- .../drawing_surface/checkerboard_pattern.dart | 9 +- .../drawing_surface/drawing_canvas.dart | 20 +- .../exit_fullscreen_button.dart | 16 +- .../components/top_bar/overflow_menu.dart | 25 +- .../components/top_bar/top_app_bar.dart | 10 +- .../pages/workspace_page/workspace_page.dart | 90 ++++ lib/ui/shared/bottom_nav_bar_icon.dart | 22 + .../ui/shared}/custom_action_chip.dart | 1 + .../ui/shared/dialogs}/about_dialog.dart | 26 +- .../dialogs}/delete_project_dialog.dart | 7 +- .../dialogs}/discard_changes_dialog.dart | 7 +- .../ui/shared/dialogs}/generic_dialog.dart | 32 +- .../ui/shared/dialogs}/load_image_dialog.dart | 7 +- .../ui/shared/dialogs}/overwrite_dialog.dart | 5 +- .../dialogs}/project_details_dialog.dart | 21 +- .../ui/shared/dialogs}/save_image_dialog.dart | 67 ++- .../ui/shared}/icon_button_with_label.dart | 13 +- .../ui/shared}/icon_svg.dart | 9 +- .../ui/shared}/image_format_info.dart | 20 +- lib/ui/shared/images/checkerboard.dart | 19 + .../images/pocketpaint_intro_landscape.dart | 16 + .../images/pocketpaint_intro_portrait.dart | 16 + .../shared/images/pocketpaint_logo_small.dart | 15 + .../ui/shared}/loading_overlay.dart | 14 +- .../ui/shared}/pop_menu_button.dart | 15 +- lib/ui/theme/data/custom_colors.dart | 54 ++ .../theme/data/dark_paintroid_theme_data.dart | 134 +++++ lib/ui/theme/data/font_size.dart | 9 + .../data/light_paintroid_theme_data.dart | 159 ++++++ lib/ui/theme/data/paintroid_theme.dart | 35 ++ lib/ui/theme/data/paintroid_theme_data.dart | 150 ++++++ lib/ui/theme/data/spacing.dart | 10 + .../state/theme_mode_state_provider.dart | 58 +++ .../state/theme_mode_state_provider.g.dart | 26 + lib/ui/theme/theme.dart | 10 + .../lib/src => lib/ui}/utils/toast_utils.dart | 1 + packages/command/.metadata | 10 - packages/command/analysis_options.yaml | 23 - packages/command/lib/command.dart | 10 - packages/command/lib/command_providers.dart | 5 - .../src/command_factory/command_factory.dart | 11 - .../graphic/graphic_command.dart | 13 - packages/command/pubspec.yaml | 42 -- packages/component_library/.metadata | 10 - .../component_library/analysis_options.yaml | 23 - .../lib/component_library.dart | 13 - .../src/components/bottom_nav_bar_icon.dart | 18 - .../lib/src/components/imgs.dart | 59 --- .../lib/src/theme/color_schemes.dart | 33 -- .../lib/src/theme/styles.dart | 33 -- packages/component_library/pubspec.yaml | 43 -- packages/database/.metadata | 10 - packages/database/analysis_options.yaml | 24 - packages/database/lib/database.dart | 8 - packages/database/pubspec.yaml | 35 -- .../features/landing_page_screen/.metadata | 10 - .../landing_page_screen/analysis_options.yaml | 23 - .../lib/landing_page_screen.dart | 9 - .../features/landing_page_screen/pubspec.yaml | 55 -- packages/features/onboarding_screen/.metadata | 10 - .../onboarding_screen/analysis_options.yaml | 23 - .../lib/onboarding_screen.dart | 13 - .../features/onboarding_screen/pubspec.yaml | 46 -- packages/features/workspace_screen/.metadata | 10 - .../workspace_screen/analysis_options.yaml | 23 - .../bottom_bar/tools/tool_button.dart | 34 -- .../src/states/workspace_state_notifier.dart | 30 -- .../lib/src/workspace_screen.dart | 80 --- .../lib/workspace_screen.dart | 27 - .../features/workspace_screen/pubspec.yaml | 57 -- packages/io_library/.metadata | 10 - packages/io_library/analysis_options.yaml | 23 - packages/io_library/lib/io_library.dart | 34 -- packages/io_library/pubspec.yaml | 59 --- .../io_library/test/fixture/image/test.jpg | Bin 1731 -> 0 bytes .../io_library/test/fixture/image/test.png | Bin 1272 -> 0 bytes .../io_library/test/fixture/image/test1.png | Bin 1272 -> 0 bytes packages/l10n/.metadata | 10 - packages/l10n/analysis_options.yaml | 25 - packages/l10n/l10n.yaml | 6 - packages/l10n/lib/l10n.dart | 4 - packages/l10n/pubspec.yaml | 26 - packages/tools/.metadata | 10 - packages/tools/analysis_options.yaml | 23 - .../src/brush_tool/brush_tool_provider.dart | 16 - .../src/eraser_tool/eraser_tool_provider.dart | 16 - .../lib/src/hand_tool/hand_tool_provider.dart | 15 - packages/tools/lib/tools.dart | 19 - packages/tools/pubspec.yaml | 45 -- pubspec.lock | 485 +++++++---------- pubspec.yaml | 56 +- .../image => test/assets/images}/test.jpg | Bin .../image => test/assets/images}/test.png | Bin .../image => test/assets/images}/test1.png | Bin .../unit/command}/command_factory_test.dart | 8 +- .../unit/command}/draw_path_command_test.dart | 10 +- .../draw_path_command_test.mocks.dart | 9 +- .../unit/database}/project_database_test.dart | 7 +- .../unit/provider}/file_service_test.dart | 12 +- .../unit/provider}/image_service_test.dart | 13 +- .../load_image_from_photo_library_test.dart | 9 +- ...d_image_from_photo_library_test.mocks.dart | 74 +-- .../provider}/photo_library_service_test.dart | 9 +- .../photo_library_service_test.mocks.dart | 57 +- .../provider}/save_as_raster_image_test.dart | 12 +- .../save_as_raster_image_test.mocks.dart | 124 +++-- .../draw_path_command_serializer_test.dart | 11 +- .../converter/paint_converter_test.dart | 7 +- .../converter/path_action_converter_test.dart | 7 +- ...th_with_action_history_converter_test.dart | 6 +- .../image/catrobat_image_serializer_test.dart | 9 +- .../utils/dummy_command_factory.dart | 11 +- .../utils/dummy_paint_factory.dart | 5 +- .../utils/dummy_path_factory.dart | 3 +- .../utils/dummy_version_strategy.dart | 4 +- .../unit/tools}/brush_tool_state_test.dart | 9 +- .../unit/tools}/brush_tool_test.dart | 73 ++- .../unit/tools}/brush_tool_test.mocks.dart | 203 +++++--- test/unit/tools/eraser_tool_test.dart | 44 ++ test/unit/tools/eraser_tool_test.mocks.dart | 488 ++++++++++++++++++ .../unit/tools}/hand_tool_test.dart | 14 +- .../unit/tools}/hand_tool_test.mocks.dart | 40 +- .../render_image_for_export_test.dart | 15 +- .../render_image_for_export_test.mocks.dart | 27 +- .../landing_page}/landing_page_test.dart | 93 +++- .../landing_page_test.mocks.dart | 166 +++--- .../onboarding_page/onboarding_page_test.dart | 33 +- .../bottom_control_navigation_bar_test.dart | 36 +- .../bottom_nav_bar_interactions.dart | 42 +- .../workspace_page}/canvas_interactions.dart | 8 +- .../workspace_page}/eraser_tool_test.dart | 35 +- .../workspace_page}/hand_tool_test.dart | 33 +- .../interactive_viewer_interactions.dart | 3 + .../workspace_page/workspace_page_test.dart | 67 ++- 283 files changed, 3958 insertions(+), 2622 deletions(-) create mode 100644 .fvmrc create mode 100644 .github/workflows/update_app_identifiers.sh rename {packages/component_library/assets => assets}/img/checkerboard.png (100%) rename {packages/component_library/assets => assets}/img/pocketpaint_intro_landscape.png (100%) rename {packages/component_library/assets => assets}/img/pocketpaint_intro_portrait.png (100%) rename {packages/component_library/assets => assets}/img/pocketpaint_logo_small.png (100%) rename {packages/l10n/lib/src/l10n => assets/lang}/app_translations_en.arb (100%) rename {packages/component_library/assets => assets}/svg/ic_brush.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_clipboard.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_clipping.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_cursor.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_edit_circle.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_eraser.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_fill.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_hand.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_import.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_layers.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_line.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_pipette.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_shapes.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_smudge.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_spray_can.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_stamp.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_text.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_tools.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_transform.svg (100%) rename {packages/component_library/assets => assets}/svg/ic_watercolor.svg (100%) create mode 100644 lib/app.dart create mode 100644 lib/core/commands/command_factory/command_factory.dart rename {packages/command/lib/src => lib/core/commands}/command_factory/command_factory_provider.dart (61%) rename {packages/command/lib/src => lib/core/commands}/command_factory/command_factory_provider.g.dart (93%) rename {packages/command/lib/src => lib/core/commands}/command_implementation/command.dart (65%) rename {packages/command/lib/src => lib/core/commands}/command_implementation/graphic/draw_path_command.dart (65%) rename {packages/command/lib/src => lib/core/commands}/command_implementation/graphic/draw_path_command.g.dart (94%) create mode 100644 lib/core/commands/command_implementation/graphic/graphic_command.dart rename {packages/command/lib/src => lib/core/commands}/command_manager/command_manager.dart (61%) rename {packages/command/lib/src => lib/core/commands}/command_manager/command_manager_provider.dart (50%) rename {packages/command/lib/src => lib/core/commands}/command_manager/command_manager_provider.g.dart (93%) rename {packages/command/lib/src => lib/core/commands}/command_manager/sync_command_manager.dart (78%) rename {packages/features/workspace_screen/lib/src/components/drawing_surface => lib/core/commands}/command_painter.dart (77%) rename {packages/command/lib => lib/core/commands}/graphic_factory/graphic_factory.dart (89%) rename {packages/command/lib => lib/core/commands}/graphic_factory/graphic_factory_provider.dart (61%) rename {packages/command/lib => lib/core/commands}/graphic_factory/graphic_factory_provider.g.dart (93%) rename {packages/command/lib/utils => lib/core/commands}/path_with_action_history.dart (81%) rename {packages/database/lib/src => lib/core/database}/project_dao.dart (86%) rename {packages/database/lib/src => lib/core/database}/project_database.dart (63%) rename {packages/database/lib/src => lib/core/database}/project_database.g.dart (100%) rename {packages/io_library/lib/src => lib/core}/enums/image_format.dart (100%) rename {packages/io_library/lib/src => lib/core}/enums/image_location.dart (100%) rename {packages/tools/lib/src => lib/core}/enums/tool_types.dart (100%) rename {packages/io_library/lib/src => lib/core}/json_serialization/converter/paint_converter.dart (92%) rename {packages/io_library/lib/src => lib/core}/json_serialization/converter/path_action_converter.dart (81%) rename {packages/io_library/lib/src => lib/core}/json_serialization/converter/path_with_action_history_converter.dart (84%) rename {packages/io_library/lib/src => lib/core}/json_serialization/versioning/serializer_version.dart (100%) rename {packages/io_library/lib/src => lib/core}/json_serialization/versioning/version_strategy.dart (82%) rename {packages/l10n/lib/src/l10n => lib/core/localization}/app_localizations.dart (97%) rename {packages/l10n/lib/src/l10n => lib/core/localization}/app_localizations_en.dart (78%) rename {packages/io_library/lib/src => lib/core}/models/catrobat_image.dart (80%) rename {packages/io_library/lib/src => lib/core}/models/catrobat_image.g.dart (87%) rename {packages/database/lib/src/models => lib/core/models/database}/project.dart (96%) rename {packages/io_library/lib/src => lib/core}/models/image_from_file.dart (79%) rename {packages/io_library/lib/src => lib/core}/models/image_meta_data.dart (90%) rename {packages/features/workspace_screen/lib/src => lib/core}/models/image_with_pixel_info.dart (97%) rename {packages/io_library/lib/src => lib/core}/models/loggable_mixin.dart (85%) rename packages/features/workspace_screen/lib/src/states/canvas_dirty_state.dart => lib/core/providers/object/canvas_dirty_notifier.dart (60%) rename {packages/features/workspace_screen/lib/src/service => lib/core/providers/object}/device_service.dart (94%) rename {packages/io_library/lib/src/service => lib/core/providers/object}/file_service.dart (92%) rename {packages/io_library/lib/src/service => lib/core/providers/object}/image_service.dart (89%) rename {packages/io_library/lib/src => lib/core/providers/object}/io_handler.dart (82%) rename {packages/io_library/lib/src/usecase => lib/core/providers/object}/load_image_from_file_manager.dart (81%) rename {packages/io_library/lib/src/usecase => lib/core/providers/object}/load_image_from_photo_library.dart (73%) rename {packages/io_library/lib/src/service => lib/core/providers/object}/permission_service.dart (96%) rename {packages/io_library/lib/src/service => lib/core/providers/object}/photo_library_service.dart (85%) rename {packages/features/workspace_screen/lib/src/usecase => lib/core/providers/object}/render_image_for_export.dart (83%) rename {packages/io_library/lib/src/usecase => lib/core/providers/object}/save_as_catrobat_image.dart (72%) rename {packages/io_library/lib/src/usecase => lib/core/providers/object}/save_as_raster_image.dart (73%) create mode 100644 lib/core/providers/object/tools/brush_tool_provider.dart rename {packages/tools/lib/src/brush_tool => lib/core/providers/object/tools}/brush_tool_provider.g.dart (85%) create mode 100644 lib/core/providers/object/tools/eraser_tool_provider.dart rename {packages/tools/lib/src/eraser_tool => lib/core/providers/object/tools}/eraser_tool_provider.g.dart (85%) create mode 100644 lib/core/providers/object/tools/hand_tool_provider.dart rename {packages/tools/lib/src/hand_tool => lib/core/providers/object/tools}/hand_tool_provider.g.dart (85%) rename {packages/features/workspace_screen/lib/src/states => lib/core/providers/state}/canvas_state_data.dart (66%) rename {packages/features/workspace_screen/lib/src/states => lib/core/providers/state}/canvas_state_data.freezed.dart (86%) rename {packages/features/workspace_screen/lib/src/states => lib/core/providers/state}/canvas_state_provider.dart (84%) rename {packages/features/workspace_screen/lib/src/states => lib/core/providers/state}/canvas_state_provider.g.dart (93%) rename {packages/features/workspace_screen/lib/src/states => lib/core/providers/state}/tool_options_visibility_state_provider.dart (93%) rename {packages/features/workspace_screen/lib/src/states => lib/core/providers/state}/tool_options_visibility_state_provider.g.dart (94%) rename {packages/tools/lib/src/brush_tool => lib/core/providers/state/tools/brush}/brush_tool_state_data.dart (88%) rename {packages/tools/lib/src/brush_tool => lib/core/providers/state/tools/brush}/brush_tool_state_data.freezed.dart (74%) rename {packages/tools/lib/src/brush_tool => lib/core/providers/state/tools/brush}/brush_tool_state_provider.dart (81%) rename {packages/tools/lib/src/brush_tool => lib/core/providers/state/tools/brush}/brush_tool_state_provider.g.dart (94%) rename {packages/tools/lib/src => lib/core/providers/state/tools}/toolbox/toolbox_state_data.dart (69%) rename {packages/tools/lib/src => lib/core/providers/state/tools}/toolbox/toolbox_state_data.freezed.dart (81%) rename {packages/tools/lib/src => lib/core/providers/state/tools}/toolbox/toolbox_state_provider.dart (77%) rename {packages/tools/lib/src => lib/core/providers/state/tools}/toolbox/toolbox_state_provider.g.dart (94%) rename {packages/features/workspace_screen/lib/src/states => lib/core/providers/state}/workspace_state.dart (75%) create mode 100644 lib/core/providers/state/workspace_state_notifier.dart rename {packages/tools/lib/src/brush_tool => lib/core/tools/implementation}/brush_tool.dart (71%) create mode 100644 lib/core/tools/implementation/eraser_tool.dart rename {packages/tools/lib/src/hand_tool => lib/core/tools/implementation}/hand_tool.dart (65%) rename {packages/tools/lib/src => lib/core/tools}/tool.dart (65%) rename {packages/tools/lib/src => lib/core/tools}/tool_data.dart (96%) rename {packages/database/lib/src => lib/core}/utils/date_time_converter.dart (93%) rename {packages/io_library/lib/src/models => lib/core/utils}/failure.dart (100%) rename {packages/io_library/lib/src/failure => lib/core/utils}/load_image_failure.dart (85%) rename {packages/component_library/lib/src => lib/core}/utils/open_url.dart (89%) rename {packages/io_library/lib/src/failure => lib/core/utils}/save_image_failure.dart (86%) delete mode 100644 lib/pocket_paint_app.dart rename {packages/features/landing_page_screen/lib/src => lib/ui/pages/landing_page}/components/custom_action_button.dart (69%) rename {packages/features/landing_page_screen/lib/src => lib/ui/pages/landing_page}/components/image_preview.dart (84%) rename {packages/features/landing_page_screen/lib/src => lib/ui/pages/landing_page}/components/main_overflow_menu.dart (76%) rename {packages/features/landing_page_screen/lib/src => lib/ui/pages/landing_page}/components/project_list_tile.dart (76%) rename {packages/features/landing_page_screen/lib/src => lib/ui/pages/landing_page}/components/project_overflow_menu.dart (72%) rename {packages/features/landing_page_screen/lib/src => lib/ui/pages/landing_page}/landing_page.dart (73%) rename {packages/features/onboarding_screen/lib/src => lib/ui/pages/onboarding_page}/components/bottom_nav_bar_container.dart (69%) rename {packages/features/onboarding_screen/lib/src => lib/ui/pages/onboarding_page}/components/onboarding_page_app_bar.dart (95%) rename {packages/features/onboarding_screen/lib/src => lib/ui/pages/onboarding_page}/components/onboarding_page_bottom_nav_bar.dart (69%) rename packages/features/onboarding_screen/lib/src/onboarding_screen.dart => lib/ui/pages/onboarding_page/onboarding_page.dart (73%) rename {packages/features/onboarding_screen/lib/src => lib/ui/pages/onboarding_page}/screens/screen1.dart (68%) rename {packages/features/onboarding_screen/lib/src => lib/ui/pages/onboarding_page}/screens/screen2.dart (72%) rename {packages/features/onboarding_screen/lib/src => lib/ui/pages/onboarding_page}/screens/screen3.dart (77%) rename {packages/features/onboarding_screen/lib/src => lib/ui/pages/onboarding_page}/screens/screen4.dart (74%) rename {packages/features/onboarding_screen/lib/src => lib/ui/pages/onboarding_page}/screens/screen5.dart (75%) rename {packages/features/workspace_screen/lib/src => lib/ui/pages/workspace_page}/components/bottom_bar/bottom_nav_bar.dart (65%) rename {packages/features/workspace_screen/lib/src => lib/ui/pages/workspace_page}/components/bottom_bar/bottom_nav_bar_items.dart (100%) rename {packages/features/workspace_screen/lib/src => lib/ui/pages/workspace_page}/components/bottom_bar/tool_options/stroke_cap_tool_option.dart (83%) rename {packages/features/workspace_screen/lib/src => lib/ui/pages/workspace_page}/components/bottom_bar/tool_options/stroke_tool_options.dart (51%) rename {packages/features/workspace_screen/lib/src => lib/ui/pages/workspace_page}/components/bottom_bar/tool_options/stroke_width_tool_option.dart (89%) rename {packages/features/workspace_screen/lib/src => lib/ui/pages/workspace_page}/components/bottom_bar/tool_options/tool_option.dart (93%) rename {packages/features/workspace_screen/lib/src => lib/ui/pages/workspace_page}/components/bottom_bar/tool_options/tool_options.dart (62%) create mode 100644 lib/ui/pages/workspace_page/components/bottom_bar/tools/tool_button.dart rename {packages/features/workspace_screen/lib/src => lib/ui/pages/workspace_page}/components/bottom_bar/tools/tools_bottom_sheet.dart (52%) rename {packages/features/workspace_screen/lib/src => lib/ui/pages/workspace_page}/components/drawing_surface/canvas_painter.dart (77%) rename {packages/features/workspace_screen/lib/src => lib/ui/pages/workspace_page}/components/drawing_surface/checkerboard_pattern.dart (60%) rename {packages/features/workspace_screen/lib/src => lib/ui/pages/workspace_page}/components/drawing_surface/drawing_canvas.dart (84%) rename {packages/features/workspace_screen/lib/src => lib/ui/pages/workspace_page}/components/drawing_surface/exit_fullscreen_button.dart (61%) rename {packages/features/workspace_screen/lib/src => lib/ui/pages/workspace_page}/components/top_bar/overflow_menu.dart (84%) rename {packages/features/workspace_screen/lib/src => lib/ui/pages/workspace_page}/components/top_bar/top_app_bar.dart (50%) create mode 100644 lib/ui/pages/workspace_page/workspace_page.dart create mode 100644 lib/ui/shared/bottom_nav_bar_icon.dart rename {packages/component_library/lib/src/components => lib/ui/shared}/custom_action_chip.dart (98%) rename {packages/io_library/lib/src/ui => lib/ui/shared/dialogs}/about_dialog.dart (82%) rename {packages/io_library/lib/src/ui => lib/ui/shared/dialogs}/delete_project_dialog.dart (82%) rename {packages/io_library/lib/src/ui => lib/ui/shared/dialogs}/discard_changes_dialog.dart (83%) rename {packages/io_library/lib/src/ui => lib/ui/shared/dialogs}/generic_dialog.dart (66%) rename {packages/io_library/lib/src/ui => lib/ui/shared/dialogs}/load_image_dialog.dart (83%) rename {packages/io_library/lib/src/ui => lib/ui/shared/dialogs}/overwrite_dialog.dart (87%) rename {packages/io_library/lib/src/ui => lib/ui/shared/dialogs}/project_details_dialog.dart (85%) rename {packages/io_library/lib/src/ui => lib/ui/shared/dialogs}/save_image_dialog.dart (67%) rename {packages/component_library/lib/src/components => lib/ui/shared}/icon_button_with_label.dart (74%) rename {packages/component_library/lib/src/components => lib/ui/shared}/icon_svg.dart (85%) rename {packages/io_library/lib/src/ui => lib/ui/shared}/image_format_info.dart (66%) create mode 100644 lib/ui/shared/images/checkerboard.dart create mode 100644 lib/ui/shared/images/pocketpaint_intro_landscape.dart create mode 100644 lib/ui/shared/images/pocketpaint_intro_portrait.dart create mode 100644 lib/ui/shared/images/pocketpaint_logo_small.dart rename {packages/component_library/lib/src/components => lib/ui/shared}/loading_overlay.dart (87%) rename {packages/component_library/lib/src/components => lib/ui/shared}/pop_menu_button.dart (65%) create mode 100644 lib/ui/theme/data/custom_colors.dart create mode 100644 lib/ui/theme/data/dark_paintroid_theme_data.dart create mode 100644 lib/ui/theme/data/font_size.dart create mode 100644 lib/ui/theme/data/light_paintroid_theme_data.dart create mode 100644 lib/ui/theme/data/paintroid_theme.dart create mode 100644 lib/ui/theme/data/paintroid_theme_data.dart create mode 100644 lib/ui/theme/data/spacing.dart create mode 100644 lib/ui/theme/state/theme_mode_state_provider.dart create mode 100644 lib/ui/theme/state/theme_mode_state_provider.g.dart create mode 100644 lib/ui/theme/theme.dart rename {packages/component_library/lib/src => lib/ui}/utils/toast_utils.dart (91%) delete mode 100644 packages/command/.metadata delete mode 100644 packages/command/analysis_options.yaml delete mode 100644 packages/command/lib/command.dart delete mode 100644 packages/command/lib/command_providers.dart delete mode 100644 packages/command/lib/src/command_factory/command_factory.dart delete mode 100644 packages/command/lib/src/command_implementation/graphic/graphic_command.dart delete mode 100644 packages/command/pubspec.yaml delete mode 100644 packages/component_library/.metadata delete mode 100644 packages/component_library/analysis_options.yaml delete mode 100644 packages/component_library/lib/component_library.dart delete mode 100644 packages/component_library/lib/src/components/bottom_nav_bar_icon.dart delete mode 100644 packages/component_library/lib/src/components/imgs.dart delete mode 100644 packages/component_library/lib/src/theme/color_schemes.dart delete mode 100644 packages/component_library/lib/src/theme/styles.dart delete mode 100644 packages/component_library/pubspec.yaml delete mode 100644 packages/database/.metadata delete mode 100644 packages/database/analysis_options.yaml delete mode 100644 packages/database/lib/database.dart delete mode 100644 packages/database/pubspec.yaml delete mode 100644 packages/features/landing_page_screen/.metadata delete mode 100644 packages/features/landing_page_screen/analysis_options.yaml delete mode 100644 packages/features/landing_page_screen/lib/landing_page_screen.dart delete mode 100644 packages/features/landing_page_screen/pubspec.yaml delete mode 100644 packages/features/onboarding_screen/.metadata delete mode 100644 packages/features/onboarding_screen/analysis_options.yaml delete mode 100644 packages/features/onboarding_screen/lib/onboarding_screen.dart delete mode 100644 packages/features/onboarding_screen/pubspec.yaml delete mode 100644 packages/features/workspace_screen/.metadata delete mode 100644 packages/features/workspace_screen/analysis_options.yaml delete mode 100644 packages/features/workspace_screen/lib/src/components/bottom_bar/tools/tool_button.dart delete mode 100644 packages/features/workspace_screen/lib/src/states/workspace_state_notifier.dart delete mode 100644 packages/features/workspace_screen/lib/src/workspace_screen.dart delete mode 100644 packages/features/workspace_screen/lib/workspace_screen.dart delete mode 100644 packages/features/workspace_screen/pubspec.yaml delete mode 100644 packages/io_library/.metadata delete mode 100644 packages/io_library/analysis_options.yaml delete mode 100644 packages/io_library/lib/io_library.dart delete mode 100644 packages/io_library/pubspec.yaml delete mode 100644 packages/io_library/test/fixture/image/test.jpg delete mode 100644 packages/io_library/test/fixture/image/test.png delete mode 100644 packages/io_library/test/fixture/image/test1.png delete mode 100644 packages/l10n/.metadata delete mode 100644 packages/l10n/analysis_options.yaml delete mode 100644 packages/l10n/l10n.yaml delete mode 100644 packages/l10n/lib/l10n.dart delete mode 100644 packages/l10n/pubspec.yaml delete mode 100644 packages/tools/.metadata delete mode 100644 packages/tools/analysis_options.yaml delete mode 100644 packages/tools/lib/src/brush_tool/brush_tool_provider.dart delete mode 100644 packages/tools/lib/src/eraser_tool/eraser_tool_provider.dart delete mode 100644 packages/tools/lib/src/hand_tool/hand_tool_provider.dart delete mode 100644 packages/tools/lib/tools.dart delete mode 100644 packages/tools/pubspec.yaml rename {packages/features/landing_page_screen/test/fixture/image => test/assets/images}/test.jpg (100%) rename {packages/features/landing_page_screen/test/fixture/image => test/assets/images}/test.png (100%) rename {packages/features/landing_page_screen/test/fixture/image => test/assets/images}/test1.png (100%) rename {packages/command/test/unit => test/unit/command}/command_factory_test.dart (65%) rename {packages/command/test/unit => test/unit/command}/draw_path_command_test.dart (65%) rename {packages/command/test/unit => test/unit/command}/draw_path_command_test.mocks.dart (97%) rename {packages/database/test/unit => test/unit/database}/project_database_test.dart (94%) rename {packages/io_library/test/unit/service => test/unit/provider}/file_service_test.dart (91%) rename {packages/io_library/test/unit/service => test/unit/provider}/image_service_test.dart (81%) rename {packages/io_library/test/unit/usecase => test/unit/provider}/load_image_from_photo_library_test.dart (90%) rename {packages/io_library/test/unit/usecase => test/unit/provider}/load_image_from_photo_library_test.mocks.dart (66%) rename {packages/io_library/test/unit/service => test/unit/provider}/photo_library_service_test.dart (95%) rename {packages/io_library/test/unit/service => test/unit/provider}/photo_library_service_test.mocks.dart (90%) rename {packages/io_library/test/unit/usecase => test/unit/provider}/save_as_raster_image_test.dart (93%) rename {packages/io_library/test/unit/usecase => test/unit/provider}/save_as_raster_image_test.mocks.dart (63%) rename {packages/io_library/test => test}/unit/serialization/command/draw_path_command_serializer_test.dart (85%) rename {packages/io_library/test => test}/unit/serialization/converter/paint_converter_test.dart (91%) rename {packages/io_library/test => test}/unit/serialization/converter/path_action_converter_test.dart (86%) rename {packages/io_library/test => test}/unit/serialization/converter/path_with_action_history_converter_test.dart (84%) rename {packages/io_library/test => test}/unit/serialization/image/catrobat_image_serializer_test.dart (85%) rename {packages/io_library/test => test}/unit/serialization/utils/dummy_command_factory.dart (78%) rename {packages/io_library/test => test}/unit/serialization/utils/dummy_paint_factory.dart (90%) rename {packages/io_library/test => test}/unit/serialization/utils/dummy_path_factory.dart (83%) rename {packages/io_library/test => test}/unit/serialization/utils/dummy_version_strategy.dart (70%) rename {packages/tools/test/unit => test/unit/tools}/brush_tool_state_test.dart (89%) rename {packages/tools/test/unit => test/unit/tools}/brush_tool_test.dart (60%) rename {packages/tools/test/unit => test/unit/tools}/brush_tool_test.mocks.dart (88%) create mode 100644 test/unit/tools/eraser_tool_test.dart create mode 100644 test/unit/tools/eraser_tool_test.mocks.dart rename {packages/tools/test/unit => test/unit/tools}/hand_tool_test.dart (80%) rename {packages/tools/test/unit => test/unit/tools}/hand_tool_test.mocks.dart (86%) rename {packages/features/workspace_screen/test/unit => test/unit/workspace}/render_image_for_export_test.dart (91%) rename {packages/features/workspace_screen/test/unit => test/unit/workspace}/render_image_for_export_test.mocks.dart (94%) rename {packages/features/landing_page_screen/test/widget => test/widget/landing_page}/landing_page_test.dart (79%) rename {packages/features/landing_page_screen/test/widget => test/widget/landing_page}/landing_page_test.mocks.dart (63%) rename packages/features/onboarding_screen/test/widget/onboarding_screen_test.dart => test/widget/onboarding_page/onboarding_page_test.dart (90%) rename {packages/features/workspace_screen/test/widget => test/widget/workspace_page}/bottom_control_navigation_bar_test.dart (84%) rename {packages/features/workspace_screen/test/widget => test/widget/workspace_page}/bottom_nav_bar_interactions.dart (94%) rename {packages/features/workspace_screen/test/widget => test/widget/workspace_page}/canvas_interactions.dart (90%) rename {packages/features/workspace_screen/test/widget => test/widget/workspace_page}/eraser_tool_test.dart (61%) rename {packages/features/workspace_screen/test/widget => test/widget/workspace_page}/hand_tool_test.dart (72%) rename {packages/features/workspace_screen/test/widget => test/widget/workspace_page}/interactive_viewer_interactions.dart (96%) rename packages/features/workspace_screen/test/widget/workspace_screen_test.dart => test/widget/workspace_page/workspace_page_test.dart (63%) diff --git a/.fvmrc b/.fvmrc new file mode 100644 index 00000000..03c3fb3b --- /dev/null +++ b/.fvmrc @@ -0,0 +1,3 @@ +{ + "flutter": "3.19.6" +} \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 3f60e012..fe379d3f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -11,17 +11,18 @@ Please review the [contributing guidelines](https://github.com/Catrobat/Paintroid/blob/develop/README.md) and [wiki pages](https://github.com/Catrobat/Catroid/wiki/) of this repository. - [ ] Include the name of the Jira ticket in the PR’s title +- [ ] Add the link to the ticket in Jira in the description of the PR - [ ] Include a summary of the changes plus the relevant context - [ ] Choose the proper base branch (*develop*) -- [ ] Confirm that the changes follow the project’s coding guidelines +- [ ] Make sure to organize imports with 'make sort' before committing +- [ ] Confirm that the changes follow the project’s coding guidelines (Wiki) - [ ] Verify that the changes generate no compiler or linter warnings - [ ] Perform a self-review of the changes - [ ] Verify to commit no other files than the intentionally changed ones - [ ] Include reasonable and readable tests verifying the added or changed behavior -- [ ] Confirm that new and existing unit tests pass locally +- [ ] Confirm that new and existing tests pass locally - [ ] Check that the commits’ message style matches the [project’s guideline](https://github.com/Catrobat/Catroid/wiki/Commit-Message-Guidelines) -- [ ] Stick to the project’s gitflow workflow - [ ] Verify that your changes do not have any conflicts with the base branch - [ ] After the PR, verify that all CI checks have passed -- [ ] Post a message in the *#paintroid* [Slack channel](https://catrobat.slack.com) and ask for a code reviewer +- [ ] Add new information to the [Wiki](https://github.com/Catrobat/Paintroid-Flutter/wiki) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b522c6d9..f6853bc6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,28 +6,35 @@ jobs: main: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4.1.4 - uses: subosito/flutter-action@v2.10.0 with: - flutter-version: "3.10.5" + flutter-version: "3.19.6" channel: "stable" cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:" cache-path: "${{ runner.tool_cache }}/flutter/:channel:-:version:-:arch:" - architecture: x64 # optional, x64 or arm64 + architecture: x64 - name: Setup - run: | - make get + run: make get - name: Static Analysis run: make lint - name: Unit Tests - run: melos run test:unit + run: make test-unit - name: Widget Tests - run: melos run test:widget + run: make test-widget + - name: Install xmlstarlet + run: sudo apt-get install -y xmlstarlet + - name: Prepare App Name and Identifier + run: | + chmod +x ./.github/workflows/update_app_identifiers.sh + ./.github/workflows/update_app_identifiers.sh ${{ github.event.number }} - name: Build release package - run: flutter build apk --release + run: | + flutter build apk --release + mv build/app/outputs/flutter-apk/app-release.apk build/app/outputs/flutter-apk/flutter-paint-${{ github.event.number }}.apk - name: Archive build artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4.3.3 with: - name: apk + name: flutter-paint-apk-${{ github.event.number }} path: | - build/app/outputs/flutter-apk/app-release.apk + build/app/outputs/flutter-apk/flutter-paint-${{ github.event.number }}.apk diff --git a/.github/workflows/update_app_identifiers.sh b/.github/workflows/update_app_identifiers.sh new file mode 100644 index 00000000..702c46c3 --- /dev/null +++ b/.github/workflows/update_app_identifiers.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +PR_NUMBER=$1 + +MAIN_MANIFEST="android/app/src/main/AndroidManifest.xml" +DEBUG_MANIFEST="android/app/src/debug/AndroidManifest.xml" +PROFILE_MANIFEST="android/app/src/profile/AndroidManifest.xml" +BUILD_GRADLE="android/app/build.gradle" + +if [ -f "$MAIN_MANIFEST" ]; then + echo "Updating $MAIN_MANIFEST with PR number $PR_NUMBER" + sed -i "s/package=\"org.catrobat.paintroid\"/package=\"org.catrobat.paintroid.pr$PR_NUMBER\"/" $MAIN_MANIFEST + sed -i "s/android:label=\"Pocket Paint\"/android:label=\"Pocket Paint PR$PR_NUMBER\"/" $MAIN_MANIFEST +else + echo "$MAIN_MANIFEST does not exist." +fi + +if [ -f "$DEBUG_MANIFEST" ]; then + echo "Updating $DEBUG_MANIFEST with PR number $PR_NUMBER" + sed -i "s/package=\"org.catrobat.paintroid\"/package=\"org.catrobat.paintroid.pr$PR_NUMBER\"/" $DEBUG_MANIFEST +else + echo "$DEBUG_MANIFEST does not exist." +fi + +if [ -f "$PROFILE_MANIFEST" ]; then + echo "Updating $PROFILE_MANIFEST with PR number $PR_NUMBER" + sed -i "s/package=\"org.catrobat.paintroid\"/package=\"org.catrobat.paintroid.pr$PR_NUMBER\"/" $PROFILE_MANIFEST +else + echo "$PROFILE_MANIFEST does not exist." +fi + +if [ -f "$BUILD_GRADLE" ]; then + echo "Updating applicationId in $BUILD_GRADLE with PR number $PR_NUMBER" + sed -i "s/applicationId \"org.catrobat.paintroidflutter\"/applicationId \"org.catrobat.paintroidflutter.pr$PR_NUMBER\"/" $BUILD_GRADLE +else + echo "$BUILD_GRADLE does not exist." +fi + +KOTLIN_MAIN_ACTIVITY="android/app/src/main/kotlin/org/catrobat/paintroid/MainActivity.kt" + +if [ -f "$KOTLIN_MAIN_ACTIVITY" ]; then + echo "Updating MainActivity package in Kotlin with PR number $PR_NUMBER" + sed -i "s/package org.catrobat.paintroid/package org.catrobat.paintroid.pr$PR_NUMBER/" $KOTLIN_MAIN_ACTIVITY +else + echo "MainActivity Kotlin file does not exist." +fi + +INFO_PLIST="ios/Runner/Info.plist" +if [ -f "$INFO_PLIST" ]; then + echo "Updating $INFO_PLIST with PR number $PR_NUMBER" + xmlstarlet ed -L -u "/plist/dict/key[text()='CFBundleName']/following-sibling::string[1]" -v "paintroid PR$PR_NUMBER" $INFO_PLIST + xmlstarlet ed -L -u "/plist/dict/key[text()='CFBundleDisplayName']/following-sibling::string[1]" -v "Pocket Paint PR$PR_NUMBER" $INFO_PLIST + if ! xmlstarlet sel -t -c "/plist/dict/key[text()='CFBundleDisplayName']" $INFO_PLIST | grep -q 'CFBundleDisplayName'; then + xmlstarlet ed -L -s "/plist/dict" -t elem -n "key" -v "CFBundleDisplayName" \ + -s "/plist/dict/key[last()]" -t elem -n "string" -v "Pocket Paint PR$PR_NUMBER" $INFO_PLIST + fi + xmlstarlet ed -L -u "/plist/dict/key[text()='CFBundleIdentifier']/following-sibling::string[1]" -v "org.catrobat.paintroidflutter.pr$PR_NUMBER" $INFO_PLIST +else + echo "$INFO_PLIST does not exist." +fi diff --git a/.gitignore b/.gitignore index ac8927d7..9642c494 100644 --- a/.gitignore +++ b/.gitignore @@ -51,8 +51,6 @@ app.*.map.json /android/app/profile /android/app/release -.fvm/flutter_sdk - # Melos pubspec_overrides.yaml @@ -62,3 +60,6 @@ packages/*/build packages/features/*/pubspec.lock packages/features/*/build + +# FVM Version Cache +.fvm/ \ No newline at end of file diff --git a/Makefile b/Makefile index 516b0a8d..8fa8b8c5 100644 --- a/Makefile +++ b/Makefile @@ -1,56 +1,46 @@ -.PHONY: run pods-clean get clean build languages lint format test watch +.PHONY: get build watch clean test analyze test-unit test-widget test-all all fvm_check -FLUTTER := fvm flutter -DART := fvm dart +# Check if FVM is installed +FVM_PRESENT := $(shell command -v fvm 2> /dev/null) -run: - $(FLUTTER) run - -pods-clean: - rm -Rf ios/Pods ; \ - rm -Rf ios/.symlinks ; \ - rm -Rf ios/Flutter/Flutter.framework ; \ - rm -Rf ios/Flutter/Flutter.podspec ; \ - rm ios/Podfile ; \ - rm ios/Podfile.lock ; \ +# Use fvm if installed; otherwise use flutter directly +FLUTTER_CMD := $(if $(FVM_PRESENT),fvm flutter,flutter) +DART_CMD := $(if $(FVM_PRESENT),fvm dart,dart) +clean: + $(FLUTTER_CMD) clean + get: - chmod +x ./setup_sdk.sh - ./setup_sdk.sh - chmod +x ./setup_melos.sh - ./setup_melos.sh - melos bootstrap + $(FLUTTER_CMD) pub get -clean: - melos clean +run: + $(FLUTTER_CMD) run -build: - melos run build:all +all: clean get build sort run -languages: - @cd packages/l10n ; \ - $(FLUTTER) gen-l10n - @echo "-> Generated l10n" +watch: + $(DART_CMD) run build_runner watch --delete-conflicting-outputs lint: - $(FLUTTER) analyze - melos run lint:all + $(FLUTTER_CMD) analyze -format: - $(DART) format --set-exit-if-changed . +build: + $(DART_CMD) run build_runner build --delete-conflicting-outputs -test: - melos run test:all +analyze: + $(FLUTTER_CMD) analyze test-unit: - melos run test:unit + $(FLUTTER_CMD) test test/unit test-widget: - melos run test:widget + $(FLUTTER_CMD) test test/widget -watch: - $(DART) run build_runner watch --delete-conflicting-outputs +test: + $(FLUTTER_CMD) test + +sort: + $(DART_CMD) run import_sorter:main -melos: - $(DART) pub global activate melos - \ No newline at end of file +fvm_check: + @echo Using $(FLUTTER_CMD) and $(DART_CMD) based on availability of FVM diff --git a/README.md b/README.md index d3a25760..1da95f9b 100644 --- a/README.md +++ b/README.md @@ -55,13 +55,13 @@ What `make get` does: ## Issues -**Please report all bugs on our [Jira Bugtracker](https://jira.catrob.at/secure/CreateIssue.jspa?pid=10401&issuetype=1)** +**Please report all bugs on our [Jira Bugtracker](https://catrobat.atlassian.net/jira/)** ## Contributing -If you want to contribute we suggest that you start with [forking](https://help.github.com/articles/fork-a-repo/) our repository and browse the code. Then you can look at our [Issue-Tracker](https://jira.catrob.at/secure/RapidBoard.jspa?rapidView=60) and start with fixing one ticket. We strictly use [Test-Driven Development](http://c2.com/cgi/wiki?TestDrivenDevelopment) and [Clean Code](http://www.planetgeek.ch/wp-content/uploads/2013/06/Clean-Code-V2.2.pdf), so first read everything you can about these development methods. Code developed in a different style will not be accepted. After you've created a pull request we will review your code and do a full testrun on your branch. - -If you want to implement a new feature, please ask about the details in JIRA or our IRC channel (#catrobat or #catrobatdev) first. +If you want to contribute we suggest that you start with [forking](https://help.github.com/articles/fork-a-repo/) our repository and browse the code. Then you can look at our [Issue-Tracker](https://catrobat.atlassian.net/jira/software/c/projects/PAINTROID/issues/PAINTROID-678?filter=allissues&jql=project%20%3D%20%22PAINTROID%22%0Aand%20status%20%3D%20%22Ready%20For%20Development%22%0Aand%20assignee%20%3D%20empty%0Aand%20type%20in%20%28Bug%2C%20Story%2C%20Task%29%0Aand%20labels%20%3D%20Flutter%0AORDER%20BY%20created%20DESC) and start with fixing one ticket. Please make sure to pick a ticket with the status "Ready for development" and comment on the ticket that you are working on it. We strictly use [Test-Driven Development](http://c2.com/cgi/wiki?TestDrivenDevelopment) and [Clean Code](http://www.planetgeek.ch/wp-content/uploads/2013/06/Clean-Code-V2.2.pdf), so first read everything you can about these development methods. Code developed in a different style will not be accepted. +When you are done, comment again on the ticket and create a pull request on github. +After you've created a pull request we will review your code and do a full testrun on your branch. Let's start to set up the working environment using the instructions in our [Wiki](https://github.com/Catrobat/Catroid/wiki/Setup-working-environment)! diff --git a/analysis_options.yaml b/analysis_options.yaml index 1ee68bd9..68e5ef8b 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -20,4 +20,4 @@ analyzer: exclude: - lib/src/**.pb*.dart - - lib/src/data/*.g.dart + - lib/**.g.dart diff --git a/android/app/build.gradle b/android/app/build.gradle index 088a65b4..6db03ec8 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,3 +1,9 @@ +plugins { + id "com.android.application" + id "kotlin-android" + id "dev.flutter.flutter-gradle-plugin" +} + def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { @@ -6,17 +12,8 @@ if (localPropertiesFile.exists()) { } } -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - android { - compileSdkVersion 33 + compileSdkVersion 34 ndkVersion flutter.ndkVersion compileOptions { @@ -35,7 +32,7 @@ android { defaultConfig { applicationId "org.catrobat.paintroidflutter" minSdkVersion 21 - targetSdkVersion 33 + targetSdkVersion 34 versionCode 1 versionName "1.0.0" } @@ -52,6 +49,5 @@ flutter { } dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "androidx.window:window:1.0.0" } diff --git a/android/build.gradle b/android/build.gradle index d02fac26..bc157bd1 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,16 +1,3 @@ -buildscript { - ext.kotlin_version = '1.8.21' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - allprojects { repositories { google() diff --git a/android/settings.gradle b/android/settings.gradle index 44e62bcf..5e263121 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -1,11 +1,25 @@ -include ':app' +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "7.4.2" apply false + id "org.jetbrains.kotlin.android" version "1.8.21" apply false +} + +include ":app" \ No newline at end of file diff --git a/packages/component_library/assets/img/checkerboard.png b/assets/img/checkerboard.png similarity index 100% rename from packages/component_library/assets/img/checkerboard.png rename to assets/img/checkerboard.png diff --git a/packages/component_library/assets/img/pocketpaint_intro_landscape.png b/assets/img/pocketpaint_intro_landscape.png similarity index 100% rename from packages/component_library/assets/img/pocketpaint_intro_landscape.png rename to assets/img/pocketpaint_intro_landscape.png diff --git a/packages/component_library/assets/img/pocketpaint_intro_portrait.png b/assets/img/pocketpaint_intro_portrait.png similarity index 100% rename from packages/component_library/assets/img/pocketpaint_intro_portrait.png rename to assets/img/pocketpaint_intro_portrait.png diff --git a/packages/component_library/assets/img/pocketpaint_logo_small.png b/assets/img/pocketpaint_logo_small.png similarity index 100% rename from packages/component_library/assets/img/pocketpaint_logo_small.png rename to assets/img/pocketpaint_logo_small.png diff --git a/packages/l10n/lib/src/l10n/app_translations_en.arb b/assets/lang/app_translations_en.arb similarity index 100% rename from packages/l10n/lib/src/l10n/app_translations_en.arb rename to assets/lang/app_translations_en.arb diff --git a/packages/component_library/assets/svg/ic_brush.svg b/assets/svg/ic_brush.svg similarity index 100% rename from packages/component_library/assets/svg/ic_brush.svg rename to assets/svg/ic_brush.svg diff --git a/packages/component_library/assets/svg/ic_clipboard.svg b/assets/svg/ic_clipboard.svg similarity index 100% rename from packages/component_library/assets/svg/ic_clipboard.svg rename to assets/svg/ic_clipboard.svg diff --git a/packages/component_library/assets/svg/ic_clipping.svg b/assets/svg/ic_clipping.svg similarity index 100% rename from packages/component_library/assets/svg/ic_clipping.svg rename to assets/svg/ic_clipping.svg diff --git a/packages/component_library/assets/svg/ic_cursor.svg b/assets/svg/ic_cursor.svg similarity index 100% rename from packages/component_library/assets/svg/ic_cursor.svg rename to assets/svg/ic_cursor.svg diff --git a/packages/component_library/assets/svg/ic_edit_circle.svg b/assets/svg/ic_edit_circle.svg similarity index 100% rename from packages/component_library/assets/svg/ic_edit_circle.svg rename to assets/svg/ic_edit_circle.svg diff --git a/packages/component_library/assets/svg/ic_eraser.svg b/assets/svg/ic_eraser.svg similarity index 100% rename from packages/component_library/assets/svg/ic_eraser.svg rename to assets/svg/ic_eraser.svg diff --git a/packages/component_library/assets/svg/ic_fill.svg b/assets/svg/ic_fill.svg similarity index 100% rename from packages/component_library/assets/svg/ic_fill.svg rename to assets/svg/ic_fill.svg diff --git a/packages/component_library/assets/svg/ic_hand.svg b/assets/svg/ic_hand.svg similarity index 100% rename from packages/component_library/assets/svg/ic_hand.svg rename to assets/svg/ic_hand.svg diff --git a/packages/component_library/assets/svg/ic_import.svg b/assets/svg/ic_import.svg similarity index 100% rename from packages/component_library/assets/svg/ic_import.svg rename to assets/svg/ic_import.svg diff --git a/packages/component_library/assets/svg/ic_layers.svg b/assets/svg/ic_layers.svg similarity index 100% rename from packages/component_library/assets/svg/ic_layers.svg rename to assets/svg/ic_layers.svg diff --git a/packages/component_library/assets/svg/ic_line.svg b/assets/svg/ic_line.svg similarity index 100% rename from packages/component_library/assets/svg/ic_line.svg rename to assets/svg/ic_line.svg diff --git a/packages/component_library/assets/svg/ic_pipette.svg b/assets/svg/ic_pipette.svg similarity index 100% rename from packages/component_library/assets/svg/ic_pipette.svg rename to assets/svg/ic_pipette.svg diff --git a/packages/component_library/assets/svg/ic_shapes.svg b/assets/svg/ic_shapes.svg similarity index 100% rename from packages/component_library/assets/svg/ic_shapes.svg rename to assets/svg/ic_shapes.svg diff --git a/packages/component_library/assets/svg/ic_smudge.svg b/assets/svg/ic_smudge.svg similarity index 100% rename from packages/component_library/assets/svg/ic_smudge.svg rename to assets/svg/ic_smudge.svg diff --git a/packages/component_library/assets/svg/ic_spray_can.svg b/assets/svg/ic_spray_can.svg similarity index 100% rename from packages/component_library/assets/svg/ic_spray_can.svg rename to assets/svg/ic_spray_can.svg diff --git a/packages/component_library/assets/svg/ic_stamp.svg b/assets/svg/ic_stamp.svg similarity index 100% rename from packages/component_library/assets/svg/ic_stamp.svg rename to assets/svg/ic_stamp.svg diff --git a/packages/component_library/assets/svg/ic_text.svg b/assets/svg/ic_text.svg similarity index 100% rename from packages/component_library/assets/svg/ic_text.svg rename to assets/svg/ic_text.svg diff --git a/packages/component_library/assets/svg/ic_tools.svg b/assets/svg/ic_tools.svg similarity index 100% rename from packages/component_library/assets/svg/ic_tools.svg rename to assets/svg/ic_tools.svg diff --git a/packages/component_library/assets/svg/ic_transform.svg b/assets/svg/ic_transform.svg similarity index 100% rename from packages/component_library/assets/svg/ic_transform.svg rename to assets/svg/ic_transform.svg diff --git a/packages/component_library/assets/svg/ic_watercolor.svg b/assets/svg/ic_watercolor.svg similarity index 100% rename from packages/component_library/assets/svg/ic_watercolor.svg rename to assets/svg/ic_watercolor.svg diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index 9625e105..7c569640 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 12.0 diff --git a/ios/Podfile b/ios/Podfile index 3854b694..55d1275b 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '11.0' +platform :ios, '12.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 62cb12ec..d46e4e93 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -38,9 +38,6 @@ PODS: - Flutter (1.0.0) - flutter_localization (0.0.1): - Flutter - - FMDB (2.7.5): - - FMDB/standard (= 2.7.5) - - FMDB/standard (2.7.5) - image_picker_ios (0.0.1): - Flutter - integration_test (0.0.1): @@ -62,7 +59,7 @@ PODS: - FlutterMacOS - sqflite (0.0.3): - Flutter - - FMDB (>= 2.7.5) + - FlutterMacOS - SwiftyGif (5.4.3) - url_launcher_ios (0.0.1): - Flutter @@ -79,14 +76,13 @@ DEPENDENCIES: - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - - sqflite (from `.symlinks/plugins/sqflite/ios`) + - sqflite (from `.symlinks/plugins/sqflite/darwin`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) SPEC REPOS: trunk: - DKImagePickerController - DKPhotoGallery - - FMDB - SDWebImage - SwiftyGif @@ -114,7 +110,7 @@ EXTERNAL SOURCES: shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/darwin" sqflite: - :path: ".symlinks/plugins/sqflite/ios" + :path: ".symlinks/plugins/sqflite/darwin" url_launcher_ios: :path: ".symlinks/plugins/url_launcher_ios/ios" @@ -123,21 +119,20 @@ SPEC CHECKSUMS: DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 file_picker: ce3938a0df3cc1ef404671531facef740d03f920 - Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_localization: f43b18844a2b3d2c71fd64f04ffd6b1e64dd54d4 - FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a - image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5 + image_picker_ios: b545a5f16c0fa88e3ecbbce3ed4de45567a8ec18 integration_test: 13825b8a9334a850581300559b8839134b124670 launch_review: 75d5a956ba8eaa493e9c9d4bf4c05e505e8d5ed0 package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85 - path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 + path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 SDWebImage: fb26a455eeda4c7a55e4dcb6172dbb258af7a4ca - shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 - sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a + shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 + sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780 - url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b + url_launcher_ios: 6116280ddcfe98ab8820085d8d76ae7449447586 -PODFILE CHECKSUM: a62623f56f2d1d0e85a4a3c73509cd2832d5c86f +PODFILE CHECKSUM: e2a224bbf6f8e33f28e7ef2957601a0b8926a718 COCOAPODS: 1.14.3 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index a7efac41..6b863eca 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -156,7 +156,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -343,7 +343,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -421,7 +421,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -470,7 +470,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index c87d15a3..5e31d3d3 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ showOnboardingPage + ? const OnboardingPage( + navigateTo: LandingPage(title: 'Pocket Paint'), + ) + : const LandingPage(title: 'Pocket Paint'), + ); + case '/PocketPaint': + return MaterialPageRoute( + builder: (context) => const WorkspacePage(), + ); + case '/OnboardingPage': + return MaterialPageRoute( + builder: (context) => const OnboardingPage(), + ); + } + return null; + }, + home: Consumer( + builder: (BuildContext context, WidgetRef ref, Widget? child) { + return LoadingOverlay( + isLoading: ref.watch( + WorkspaceState.provider + .select((state) => state.isPerformingIOTask), + ), + child: child); + }, + child: const LandingPage(title: 'Pocket Paint'), + ), + ), + ); + } +} diff --git a/lib/core/commands/command_factory/command_factory.dart b/lib/core/commands/command_factory/command_factory.dart new file mode 100644 index 00000000..6abfd828 --- /dev/null +++ b/lib/core/commands/command_factory/command_factory.dart @@ -0,0 +1,14 @@ +// Dart imports: +import 'dart:ui'; + +// Project imports: +import 'package:paintroid/core/commands/command_implementation/graphic/draw_path_command.dart'; +import 'package:paintroid/core/commands/path_with_action_history.dart'; + +class CommandFactory { + const CommandFactory(); + + DrawPathCommand createDrawPathCommand( + PathWithActionHistory path, Paint paint) => + DrawPathCommand(path, paint); +} diff --git a/packages/command/lib/src/command_factory/command_factory_provider.dart b/lib/core/commands/command_factory/command_factory_provider.dart similarity index 61% rename from packages/command/lib/src/command_factory/command_factory_provider.dart rename to lib/core/commands/command_factory/command_factory_provider.dart index 2145599c..bd874239 100644 --- a/packages/command/lib/src/command_factory/command_factory_provider.dart +++ b/lib/core/commands/command_factory/command_factory_provider.dart @@ -1,6 +1,11 @@ -import 'package:command/command.dart'; +// Package imports: + +// Package imports: import 'package:riverpod_annotation/riverpod_annotation.dart'; +// Project imports: +import 'package:paintroid/core/commands/command_factory/command_factory.dart'; + part 'command_factory_provider.g.dart'; @Riverpod(keepAlive: true) diff --git a/packages/command/lib/src/command_factory/command_factory_provider.g.dart b/lib/core/commands/command_factory/command_factory_provider.g.dart similarity index 93% rename from packages/command/lib/src/command_factory/command_factory_provider.g.dart rename to lib/core/commands/command_factory/command_factory_provider.g.dart index c851d50b..ce843453 100644 --- a/packages/command/lib/src/command_factory/command_factory_provider.g.dart +++ b/lib/core/commands/command_factory/command_factory_provider.g.dart @@ -22,4 +22,4 @@ final commandFactoryProvider = Provider.internal( typedef CommandFactoryRef = ProviderRef; // ignore_for_file: type=lint -// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/packages/command/lib/src/command_implementation/command.dart b/lib/core/commands/command_implementation/command.dart similarity index 65% rename from packages/command/lib/src/command_implementation/command.dart rename to lib/core/commands/command_implementation/command.dart index e5377362..c46106ad 100644 --- a/packages/command/lib/src/command_implementation/command.dart +++ b/lib/core/commands/command_implementation/command.dart @@ -1,6 +1,9 @@ -import 'package:command/command.dart'; +// Package imports: import 'package:equatable/equatable.dart'; -import 'package:io_library/io_library.dart'; + +// Project imports: +import 'package:paintroid/core/commands/command_implementation/graphic/draw_path_command.dart'; +import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart'; abstract class Command with EquatableMixin { const Command(); diff --git a/packages/command/lib/src/command_implementation/graphic/draw_path_command.dart b/lib/core/commands/command_implementation/graphic/draw_path_command.dart similarity index 65% rename from packages/command/lib/src/command_implementation/graphic/draw_path_command.dart rename to lib/core/commands/command_implementation/graphic/draw_path_command.dart index 9b715d4c..9d9c9795 100644 --- a/packages/command/lib/src/command_implementation/graphic/draw_path_command.dart +++ b/lib/core/commands/command_implementation/graphic/draw_path_command.dart @@ -1,10 +1,20 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; +// Flutter imports: import 'package:flutter/widgets.dart'; -import 'package:io_library/io_library.dart'; + +// Package imports: import 'package:json_annotation/json_annotation.dart'; +// Project imports: +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 'draw_path_command.g.dart'; @JsonSerializable() @@ -25,7 +35,7 @@ class DrawPathCommand extends GraphicCommand { @override void call(Canvas canvas) { - canvas.drawPath(path, paint); + canvas.drawPath(path.path, paint); } @override diff --git a/packages/command/lib/src/command_implementation/graphic/draw_path_command.g.dart b/lib/core/commands/command_implementation/graphic/draw_path_command.g.dart similarity index 94% rename from packages/command/lib/src/command_implementation/graphic/draw_path_command.g.dart rename to lib/core/commands/command_implementation/graphic/draw_path_command.g.dart index 5d76772c..2e2d5bfc 100644 --- a/packages/command/lib/src/command_implementation/graphic/draw_path_command.g.dart +++ b/lib/core/commands/command_implementation/graphic/draw_path_command.g.dart @@ -12,7 +12,7 @@ DrawPathCommand _$DrawPathCommandFromJson(Map json) => .fromJson(json['path'] as Map), const PaintConverter().fromJson(json['paint'] as Map), type: json['type'] as String? ?? SerializerType.DRAW_PATH_COMMAND, - version: json['version'] as int?, + version: (json['version'] as num?)?.toInt(), ); Map _$DrawPathCommandToJson(DrawPathCommand instance) => diff --git a/lib/core/commands/command_implementation/graphic/graphic_command.dart b/lib/core/commands/command_implementation/graphic/graphic_command.dart new file mode 100644 index 00000000..9219e9ac --- /dev/null +++ b/lib/core/commands/command_implementation/graphic/graphic_command.dart @@ -0,0 +1,15 @@ +// Dart imports: +import 'dart:ui'; + +// Project imports: +import 'package:paintroid/core/commands/command_implementation/command.dart'; +import 'package:paintroid/core/json_serialization/converter/paint_converter.dart'; + +abstract class GraphicCommand extends Command { + const GraphicCommand(this.paint); + + @PaintConverter() + final Paint paint; + + void call(Canvas canvas); +} diff --git a/packages/command/lib/src/command_manager/command_manager.dart b/lib/core/commands/command_manager/command_manager.dart similarity index 61% rename from packages/command/lib/src/command_manager/command_manager.dart rename to lib/core/commands/command_manager/command_manager.dart index e854432b..5ee68981 100644 --- a/packages/command/lib/src/command_manager/command_manager.dart +++ b/lib/core/commands/command_manager/command_manager.dart @@ -1,6 +1,9 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; +// Project imports: +import 'package:paintroid/core/commands/command_implementation/command.dart'; +import 'package:paintroid/core/commands/command_implementation/graphic/graphic_command.dart'; abstract class CommandManager { Iterable get history; diff --git a/packages/command/lib/src/command_manager/command_manager_provider.dart b/lib/core/commands/command_manager/command_manager_provider.dart similarity index 50% rename from packages/command/lib/src/command_manager/command_manager_provider.dart rename to lib/core/commands/command_manager/command_manager_provider.dart index f9b73082..d3cf391d 100644 --- a/packages/command/lib/src/command_manager/command_manager_provider.dart +++ b/lib/core/commands/command_manager/command_manager_provider.dart @@ -1,6 +1,12 @@ -import 'package:command/command.dart'; +// Package imports: + +// Package imports: import 'package:riverpod_annotation/riverpod_annotation.dart'; +// Project imports: +import 'package:paintroid/core/commands/command_manager/command_manager.dart'; +import 'package:paintroid/core/commands/command_manager/sync_command_manager.dart'; + part 'command_manager_provider.g.dart'; @Riverpod(keepAlive: true) diff --git a/packages/command/lib/src/command_manager/command_manager_provider.g.dart b/lib/core/commands/command_manager/command_manager_provider.g.dart similarity index 93% rename from packages/command/lib/src/command_manager/command_manager_provider.g.dart rename to lib/core/commands/command_manager/command_manager_provider.g.dart index 528fd2be..1fd7883f 100644 --- a/packages/command/lib/src/command_manager/command_manager_provider.g.dart +++ b/lib/core/commands/command_manager/command_manager_provider.g.dart @@ -22,4 +22,4 @@ final commandManagerProvider = Provider.internal( typedef CommandManagerRef = ProviderRef; // ignore_for_file: type=lint -// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/packages/command/lib/src/command_manager/sync_command_manager.dart b/lib/core/commands/command_manager/sync_command_manager.dart similarity index 78% rename from packages/command/lib/src/command_manager/sync_command_manager.dart rename to lib/core/commands/command_manager/sync_command_manager.dart index 9c060087..888a5407 100644 --- a/packages/command/lib/src/command_manager/sync_command_manager.dart +++ b/lib/core/commands/command_manager/sync_command_manager.dart @@ -1,6 +1,10 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; +// Project imports: +import 'package:paintroid/core/commands/command_implementation/command.dart'; +import 'package:paintroid/core/commands/command_implementation/graphic/graphic_command.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager.dart'; class SyncCommandManager implements CommandManager { SyncCommandManager({required List commands}) : _history = commands; diff --git a/packages/features/workspace_screen/lib/src/components/drawing_surface/command_painter.dart b/lib/core/commands/command_painter.dart similarity index 77% rename from packages/features/workspace_screen/lib/src/components/drawing_surface/command_painter.dart rename to lib/core/commands/command_painter.dart index dc50e60b..9f3c7f81 100644 --- a/packages/features/workspace_screen/lib/src/components/drawing_surface/command_painter.dart +++ b/lib/core/commands/command_painter.dart @@ -1,6 +1,9 @@ -import 'package:command/command.dart'; +// Flutter imports: import 'package:flutter/material.dart'; +// Project imports: +import 'package:paintroid/core/commands/command_manager/command_manager.dart'; + class CommandPainter extends CustomPainter { CommandPainter(this.commandManager); diff --git a/packages/command/lib/graphic_factory/graphic_factory.dart b/lib/core/commands/graphic_factory/graphic_factory.dart similarity index 89% rename from packages/command/lib/graphic_factory/graphic_factory.dart rename to lib/core/commands/graphic_factory/graphic_factory.dart index d1ddb975..d789c61f 100644 --- a/packages/command/lib/graphic_factory/graphic_factory.dart +++ b/lib/core/commands/graphic_factory/graphic_factory.dart @@ -1,6 +1,8 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; +// Project imports: +import 'package:paintroid/core/commands/path_with_action_history.dart'; class GraphicFactory { const GraphicFactory(); diff --git a/packages/command/lib/graphic_factory/graphic_factory_provider.dart b/lib/core/commands/graphic_factory/graphic_factory_provider.dart similarity index 61% rename from packages/command/lib/graphic_factory/graphic_factory_provider.dart rename to lib/core/commands/graphic_factory/graphic_factory_provider.dart index 887ee7bb..7022daed 100644 --- a/packages/command/lib/graphic_factory/graphic_factory_provider.dart +++ b/lib/core/commands/graphic_factory/graphic_factory_provider.dart @@ -1,6 +1,11 @@ -import 'package:command/graphic_factory/graphic_factory.dart'; +// Package imports: + +// Package imports: import 'package:riverpod_annotation/riverpod_annotation.dart'; +// Project imports: +import 'package:paintroid/core/commands/graphic_factory/graphic_factory.dart'; + part 'graphic_factory_provider.g.dart'; @Riverpod(keepAlive: true) diff --git a/packages/command/lib/graphic_factory/graphic_factory_provider.g.dart b/lib/core/commands/graphic_factory/graphic_factory_provider.g.dart similarity index 93% rename from packages/command/lib/graphic_factory/graphic_factory_provider.g.dart rename to lib/core/commands/graphic_factory/graphic_factory_provider.g.dart index af0d0b89..941bc82e 100644 --- a/packages/command/lib/graphic_factory/graphic_factory_provider.g.dart +++ b/lib/core/commands/graphic_factory/graphic_factory_provider.g.dart @@ -22,4 +22,4 @@ final graphicFactoryProvider = Provider.internal( typedef GraphicFactoryRef = ProviderRef; // ignore_for_file: type=lint -// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/packages/command/lib/utils/path_with_action_history.dart b/lib/core/commands/path_with_action_history.dart similarity index 81% rename from packages/command/lib/utils/path_with_action_history.dart rename to lib/core/commands/path_with_action_history.dart index e5657dde..8cb66a74 100644 --- a/packages/command/lib/utils/path_with_action_history.dart +++ b/lib/core/commands/path_with_action_history.dart @@ -1,30 +1,34 @@ +// Dart imports: import 'dart:ui'; +// Package imports: import 'package:collection/collection.dart'; -import 'package:io_library/io_library.dart'; -class PathWithActionHistory extends Path { +// Project imports: +import 'package:paintroid/core/json_serialization/converter/path_action_converter.dart'; +import 'package:paintroid/core/json_serialization/converter/path_with_action_history_converter.dart'; + +class PathWithActionHistory { PathWithActionHistory(); + final path = Path(); + @PathActionConverter() final actions = []; - @override void moveTo(double x, double y) { actions.add(MoveToAction(x, y)); - super.moveTo(x, y); + path.moveTo(x, y); } - @override void lineTo(double x, double y) { actions.add(LineToAction(x, y)); - super.lineTo(x, y); + path.lineTo(x, y); } - @override void close() { actions.add(const CloseAction()); - super.close(); + path.close(); } Map toJson() { diff --git a/packages/database/lib/src/project_dao.dart b/lib/core/database/project_dao.dart similarity index 86% rename from packages/database/lib/src/project_dao.dart rename to lib/core/database/project_dao.dart index 0f173cca..544bc0f8 100644 --- a/packages/database/lib/src/project_dao.dart +++ b/lib/core/database/project_dao.dart @@ -1,6 +1,9 @@ -import 'package:database/src/models/project.dart'; +// Package imports: import 'package:floor/floor.dart'; +// Project imports: +import 'package:paintroid/core/models/database/project.dart'; + @dao abstract class ProjectDAO { @Insert(onConflict: OnConflictStrategy.replace) diff --git a/packages/database/lib/src/project_database.dart b/lib/core/database/project_database.dart similarity index 63% rename from packages/database/lib/src/project_database.dart rename to lib/core/database/project_database.dart index bfde21c2..d06e52b3 100644 --- a/packages/database/lib/src/project_database.dart +++ b/lib/core/database/project_database.dart @@ -1,15 +1,20 @@ +// Dart imports: import 'dart:async'; -import 'package:database/src/models/project.dart'; -import 'package:database/src/project_dao.dart'; -import 'package:database/src/utils/date_time_converter.dart'; +// Package imports: import 'package:floor/floor.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; - import 'package:sqflite/sqflite.dart' as sqflite; +// Project imports: +import 'package:paintroid/core/database/project_dao.dart'; +import 'package:paintroid/core/models/database/project.dart'; +import 'package:paintroid/core/utils/date_time_converter.dart'; + part 'project_database.g.dart'; +String databaseName = 'project_database.db'; + @TypeConverters([DateTimeConverter]) @Database(version: 1, entities: [Project]) abstract class ProjectDatabase extends FloorDatabase { diff --git a/packages/database/lib/src/project_database.g.dart b/lib/core/database/project_database.g.dart similarity index 100% rename from packages/database/lib/src/project_database.g.dart rename to lib/core/database/project_database.g.dart diff --git a/packages/io_library/lib/src/enums/image_format.dart b/lib/core/enums/image_format.dart similarity index 100% rename from packages/io_library/lib/src/enums/image_format.dart rename to lib/core/enums/image_format.dart diff --git a/packages/io_library/lib/src/enums/image_location.dart b/lib/core/enums/image_location.dart similarity index 100% rename from packages/io_library/lib/src/enums/image_location.dart rename to lib/core/enums/image_location.dart diff --git a/packages/tools/lib/src/enums/tool_types.dart b/lib/core/enums/tool_types.dart similarity index 100% rename from packages/tools/lib/src/enums/tool_types.dart rename to lib/core/enums/tool_types.dart diff --git a/packages/io_library/lib/src/json_serialization/converter/paint_converter.dart b/lib/core/json_serialization/converter/paint_converter.dart similarity index 92% rename from packages/io_library/lib/src/json_serialization/converter/paint_converter.dart rename to lib/core/json_serialization/converter/paint_converter.dart index 902a4c0c..59cd971b 100644 --- a/packages/io_library/lib/src/json_serialization/converter/paint_converter.dart +++ b/lib/core/json_serialization/converter/paint_converter.dart @@ -1,8 +1,12 @@ +// Dart imports: import 'dart:ui'; -import 'package:io_library/io_library.dart'; +// Package imports: import 'package:json_annotation/json_annotation.dart'; +// Project imports: +import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart'; + class PaintConverter implements JsonConverter> { const PaintConverter(); diff --git a/packages/io_library/lib/src/json_serialization/converter/path_action_converter.dart b/lib/core/json_serialization/converter/path_action_converter.dart similarity index 81% rename from packages/io_library/lib/src/json_serialization/converter/path_action_converter.dart rename to lib/core/json_serialization/converter/path_action_converter.dart index d1dd5dd9..2b6d5171 100644 --- a/packages/io_library/lib/src/json_serialization/converter/path_action_converter.dart +++ b/lib/core/json_serialization/converter/path_action_converter.dart @@ -1,6 +1,9 @@ -import 'package:command/command.dart'; +// Package imports: import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:io_library/io_library.dart'; + +// Project imports: +import 'package:paintroid/core/commands/path_with_action_history.dart'; +import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart'; class PathActionConverter implements JsonConverter> { @@ -23,14 +26,14 @@ class PathActionConverter @override Map toJson(PathAction action) { switch (action.runtimeType) { - case MoveToAction: + case == MoveToAction: action as MoveToAction; return { 'type': SerializerType.MOVE_TO_ACTION, 'x': action.x, 'y': action.y, }; - case LineToAction: + case == LineToAction: action as LineToAction; return { 'type': SerializerType.LINE_TO_ACTION, diff --git a/packages/io_library/lib/src/json_serialization/converter/path_with_action_history_converter.dart b/lib/core/json_serialization/converter/path_with_action_history_converter.dart similarity index 84% rename from packages/io_library/lib/src/json_serialization/converter/path_with_action_history_converter.dart rename to lib/core/json_serialization/converter/path_with_action_history_converter.dart index 0edb3902..071b4299 100644 --- a/packages/io_library/lib/src/json_serialization/converter/path_with_action_history_converter.dart +++ b/lib/core/json_serialization/converter/path_with_action_history_converter.dart @@ -1,6 +1,9 @@ -import 'package:command/command.dart'; +// Package imports: import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:io_library/io_library.dart'; + +// Project imports: +import 'package:paintroid/core/commands/path_with_action_history.dart'; +import 'package:paintroid/core/json_serialization/converter/path_action_converter.dart'; class PathWithActionHistoryConverter implements JsonConverter> { diff --git a/packages/io_library/lib/src/json_serialization/versioning/serializer_version.dart b/lib/core/json_serialization/versioning/serializer_version.dart similarity index 100% rename from packages/io_library/lib/src/json_serialization/versioning/serializer_version.dart rename to lib/core/json_serialization/versioning/serializer_version.dart diff --git a/packages/io_library/lib/src/json_serialization/versioning/version_strategy.dart b/lib/core/json_serialization/versioning/version_strategy.dart similarity index 82% rename from packages/io_library/lib/src/json_serialization/versioning/version_strategy.dart rename to lib/core/json_serialization/versioning/version_strategy.dart index 0f4ca73f..e7ddb3d6 100644 --- a/packages/io_library/lib/src/json_serialization/versioning/version_strategy.dart +++ b/lib/core/json_serialization/versioning/version_strategy.dart @@ -1,4 +1,7 @@ -import 'package:io_library/io_library.dart'; +// Project imports: + +// Project imports: +import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart'; abstract class IVersionStrategy { int getCatrobatImageVersion(); diff --git a/packages/l10n/lib/src/l10n/app_localizations.dart b/lib/core/localization/app_localizations.dart similarity index 97% rename from packages/l10n/lib/src/l10n/app_localizations.dart rename to lib/core/localization/app_localizations.dart index 86fb2fbb..419d86cf 100644 --- a/packages/l10n/lib/src/l10n/app_localizations.dart +++ b/lib/core/localization/app_localizations.dart @@ -1,11 +1,16 @@ +// Dart imports: import 'dart:async'; +// Flutter imports: import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; + +// Package imports: import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:intl/intl.dart' as intl; -import 'app_localizations_en.dart'; +// Project imports: +import 'package:paintroid/core/localization/app_localizations_en.dart'; /// Callers can lookup localized strings with an instance of AppLocalizations /// returned by `AppLocalizations.of(context)`. diff --git a/packages/l10n/lib/src/l10n/app_localizations_en.dart b/lib/core/localization/app_localizations_en.dart similarity index 78% rename from packages/l10n/lib/src/l10n/app_localizations_en.dart rename to lib/core/localization/app_localizations_en.dart index 3d07e5cc..44130e0f 100644 --- a/packages/l10n/lib/src/l10n/app_localizations_en.dart +++ b/lib/core/localization/app_localizations_en.dart @@ -1,8 +1,8 @@ -import 'app_localizations.dart'; +// Project imports: +import 'package:paintroid/core/localization/app_localizations.dart'; -/// The translations for English (`en`). class AppLocalizationsEn extends AppLocalizations { - AppLocalizationsEn([String locale = 'en']) : super(locale); + AppLocalizationsEn([super.locale = 'en']); @override String get fullscreen => 'Fullscreen'; diff --git a/packages/io_library/lib/src/models/catrobat_image.dart b/lib/core/models/catrobat_image.dart similarity index 80% rename from packages/io_library/lib/src/models/catrobat_image.dart rename to lib/core/models/catrobat_image.dart index 49eb9c04..22c2b3b4 100644 --- a/packages/io_library/lib/src/models/catrobat_image.dart +++ b/lib/core/models/catrobat_image.dart @@ -1,9 +1,14 @@ +// Dart imports: import 'dart:convert'; import 'dart:typed_data'; -import 'package:command/command.dart'; +// Package imports: import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:io_library/io_library.dart'; + +// Project imports: +import 'package:paintroid/core/commands/command_implementation/command.dart'; +import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart'; +import 'package:paintroid/core/json_serialization/versioning/version_strategy.dart'; part 'catrobat_image.g.dart'; @@ -29,7 +34,7 @@ class CatrobatImage { Uint8List toBytes() { Map jsonMap = toJson(); String jsonString = json.encode(jsonMap); - return utf8.encode(jsonString) as Uint8List; + return utf8.encode(jsonString); } static CatrobatImage fromBytes(Uint8List bytes) { diff --git a/packages/io_library/lib/src/models/catrobat_image.g.dart b/lib/core/models/catrobat_image.g.dart similarity index 87% rename from packages/io_library/lib/src/models/catrobat_image.g.dart rename to lib/core/models/catrobat_image.g.dart index 9d900f86..3d0e763b 100644 --- a/packages/io_library/lib/src/models/catrobat_image.g.dart +++ b/lib/core/models/catrobat_image.g.dart @@ -10,10 +10,10 @@ CatrobatImage _$CatrobatImageFromJson(Map json) => CatrobatImage( (json['commands'] as List) .map((e) => Command.fromJson(e as Map)), - json['width'] as int, - json['height'] as int, + (json['width'] as num).toInt(), + (json['height'] as num).toInt(), json['backgroundImage'] as String, - version: json['version'] as int?, + version: (json['version'] as num?)?.toInt(), magicValue: json['magicValue'] as String? ?? 'CATROBAT', ); diff --git a/packages/database/lib/src/models/project.dart b/lib/core/models/database/project.dart similarity index 96% rename from packages/database/lib/src/models/project.dart rename to lib/core/models/database/project.dart index ca901d2e..6af69b76 100644 --- a/packages/database/lib/src/models/project.dart +++ b/lib/core/models/database/project.dart @@ -1,3 +1,4 @@ +// Package imports: import 'package:floor/floor.dart'; @entity diff --git a/packages/io_library/lib/src/models/image_from_file.dart b/lib/core/models/image_from_file.dart similarity index 79% rename from packages/io_library/lib/src/models/image_from_file.dart rename to lib/core/models/image_from_file.dart index 7183b72c..93c5f1e3 100644 --- a/packages/io_library/lib/src/models/image_from_file.dart +++ b/lib/core/models/image_from_file.dart @@ -1,6 +1,8 @@ +// Dart imports: import 'dart:ui'; -import 'package:io_library/io_library.dart'; +// Project imports: +import 'package:paintroid/core/models/catrobat_image.dart'; class ImageFromFile { final Image? rasterImage; diff --git a/packages/io_library/lib/src/models/image_meta_data.dart b/lib/core/models/image_meta_data.dart similarity index 90% rename from packages/io_library/lib/src/models/image_meta_data.dart rename to lib/core/models/image_meta_data.dart index ee9385c3..7045acca 100644 --- a/packages/io_library/lib/src/models/image_meta_data.dart +++ b/lib/core/models/image_meta_data.dart @@ -1,4 +1,5 @@ -import 'package:io_library/io_library.dart'; +// Project imports: +import 'package:paintroid/core/enums/image_format.dart'; abstract class ImageMetaData { final String name; diff --git a/packages/features/workspace_screen/lib/src/models/image_with_pixel_info.dart b/lib/core/models/image_with_pixel_info.dart similarity index 97% rename from packages/features/workspace_screen/lib/src/models/image_with_pixel_info.dart rename to lib/core/models/image_with_pixel_info.dart index 4d87ea2a..5644bff1 100644 --- a/packages/features/workspace_screen/lib/src/models/image_with_pixel_info.dart +++ b/lib/core/models/image_with_pixel_info.dart @@ -1,5 +1,7 @@ +// Dart imports: import 'dart:ui'; +// Flutter imports: import 'package:flutter/foundation.dart'; import 'package:flutter/painting.dart'; import 'package:flutter/services.dart'; diff --git a/packages/io_library/lib/src/models/loggable_mixin.dart b/lib/core/models/loggable_mixin.dart similarity index 85% rename from packages/io_library/lib/src/models/loggable_mixin.dart rename to lib/core/models/loggable_mixin.dart index 9046ec84..08ae906c 100644 --- a/packages/io_library/lib/src/models/loggable_mixin.dart +++ b/lib/core/models/loggable_mixin.dart @@ -1,3 +1,4 @@ +// Package imports: import 'package:logging/logging.dart'; mixin LoggableMixin { diff --git a/packages/features/workspace_screen/lib/src/states/canvas_dirty_state.dart b/lib/core/providers/object/canvas_dirty_notifier.dart similarity index 60% rename from packages/features/workspace_screen/lib/src/states/canvas_dirty_state.dart rename to lib/core/providers/object/canvas_dirty_notifier.dart index 4d19c4aa..61f1c97e 100644 --- a/packages/features/workspace_screen/lib/src/states/canvas_dirty_state.dart +++ b/lib/core/providers/object/canvas_dirty_notifier.dart @@ -1,9 +1,12 @@ +// Flutter imports: import 'package:flutter/foundation.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -class CanvasDirtyState extends ChangeNotifier { +class CanvasDirtyNotifier extends ChangeNotifier { static final provider = ChangeNotifierProvider( - (ref) => CanvasDirtyState(), + (ref) => CanvasDirtyNotifier(), ); void repaint() => notifyListeners(); diff --git a/packages/features/workspace_screen/lib/src/service/device_service.dart b/lib/core/providers/object/device_service.dart similarity index 94% rename from packages/features/workspace_screen/lib/src/service/device_service.dart rename to lib/core/providers/object/device_service.dart index d37a6509..58fb11a1 100644 --- a/packages/features/workspace_screen/lib/src/service/device_service.dart +++ b/lib/core/providers/object/device_service.dart @@ -1,8 +1,12 @@ +// Dart imports: import 'dart:io'; import 'dart:ui' as ui; +// Flutter imports: import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; abstract class IDeviceService { diff --git a/packages/io_library/lib/src/service/file_service.dart b/lib/core/providers/object/file_service.dart similarity index 92% rename from packages/io_library/lib/src/service/file_service.dart rename to lib/core/providers/object/file_service.dart index 2d72e9b9..2f20d1ae 100644 --- a/packages/io_library/lib/src/service/file_service.dart +++ b/lib/core/providers/object/file_service.dart @@ -1,13 +1,19 @@ +// Dart imports: import 'dart:io'; import 'dart:typed_data'; +// Package imports: import 'package:file_picker/file_picker.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; - import 'package:path_provider/path_provider.dart'; +// Project imports: +import 'package:paintroid/core/models/loggable_mixin.dart'; +import 'package:paintroid/core/utils/failure.dart'; +import 'package:paintroid/core/utils/load_image_failure.dart'; +import 'package:paintroid/core/utils/save_image_failure.dart'; + abstract class IFileService { Future> save(String filename, Uint8List data); diff --git a/packages/io_library/lib/src/service/image_service.dart b/lib/core/providers/object/image_service.dart similarity index 89% rename from packages/io_library/lib/src/service/image_service.dart rename to lib/core/providers/object/image_service.dart index 353a736c..a49a2bdb 100644 --- a/packages/io_library/lib/src/service/image_service.dart +++ b/lib/core/providers/object/image_service.dart @@ -1,13 +1,22 @@ +// Dart imports: import 'dart:io'; import 'dart:typed_data'; import 'dart:ui' as ui; +// Flutter imports: import 'package:flutter/painting.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:image/image.dart'; -import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; +// Project imports: +import 'package:paintroid/core/models/loggable_mixin.dart'; +import 'package:paintroid/core/utils/failure.dart'; +import 'package:paintroid/core/utils/load_image_failure.dart'; +import 'package:paintroid/core/utils/save_image_failure.dart'; + abstract class IImageService { Future> import(Uint8List fileData); diff --git a/packages/io_library/lib/src/io_handler.dart b/lib/core/providers/object/io_handler.dart similarity index 82% rename from packages/io_library/lib/src/io_handler.dart rename to lib/core/providers/object/io_handler.dart index 72c0a782..b5e01218 100644 --- a/packages/io_library/lib/src/io_handler.dart +++ b/lib/core/providers/object/io_handler.dart @@ -1,14 +1,36 @@ +// Dart imports: import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; -import 'package:command/command_providers.dart'; -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; -import 'package:workspace_screen/workspace_screen.dart'; + +// Project imports: +import 'package:paintroid/core/commands/command_manager/command_manager_provider.dart'; +import 'package:paintroid/core/enums/image_format.dart'; +import 'package:paintroid/core/enums/image_location.dart'; +import 'package:paintroid/core/models/catrobat_image.dart'; +import 'package:paintroid/core/models/image_meta_data.dart'; +import 'package:paintroid/core/providers/object/file_service.dart'; +import 'package:paintroid/core/providers/object/image_service.dart'; +import 'package:paintroid/core/providers/object/load_image_from_file_manager.dart'; +import 'package:paintroid/core/providers/object/load_image_from_photo_library.dart'; +import 'package:paintroid/core/providers/object/render_image_for_export.dart'; +import 'package:paintroid/core/providers/object/save_as_catrobat_image.dart'; +import 'package:paintroid/core/providers/object/save_as_raster_image.dart'; +import 'package:paintroid/core/providers/state/canvas_state_provider.dart'; +import 'package:paintroid/core/providers/state/workspace_state_notifier.dart'; +import 'package:paintroid/core/utils/failure.dart'; +import 'package:paintroid/core/utils/load_image_failure.dart'; +import 'package:paintroid/ui/shared/dialogs/discard_changes_dialog.dart'; +import 'package:paintroid/ui/shared/dialogs/load_image_dialog.dart'; +import 'package:paintroid/ui/shared/dialogs/save_image_dialog.dart'; +import 'package:paintroid/ui/utils/toast_utils.dart'; class IOHandler { final Ref ref; @@ -26,7 +48,13 @@ class IOHandler { } final isFileSaved = await workspaceStateNotifier .performIOTask(() => _saveImageWith(imageMetaData)); - workspaceStateNotifier.updateLastSavedCommandCount(); + + if (!isFileSaved) { + workspaceStateNotifier.markUnsavedChanges(); + } else { + workspaceStateNotifier.updateLastSavedCommandCount(); + } + return isFileSaved; } @@ -48,6 +76,7 @@ class IOHandler { final shouldDiscard = await showDiscardChangesDialog(context); if (shouldDiscard == null || !state.mounted) return false; if (!shouldDiscard) { + if (!context.mounted) return false; final didSave = await saveImage(context); if (!didSave) return false; } @@ -64,6 +93,7 @@ class IOHandler { } if (Platform.isIOS) { if (!state.mounted) return false; + if (!context.mounted) return false; final location = await showLoadImageDialog(context); if (location == null) return false; return ref diff --git a/packages/io_library/lib/src/usecase/load_image_from_file_manager.dart b/lib/core/providers/object/load_image_from_file_manager.dart similarity index 81% rename from packages/io_library/lib/src/usecase/load_image_from_file_manager.dart rename to lib/core/providers/object/load_image_from_file_manager.dart index aaa4d2fd..58636a13 100644 --- a/packages/io_library/lib/src/usecase/load_image_from_file_manager.dart +++ b/lib/core/providers/object/load_image_from_file_manager.dart @@ -1,12 +1,24 @@ +// Dart imports: import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'dart:ui'; +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; +// Project imports: +import 'package:paintroid/core/models/catrobat_image.dart'; +import 'package:paintroid/core/models/image_from_file.dart'; +import 'package:paintroid/core/models/loggable_mixin.dart'; +import 'package:paintroid/core/providers/object/file_service.dart'; +import 'package:paintroid/core/providers/object/image_service.dart'; +import 'package:paintroid/core/providers/object/permission_service.dart'; +import 'package:paintroid/core/utils/failure.dart'; +import 'package:paintroid/core/utils/load_image_failure.dart'; +import 'package:paintroid/core/utils/save_image_failure.dart'; + extension on File { String? get extension { final list = path.split('.'); diff --git a/packages/io_library/lib/src/usecase/load_image_from_photo_library.dart b/lib/core/providers/object/load_image_from_photo_library.dart similarity index 73% rename from packages/io_library/lib/src/usecase/load_image_from_photo_library.dart rename to lib/core/providers/object/load_image_from_photo_library.dart index 92366e3f..1d03c9f7 100644 --- a/packages/io_library/lib/src/usecase/load_image_from_photo_library.dart +++ b/lib/core/providers/object/load_image_from_photo_library.dart @@ -1,9 +1,17 @@ +// Dart imports: import 'dart:ui'; +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; +// Project imports: +import 'package:paintroid/core/providers/object/image_service.dart'; +import 'package:paintroid/core/providers/object/permission_service.dart'; +import 'package:paintroid/core/providers/object/photo_library_service.dart'; +import 'package:paintroid/core/utils/failure.dart'; +import 'package:paintroid/core/utils/load_image_failure.dart'; + class LoadImageFromPhotoLibrary { final IImageService imageService; final IPermissionService permissionService; diff --git a/packages/io_library/lib/src/service/permission_service.dart b/lib/core/providers/object/permission_service.dart similarity index 96% rename from packages/io_library/lib/src/service/permission_service.dart rename to lib/core/providers/object/permission_service.dart index 1095f64e..c53cf922 100644 --- a/packages/io_library/lib/src/service/permission_service.dart +++ b/lib/core/providers/object/permission_service.dart @@ -1,10 +1,14 @@ +// Dart imports: import 'dart:io'; +// Package imports: import 'package:device_info_plus/device_info_plus.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; import 'package:permission_handler/permission_handler.dart'; +// Project imports: +import 'package:paintroid/core/models/loggable_mixin.dart'; + abstract class IPermissionService { Future requestAccessToPickPhotos(); diff --git a/packages/io_library/lib/src/service/photo_library_service.dart b/lib/core/providers/object/photo_library_service.dart similarity index 85% rename from packages/io_library/lib/src/service/photo_library_service.dart rename to lib/core/providers/object/photo_library_service.dart index 1d247b55..2894578f 100644 --- a/packages/io_library/lib/src/service/photo_library_service.dart +++ b/lib/core/providers/object/photo_library_service.dart @@ -1,9 +1,17 @@ +// Flutter imports: import 'package:flutter/services.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:image_picker/image_picker.dart'; -import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; +// Project imports: +import 'package:paintroid/core/models/loggable_mixin.dart'; +import 'package:paintroid/core/utils/failure.dart'; +import 'package:paintroid/core/utils/load_image_failure.dart'; +import 'package:paintroid/core/utils/save_image_failure.dart'; + abstract class IPhotoLibraryService { Future> save(String filename, Uint8List data); diff --git a/packages/features/workspace_screen/lib/src/usecase/render_image_for_export.dart b/lib/core/providers/object/render_image_for_export.dart similarity index 83% rename from packages/features/workspace_screen/lib/src/usecase/render_image_for_export.dart rename to lib/core/providers/object/render_image_for_export.dart index f27fe205..2ba37b83 100644 --- a/packages/features/workspace_screen/lib/src/usecase/render_image_for_export.dart +++ b/lib/core/providers/object/render_image_for_export.dart @@ -1,10 +1,18 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; -import 'package:command/command_providers.dart'; +// Flutter imports: import 'package:flutter/painting.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:workspace_screen/workspace_screen.dart'; + +// Project imports: +import 'package:paintroid/core/commands/command_manager/command_manager.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager_provider.dart'; +import 'package:paintroid/core/commands/graphic_factory/graphic_factory.dart'; +import 'package:paintroid/core/commands/graphic_factory/graphic_factory_provider.dart'; +import 'package:paintroid/core/providers/state/canvas_state_provider.dart'; class RenderImageForExport { final Ref _ref; diff --git a/packages/io_library/lib/src/usecase/save_as_catrobat_image.dart b/lib/core/providers/object/save_as_catrobat_image.dart similarity index 72% rename from packages/io_library/lib/src/usecase/save_as_catrobat_image.dart rename to lib/core/providers/object/save_as_catrobat_image.dart index c97deb6a..41c75d27 100644 --- a/packages/io_library/lib/src/usecase/save_as_catrobat_image.dart +++ b/lib/core/providers/object/save_as_catrobat_image.dart @@ -1,9 +1,19 @@ +// Dart imports: import 'dart:io'; +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; +// Project imports: +import 'package:paintroid/core/models/catrobat_image.dart'; +import 'package:paintroid/core/models/image_meta_data.dart'; +import 'package:paintroid/core/models/loggable_mixin.dart'; +import 'package:paintroid/core/providers/object/file_service.dart'; +import 'package:paintroid/core/providers/object/permission_service.dart'; +import 'package:paintroid/core/utils/failure.dart'; +import 'package:paintroid/core/utils/save_image_failure.dart'; + class SaveAsCatrobatImage with LoggableMixin { final IFileService _fileService; final IPermissionService permissionService; diff --git a/packages/io_library/lib/src/usecase/save_as_raster_image.dart b/lib/core/providers/object/save_as_raster_image.dart similarity index 73% rename from packages/io_library/lib/src/usecase/save_as_raster_image.dart rename to lib/core/providers/object/save_as_raster_image.dart index 2051142e..765bdde2 100644 --- a/packages/io_library/lib/src/usecase/save_as_raster_image.dart +++ b/lib/core/providers/object/save_as_raster_image.dart @@ -1,9 +1,18 @@ +// Dart imports: import 'dart:ui'; +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart' show Provider; -import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; +// Project imports: +import 'package:paintroid/core/models/image_meta_data.dart'; +import 'package:paintroid/core/providers/object/image_service.dart'; +import 'package:paintroid/core/providers/object/permission_service.dart'; +import 'package:paintroid/core/providers/object/photo_library_service.dart'; +import 'package:paintroid/core/utils/failure.dart'; +import 'package:paintroid/core/utils/save_image_failure.dart'; + class SaveAsRasterImage { final IImageService imageService; final IPermissionService permissionService; diff --git a/lib/core/providers/object/tools/brush_tool_provider.dart b/lib/core/providers/object/tools/brush_tool_provider.dart new file mode 100644 index 00000000..81514d76 --- /dev/null +++ b/lib/core/providers/object/tools/brush_tool_provider.dart @@ -0,0 +1,23 @@ +// Package imports: + +// Package imports: +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +// Project imports: +import 'package:paintroid/core/commands/command_factory/command_factory_provider.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager_provider.dart'; +import 'package:paintroid/core/commands/graphic_factory/graphic_factory_provider.dart'; +import 'package:paintroid/core/providers/state/tools/brush/brush_tool_state_provider.dart'; +import 'package:paintroid/core/tools/implementation/brush_tool.dart'; + +part 'brush_tool_provider.g.dart'; + +@riverpod +BrushTool brushTool(BrushToolRef ref) { + return BrushTool( + paint: ref.watch(brushToolStateProvider.select((state) => state.paint)), + commandManager: ref.watch(commandManagerProvider), + commandFactory: ref.watch(commandFactoryProvider), + graphicFactory: ref.watch(graphicFactoryProvider), + ); +} diff --git a/packages/tools/lib/src/brush_tool/brush_tool_provider.g.dart b/lib/core/providers/object/tools/brush_tool_provider.g.dart similarity index 85% rename from packages/tools/lib/src/brush_tool/brush_tool_provider.g.dart rename to lib/core/providers/object/tools/brush_tool_provider.g.dart index b08cd4a0..9c37e94d 100644 --- a/packages/tools/lib/src/brush_tool/brush_tool_provider.g.dart +++ b/lib/core/providers/object/tools/brush_tool_provider.g.dart @@ -6,7 +6,7 @@ part of 'brush_tool_provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$brushToolHash() => r'dfa4f2e7a9cb8734828ec99dd983c7904c231e46'; +String _$brushToolHash() => r'304f2061bc0aacc65e1126a253fd78d56e247dd2'; /// See also [brushTool]. @ProviderFor(brushTool) @@ -21,4 +21,4 @@ final brushToolProvider = AutoDisposeProvider.internal( typedef BrushToolRef = AutoDisposeProviderRef; // ignore_for_file: type=lint -// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/lib/core/providers/object/tools/eraser_tool_provider.dart b/lib/core/providers/object/tools/eraser_tool_provider.dart new file mode 100644 index 00000000..814ad3a3 --- /dev/null +++ b/lib/core/providers/object/tools/eraser_tool_provider.dart @@ -0,0 +1,21 @@ +// Package imports: +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +// Project imports: +import 'package:paintroid/core/commands/command_factory/command_factory_provider.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager_provider.dart'; +import 'package:paintroid/core/commands/graphic_factory/graphic_factory_provider.dart'; +import 'package:paintroid/core/providers/state/tools/brush/brush_tool_state_provider.dart'; +import 'package:paintroid/core/tools/implementation/brush_tool.dart'; + +part 'eraser_tool_provider.g.dart'; + +@riverpod +BrushTool eraserTool(EraserToolRef ref) { + return BrushTool( + paint: ref.watch(brushToolStateProvider.select((state) => state.paint)), + commandManager: ref.watch(commandManagerProvider), + commandFactory: ref.watch(commandFactoryProvider), + graphicFactory: ref.watch(graphicFactoryProvider), + ); +} diff --git a/packages/tools/lib/src/eraser_tool/eraser_tool_provider.g.dart b/lib/core/providers/object/tools/eraser_tool_provider.g.dart similarity index 85% rename from packages/tools/lib/src/eraser_tool/eraser_tool_provider.g.dart rename to lib/core/providers/object/tools/eraser_tool_provider.g.dart index 6de891a9..60f83c2c 100644 --- a/packages/tools/lib/src/eraser_tool/eraser_tool_provider.g.dart +++ b/lib/core/providers/object/tools/eraser_tool_provider.g.dart @@ -6,7 +6,7 @@ part of 'eraser_tool_provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$eraserToolHash() => r'a92e9502cc061e5298bc9c8a20fcb30f8759e1e4'; +String _$eraserToolHash() => r'0f4b6c747b0f67d0c93e029997abe8efbda136e2'; /// See also [eraserTool]. @ProviderFor(eraserTool) @@ -21,4 +21,4 @@ final eraserToolProvider = AutoDisposeProvider.internal( typedef EraserToolRef = AutoDisposeProviderRef; // ignore_for_file: type=lint -// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/lib/core/providers/object/tools/hand_tool_provider.dart b/lib/core/providers/object/tools/hand_tool_provider.dart new file mode 100644 index 00000000..1e97861e --- /dev/null +++ b/lib/core/providers/object/tools/hand_tool_provider.dart @@ -0,0 +1,21 @@ +// Package imports: + +// Package imports: +import 'package:riverpod_annotation/riverpod_annotation.dart'; + +// Project imports: +import 'package:paintroid/core/commands/command_factory/command_factory_provider.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager_provider.dart'; +import 'package:paintroid/core/providers/state/tools/brush/brush_tool_state_provider.dart'; +import 'package:paintroid/core/tools/implementation/hand_tool.dart'; + +part 'hand_tool_provider.g.dart'; + +@riverpod +HandTool handTool(HandToolRef ref) { + return HandTool( + paint: ref.watch(brushToolStateProvider.select((state) => state.paint)), + commandManager: ref.watch(commandManagerProvider), + commandFactory: ref.watch(commandFactoryProvider), + ); +} diff --git a/packages/tools/lib/src/hand_tool/hand_tool_provider.g.dart b/lib/core/providers/object/tools/hand_tool_provider.g.dart similarity index 85% rename from packages/tools/lib/src/hand_tool/hand_tool_provider.g.dart rename to lib/core/providers/object/tools/hand_tool_provider.g.dart index 9788d25b..a69ba1d1 100644 --- a/packages/tools/lib/src/hand_tool/hand_tool_provider.g.dart +++ b/lib/core/providers/object/tools/hand_tool_provider.g.dart @@ -6,7 +6,7 @@ part of 'hand_tool_provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$handToolHash() => r'693afd99b7c1ad8fb5857ebf4c75d1482f0facc5'; +String _$handToolHash() => r'0904f19a26fe0a1d18477ef1be781f3a42e82904'; /// See also [handTool]. @ProviderFor(handTool) @@ -21,4 +21,4 @@ final handToolProvider = AutoDisposeProvider.internal( typedef HandToolRef = AutoDisposeProviderRef; // ignore_for_file: type=lint -// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/packages/features/workspace_screen/lib/src/states/canvas_state_data.dart b/lib/core/providers/state/canvas_state_data.dart similarity index 66% rename from packages/features/workspace_screen/lib/src/states/canvas_state_data.dart rename to lib/core/providers/state/canvas_state_data.dart index ac45268a..fd019611 100644 --- a/packages/features/workspace_screen/lib/src/states/canvas_state_data.dart +++ b/lib/core/providers/state/canvas_state_data.dart @@ -1,9 +1,16 @@ +// Dart imports: import 'dart:ui' as ui; -import 'package:command/command.dart'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:freezed_annotation/freezed_annotation.dart'; +// Project imports: +import 'package:paintroid/core/commands/command_manager/command_manager.dart'; +import 'package:paintroid/core/commands/graphic_factory/graphic_factory.dart'; + part 'canvas_state_data.freezed.dart'; @immutable diff --git a/packages/features/workspace_screen/lib/src/states/canvas_state_data.freezed.dart b/lib/core/providers/state/canvas_state_data.freezed.dart similarity index 86% rename from packages/features/workspace_screen/lib/src/states/canvas_state_data.freezed.dart rename to lib/core/providers/state/canvas_state_data.freezed.dart index 63ce1189..2a5fe886 100644 --- a/packages/features/workspace_screen/lib/src/states/canvas_state_data.freezed.dart +++ b/lib/core/providers/state/canvas_state_data.freezed.dart @@ -12,7 +12,7 @@ part of 'canvas_state_data.dart'; T _$identity(T value) => value; final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); /// @nodoc mixin _$CanvasStateData { @@ -86,11 +86,11 @@ class _$CanvasStateDataCopyWithImpl<$Res, $Val extends CanvasStateData> } /// @nodoc -abstract class _$$_CanvasStateDataCopyWith<$Res> +abstract class _$$CanvasStateDataImplCopyWith<$Res> implements $CanvasStateDataCopyWith<$Res> { - factory _$$_CanvasStateDataCopyWith( - _$_CanvasStateData value, $Res Function(_$_CanvasStateData) then) = - __$$_CanvasStateDataCopyWithImpl<$Res>; + factory _$$CanvasStateDataImplCopyWith(_$CanvasStateDataImpl value, + $Res Function(_$CanvasStateDataImpl) then) = + __$$CanvasStateDataImplCopyWithImpl<$Res>; @override @useResult $Res call( @@ -102,11 +102,11 @@ abstract class _$$_CanvasStateDataCopyWith<$Res> } /// @nodoc -class __$$_CanvasStateDataCopyWithImpl<$Res> - extends _$CanvasStateDataCopyWithImpl<$Res, _$_CanvasStateData> - implements _$$_CanvasStateDataCopyWith<$Res> { - __$$_CanvasStateDataCopyWithImpl( - _$_CanvasStateData _value, $Res Function(_$_CanvasStateData) _then) +class __$$CanvasStateDataImplCopyWithImpl<$Res> + extends _$CanvasStateDataCopyWithImpl<$Res, _$CanvasStateDataImpl> + implements _$$CanvasStateDataImplCopyWith<$Res> { + __$$CanvasStateDataImplCopyWithImpl( + _$CanvasStateDataImpl _value, $Res Function(_$CanvasStateDataImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -118,7 +118,7 @@ class __$$_CanvasStateDataCopyWithImpl<$Res> Object? commandManager = null, Object? graphicFactory = null, }) { - return _then(_$_CanvasStateData( + return _then(_$CanvasStateDataImpl( backgroundImage: freezed == backgroundImage ? _value.backgroundImage : backgroundImage // ignore: cast_nullable_to_non_nullable @@ -145,8 +145,8 @@ class __$$_CanvasStateDataCopyWithImpl<$Res> /// @nodoc -class _$_CanvasStateData implements _CanvasStateData { - const _$_CanvasStateData( +class _$CanvasStateDataImpl implements _CanvasStateData { + const _$CanvasStateDataImpl( {this.backgroundImage, this.cachedImage, required this.size, @@ -170,10 +170,10 @@ class _$_CanvasStateData implements _CanvasStateData { } @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$_CanvasStateData && + other is _$CanvasStateDataImpl && (identical(other.backgroundImage, backgroundImage) || other.backgroundImage == backgroundImage) && (identical(other.cachedImage, cachedImage) || @@ -192,8 +192,9 @@ class _$_CanvasStateData implements _CanvasStateData { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$_CanvasStateDataCopyWith<_$_CanvasStateData> get copyWith => - __$$_CanvasStateDataCopyWithImpl<_$_CanvasStateData>(this, _$identity); + _$$CanvasStateDataImplCopyWith<_$CanvasStateDataImpl> get copyWith => + __$$CanvasStateDataImplCopyWithImpl<_$CanvasStateDataImpl>( + this, _$identity); } abstract class _CanvasStateData implements CanvasStateData { @@ -202,7 +203,7 @@ abstract class _CanvasStateData implements CanvasStateData { final ui.Image? cachedImage, required final ui.Size size, required final CommandManager commandManager, - required final GraphicFactory graphicFactory}) = _$_CanvasStateData; + required final GraphicFactory graphicFactory}) = _$CanvasStateDataImpl; @override ui.Image? get backgroundImage; @@ -216,6 +217,6 @@ abstract class _CanvasStateData implements CanvasStateData { GraphicFactory get graphicFactory; @override @JsonKey(ignore: true) - _$$_CanvasStateDataCopyWith<_$_CanvasStateData> get copyWith => + _$$CanvasStateDataImplCopyWith<_$CanvasStateDataImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/packages/features/workspace_screen/lib/src/states/canvas_state_provider.dart b/lib/core/providers/state/canvas_state_provider.dart similarity index 84% rename from packages/features/workspace_screen/lib/src/states/canvas_state_provider.dart rename to lib/core/providers/state/canvas_state_provider.dart index 8e13c3c3..8ab0f52c 100644 --- a/packages/features/workspace_screen/lib/src/states/canvas_state_provider.dart +++ b/lib/core/providers/state/canvas_state_provider.dart @@ -1,12 +1,19 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; -import 'package:command/command_providers.dart'; +// Flutter imports: import 'package:flutter/painting.dart'; import 'package:flutter/widgets.dart' as widgets; + +// Package imports: import 'package:riverpod_annotation/riverpod_annotation.dart'; -import 'package:workspace_screen/src/service/device_service.dart'; -import 'package:workspace_screen/src/states/canvas_state_data.dart'; + +// Project imports: +import 'package:paintroid/core/commands/command_implementation/command.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager_provider.dart'; +import 'package:paintroid/core/commands/graphic_factory/graphic_factory_provider.dart'; +import 'package:paintroid/core/providers/object/device_service.dart'; +import 'package:paintroid/core/providers/state/canvas_state_data.dart'; part 'canvas_state_provider.g.dart'; diff --git a/packages/features/workspace_screen/lib/src/states/canvas_state_provider.g.dart b/lib/core/providers/state/canvas_state_provider.g.dart similarity index 93% rename from packages/features/workspace_screen/lib/src/states/canvas_state_provider.g.dart rename to lib/core/providers/state/canvas_state_provider.g.dart index 870eb159..7013478d 100644 --- a/packages/features/workspace_screen/lib/src/states/canvas_state_provider.g.dart +++ b/lib/core/providers/state/canvas_state_provider.g.dart @@ -22,4 +22,4 @@ final canvasStateProvider = typedef _$CanvasState = Notifier; // ignore_for_file: type=lint -// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/packages/features/workspace_screen/lib/src/states/tool_options_visibility_state_provider.dart b/lib/core/providers/state/tool_options_visibility_state_provider.dart similarity index 93% rename from packages/features/workspace_screen/lib/src/states/tool_options_visibility_state_provider.dart rename to lib/core/providers/state/tool_options_visibility_state_provider.dart index 60b650ed..94efbefd 100644 --- a/packages/features/workspace_screen/lib/src/states/tool_options_visibility_state_provider.dart +++ b/lib/core/providers/state/tool_options_visibility_state_provider.dart @@ -1,3 +1,4 @@ +// Package imports: import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'tool_options_visibility_state_provider.g.dart'; diff --git a/packages/features/workspace_screen/lib/src/states/tool_options_visibility_state_provider.g.dart b/lib/core/providers/state/tool_options_visibility_state_provider.g.dart similarity index 94% rename from packages/features/workspace_screen/lib/src/states/tool_options_visibility_state_provider.g.dart rename to lib/core/providers/state/tool_options_visibility_state_provider.g.dart index ebe6c0e7..3f9bdb29 100644 --- a/packages/features/workspace_screen/lib/src/states/tool_options_visibility_state_provider.g.dart +++ b/lib/core/providers/state/tool_options_visibility_state_provider.g.dart @@ -24,4 +24,4 @@ final toolOptionsVisibilityStateProvider = typedef _$ToolOptionsVisibilityState = AutoDisposeNotifier; // ignore_for_file: type=lint -// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/packages/tools/lib/src/brush_tool/brush_tool_state_data.dart b/lib/core/providers/state/tools/brush/brush_tool_state_data.dart similarity index 88% rename from packages/tools/lib/src/brush_tool/brush_tool_state_data.dart rename to lib/core/providers/state/tools/brush/brush_tool_state_data.dart index 920039d2..8150da34 100644 --- a/packages/tools/lib/src/brush_tool/brush_tool_state_data.dart +++ b/lib/core/providers/state/tools/brush/brush_tool_state_data.dart @@ -1,4 +1,7 @@ +// Flutter imports: import 'package:flutter/painting.dart'; + +// Package imports: import 'package:freezed_annotation/freezed_annotation.dart'; part 'brush_tool_state_data.freezed.dart'; diff --git a/packages/tools/lib/src/brush_tool/brush_tool_state_data.freezed.dart b/lib/core/providers/state/tools/brush/brush_tool_state_data.freezed.dart similarity index 74% rename from packages/tools/lib/src/brush_tool/brush_tool_state_data.freezed.dart rename to lib/core/providers/state/tools/brush/brush_tool_state_data.freezed.dart index f48b047f..fe4c8d14 100644 --- a/packages/tools/lib/src/brush_tool/brush_tool_state_data.freezed.dart +++ b/lib/core/providers/state/tools/brush/brush_tool_state_data.freezed.dart @@ -12,7 +12,7 @@ part of 'brush_tool_state_data.dart'; T _$identity(T value) => value; final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); /// @nodoc mixin _$BrushToolStateData { @@ -57,22 +57,22 @@ class _$BrushToolStateDataCopyWithImpl<$Res, $Val extends BrushToolStateData> } /// @nodoc -abstract class _$$_BrushToolStateDataCopyWith<$Res> +abstract class _$$BrushToolStateDataImplCopyWith<$Res> implements $BrushToolStateDataCopyWith<$Res> { - factory _$$_BrushToolStateDataCopyWith(_$_BrushToolStateData value, - $Res Function(_$_BrushToolStateData) then) = - __$$_BrushToolStateDataCopyWithImpl<$Res>; + factory _$$BrushToolStateDataImplCopyWith(_$BrushToolStateDataImpl value, + $Res Function(_$BrushToolStateDataImpl) then) = + __$$BrushToolStateDataImplCopyWithImpl<$Res>; @override @useResult $Res call({Paint paint}); } /// @nodoc -class __$$_BrushToolStateDataCopyWithImpl<$Res> - extends _$BrushToolStateDataCopyWithImpl<$Res, _$_BrushToolStateData> - implements _$$_BrushToolStateDataCopyWith<$Res> { - __$$_BrushToolStateDataCopyWithImpl( - _$_BrushToolStateData _value, $Res Function(_$_BrushToolStateData) _then) +class __$$BrushToolStateDataImplCopyWithImpl<$Res> + extends _$BrushToolStateDataCopyWithImpl<$Res, _$BrushToolStateDataImpl> + implements _$$BrushToolStateDataImplCopyWith<$Res> { + __$$BrushToolStateDataImplCopyWithImpl(_$BrushToolStateDataImpl _value, + $Res Function(_$BrushToolStateDataImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -80,7 +80,7 @@ class __$$_BrushToolStateDataCopyWithImpl<$Res> $Res call({ Object? paint = null, }) { - return _then(_$_BrushToolStateData( + return _then(_$BrushToolStateDataImpl( paint: null == paint ? _value.paint : paint // ignore: cast_nullable_to_non_nullable @@ -91,8 +91,8 @@ class __$$_BrushToolStateDataCopyWithImpl<$Res> /// @nodoc -class _$_BrushToolStateData implements _BrushToolStateData { - const _$_BrushToolStateData({required this.paint}); +class _$BrushToolStateDataImpl implements _BrushToolStateData { + const _$BrushToolStateDataImpl({required this.paint}); @override final Paint paint; @@ -103,10 +103,10 @@ class _$_BrushToolStateData implements _BrushToolStateData { } @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$_BrushToolStateData && + other is _$BrushToolStateDataImpl && (identical(other.paint, paint) || other.paint == paint)); } @@ -116,19 +116,19 @@ class _$_BrushToolStateData implements _BrushToolStateData { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$_BrushToolStateDataCopyWith<_$_BrushToolStateData> get copyWith => - __$$_BrushToolStateDataCopyWithImpl<_$_BrushToolStateData>( + _$$BrushToolStateDataImplCopyWith<_$BrushToolStateDataImpl> get copyWith => + __$$BrushToolStateDataImplCopyWithImpl<_$BrushToolStateDataImpl>( this, _$identity); } abstract class _BrushToolStateData implements BrushToolStateData { const factory _BrushToolStateData({required final Paint paint}) = - _$_BrushToolStateData; + _$BrushToolStateDataImpl; @override Paint get paint; @override @JsonKey(ignore: true) - _$$_BrushToolStateDataCopyWith<_$_BrushToolStateData> get copyWith => + _$$BrushToolStateDataImplCopyWith<_$BrushToolStateDataImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/packages/tools/lib/src/brush_tool/brush_tool_state_provider.dart b/lib/core/providers/state/tools/brush/brush_tool_state_provider.dart similarity index 81% rename from packages/tools/lib/src/brush_tool/brush_tool_state_provider.dart rename to lib/core/providers/state/tools/brush/brush_tool_state_provider.dart index 52921062..9fd4f94f 100644 --- a/packages/tools/lib/src/brush_tool/brush_tool_state_provider.dart +++ b/lib/core/providers/state/tools/brush/brush_tool_state_provider.dart @@ -1,9 +1,14 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/graphic_factory/graphic_factory_provider.dart'; +// Package imports: import 'package:riverpod_annotation/riverpod_annotation.dart'; -import 'package:tools/tools.dart'; +// Project imports: +import 'package:paintroid/core/commands/graphic_factory/graphic_factory_provider.dart'; +import 'package:paintroid/core/providers/state/tools/brush/brush_tool_state_data.dart'; + +// Project imports: part 'brush_tool_state_provider.g.dart'; @riverpod diff --git a/packages/tools/lib/src/brush_tool/brush_tool_state_provider.g.dart b/lib/core/providers/state/tools/brush/brush_tool_state_provider.g.dart similarity index 94% rename from packages/tools/lib/src/brush_tool/brush_tool_state_provider.g.dart rename to lib/core/providers/state/tools/brush/brush_tool_state_provider.g.dart index 4bffdbde..fec7bdfd 100644 --- a/packages/tools/lib/src/brush_tool/brush_tool_state_provider.g.dart +++ b/lib/core/providers/state/tools/brush/brush_tool_state_provider.g.dart @@ -23,4 +23,4 @@ final brushToolStateProvider = typedef _$BrushToolState = AutoDisposeNotifier; // ignore_for_file: type=lint -// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/packages/tools/lib/src/toolbox/toolbox_state_data.dart b/lib/core/providers/state/tools/toolbox/toolbox_state_data.dart similarity index 69% rename from packages/tools/lib/src/toolbox/toolbox_state_data.dart rename to lib/core/providers/state/tools/toolbox/toolbox_state_data.dart index 6d0719de..9cfdda03 100644 --- a/packages/tools/lib/src/toolbox/toolbox_state_data.dart +++ b/lib/core/providers/state/tools/toolbox/toolbox_state_data.dart @@ -1,5 +1,9 @@ +// Package imports: import 'package:freezed_annotation/freezed_annotation.dart'; -import 'package:tools/tools.dart'; + +// Project imports: +import 'package:paintroid/core/enums/tool_types.dart'; +import 'package:paintroid/core/tools/tool.dart'; part 'toolbox_state_data.freezed.dart'; diff --git a/packages/tools/lib/src/toolbox/toolbox_state_data.freezed.dart b/lib/core/providers/state/tools/toolbox/toolbox_state_data.freezed.dart similarity index 81% rename from packages/tools/lib/src/toolbox/toolbox_state_data.freezed.dart rename to lib/core/providers/state/tools/toolbox/toolbox_state_data.freezed.dart index a7c007ad..98af0bbb 100644 --- a/packages/tools/lib/src/toolbox/toolbox_state_data.freezed.dart +++ b/lib/core/providers/state/tools/toolbox/toolbox_state_data.freezed.dart @@ -12,7 +12,7 @@ part of 'toolbox_state_data.dart'; T _$identity(T value) => value; final _privateConstructorUsedError = UnsupportedError( - 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); /// @nodoc mixin _$ToolBoxStateData { @@ -69,22 +69,22 @@ class _$ToolBoxStateDataCopyWithImpl<$Res, $Val extends ToolBoxStateData> } /// @nodoc -abstract class _$$_ToolBoxStateDataCopyWith<$Res> +abstract class _$$ToolBoxStateDataImplCopyWith<$Res> implements $ToolBoxStateDataCopyWith<$Res> { - factory _$$_ToolBoxStateDataCopyWith( - _$_ToolBoxStateData value, $Res Function(_$_ToolBoxStateData) then) = - __$$_ToolBoxStateDataCopyWithImpl<$Res>; + factory _$$ToolBoxStateDataImplCopyWith(_$ToolBoxStateDataImpl value, + $Res Function(_$ToolBoxStateDataImpl) then) = + __$$ToolBoxStateDataImplCopyWithImpl<$Res>; @override @useResult $Res call({Tool currentTool, ToolType currentToolType, bool isDown}); } /// @nodoc -class __$$_ToolBoxStateDataCopyWithImpl<$Res> - extends _$ToolBoxStateDataCopyWithImpl<$Res, _$_ToolBoxStateData> - implements _$$_ToolBoxStateDataCopyWith<$Res> { - __$$_ToolBoxStateDataCopyWithImpl( - _$_ToolBoxStateData _value, $Res Function(_$_ToolBoxStateData) _then) +class __$$ToolBoxStateDataImplCopyWithImpl<$Res> + extends _$ToolBoxStateDataCopyWithImpl<$Res, _$ToolBoxStateDataImpl> + implements _$$ToolBoxStateDataImplCopyWith<$Res> { + __$$ToolBoxStateDataImplCopyWithImpl(_$ToolBoxStateDataImpl _value, + $Res Function(_$ToolBoxStateDataImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -94,7 +94,7 @@ class __$$_ToolBoxStateDataCopyWithImpl<$Res> Object? currentToolType = null, Object? isDown = null, }) { - return _then(_$_ToolBoxStateData( + return _then(_$ToolBoxStateDataImpl( currentTool: null == currentTool ? _value.currentTool : currentTool // ignore: cast_nullable_to_non_nullable @@ -113,8 +113,8 @@ class __$$_ToolBoxStateDataCopyWithImpl<$Res> /// @nodoc -class _$_ToolBoxStateData implements _ToolBoxStateData { - const _$_ToolBoxStateData( +class _$ToolBoxStateDataImpl implements _ToolBoxStateData { + const _$ToolBoxStateDataImpl( {required this.currentTool, required this.currentToolType, required this.isDown}); @@ -132,10 +132,10 @@ class _$_ToolBoxStateData implements _ToolBoxStateData { } @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$_ToolBoxStateData && + other is _$ToolBoxStateDataImpl && (identical(other.currentTool, currentTool) || other.currentTool == currentTool) && (identical(other.currentToolType, currentToolType) || @@ -150,15 +150,16 @@ class _$_ToolBoxStateData implements _ToolBoxStateData { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$_ToolBoxStateDataCopyWith<_$_ToolBoxStateData> get copyWith => - __$$_ToolBoxStateDataCopyWithImpl<_$_ToolBoxStateData>(this, _$identity); + _$$ToolBoxStateDataImplCopyWith<_$ToolBoxStateDataImpl> get copyWith => + __$$ToolBoxStateDataImplCopyWithImpl<_$ToolBoxStateDataImpl>( + this, _$identity); } abstract class _ToolBoxStateData implements ToolBoxStateData { const factory _ToolBoxStateData( {required final Tool currentTool, required final ToolType currentToolType, - required final bool isDown}) = _$_ToolBoxStateData; + required final bool isDown}) = _$ToolBoxStateDataImpl; @override Tool get currentTool; @@ -168,6 +169,6 @@ abstract class _ToolBoxStateData implements ToolBoxStateData { bool get isDown; @override @JsonKey(ignore: true) - _$$_ToolBoxStateDataCopyWith<_$_ToolBoxStateData> get copyWith => + _$$ToolBoxStateDataImplCopyWith<_$ToolBoxStateDataImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/packages/tools/lib/src/toolbox/toolbox_state_provider.dart b/lib/core/providers/state/tools/toolbox/toolbox_state_provider.dart similarity index 77% rename from packages/tools/lib/src/toolbox/toolbox_state_provider.dart rename to lib/core/providers/state/tools/toolbox/toolbox_state_provider.dart index e2a98847..5f1927ba 100644 --- a/packages/tools/lib/src/toolbox/toolbox_state_provider.dart +++ b/lib/core/providers/state/tools/toolbox/toolbox_state_provider.dart @@ -1,8 +1,18 @@ +// Dart imports: import 'dart:ui'; +// Package imports: import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:toast/toast.dart'; -import 'package:tools/tools.dart'; + +// Project imports: +import 'package:paintroid/core/enums/tool_types.dart'; +import 'package:paintroid/core/providers/object/tools/brush_tool_provider.dart'; +import 'package:paintroid/core/providers/object/tools/eraser_tool_provider.dart'; +import 'package:paintroid/core/providers/object/tools/hand_tool_provider.dart'; +import 'package:paintroid/core/providers/state/tools/brush/brush_tool_state_provider.dart'; +import 'package:paintroid/core/providers/state/tools/toolbox/toolbox_state_data.dart'; +import 'package:paintroid/core/tools/tool_data.dart'; part 'toolbox_state_provider.g.dart'; diff --git a/packages/tools/lib/src/toolbox/toolbox_state_provider.g.dart b/lib/core/providers/state/tools/toolbox/toolbox_state_provider.g.dart similarity index 94% rename from packages/tools/lib/src/toolbox/toolbox_state_provider.g.dart rename to lib/core/providers/state/tools/toolbox/toolbox_state_provider.g.dart index ef1abc1d..fc298b0d 100644 --- a/packages/tools/lib/src/toolbox/toolbox_state_provider.g.dart +++ b/lib/core/providers/state/tools/toolbox/toolbox_state_provider.g.dart @@ -22,4 +22,4 @@ final toolBoxStateProvider = typedef _$ToolBoxState = AutoDisposeNotifier; // ignore_for_file: type=lint -// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/packages/features/workspace_screen/lib/src/states/workspace_state.dart b/lib/core/providers/state/workspace_state.dart similarity index 75% rename from packages/features/workspace_screen/lib/src/states/workspace_state.dart rename to lib/core/providers/state/workspace_state.dart index 9a621cd7..42c0533c 100644 --- a/packages/features/workspace_screen/lib/src/states/workspace_state.dart +++ b/lib/core/providers/state/workspace_state.dart @@ -4,8 +4,7 @@ part of 'workspace_state_notifier.dart'; class WorkspaceState { final bool isFullscreen; final bool isPerformingIOTask; - final int _commandCountWhenLastSaved; - + final int commandCountWhenLastSaved; static const initial = WorkspaceState(); static final provider = @@ -19,19 +18,19 @@ class WorkspaceState { const WorkspaceState({ this.isFullscreen = false, this.isPerformingIOTask = false, - int commandCountWhenLastSaved = 0, - }) : _commandCountWhenLastSaved = commandCountWhenLastSaved; + this.commandCountWhenLastSaved = 0, + }); WorkspaceState copyWith({ bool? isFullscreen, bool? isPerformingIOTask, - int? updatedLastSavedCommandCount, + int? commandCountWhenLastSaved, }) { return WorkspaceState( isFullscreen: isFullscreen ?? this.isFullscreen, isPerformingIOTask: isPerformingIOTask ?? this.isPerformingIOTask, commandCountWhenLastSaved: - updatedLastSavedCommandCount ?? _commandCountWhenLastSaved, + commandCountWhenLastSaved ?? this.commandCountWhenLastSaved, ); } } diff --git a/lib/core/providers/state/workspace_state_notifier.dart b/lib/core/providers/state/workspace_state_notifier.dart new file mode 100644 index 00000000..8a368a79 --- /dev/null +++ b/lib/core/providers/state/workspace_state_notifier.dart @@ -0,0 +1,48 @@ +// Flutter imports: + +// Flutter imports: +import 'package:flutter/foundation.dart'; + +// Package imports: +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +// Project imports: +import 'package:paintroid/core/commands/command_manager/command_manager.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager_provider.dart'; + +part 'workspace_state.dart'; + +class WorkspaceStateNotifier extends StateNotifier { + WorkspaceStateNotifier(super.state, this._commandManager) { + _hasUnsavedChanges = + state.commandCountWhenLastSaved != _commandManager.count; + } + + final CommandManager _commandManager; + bool _hasUnsavedChanges = false; + + bool get hasUnsavedChanges => _hasUnsavedChanges; + + void markUnsavedChanges() { + _hasUnsavedChanges = true; + } + + void updateLastSavedCommandCount() { + _hasUnsavedChanges = false; + state = state.copyWith(commandCountWhenLastSaved: _commandManager.count); + } + + bool get hasSavedLastWork => + state.commandCountWhenLastSaved == _commandManager.count; + + Future performIOTask(Future Function() task) async { + state = state.copyWith(isPerformingIOTask: true); + final result = await task(); + state = state.copyWith(isPerformingIOTask: false); + return result; + } + + void toggleFullscreen(bool isEnabled) => state = state.copyWith( + isFullscreen: isEnabled, + ); +} diff --git a/packages/tools/lib/src/brush_tool/brush_tool.dart b/lib/core/tools/implementation/brush_tool.dart similarity index 71% rename from packages/tools/lib/src/brush_tool/brush_tool.dart rename to lib/core/tools/implementation/brush_tool.dart index 65379ac2..2a0bde98 100644 --- a/packages/tools/lib/src/brush_tool/brush_tool.dart +++ b/lib/core/tools/implementation/brush_tool.dart @@ -1,9 +1,19 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; -import 'package:equatable/equatable.dart'; +// Flutter imports: import 'package:flutter/foundation.dart'; -import 'package:tools/tools.dart'; + +// Package imports: +import 'package:equatable/equatable.dart'; + +// Project imports: +import 'package:paintroid/core/commands/command_factory/command_factory.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager.dart'; +import 'package:paintroid/core/commands/graphic_factory/graphic_factory.dart'; +import 'package:paintroid/core/commands/path_with_action_history.dart'; +import 'package:paintroid/core/enums/tool_types.dart'; +import 'package:paintroid/core/tools/tool.dart'; class BrushTool extends Tool with EquatableMixin { BrushTool({ @@ -11,9 +21,10 @@ class BrushTool extends Tool with EquatableMixin { required super.commandFactory, required super.commandManager, required this.graphicFactory, - required super.type, }); + final ToolType type = ToolType.BRUSH; + final GraphicFactory graphicFactory; @visibleForTesting @@ -36,7 +47,7 @@ class BrushTool extends Tool with EquatableMixin { @override void onUp(Offset? point) { - if (pathToDraw.getBounds().size == Size.zero) { + if (pathToDraw.path.getBounds().size == Size.zero) { pathToDraw.close(); } } @@ -61,7 +72,6 @@ class BrushTool extends Tool with EquatableMixin { commandFactory: commandFactory ?? this.commandFactory, commandManager: commandManager ?? this.commandManager, graphicFactory: graphicFactory ?? this.graphicFactory, - type: type ?? this.type, ); } } diff --git a/lib/core/tools/implementation/eraser_tool.dart b/lib/core/tools/implementation/eraser_tool.dart new file mode 100644 index 00000000..dbc42c3e --- /dev/null +++ b/lib/core/tools/implementation/eraser_tool.dart @@ -0,0 +1,15 @@ +// Project imports: +import 'package:paintroid/core/enums/tool_types.dart'; +import 'package:paintroid/core/tools/implementation/brush_tool.dart'; + +class EraserTool extends BrushTool { + EraserTool({ + required super.paint, + required super.commandFactory, + required super.commandManager, + required super.graphicFactory, + }) : super(); + + @override + ToolType get type => ToolType.ERASER; +} diff --git a/packages/tools/lib/src/hand_tool/hand_tool.dart b/lib/core/tools/implementation/hand_tool.dart similarity index 65% rename from packages/tools/lib/src/hand_tool/hand_tool.dart rename to lib/core/tools/implementation/hand_tool.dart index b130941b..54bbf3bf 100644 --- a/packages/tools/lib/src/hand_tool/hand_tool.dart +++ b/lib/core/tools/implementation/hand_tool.dart @@ -1,17 +1,25 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; +// Package imports: import 'package:equatable/equatable.dart'; -import 'package:tools/tools.dart'; + +// Project imports: +import 'package:paintroid/core/commands/command_factory/command_factory.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager.dart'; +import 'package:paintroid/core/commands/graphic_factory/graphic_factory.dart'; +import 'package:paintroid/core/enums/tool_types.dart'; +import 'package:paintroid/core/tools/tool.dart'; class HandTool extends Tool with EquatableMixin { HandTool({ required super.paint, required super.commandFactory, required super.commandManager, - required super.type, }); + final ToolType type = ToolType.HAND; + @override void onDown(Offset point) {} @@ -38,7 +46,6 @@ class HandTool extends Tool with EquatableMixin { paint: paint ?? this.paint, commandFactory: commandFactory ?? this.commandFactory, commandManager: commandManager ?? this.commandManager, - type: type ?? this.type, ); } } diff --git a/packages/tools/lib/src/tool.dart b/lib/core/tools/tool.dart similarity index 65% rename from packages/tools/lib/src/tool.dart rename to lib/core/tools/tool.dart index 78ac0831..ce9223a0 100644 --- a/packages/tools/lib/src/tool.dart +++ b/lib/core/tools/tool.dart @@ -1,18 +1,18 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; -import 'package:tools/src/enums/tool_types.dart'; +// Project imports: +import 'package:paintroid/core/commands/command_factory/command_factory.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager.dart'; abstract class Tool { const Tool({ required this.paint, required this.commandManager, required this.commandFactory, - required this.type, }); final Paint paint; - final ToolType type; final CommandManager commandManager; final CommandFactory commandFactory; diff --git a/packages/tools/lib/src/tool_data.dart b/lib/core/tools/tool_data.dart similarity index 96% rename from packages/tools/lib/src/tool_data.dart rename to lib/core/tools/tool_data.dart index bb0a161e..ad5b986f 100644 --- a/packages/tools/lib/src/tool_data.dart +++ b/lib/core/tools/tool_data.dart @@ -1,4 +1,5 @@ -import 'package:tools/src/enums/tool_types.dart'; +// Project imports: +import 'package:paintroid/core/enums/tool_types.dart'; class ToolData { final String name; @@ -78,7 +79,7 @@ class ToolData { ); static const IMPORT = ToolData._( - 'Import image', + 'Import', 'assets/svg/ic_import.svg', ToolType.IMPORT, ); diff --git a/packages/database/lib/src/utils/date_time_converter.dart b/lib/core/utils/date_time_converter.dart similarity index 93% rename from packages/database/lib/src/utils/date_time_converter.dart rename to lib/core/utils/date_time_converter.dart index e66e614a..b96339e6 100644 --- a/packages/database/lib/src/utils/date_time_converter.dart +++ b/lib/core/utils/date_time_converter.dart @@ -1,3 +1,4 @@ +// Package imports: import 'package:floor/floor.dart'; class DateTimeConverter extends TypeConverter { diff --git a/packages/io_library/lib/src/models/failure.dart b/lib/core/utils/failure.dart similarity index 100% rename from packages/io_library/lib/src/models/failure.dart rename to lib/core/utils/failure.dart diff --git a/packages/io_library/lib/src/failure/load_image_failure.dart b/lib/core/utils/load_image_failure.dart similarity index 85% rename from packages/io_library/lib/src/failure/load_image_failure.dart rename to lib/core/utils/load_image_failure.dart index 191a66a0..c7c43855 100644 --- a/packages/io_library/lib/src/failure/load_image_failure.dart +++ b/lib/core/utils/load_image_failure.dart @@ -1,4 +1,5 @@ -import 'package:io_library/io_library.dart'; +// Project imports: +import 'package:paintroid/core/utils/failure.dart'; class LoadImageFailure extends Failure { const LoadImageFailure._(super.message); diff --git a/packages/component_library/lib/src/utils/open_url.dart b/lib/core/utils/open_url.dart similarity index 89% rename from packages/component_library/lib/src/utils/open_url.dart rename to lib/core/utils/open_url.dart index 794ce84b..24d2c07a 100644 --- a/packages/component_library/lib/src/utils/open_url.dart +++ b/lib/core/utils/open_url.dart @@ -1,3 +1,4 @@ +// Package imports: import 'package:url_launcher/url_launcher.dart'; Future openUrl(url) async { diff --git a/packages/io_library/lib/src/failure/save_image_failure.dart b/lib/core/utils/save_image_failure.dart similarity index 86% rename from packages/io_library/lib/src/failure/save_image_failure.dart rename to lib/core/utils/save_image_failure.dart index a0b4aff4..7071f99b 100644 --- a/packages/io_library/lib/src/failure/save_image_failure.dart +++ b/lib/core/utils/save_image_failure.dart @@ -1,4 +1,5 @@ -import 'package:io_library/io_library.dart'; +// Project imports: +import 'package:paintroid/core/utils/failure.dart'; class SaveImageFailure extends Failure { const SaveImageFailure._(super.message); diff --git a/lib/main.dart b/lib/main.dart index 27182e3a..2852a863 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,12 +1,17 @@ +// Dart imports: import 'dart:developer'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:logging/logging.dart'; -import 'package:paintroid/pocket_paint_app.dart'; - import 'package:shared_preferences/shared_preferences.dart'; +// Project imports: +import 'package:paintroid/app.dart'; + void main() async { Logger.root.onRecord.listen((record) { log(record.message, @@ -25,7 +30,7 @@ void main() async { runApp( ProviderScope( - child: PocketPaintApp( + child: App( showOnboardingPage: showOnboarding, ), ), diff --git a/lib/pocket_paint_app.dart b/lib/pocket_paint_app.dart deleted file mode 100644 index 3d617c6a..00000000 --- a/lib/pocket_paint_app.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:component_library/component_library.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:l10n/l10n.dart'; -import 'package:landing_page_screen/landing_page_screen.dart'; -import 'package:onboarding_screen/onboarding_screen.dart'; -import 'package:workspace_screen/workspace_screen.dart'; -import 'package:flutter_localizations/flutter_localizations.dart'; - -class PocketPaintApp extends StatelessWidget { - final bool showOnboardingPage; - - const PocketPaintApp({Key? key, required this.showOnboardingPage}) - : super(key: key); - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Pocket Paint', - localizationsDelegates: const [ - AppLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - GlobalCupertinoLocalizations.delegate, - ], - supportedLocales: AppLocalizations.supportedLocales, - theme: ThemeData.from( - useMaterial3: true, - colorScheme: lightColorScheme, - ), - initialRoute: '/', - onGenerateRoute: (settings) { - switch (settings.name) { - case '/': - return MaterialPageRoute( - builder: (context) => showOnboardingPage - ? const OnboardingPage( - navigateTo: LandingPage(title: 'Pocket Paint'), - ) - : const LandingPage(title: 'Pocket Paint'), - ); - case '/PocketPaint': - return MaterialPageRoute( - builder: (context) => const WorkspaceScreen(), - ); - case '/OnboardingPage': - return MaterialPageRoute( - builder: (context) => const OnboardingPage(), - ); - } - return null; - }, - home: Consumer( - builder: (BuildContext context, WidgetRef ref, Widget? child) { - return LoadingOverlay( - isLoading: ref.watch( - WorkspaceState.provider - .select((state) => state.isPerformingIOTask), - ), - child: child); - }, - child: const LandingPage(title: 'Pocket Paint'), - ), - ); - } -} diff --git a/packages/features/landing_page_screen/lib/src/components/custom_action_button.dart b/lib/ui/pages/landing_page/components/custom_action_button.dart similarity index 69% rename from packages/features/landing_page_screen/lib/src/components/custom_action_button.dart rename to lib/ui/pages/landing_page/components/custom_action_button.dart index bb8b6ae9..0b9e8a15 100644 --- a/packages/features/landing_page_screen/lib/src/components/custom_action_button.dart +++ b/lib/ui/pages/landing_page/components/custom_action_button.dart @@ -1,5 +1,9 @@ +// Flutter imports: import 'package:flutter/material.dart'; +// Project imports: +import 'package:paintroid/ui/theme/theme.dart'; + class CustomActionButton extends StatelessWidget { final String heroTag; final IconData icon; @@ -7,19 +11,19 @@ class CustomActionButton extends StatelessWidget { final String hint; const CustomActionButton({ - Key? key, + super.key, required this.heroTag, required this.icon, required this.onPressed, required this.hint, - }) : super(key: key); + }); @override Widget build(BuildContext context) { return FloatingActionButton( heroTag: heroTag, - backgroundColor: const Color(0xFFFFAB08), - foregroundColor: const Color(0xFFFFFFFF), + backgroundColor: PaintroidTheme.of(context).orangeColor, + foregroundColor: PaintroidTheme.of(context).onSurfaceColor, tooltip: hint, child: Icon(icon), onPressed: () async => onPressed(), diff --git a/packages/features/landing_page_screen/lib/src/components/image_preview.dart b/lib/ui/pages/landing_page/components/image_preview.dart similarity index 84% rename from packages/features/landing_page_screen/lib/src/components/image_preview.dart rename to lib/ui/pages/landing_page/components/image_preview.dart index 31a6b886..876313d1 100644 --- a/packages/features/landing_page_screen/lib/src/components/image_preview.dart +++ b/lib/ui/pages/landing_page/components/image_preview.dart @@ -1,8 +1,11 @@ -import 'package:component_library/component_library.dart'; -import 'package:database/database.dart'; +// Flutter imports: import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:io_library/io_library.dart'; + +// Project imports: +import 'package:paintroid/core/models/database/project.dart'; +import 'package:paintroid/core/providers/object/image_service.dart'; +import 'package:paintroid/ui/utils/toast_utils.dart'; class ImagePreview extends StatelessWidget { final Project? project; @@ -11,12 +14,12 @@ class ImagePreview extends StatelessWidget { final IImageService imageService; const ImagePreview({ - Key? key, + super.key, this.width, required this.color, this.project, required this.imageService, - }) : super(key: key); + }); ImageProvider _getProjectPreviewImageProvider(Uint8List img) => Image.memory(img, fit: BoxFit.cover).image; diff --git a/packages/features/landing_page_screen/lib/src/components/main_overflow_menu.dart b/lib/ui/pages/landing_page/components/main_overflow_menu.dart similarity index 76% rename from packages/features/landing_page_screen/lib/src/components/main_overflow_menu.dart rename to lib/ui/pages/landing_page/components/main_overflow_menu.dart index ab968f0c..e9816018 100644 --- a/packages/features/landing_page_screen/lib/src/components/main_overflow_menu.dart +++ b/lib/ui/pages/landing_page/components/main_overflow_menu.dart @@ -1,10 +1,17 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; import 'package:launch_review/launch_review.dart'; import 'package:package_info_plus/package_info_plus.dart'; +// Project imports: +import 'package:paintroid/core/utils/open_url.dart'; +import 'package:paintroid/ui/shared/dialogs/about_dialog.dart'; +import 'package:paintroid/ui/shared/pop_menu_button.dart'; +import 'package:paintroid/ui/theme/theme.dart'; + enum MainOverflowMenuOption { rate('Rate us!'), help('Help'), @@ -17,7 +24,7 @@ enum MainOverflowMenuOption { } class MainOverflowMenu extends ConsumerStatefulWidget { - const MainOverflowMenu({Key? key}) : super(key: key); + const MainOverflowMenu({super.key}); @override ConsumerState createState() => _MainOverFlowMenuState(); @@ -33,9 +40,15 @@ class _MainOverFlowMenuState extends ConsumerState { return StyledPopMenuButton( onSelected: _handleSelectedOption, itemBuilder: (BuildContext context) => MainOverflowMenuOption.values - .map((option) => PopupMenuItem( + .map( + (option) => PopupMenuItem( value: option, - child: Text(option.label, style: TextThemes.menuItem))) + child: Text( + option.label, + style: PaintroidTheme.of(context).textTheme.bodyMedium, + ), + ), + ) .toList(), ); } diff --git a/packages/features/landing_page_screen/lib/src/components/project_list_tile.dart b/lib/ui/pages/landing_page/components/project_list_tile.dart similarity index 76% rename from packages/features/landing_page_screen/lib/src/components/project_list_tile.dart rename to lib/ui/pages/landing_page/components/project_list_tile.dart index c087f805..5795be24 100644 --- a/packages/features/landing_page_screen/lib/src/components/project_list_tile.dart +++ b/lib/ui/pages/landing_page/components/project_list_tile.dart @@ -1,8 +1,14 @@ -import 'package:database/database.dart'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:intl/intl.dart'; -import 'package:io_library/io_library.dart'; -import 'package:landing_page_screen/landing_page_screen.dart'; + +// Project imports: +import 'package:paintroid/core/models/database/project.dart'; +import 'package:paintroid/core/providers/object/image_service.dart'; +import 'package:paintroid/ui/pages/landing_page/components/image_preview.dart'; +import 'package:paintroid/ui/pages/landing_page/components/project_overflow_menu.dart'; class ProjectListTile extends StatelessWidget { final Project project; diff --git a/packages/features/landing_page_screen/lib/src/components/project_overflow_menu.dart b/lib/ui/pages/landing_page/components/project_overflow_menu.dart similarity index 72% rename from packages/features/landing_page_screen/lib/src/components/project_overflow_menu.dart rename to lib/ui/pages/landing_page/components/project_overflow_menu.dart index 78d68833..ee747a5c 100644 --- a/packages/features/landing_page_screen/lib/src/components/project_overflow_menu.dart +++ b/lib/ui/pages/landing_page/components/project_overflow_menu.dart @@ -1,10 +1,19 @@ +// Dart imports: import 'dart:io'; -import 'package:component_library/component_library.dart'; -import 'package:database/database.dart'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; + +// Project imports: +import 'package:paintroid/core/database/project_database.dart'; +import 'package:paintroid/core/models/database/project.dart'; +import 'package:paintroid/ui/shared/dialogs/delete_project_dialog.dart'; +import 'package:paintroid/ui/shared/dialogs/project_details_dialog.dart'; +import 'package:paintroid/ui/theme/theme.dart'; +import 'package:paintroid/ui/utils/toast_utils.dart'; enum ProjectOverflowMenuOption { deleteProject('Delete'), @@ -18,8 +27,7 @@ enum ProjectOverflowMenuOption { class ProjectOverflowMenu extends ConsumerStatefulWidget { final Project project; - const ProjectOverflowMenu({Key? key, required this.project}) - : super(key: key); + const ProjectOverflowMenu({super.key, required this.project}); @override ConsumerState createState() => @@ -40,7 +48,7 @@ class _ProjectOverFlowMenuState extends ConsumerState { ); return PopupMenuButton( - color: Theme.of(context).colorScheme.background, + color: PaintroidTheme.of(context).backgroundColor, icon: const Icon(Icons.more_vert), shape: RoundedRectangleBorder( side: const BorderSide(), @@ -48,8 +56,15 @@ class _ProjectOverFlowMenuState extends ConsumerState { ), onSelected: _handleSelectedOption, itemBuilder: (BuildContext context) => ProjectOverflowMenuOption.values - .map((option) => - PopupMenuItem(value: option, child: Text(option.label))) + .map((option) => PopupMenuItem( + value: option, + child: Text( + option.label, + style: TextStyle( + color: PaintroidTheme.of(context).onBackgroundColor, + ), + ), + )) .toList(), ); } diff --git a/packages/features/landing_page_screen/lib/src/landing_page.dart b/lib/ui/pages/landing_page/landing_page.dart similarity index 73% rename from packages/features/landing_page_screen/lib/src/landing_page.dart rename to lib/ui/pages/landing_page/landing_page.dart index 9170a6da..71e3b6cb 100644 --- a/packages/features/landing_page_screen/lib/src/landing_page.dart +++ b/lib/ui/pages/landing_page/landing_page.dart @@ -1,17 +1,34 @@ -import 'package:component_library/component_library.dart'; -import 'package:database/database.dart'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; -import 'package:landing_page_screen/landing_page_screen.dart'; import 'package:oxidized/oxidized.dart'; import 'package:toast/toast.dart'; -import 'package:workspace_screen/workspace_screen.dart'; + +// Project imports: +import 'package:paintroid/core/database/project_database.dart'; +import 'package:paintroid/core/models/database/project.dart'; +import 'package:paintroid/core/providers/object/device_service.dart'; +import 'package:paintroid/core/providers/object/file_service.dart'; +import 'package:paintroid/core/providers/object/image_service.dart'; +import 'package:paintroid/core/providers/object/io_handler.dart'; +import 'package:paintroid/core/providers/state/canvas_state_provider.dart'; +import 'package:paintroid/core/providers/state/workspace_state_notifier.dart'; +import 'package:paintroid/core/utils/load_image_failure.dart'; +import 'package:paintroid/ui/pages/landing_page/components/custom_action_button.dart'; +import 'package:paintroid/ui/pages/landing_page/components/image_preview.dart'; +import 'package:paintroid/ui/pages/landing_page/components/main_overflow_menu.dart'; +import 'package:paintroid/ui/pages/landing_page/components/project_list_tile.dart'; +import 'package:paintroid/ui/pages/landing_page/components/project_overflow_menu.dart'; +import 'package:paintroid/ui/shared/icon_svg.dart'; +import 'package:paintroid/ui/theme/theme.dart'; +import 'package:paintroid/ui/utils/toast_utils.dart'; class LandingPage extends ConsumerStatefulWidget { final String title; - const LandingPage({Key? key, required this.title}) : super(key: key); + const LandingPage({super.key, required this.title}); @override ConsumerState createState() => _LandingPageState(); @@ -22,8 +39,9 @@ class _LandingPageState extends ConsumerState { late IFileService fileService; late IImageService imageService; - Future> _getProjects() async => - database.projectDAO.getProjects(); + Future> _getProjects() async { + return database.projectDAO.getProjects(); + } Future _navigateToPocketPaint() async { await Navigator.pushNamed(context, '/PocketPaint'); @@ -53,10 +71,14 @@ class _LandingPageState extends ConsumerState { ref.read(WorkspaceState.provider.notifier).updateLastSavedCommandCount(); } - Future _openProject(Project? project, IOHandler ioHandler) async { + Future _openProject( + Project? project, IOHandler ioHandler, WidgetRef ref) async { if (project != null) { - bool loaded = await _loadProject(ioHandler, project); - if (loaded) _navigateToPocketPaint(); + ref.read(WorkspaceState.provider.notifier).performIOTask(() async { + await ref.read(IDeviceService.sizeProvider.future); + bool loaded = await _loadProject(ioHandler, project); + if (loaded) _navigateToPocketPaint(); + }); } } @@ -77,7 +99,7 @@ class _LandingPageState extends ConsumerState { imageService = ref.watch(IImageService.provider); return Scaffold( - backgroundColor: lightColorScheme.primary, + backgroundColor: PaintroidTheme.of(context).primaryColor, appBar: AppBar( title: Text(widget.title), actions: const [MainOverflowMenu()], @@ -99,20 +121,20 @@ class _LandingPageState extends ConsumerState { imageService: imageService, latestModifiedProject: latestModifiedProject, openProject: () => - _openProject(latestModifiedProject, ioHandler), + _openProject(latestModifiedProject, ioHandler, ref), ), ), Container( - color: lightColorScheme.primaryContainer, + color: PaintroidTheme.of(context).primaryContainerColor, padding: const EdgeInsets.all(20), - child: const Align( + child: Align( alignment: Alignment.centerLeft, child: Text( 'My Projects', style: TextStyle( fontWeight: FontWeight.bold, fontSize: 20, - color: Color(0xFFFFFFFF), + color: PaintroidTheme.of(context).onSurfaceColor, ), ), ), @@ -127,7 +149,8 @@ class _LandingPageState extends ConsumerState { project: project, imageService: imageService, index: index, - onTap: () async => _openProject(project, ioHandler), + onTap: () async => + _openProject(project, ioHandler, ref), ); } return Container(); @@ -140,7 +163,7 @@ class _LandingPageState extends ConsumerState { } else { return Center( child: CircularProgressIndicator( - backgroundColor: lightColorScheme.background, + backgroundColor: PaintroidTheme.of(context).fabBackgroundColor, ), ); } @@ -202,7 +225,7 @@ class _ProjectPreview extends StatelessWidget { child: ImagePreview( project: latestModifiedProject, imageService: imageService, - color: Colors.white54, + color: PaintroidTheme.of(context).onSurfaceColor.withOpacity(0.5), ), ), ), diff --git a/packages/features/onboarding_screen/lib/src/components/bottom_nav_bar_container.dart b/lib/ui/pages/onboarding_page/components/bottom_nav_bar_container.dart similarity index 69% rename from packages/features/onboarding_screen/lib/src/components/bottom_nav_bar_container.dart rename to lib/ui/pages/onboarding_page/components/bottom_nav_bar_container.dart index d043b7ba..1dddc6b7 100644 --- a/packages/features/onboarding_screen/lib/src/components/bottom_nav_bar_container.dart +++ b/lib/ui/pages/onboarding_page/components/bottom_nav_bar_container.dart @@ -1,22 +1,25 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; -import 'package:onboarding_screen/onboarding_screen.dart'; + +// Project imports: +import 'package:paintroid/ui/pages/onboarding_page/components/onboarding_page_bottom_nav_bar.dart'; +import 'package:paintroid/ui/theme/theme.dart'; class BottomNavigationBarContainer extends StatelessWidget { final List navBarItems; final List onPressedFunctions; const BottomNavigationBarContainer({ - Key? key, + super.key, required this.navBarItems, required this.onPressedFunctions, - }) : super(key: key); + }); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(vertical: 10), - color: lightColorScheme.surface, + color: PaintroidTheme.of(context).surfaceColor, child: OnboardingPageBottomNavigationBar( onPressedFunctions: onPressedFunctions, barItems: navBarItems, diff --git a/packages/features/onboarding_screen/lib/src/components/onboarding_page_app_bar.dart b/lib/ui/pages/onboarding_page/components/onboarding_page_app_bar.dart similarity index 95% rename from packages/features/onboarding_screen/lib/src/components/onboarding_page_app_bar.dart rename to lib/ui/pages/onboarding_page/components/onboarding_page_app_bar.dart index 69170338..542621d1 100644 --- a/packages/features/onboarding_screen/lib/src/components/onboarding_page_app_bar.dart +++ b/lib/ui/pages/onboarding_page/components/onboarding_page_app_bar.dart @@ -1,14 +1,14 @@ +// Flutter imports: import 'package:flutter/material.dart'; class OnboardingPageAppBar extends AppBar { final List onPressed; OnboardingPageAppBar({ - Key? key, + super.key, required String title, required this.onPressed, }) : super( - key: key, title: Text(title), centerTitle: false, automaticallyImplyLeading: false, diff --git a/packages/features/onboarding_screen/lib/src/components/onboarding_page_bottom_nav_bar.dart b/lib/ui/pages/onboarding_page/components/onboarding_page_bottom_nav_bar.dart similarity index 69% rename from packages/features/onboarding_screen/lib/src/components/onboarding_page_bottom_nav_bar.dart rename to lib/ui/pages/onboarding_page/components/onboarding_page_bottom_nav_bar.dart index 2c4a0b26..410918c4 100644 --- a/packages/features/onboarding_screen/lib/src/components/onboarding_page_bottom_nav_bar.dart +++ b/lib/ui/pages/onboarding_page/components/onboarding_page_bottom_nav_bar.dart @@ -1,13 +1,17 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; +// Project imports: +import 'package:paintroid/ui/theme/theme.dart'; + +// Project imports: + class OnboardingPageBottomNavigationBar extends StatefulWidget { final List onPressedFunctions; final List barItems; const OnboardingPageBottomNavigationBar( - {Key? key, required this.onPressedFunctions, required this.barItems}) - : super(key: key); + {super.key, required this.onPressedFunctions, required this.barItems}); @override State createState() => @@ -23,9 +27,9 @@ class _OnboardingPageBottomNavigationBarState return BottomNavigationBar( type: BottomNavigationBarType.fixed, currentIndex: _currentIndex, - backgroundColor: lightColorScheme.surface, - selectedItemColor: Colors.white, - unselectedItemColor: Colors.white, + backgroundColor: PaintroidTheme.of(context).surfaceColor, + selectedItemColor: PaintroidTheme.of(context).onSurfaceColor, + unselectedItemColor: PaintroidTheme.of(context).onSurfaceColor, selectedFontSize: 12, unselectedFontSize: 12, onTap: (value) { diff --git a/packages/features/onboarding_screen/lib/src/onboarding_screen.dart b/lib/ui/pages/onboarding_page/onboarding_page.dart similarity index 73% rename from packages/features/onboarding_screen/lib/src/onboarding_screen.dart rename to lib/ui/pages/onboarding_page/onboarding_page.dart index 46ff21c8..ddc53ac1 100644 --- a/packages/features/onboarding_screen/lib/src/onboarding_screen.dart +++ b/lib/ui/pages/onboarding_page/onboarding_page.dart @@ -1,16 +1,24 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:onboarding_screen/onboarding_screen.dart'; +// Package imports: import 'package:shared_preferences/shared_preferences.dart'; import 'package:smooth_page_indicator/smooth_page_indicator.dart'; import 'package:toast/toast.dart'; +// Project imports: +import 'package:paintroid/ui/pages/onboarding_page/screens/screen1.dart'; +import 'package:paintroid/ui/pages/onboarding_page/screens/screen2.dart'; +import 'package:paintroid/ui/pages/onboarding_page/screens/screen3.dart'; +import 'package:paintroid/ui/pages/onboarding_page/screens/screen4.dart'; +import 'package:paintroid/ui/pages/onboarding_page/screens/screen5.dart'; +import 'package:paintroid/ui/theme/theme.dart'; + class OnboardingPage extends StatefulWidget { final Widget? navigateTo; - const OnboardingPage({Key? key, this.navigateTo}) : super(key: key); + const OnboardingPage({super.key, this.navigateTo}); @override State createState() => _OnboardingPageState(); @@ -80,25 +88,26 @@ class _OnboardingPageState extends State { ), Container( height: 1, - color: Colors.white, + color: PaintroidTheme.of(context).onSurfaceColor, ), ], ), ), bottomSheet: Container( - color: lightColorScheme.surface, + color: PaintroidTheme.of(context).surfaceColor, height: 40, + width: MediaQuery.of(context).size.width, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Padding( - padding: const EdgeInsets.only(left: 10), + padding: const EdgeInsets.only(left: 30), child: TextButton( onPressed: () => finish(), child: Text( _isLastPage ? '' : 'SKIP', - style: const TextStyle( - color: Colors.white, + style: TextStyle( + color: PaintroidTheme.of(context).onSurfaceColor, fontSize: 15, ), ), @@ -108,14 +117,15 @@ class _OnboardingPageState extends State { count: 5, controller: _controller, effect: SlideEffect( - dotColor: Colors.white.withOpacity(0.2), + dotColor: + PaintroidTheme.of(context).onSurfaceColor.withOpacity(0.2), dotHeight: 8, dotWidth: 8, - activeDotColor: Colors.white, + activeDotColor: PaintroidTheme.of(context).onSurfaceColor, ), ), Padding( - padding: const EdgeInsets.only(right: 10), + padding: const EdgeInsets.only(right: 30), child: TextButton( onPressed: () async { if (_isLastPage) { @@ -129,8 +139,8 @@ class _OnboardingPageState extends State { }, child: Text( _isLastPage ? "LET'S GO" : 'NEXT', - style: const TextStyle( - color: Colors.white, + style: TextStyle( + color: PaintroidTheme.of(context).onSurfaceColor, fontSize: 15, ), ), diff --git a/packages/features/onboarding_screen/lib/src/screens/screen1.dart b/lib/ui/pages/onboarding_page/screens/screen1.dart similarity index 68% rename from packages/features/onboarding_screen/lib/src/screens/screen1.dart rename to lib/ui/pages/onboarding_page/screens/screen1.dart index a58dec9b..fd81446d 100644 --- a/packages/features/onboarding_screen/lib/src/screens/screen1.dart +++ b/lib/ui/pages/onboarding_page/screens/screen1.dart @@ -1,29 +1,34 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; +// Project imports: +import 'package:paintroid/ui/theme/theme.dart'; + +// Project imports: + class Screen1 extends StatelessWidget { - const Screen1({Key? key}) : super(key: key); + const Screen1({super.key}); @override Widget build(BuildContext context) { return Container( - color: lightColorScheme.surface, + color: PaintroidTheme.of(context).surfaceColor, padding: const EdgeInsets.only(top: 100, left: 50, right: 50), child: Column( children: [ - const Text( + Text( 'Welcome To Pocket Paint', style: TextStyle( - color: Colors.white, + color: PaintroidTheme.of(context).onSurfaceColor, fontSize: 25, ), ), Container( padding: const EdgeInsets.symmetric(vertical: 50), - child: const Text( + child: Text( 'With Pocket Paint there are no limits to your creativity. If you are new, start the intro, or skip it if you are already familiar with Pocket Paint.', style: TextStyle( - color: Colors.white, + color: PaintroidTheme.of(context).onSurfaceColor, fontSize: 15, ), ), diff --git a/packages/features/onboarding_screen/lib/src/screens/screen2.dart b/lib/ui/pages/onboarding_page/screens/screen2.dart similarity index 72% rename from packages/features/onboarding_screen/lib/src/screens/screen2.dart rename to lib/ui/pages/onboarding_page/screens/screen2.dart index b9b8628c..0b3c388a 100644 --- a/packages/features/onboarding_screen/lib/src/screens/screen2.dart +++ b/lib/ui/pages/onboarding_page/screens/screen2.dart @@ -1,10 +1,15 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; -import 'package:onboarding_screen/onboarding_screen.dart'; -import 'package:workspace_screen/workspace_screen.dart'; + +// Project imports: +import 'package:paintroid/ui/pages/onboarding_page/components/onboarding_page_app_bar.dart'; +import 'package:paintroid/ui/pages/onboarding_page/components/onboarding_page_bottom_nav_bar.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/drawing_surface/drawing_canvas.dart'; +import 'package:paintroid/ui/shared/bottom_nav_bar_icon.dart'; +import 'package:paintroid/ui/theme/theme.dart'; class Screen2 extends StatefulWidget { - const Screen2({Key? key}) : super(key: key); + const Screen2({super.key}); @override State createState() => _Screen2State(); @@ -22,46 +27,15 @@ class _Screen2State extends State { 'Tap to redo an undone action.', ]; - var title = const Text( - 'More possibilities', - style: TextStyle( - color: Colors.white, - fontSize: 24, - ), - textAlign: TextAlign.start, - ); - - var desc = const Text( - 'Use the top bar to open the overflow menu and to undo or redo changes', - style: TextStyle( - color: Colors.white, - fontSize: 15, - ), - textAlign: TextAlign.start, - ); + String titleText = 'More possibilities'; + String descText = + 'Use the top bar to open the overflow menu and to undo or redo changes'; void onPressed(int i) { - setState( - () { - title = Text( - titles[i], - style: const TextStyle( - color: Colors.white, - fontSize: 24, - ), - textAlign: TextAlign.start, - ); - - desc = Text( - descriptions[i], - style: const TextStyle( - color: Colors.white, - fontSize: 15, - ), - textAlign: TextAlign.start, - ); - }, - ); + setState(() { + titleText = titles[i]; + descText = descriptions[i]; + }); } void tools() => onPressed(0); @@ -78,6 +52,18 @@ class _Screen2State extends State { @override Widget build(BuildContext context) { + var title = Text( + titleText, + style: PaintroidTheme.of(context).titleStyle, + textAlign: TextAlign.start, + ); + + var desc = Text( + descText, + style: PaintroidTheme.of(context).descStyle, + textAlign: TextAlign.start, + ); + return Scaffold( appBar: OnboardingPageAppBar( title: 'Pocket Paint', @@ -134,7 +120,7 @@ class _Screen2State extends State { icon: Icon( Icons.check_box_outline_blank, size: 24, - color: Theme.of(context).colorScheme.onSurface, + color: PaintroidTheme.of(context).onSurfaceColor, ), ), const BottomNavigationBarItem( diff --git a/packages/features/onboarding_screen/lib/src/screens/screen3.dart b/lib/ui/pages/onboarding_page/screens/screen3.dart similarity index 77% rename from packages/features/onboarding_screen/lib/src/screens/screen3.dart rename to lib/ui/pages/onboarding_page/screens/screen3.dart index a7a2d1a8..096e05a7 100644 --- a/packages/features/onboarding_screen/lib/src/screens/screen3.dart +++ b/lib/ui/pages/onboarding_page/screens/screen3.dart @@ -1,9 +1,14 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; -import 'package:onboarding_screen/onboarding_screen.dart'; + +// Project imports: +import 'package:paintroid/ui/pages/onboarding_page/components/bottom_nav_bar_container.dart'; +import 'package:paintroid/ui/shared/bottom_nav_bar_icon.dart'; +import 'package:paintroid/ui/shared/icon_svg.dart'; +import 'package:paintroid/ui/theme/theme.dart'; class Screen3 extends StatefulWidget { - const Screen3({Key? key}) : super(key: key); + const Screen3({super.key}); @override State createState() => _Screen3State(); @@ -67,65 +72,16 @@ class _Screen3State extends State { 'Mark area which should not be erased.', ]; - var title = const Row( - children: [ - Text( - 'Tools', - style: TextStyle( - color: Colors.white, - fontSize: 24, - ), - textAlign: TextAlign.start, - ) - ], - ); - - Icon? toolIcon; - - var desc = const Text( - 'Select the tool you want to use.', - style: TextStyle( - color: Colors.white, - fontSize: 15, - ), - textAlign: TextAlign.start, - ); + String titleText = 'Tools'; + String descText = 'Select the tool you want to use.'; + String? toolIconSrc; void toolPressed(int i) { - setState( - () { - title = Row( - children: [ - Text( - titles[i], - style: const TextStyle( - color: Colors.white, - fontSize: 24, - ), - textAlign: TextAlign.start, - ), - Container( - padding: const EdgeInsets.only(left: 50.0), - child: IconSvg( - path: icons[i], - height: 24.0, - width: 24.0, - color: Theme.of(context).colorScheme.onSurface, - ), - ), - ], - ); - - desc = Text( - descriptions[i], - style: const TextStyle( - color: Colors.white, - fontSize: 15, - ), - textAlign: TextAlign.start, - ); - }, - ); + setState(() { + titleText = titles[i]; + descText = descriptions[i]; + toolIconSrc = icons[i]; + }); } void brush() => toolPressed(0); @@ -175,11 +131,38 @@ class _Screen3State extends State { @override Widget build(BuildContext context) { + var title = Row( + children: [ + Text( + titleText, + style: PaintroidTheme.of(context).descStyle, + textAlign: TextAlign.start, + ), + toolIconSrc != null + ? Container( + padding: const EdgeInsets.only(left: 50.0), + child: IconSvg( + path: toolIconSrc!, + height: 24.0, + width: 24.0, + color: PaintroidTheme.of(context).onSurfaceColor, + ), + ) + : const SizedBox(), + ], + ); + + var desc = Text( + descText, + style: PaintroidTheme.of(context).descStyle, + textAlign: TextAlign.start, + ); + return Scaffold( resizeToAvoidBottomInset: false, body: Container( width: double.infinity, - color: lightColorScheme.surface, + color: PaintroidTheme.of(context).surfaceColor, padding: const EdgeInsets.only(top: 60, left: 50, right: 50), child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -196,10 +179,10 @@ class _Screen3State extends State { child: Container( padding: const EdgeInsets.only(bottom: 10), alignment: Alignment.bottomCenter, - child: const Text( + child: Text( 'Tap on a tool to get more information', style: TextStyle( - color: Colors.white, + color: PaintroidTheme.of(context).onSurfaceColor, fontSize: 15, ), textAlign: TextAlign.start, diff --git a/packages/features/onboarding_screen/lib/src/screens/screen4.dart b/lib/ui/pages/onboarding_page/screens/screen4.dart similarity index 74% rename from packages/features/onboarding_screen/lib/src/screens/screen4.dart rename to lib/ui/pages/onboarding_page/screens/screen4.dart index ff72ffa4..c4450a63 100644 --- a/packages/features/onboarding_screen/lib/src/screens/screen4.dart +++ b/lib/ui/pages/onboarding_page/screens/screen4.dart @@ -1,13 +1,17 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; +// Project imports: +import 'package:paintroid/ui/shared/images/pocketpaint_intro_landscape.dart'; +import 'package:paintroid/ui/theme/theme.dart'; + class Screen4 extends StatelessWidget { - const Screen4({Key? key}) : super(key: key); + const Screen4({super.key}); @override Widget build(BuildContext context) { return Container( - color: lightColorScheme.surface, + color: PaintroidTheme.of(context).surfaceColor, padding: const EdgeInsets.only(top: 100, left: 20, right: 20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -16,10 +20,10 @@ class Screen4 extends StatelessWidget { Expanded( child: Container( padding: const EdgeInsets.symmetric(horizontal: 30), - child: const Text( + child: Text( 'Landscape', style: TextStyle( - color: Colors.white, + color: PaintroidTheme.of(context).onSurfaceColor, fontSize: 24, ), textAlign: TextAlign.start, @@ -29,10 +33,10 @@ class Screen4 extends StatelessWidget { Expanded( child: Container( padding: const EdgeInsets.symmetric(horizontal: 30), - child: const Text( + child: Text( 'Pocket Paint also supports drawing in landscape mode to give you the best painting experience.', style: TextStyle( - color: Colors.white, + color: PaintroidTheme.of(context).onSurfaceColor, fontSize: 15, ), textAlign: TextAlign.start, diff --git a/packages/features/onboarding_screen/lib/src/screens/screen5.dart b/lib/ui/pages/onboarding_page/screens/screen5.dart similarity index 75% rename from packages/features/onboarding_screen/lib/src/screens/screen5.dart rename to lib/ui/pages/onboarding_page/screens/screen5.dart index c7b4053e..8628df16 100644 --- a/packages/features/onboarding_screen/lib/src/screens/screen5.dart +++ b/lib/ui/pages/onboarding_page/screens/screen5.dart @@ -1,13 +1,17 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; +// Project imports: +import 'package:paintroid/ui/shared/images/pocketpaint_intro_portrait.dart'; +import 'package:paintroid/ui/theme/theme.dart'; + class Screen5 extends StatelessWidget { - const Screen5({Key? key}) : super(key: key); + const Screen5({super.key}); @override Widget build(BuildContext context) { return Container( - color: lightColorScheme.surface, + color: PaintroidTheme.of(context).surfaceColor, padding: const EdgeInsets.only(top: 100, left: 20, right: 20), child: Column( mainAxisAlignment: MainAxisAlignment.start, @@ -16,10 +20,10 @@ class Screen5 extends StatelessWidget { Expanded( child: Container( padding: const EdgeInsets.symmetric(horizontal: 30), - child: const Text( + child: Text( 'You are all set. Enjoy Pocket Paint.', style: TextStyle( - color: Colors.white, + color: PaintroidTheme.of(context).onSurfaceColor, fontSize: 24, ), textAlign: TextAlign.start, @@ -29,10 +33,10 @@ class Screen5 extends StatelessWidget { Expanded( child: Container( padding: const EdgeInsets.symmetric(horizontal: 30), - child: const Text( + child: Text( 'Get started and create a new masterpiece.', style: TextStyle( - color: Colors.white, + color: PaintroidTheme.of(context).onSurfaceColor, fontSize: 15, ), textAlign: TextAlign.start, diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart b/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart similarity index 65% rename from packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart rename to lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart index 7b754afa..13b23ac5 100644 --- a/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar.dart +++ b/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart @@ -1,15 +1,26 @@ +// Flutter imports: import 'package:colorpicker/colorpicker.dart'; -import 'package:component_library/component_library.dart'; import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:l10n/l10n.dart'; -import 'package:tools/tools.dart'; -import 'package:workspace_screen/workspace_screen.dart'; + +// Project imports: +import 'package:paintroid/core/enums/tool_types.dart'; +import 'package:paintroid/core/localization/app_localizations.dart'; +import 'package:paintroid/core/providers/state/tool_options_visibility_state_provider.dart'; +import 'package:paintroid/core/providers/state/tools/brush/brush_tool_state_provider.dart'; +import 'package:paintroid/core/providers/state/tools/toolbox/toolbox_state_provider.dart'; +import 'package:paintroid/core/tools/tool_data.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar_items.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/bottom_bar/tools/tools_bottom_sheet.dart'; +import 'package:paintroid/ui/shared/bottom_nav_bar_icon.dart'; +import 'package:paintroid/ui/theme/theme.dart'; class BottomNavBar extends ConsumerWidget { static const height = 64.0; - const BottomNavBar({Key? key}) : super(key: key); + const BottomNavBar({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { @@ -18,7 +29,7 @@ class BottomNavBar extends ConsumerWidget { final currentPaint = ref.watch(brushToolStateProvider).paint; return NavigationBarTheme( - data: WidgetThemes.bottomNavBarThemeData, + data: PaintroidTheme.of(context).bottomNavBarThemeData, child: NavigationBar( height: height, onDestinationSelected: (index) => @@ -33,21 +44,22 @@ class BottomNavBar extends ConsumerWidget { icon: BottomBarIcon(asset: currentToolData.svgAssetPath), ), NavigationDestination( - label: localizations.color, - icon: InkWell( - child: Container( - height: 24.0, - width: 24.0, - decoration: BoxDecoration( - color: currentPaint.color, - border: Border.all( - color: Colors.white, - width: 1.4, - ), - borderRadius: BorderRadius.circular(2.0), + label: localizations.color, + icon: InkWell( + child: Container( + height: 24.0, + width: 24.0, + decoration: BoxDecoration( + color: currentPaint.color, + border: Border.all( + color: Colors.white, + width: 1.4, ), + borderRadius: BorderRadius.circular(2.0), ), - )), + ), + ), + ), NavigationDestination( label: localizations.layers, icon: const BottomBarIcon(asset: 'assets/svg/ic_layers.svg'), @@ -88,11 +100,12 @@ void _onNavigationItemSelected(int index, BuildContext context, WidgetRef ref) { } void _showToolBottomSheet(BuildContext context) { + double screenHeight = MediaQuery.of(context).size.height; showModalBottomSheet( context: context, - builder: (BuildContext context) => const SizedBox( - height: 270, - child: ToolsBottomSheet(), + builder: (BuildContext context) => SizedBox( + height: screenHeight * 0.5, + child: const ToolsBottomSheet(), ), ); } diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar_items.dart b/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar_items.dart similarity index 100% rename from packages/features/workspace_screen/lib/src/components/bottom_bar/bottom_nav_bar_items.dart rename to lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar_items.dart diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_cap_tool_option.dart b/lib/ui/pages/workspace_page/components/bottom_bar/tool_options/stroke_cap_tool_option.dart similarity index 83% rename from packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_cap_tool_option.dart rename to lib/ui/pages/workspace_page/components/bottom_bar/tool_options/stroke_cap_tool_option.dart index 6b1abb05..ee3a15ff 100644 --- a/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_cap_tool_option.dart +++ b/lib/ui/pages/workspace_page/components/bottom_bar/tool_options/stroke_cap_tool_option.dart @@ -1,7 +1,13 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:tools/tools.dart'; + +// Project imports: +import 'package:paintroid/core/providers/state/tools/brush/brush_tool_state_provider.dart'; +import 'package:paintroid/ui/shared/custom_action_chip.dart'; +import 'package:paintroid/ui/theme/theme.dart'; class StrokeCapToolOption extends ConsumerStatefulWidget { const StrokeCapToolOption({super.key}); @@ -57,14 +63,20 @@ class _StrokeCapToolOptionState extends ConsumerState { children: [ CustomActionChip( hint: 'Round stroke', - chipIcon: const Icon(Icons.circle), + chipIcon: Icon( + Icons.circle, + color: PaintroidTheme.of(context).shadowColor, + ), onPressed: () => _changeActionChipBackgroundColor(StrokeCap.round), chipBackgroundColor: _roundChipBackgroundColor, ), CustomActionChip( hint: 'Square stroke', - chipIcon: const Icon(Icons.square), + chipIcon: Icon( + Icons.square, + color: PaintroidTheme.of(context).shadowColor, + ), onPressed: () => _changeActionChipBackgroundColor(StrokeCap.square), chipBackgroundColor: _squareChipBackgroundColor, diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_tool_options.dart b/lib/ui/pages/workspace_page/components/bottom_bar/tool_options/stroke_tool_options.dart similarity index 51% rename from packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_tool_options.dart rename to lib/ui/pages/workspace_page/components/bottom_bar/tool_options/stroke_tool_options.dart index 7d751026..48b5fab3 100644 --- a/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_tool_options.dart +++ b/lib/ui/pages/workspace_page/components/bottom_bar/tool_options/stroke_tool_options.dart @@ -1,5 +1,11 @@ +// Flutter imports: import 'package:flutter/cupertino.dart'; -import 'package:workspace_screen/workspace_screen.dart'; + +// Project imports: +import 'package:paintroid/ui/pages/workspace_page/components/bottom_bar/tool_options/stroke_cap_tool_option.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/bottom_bar/tool_options/stroke_width_tool_option.dart'; + +// Project imports: class StrokeToolOptions extends StatelessWidget { const StrokeToolOptions({super.key}); diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_width_tool_option.dart b/lib/ui/pages/workspace_page/components/bottom_bar/tool_options/stroke_width_tool_option.dart similarity index 89% rename from packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_width_tool_option.dart rename to lib/ui/pages/workspace_page/components/bottom_bar/tool_options/stroke_width_tool_option.dart index cce4c39f..10c96527 100644 --- a/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/stroke_width_tool_option.dart +++ b/lib/ui/pages/workspace_page/components/bottom_bar/tool_options/stroke_width_tool_option.dart @@ -1,8 +1,13 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:tools/tools.dart'; + +// Project imports: +import 'package:paintroid/core/providers/state/tools/brush/brush_tool_state_provider.dart'; +import 'package:paintroid/ui/theme/theme.dart'; class StrokeWidthToolOption extends ConsumerStatefulWidget { const StrokeWidthToolOption({super.key}); @@ -54,7 +59,7 @@ class _StrokeWidthToolOptionState extends ConsumerState { flex: 1, child: TextField( controller: _strokeWidthTextController, - style: TextThemes.menuItem, + style: PaintroidTheme.of(context).textTheme.bodyMedium, textAlign: TextAlign.center, keyboardType: TextInputType.number, inputFormatters: [ @@ -66,7 +71,7 @@ class _StrokeWidthToolOptionState extends ConsumerState { onChanged: _onChangedTextField, decoration: InputDecoration( filled: true, - fillColor: Colors.white, + fillColor: PaintroidTheme.of(context).onSurfaceColor, contentPadding: EdgeInsets.zero, hintText: '1', border: OutlineInputBorder( diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/tool_option.dart b/lib/ui/pages/workspace_page/components/bottom_bar/tool_options/tool_option.dart similarity index 93% rename from packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/tool_option.dart rename to lib/ui/pages/workspace_page/components/bottom_bar/tool_options/tool_option.dart index cf627f0b..22bf0c3b 100644 --- a/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/tool_option.dart +++ b/lib/ui/pages/workspace_page/components/bottom_bar/tool_options/tool_option.dart @@ -1,3 +1,4 @@ +// Flutter imports: import 'package:flutter/material.dart'; class ToolOption extends StatelessWidget { @@ -7,12 +8,12 @@ class ToolOption extends StatelessWidget { final Duration duration; const ToolOption({ - Key? key, + super.key, required this.isIgnoring, required this.opacity, required this.child, this.duration = const Duration(milliseconds: 300), - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/tool_options.dart b/lib/ui/pages/workspace_page/components/bottom_bar/tool_options/tool_options.dart similarity index 62% rename from packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/tool_options.dart rename to lib/ui/pages/workspace_page/components/bottom_bar/tool_options/tool_options.dart index b50e3f7f..f66bc4f5 100644 --- a/packages/features/workspace_screen/lib/src/components/bottom_bar/tool_options/tool_options.dart +++ b/lib/ui/pages/workspace_page/components/bottom_bar/tool_options/tool_options.dart @@ -1,7 +1,15 @@ +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:tools/tools.dart'; -import 'package:workspace_screen/workspace_screen.dart'; + +// Project imports: +import 'package:paintroid/core/enums/tool_types.dart'; +import 'package:paintroid/core/providers/state/tool_options_visibility_state_provider.dart'; +import 'package:paintroid/core/providers/state/tools/toolbox/toolbox_state_provider.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/bottom_bar/tool_options/stroke_tool_options.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/bottom_bar/tool_options/tool_option.dart'; class ToolOptions extends ConsumerWidget { const ToolOptions({super.key}); diff --git a/lib/ui/pages/workspace_page/components/bottom_bar/tools/tool_button.dart b/lib/ui/pages/workspace_page/components/bottom_bar/tools/tool_button.dart new file mode 100644 index 00000000..73d9e8c0 --- /dev/null +++ b/lib/ui/pages/workspace_page/components/bottom_bar/tools/tool_button.dart @@ -0,0 +1,51 @@ +// Flutter imports: +import 'package:flutter/material.dart'; + +// Package imports: +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +// Project imports: +import 'package:paintroid/core/providers/state/tools/toolbox/toolbox_state_provider.dart'; +import 'package:paintroid/core/tools/tool_data.dart'; +import 'package:paintroid/ui/shared/icon_button_with_label.dart'; +import 'package:paintroid/ui/shared/icon_svg.dart'; +import 'package:paintroid/ui/theme/theme.dart'; + +class ToolButton extends StatelessWidget { + final ToolData toolData; + + const ToolButton({ + super.key, + required this.toolData, + }); + + @override + Widget build(BuildContext context) { + return Consumer( + builder: (context, ref, child) { + return SizedBox( + width: 50.0, + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0, + vertical: 8.0, + ), + child: IconButtonWithLabel( + icon: IconSvg( + path: toolData.svgAssetPath, + height: 30.0, + width: 30.0, + color: PaintroidTheme.of(context).onSurfaceColor, + ), + label: toolData.name, + onPressed: () { + Navigator.pop(context); + ref.read(toolBoxStateProvider.notifier).switchTool(toolData); + }, + ), + ), + ); + }, + ); + } +} diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/tools/tools_bottom_sheet.dart b/lib/ui/pages/workspace_page/components/bottom_bar/tools/tools_bottom_sheet.dart similarity index 52% rename from packages/features/workspace_screen/lib/src/components/bottom_bar/tools/tools_bottom_sheet.dart rename to lib/ui/pages/workspace_page/components/bottom_bar/tools/tools_bottom_sheet.dart index 3a402b19..f7914425 100644 --- a/packages/features/workspace_screen/lib/src/components/bottom_bar/tools/tools_bottom_sheet.dart +++ b/lib/ui/pages/workspace_page/components/bottom_bar/tools/tools_bottom_sheet.dart @@ -1,7 +1,13 @@ +// Flutter imports: import 'package:flutter/material.dart'; -import 'package:tools/tools.dart'; -import 'package:workspace_screen/src/components/bottom_bar/tools/tool_button.dart'; -import 'package:workspace_screen/workspace_screen.dart'; + +// Project imports: +import 'package:paintroid/core/tools/tool_data.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/bottom_bar/tools/tool_button.dart'; + +// Package imports: + +// Project imports: class ToolsBottomSheet extends StatelessWidget { const ToolsBottomSheet({ @@ -11,11 +17,12 @@ class ToolsBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { const tools = ToolData.allToolsData; + Orientation currentOrientation = MediaQuery.of(context).orientation; return GridView.count( - crossAxisCount: 4, + crossAxisCount: currentOrientation == Orientation.portrait ? 4 : 8, mainAxisSpacing: 0.0, crossAxisSpacing: 0.0, - childAspectRatio: 1.6, + childAspectRatio: 1.0, children: tools.map((toolData) { return ToolButton( toolData: toolData, diff --git a/packages/features/workspace_screen/lib/src/components/drawing_surface/canvas_painter.dart b/lib/ui/pages/workspace_page/components/drawing_surface/canvas_painter.dart similarity index 77% rename from packages/features/workspace_screen/lib/src/components/drawing_surface/canvas_painter.dart rename to lib/ui/pages/workspace_page/components/drawing_surface/canvas_painter.dart index 3de42d23..251ffa59 100644 --- a/packages/features/workspace_screen/lib/src/components/drawing_surface/canvas_painter.dart +++ b/lib/ui/pages/workspace_page/components/drawing_surface/canvas_painter.dart @@ -1,7 +1,15 @@ -import 'package:command/command_providers.dart'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:workspace_screen/workspace_screen.dart'; + +// Project imports: +import 'package:paintroid/core/commands/command_manager/command_manager_provider.dart'; +import 'package:paintroid/core/commands/command_painter.dart'; +import 'package:paintroid/core/providers/object/canvas_dirty_notifier.dart'; +import 'package:paintroid/core/providers/state/canvas_state_provider.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/drawing_surface/checkerboard_pattern.dart'; class CanvasPainter extends ConsumerWidget { const CanvasPainter({super.key}); @@ -53,7 +61,7 @@ class PaintingLayer extends ConsumerWidget { ); final commands = ref.watch(commandManagerProvider); - ref.watch(CanvasDirtyState.provider); + ref.watch(CanvasDirtyNotifier.provider); return RepaintBoundary( child: Opacity( diff --git a/packages/features/workspace_screen/lib/src/components/drawing_surface/checkerboard_pattern.dart b/lib/ui/pages/workspace_page/components/drawing_surface/checkerboard_pattern.dart similarity index 60% rename from packages/features/workspace_screen/lib/src/components/drawing_surface/checkerboard_pattern.dart rename to lib/ui/pages/workspace_page/components/drawing_surface/checkerboard_pattern.dart index f61c58be..d21575a8 100644 --- a/packages/features/workspace_screen/lib/src/components/drawing_surface/checkerboard_pattern.dart +++ b/lib/ui/pages/workspace_page/components/drawing_surface/checkerboard_pattern.dart @@ -1,17 +1,20 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; +// Project imports: +import 'package:paintroid/ui/shared/images/checkerboard.dart'; + class CheckerboardPattern extends StatelessWidget { final Widget? child; - const CheckerboardPattern({Key? key, this.child}) : super(key: key); + const CheckerboardPattern({super.key, this.child}); @override Widget build(BuildContext context) { return Stack( children: [ const Positioned.fill( - child: CheckerboardImg(), + child: CheckerboardImage(), ), if (child != null) child!, ], diff --git a/packages/features/workspace_screen/lib/src/components/drawing_surface/drawing_canvas.dart b/lib/ui/pages/workspace_page/components/drawing_surface/drawing_canvas.dart similarity index 84% rename from packages/features/workspace_screen/lib/src/components/drawing_surface/drawing_canvas.dart rename to lib/ui/pages/workspace_page/components/drawing_surface/drawing_canvas.dart index 23c5d02e..91fefb8e 100644 --- a/packages/features/workspace_screen/lib/src/components/drawing_surface/drawing_canvas.dart +++ b/lib/ui/pages/workspace_page/components/drawing_surface/drawing_canvas.dart @@ -1,10 +1,20 @@ +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:tools/tools.dart'; -import 'package:workspace_screen/workspace_screen.dart'; + +// Project imports: +import 'package:paintroid/core/enums/tool_types.dart'; +import 'package:paintroid/core/providers/object/canvas_dirty_notifier.dart'; +import 'package:paintroid/core/providers/object/device_service.dart'; +import 'package:paintroid/core/providers/state/canvas_state_provider.dart'; +import 'package:paintroid/core/providers/state/tools/toolbox/toolbox_state_provider.dart'; +import 'package:paintroid/core/providers/state/workspace_state_notifier.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/drawing_surface/canvas_painter.dart'; class DrawingCanvas extends ConsumerStatefulWidget { - const DrawingCanvas({Key? key}) : super(key: key); + const DrawingCanvas({super.key}); @override ConsumerState createState() => _DrawingCanvasState(); @@ -14,7 +24,7 @@ class _DrawingCanvasState extends ConsumerState { late final _toolBoxStateNotifier = ref.read(toolBoxStateProvider.notifier); late final _canvasStateNotifier = ref.read(canvasStateProvider.notifier); late final _canvasDirtyNotifier = - ref.read(CanvasDirtyState.provider.notifier); + ref.read(CanvasDirtyNotifier.provider.notifier); final _canvasPainterKey = GlobalKey(debugLabel: 'CanvasPainter'); final _transformationController = TransformationController(); @@ -121,7 +131,7 @@ class _DrawingCanvasState extends ConsumerState { boundaryMargin: const EdgeInsets.all(double.infinity), interactionEndFrictionCoefficient: double.minPositive, panEnabled: - ref.watch(toolBoxStateProvider).currentTool.type == ToolType.HAND, + ref.watch(toolBoxStateProvider).currentToolType == ToolType.HAND, onInteractionStart: _onInteractionStart, onInteractionUpdate: _onInteractionUpdate, onInteractionEnd: _onInteractionEnd, diff --git a/packages/features/workspace_screen/lib/src/components/drawing_surface/exit_fullscreen_button.dart b/lib/ui/pages/workspace_page/components/drawing_surface/exit_fullscreen_button.dart similarity index 61% rename from packages/features/workspace_screen/lib/src/components/drawing_surface/exit_fullscreen_button.dart rename to lib/ui/pages/workspace_page/components/drawing_surface/exit_fullscreen_button.dart index 9acf6e3f..6c12f862 100644 --- a/packages/features/workspace_screen/lib/src/components/drawing_surface/exit_fullscreen_button.dart +++ b/lib/ui/pages/workspace_page/components/drawing_surface/exit_fullscreen_button.dart @@ -1,10 +1,16 @@ +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:tools/tools.dart'; -import 'package:workspace_screen/workspace_screen.dart'; + +// Project imports: +import 'package:paintroid/core/providers/state/tools/toolbox/toolbox_state_provider.dart'; +import 'package:paintroid/core/providers/state/workspace_state_notifier.dart'; +import 'package:paintroid/ui/theme/theme.dart'; class ExitFullscreenButton extends ConsumerWidget { - const ExitFullscreenButton({Key? key}) : super(key: key); + const ExitFullscreenButton({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { @@ -18,9 +24,9 @@ class ExitFullscreenButton extends ConsumerWidget { onPressed: () { ref.read(WorkspaceState.provider.notifier).toggleFullscreen(false); }, - icon: const Icon( + icon: Icon( Icons.fullscreen_exit, - color: Colors.black, + color: PaintroidTheme.of(context).shadowColor, ), ), ); diff --git a/packages/features/workspace_screen/lib/src/components/top_bar/overflow_menu.dart b/lib/ui/pages/workspace_page/components/top_bar/overflow_menu.dart similarity index 84% rename from packages/features/workspace_screen/lib/src/components/top_bar/overflow_menu.dart rename to lib/ui/pages/workspace_page/components/top_bar/overflow_menu.dart index 238c4863..56d81e28 100644 --- a/packages/features/workspace_screen/lib/src/components/top_bar/overflow_menu.dart +++ b/lib/ui/pages/workspace_page/components/top_bar/overflow_menu.dart @@ -1,12 +1,23 @@ -import 'package:component_library/component_library.dart'; -import 'package:database/database.dart'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; -import 'package:l10n/l10n.dart'; import 'package:oxidized/oxidized.dart'; import 'package:toast/toast.dart'; -import 'package:workspace_screen/workspace_screen.dart'; + +// Project imports: +import 'package:paintroid/core/database/project_database.dart'; +import 'package:paintroid/core/localization/app_localizations.dart'; +import 'package:paintroid/core/models/database/project.dart'; +import 'package:paintroid/core/models/image_meta_data.dart'; +import 'package:paintroid/core/providers/object/file_service.dart'; +import 'package:paintroid/core/providers/object/io_handler.dart'; +import 'package:paintroid/core/providers/state/workspace_state_notifier.dart'; +import 'package:paintroid/ui/shared/dialogs/overwrite_dialog.dart'; +import 'package:paintroid/ui/shared/dialogs/save_image_dialog.dart'; +import 'package:paintroid/ui/shared/pop_menu_button.dart'; +import 'package:paintroid/ui/theme/theme.dart'; enum OverflowMenuOption { fullscreen, @@ -33,7 +44,7 @@ enum OverflowMenuOption { } class OverflowMenu extends ConsumerStatefulWidget { - const OverflowMenu({Key? key}) : super(key: key); + const OverflowMenu({super.key}); @override ConsumerState createState() => _OverflowMenuState(); @@ -51,7 +62,7 @@ class _OverflowMenuState extends ConsumerState { value: option, child: Text( option.localizedLabel(context), - style: TextThemes.menuItem, + style: PaintroidTheme.of(context).textTheme.bodyMedium, ))) .toList(), ); diff --git a/packages/features/workspace_screen/lib/src/components/top_bar/top_app_bar.dart b/lib/ui/pages/workspace_page/components/top_bar/top_app_bar.dart similarity index 50% rename from packages/features/workspace_screen/lib/src/components/top_bar/top_app_bar.dart rename to lib/ui/pages/workspace_page/components/top_bar/top_app_bar.dart index fa21bad8..d0c88be1 100644 --- a/packages/features/workspace_screen/lib/src/components/top_bar/top_app_bar.dart +++ b/lib/ui/pages/workspace_page/components/top_bar/top_app_bar.dart @@ -1,10 +1,14 @@ +// Flutter imports: import 'package:flutter/material.dart'; -import 'package:workspace_screen/workspace_screen.dart'; + +// Project imports: +import 'package:paintroid/ui/pages/workspace_page/components/top_bar/overflow_menu.dart'; + +// Project imports: class TopAppBar extends AppBar { - TopAppBar({Key? key, required String title}) + TopAppBar({super.key, required String title}) : super( - key: key, title: Text(title), centerTitle: false, actions: [const OverflowMenu()], diff --git a/lib/ui/pages/workspace_page/workspace_page.dart b/lib/ui/pages/workspace_page/workspace_page.dart new file mode 100644 index 00000000..8055cf7d --- /dev/null +++ b/lib/ui/pages/workspace_page/workspace_page.dart @@ -0,0 +1,90 @@ +// Flutter imports: +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +// Package imports: +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:toast/toast.dart'; + +// Project imports: +import 'package:paintroid/core/providers/object/io_handler.dart'; +import 'package:paintroid/core/providers/state/workspace_state_notifier.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/bottom_bar/tool_options/tool_options.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/drawing_surface/drawing_canvas.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/drawing_surface/exit_fullscreen_button.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/top_bar/top_app_bar.dart'; +import 'package:paintroid/ui/shared/dialogs/discard_changes_dialog.dart'; + +class WorkspacePage extends ConsumerStatefulWidget { + const WorkspacePage({super.key}); + + @override + ConsumerState createState() => _WorkspaceScreenState(); +} + +class _WorkspaceScreenState extends ConsumerState { + void _toggleStatusBar(bool isFullscreen) { + SystemChrome.setEnabledSystemUIMode( + isFullscreen ? SystemUiMode.immersiveSticky : SystemUiMode.manual, + overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom], + ); + } + + @override + Widget build(BuildContext context) { + ToastContext().init(context); + + final isFullscreen = ref.watch( + WorkspaceState.provider.select((state) => state.isFullscreen), + ); + ref.listen( + WorkspaceState.provider.select((state) => state.isFullscreen), + (_, isFullscreen) => _toggleStatusBar(isFullscreen), + ); + final ioHandler = ref.watch(IOHandler.provider); + final workspaceStateNotifier = ref.watch(WorkspaceState.provider.notifier); + return PopScope( + canPop: false, + onPopInvoked: (didPop) async { + if (didPop) { + return; + } + if (isFullscreen) { + workspaceStateNotifier.toggleFullscreen(false); + return; + } + if (!workspaceStateNotifier.hasSavedLastWork) { + final shouldDiscard = await showDiscardChangesDialog(context); + if (shouldDiscard != null && !shouldDiscard && context.mounted) { + bool savedImage = await ioHandler.saveImage(context); + if (!savedImage) { + return; + } + } + } + if (!context.mounted) return; + Navigator.pop(context); + }, + child: Scaffold( + appBar: isFullscreen ? null : TopAppBar(title: 'Pocket Paint'), + backgroundColor: Colors.grey.shade400, + resizeToAvoidBottomInset: true, + body: Stack( + children: [ + const DrawingCanvas(), + if (isFullscreen) + const Positioned( + top: 2, + right: 2, + child: SafeArea(child: ExitFullscreenButton()), + ) + else + const ToolOptions(), + ], + ), + bottomNavigationBar: isFullscreen ? null : const BottomNavBar(), + ), + ); + } +} diff --git a/lib/ui/shared/bottom_nav_bar_icon.dart b/lib/ui/shared/bottom_nav_bar_icon.dart new file mode 100644 index 00000000..89f430db --- /dev/null +++ b/lib/ui/shared/bottom_nav_bar_icon.dart @@ -0,0 +1,22 @@ +// Flutter imports: +import 'package:flutter/material.dart'; + +// Project imports: +import 'package:paintroid/ui/shared/icon_svg.dart'; +import 'package:paintroid/ui/theme/theme.dart'; + +class BottomBarIcon extends StatelessWidget { + final String asset; + + const BottomBarIcon({super.key, required this.asset}); + + @override + Widget build(BuildContext context) { + return IconSvg( + path: asset, + height: 24.0, + width: 24.0, + color: PaintroidTheme.of(context).onSurfaceColor, + ); + } +} diff --git a/packages/component_library/lib/src/components/custom_action_chip.dart b/lib/ui/shared/custom_action_chip.dart similarity index 98% rename from packages/component_library/lib/src/components/custom_action_chip.dart rename to lib/ui/shared/custom_action_chip.dart index 697df41a..baee9e41 100644 --- a/packages/component_library/lib/src/components/custom_action_chip.dart +++ b/lib/ui/shared/custom_action_chip.dart @@ -1,3 +1,4 @@ +// Flutter imports: import 'package:flutter/material.dart'; class CustomActionChip extends StatelessWidget { diff --git a/packages/io_library/lib/src/ui/about_dialog.dart b/lib/ui/shared/dialogs/about_dialog.dart similarity index 82% rename from packages/io_library/lib/src/ui/about_dialog.dart rename to lib/ui/shared/dialogs/about_dialog.dart index f672d6af..21b5ef29 100644 --- a/packages/io_library/lib/src/ui/about_dialog.dart +++ b/lib/ui/shared/dialogs/about_dialog.dart @@ -1,8 +1,15 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; + +// Project imports: +import 'package:paintroid/core/utils/open_url.dart'; +import 'package:paintroid/ui/shared/dialogs/generic_dialog.dart'; +import 'package:paintroid/ui/shared/images/pocketpaint_logo_small.dart'; +import 'package:paintroid/ui/theme/theme.dart'; Future showMyAboutDialog(BuildContext context, String version) => showGeneralDialog( @@ -14,7 +21,7 @@ Future showMyAboutDialog(BuildContext context, String version) => class MyAboutDialog extends ConsumerStatefulWidget { final String version; - const MyAboutDialog({Key? key, required this.version}) : super(key: key); + const MyAboutDialog({super.key, required this.version}); @override ConsumerState createState() => _MyAboutDialogState(); @@ -29,12 +36,6 @@ class _MyAboutDialogState extends ConsumerState { static const urlLicense = 'https://developer.catrobat.org/licenses'; static const urlCatrobat = 'https://catrobat.org'; - static const urlTextStyle = TextStyle( - color: Color(0xFFE68B00), - fontSize: 18, - decoration: TextDecoration.underline, - ); - TextSpan _clickableText(String text, String url, TextStyle? style) => TextSpan( text: text, @@ -47,6 +48,11 @@ class _MyAboutDialogState extends ConsumerState { @override Widget build(BuildContext context) { + final urlTextStyle = TextStyle( + color: PaintroidTheme.of(context).orangeColor, + fontSize: 18, + decoration: TextDecoration.underline, + ); return GenericDialog( title: 'About', actions: [ @@ -69,7 +75,7 @@ class _MyAboutDialogState extends ConsumerState { SelectableText.rich( textAlign: TextAlign.center, TextSpan( - style: const TextStyle(color: Colors.black), + style: TextStyle(color: PaintroidTheme.of(context).shadowColor), children: [ const TextSpan(text: content), _clickableText( diff --git a/packages/io_library/lib/src/ui/delete_project_dialog.dart b/lib/ui/shared/dialogs/delete_project_dialog.dart similarity index 82% rename from packages/io_library/lib/src/ui/delete_project_dialog.dart rename to lib/ui/shared/dialogs/delete_project_dialog.dart index 667f45e4..abf68ae9 100644 --- a/packages/io_library/lib/src/ui/delete_project_dialog.dart +++ b/lib/ui/shared/dialogs/delete_project_dialog.dart @@ -1,8 +1,9 @@ +// Flutter imports: import 'package:flutter/material.dart'; -import 'package:io_library/io_library.dart'; -/// Returns [true] if user chose to delete the project or [null] if user -/// dismiss the dialog by tapping outside +// Project imports: +import 'package:paintroid/ui/shared/dialogs/generic_dialog.dart'; + Future showDeleteDialog(BuildContext context, String name) => showGeneralDialog( context: context, diff --git a/packages/io_library/lib/src/ui/discard_changes_dialog.dart b/lib/ui/shared/dialogs/discard_changes_dialog.dart similarity index 83% rename from packages/io_library/lib/src/ui/discard_changes_dialog.dart rename to lib/ui/shared/dialogs/discard_changes_dialog.dart index 2f2d1e65..8943889a 100644 --- a/packages/io_library/lib/src/ui/discard_changes_dialog.dart +++ b/lib/ui/shared/dialogs/discard_changes_dialog.dart @@ -1,8 +1,9 @@ +// Flutter imports: import 'package:flutter/material.dart'; -import 'package:io_library/io_library.dart'; -/// Returns [true] if user chose to discard changes or [null] if user -/// dismissed the dialog by tapping outside +// Project imports: +import 'package:paintroid/ui/shared/dialogs/generic_dialog.dart'; + Future showDiscardChangesDialog(BuildContext context) => showGeneralDialog( context: context, diff --git a/packages/io_library/lib/src/ui/generic_dialog.dart b/lib/ui/shared/dialogs/generic_dialog.dart similarity index 66% rename from packages/io_library/lib/src/ui/generic_dialog.dart rename to lib/ui/shared/dialogs/generic_dialog.dart index bee333b8..6a10fb16 100644 --- a/packages/io_library/lib/src/ui/generic_dialog.dart +++ b/lib/ui/shared/dialogs/generic_dialog.dart @@ -1,17 +1,23 @@ +// Flutter imports: import 'package:flutter/material.dart'; +// Project imports: +import 'package:paintroid/ui/theme/theme.dart'; + class GenericDialogActionButton extends StatelessWidget { final String text; final Function? onPressed; const GenericDialogActionButton( - {Key? key, required this.text, this.onPressed}) - : super(key: key); + {super.key, required this.text, this.onPressed}); @override Widget build(BuildContext context) => TextButton( style: ButtonStyle( - foregroundColor: MaterialStateProperty.all(Colors.blue)), + foregroundColor: MaterialStateProperty.all( + PaintroidTheme.of(context).primaryColor, + ), + ), onPressed: () => { if (onPressed != null) {onPressed!()} }, @@ -33,31 +39,35 @@ class GenericDialog extends StatelessWidget { final List actions; const GenericDialog( - {Key? key, + {super.key, required this.title, this.text, this.content, - required this.actions}) - : super(key: key); + required this.actions}); - Widget? getContent() { + Widget? getContent(BuildContext context) { if (content != null) { return content; } if (text != null) { - return Text(text!, style: const TextStyle(color: Colors.black)); + return Text( + text!, + style: TextStyle( + color: PaintroidTheme.of(context).shadowColor, + ), + ); } return null; } @override Widget build(BuildContext context) => AlertDialog( - backgroundColor: Colors.white, + backgroundColor: PaintroidTheme.of(context).onSurfaceColor, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(2.0))), title: Text( title, - style: const TextStyle(color: Colors.black), + style: TextStyle(color: PaintroidTheme.of(context).shadowColor), ), actions: actions .map((action) => GenericDialogActionButton( @@ -65,6 +75,6 @@ class GenericDialog extends StatelessWidget { onPressed: action.onPressed, )) .toList(), - content: getContent(), + content: getContent(context), ); } diff --git a/packages/io_library/lib/src/ui/load_image_dialog.dart b/lib/ui/shared/dialogs/load_image_dialog.dart similarity index 83% rename from packages/io_library/lib/src/ui/load_image_dialog.dart rename to lib/ui/shared/dialogs/load_image_dialog.dart index 50840894..6788541c 100644 --- a/packages/io_library/lib/src/ui/load_image_dialog.dart +++ b/lib/ui/shared/dialogs/load_image_dialog.dart @@ -1,7 +1,10 @@ +// Flutter imports: import 'package:flutter/material.dart'; -import 'package:io_library/io_library.dart'; -/// Returns [null] if user dismissed the dialog by tapping outside +// Project imports: +import 'package:paintroid/core/enums/image_location.dart'; +import 'package:paintroid/ui/shared/dialogs/generic_dialog.dart'; + Future showLoadImageDialog(BuildContext context) => showGeneralDialog( context: context, diff --git a/packages/io_library/lib/src/ui/overwrite_dialog.dart b/lib/ui/shared/dialogs/overwrite_dialog.dart similarity index 87% rename from packages/io_library/lib/src/ui/overwrite_dialog.dart rename to lib/ui/shared/dialogs/overwrite_dialog.dart index e625c53b..5036e54b 100644 --- a/packages/io_library/lib/src/ui/overwrite_dialog.dart +++ b/lib/ui/shared/dialogs/overwrite_dialog.dart @@ -1,5 +1,8 @@ +// Flutter imports: import 'package:flutter/material.dart'; -import 'package:io_library/io_library.dart'; + +// Project imports: +import 'package:paintroid/ui/shared/dialogs/generic_dialog.dart'; Future showOverwriteDialog(BuildContext context) => showGeneralDialog( diff --git a/packages/io_library/lib/src/ui/project_details_dialog.dart b/lib/ui/shared/dialogs/project_details_dialog.dart similarity index 85% rename from packages/io_library/lib/src/ui/project_details_dialog.dart rename to lib/ui/shared/dialogs/project_details_dialog.dart index 33687d8f..36d4ca00 100644 --- a/packages/io_library/lib/src/ui/project_details_dialog.dart +++ b/lib/ui/shared/dialogs/project_details_dialog.dart @@ -1,12 +1,20 @@ -import 'package:component_library/component_library.dart'; -import 'package:database/database.dart'; -import 'package:filesize/filesize.dart'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: +import 'package:filesize/filesize.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; -import 'package:io_library/io_library.dart'; import 'package:oxidized/oxidized.dart'; +// Project imports: +import 'package:paintroid/core/models/database/project.dart'; +import 'package:paintroid/core/providers/object/file_service.dart'; +import 'package:paintroid/core/providers/object/image_service.dart'; +import 'package:paintroid/ui/shared/dialogs/generic_dialog.dart'; +import 'package:paintroid/ui/theme/theme.dart'; +import 'package:paintroid/ui/utils/toast_utils.dart'; + Future showDetailsDialog(BuildContext context, Project project) => showGeneralDialog( context: context, @@ -17,8 +25,7 @@ Future showDetailsDialog(BuildContext context, Project project) => class ProjectDetailsDialog extends ConsumerStatefulWidget { final Project project; - const ProjectDetailsDialog({Key? key, required this.project}) - : super(key: key); + const ProjectDetailsDialog({super.key, required this.project}); @override ConsumerState createState() => @@ -65,7 +72,7 @@ class _ProjectDetailsDialogState extends ConsumerState { mainAxisSize: MainAxisSize.min, children: [ CircularProgressIndicator( - backgroundColor: lightColorScheme.background, + backgroundColor: PaintroidTheme.of(context).backgroundColor, ), ], ); diff --git a/packages/io_library/lib/src/ui/save_image_dialog.dart b/lib/ui/shared/dialogs/save_image_dialog.dart similarity index 67% rename from packages/io_library/lib/src/ui/save_image_dialog.dart rename to lib/ui/shared/dialogs/save_image_dialog.dart index 104f4bb5..40996834 100644 --- a/packages/io_library/lib/src/ui/save_image_dialog.dart +++ b/lib/ui/shared/dialogs/save_image_dialog.dart @@ -1,8 +1,12 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; -import 'package:io_library/io_library.dart'; -/// Returns [null] if user dismissed the dialog by tapping outside +// Project imports: +import 'package:paintroid/core/enums/image_format.dart'; +import 'package:paintroid/core/models/image_meta_data.dart'; +import 'package:paintroid/ui/shared/image_format_info.dart'; +import 'package:paintroid/ui/theme/theme.dart'; + Future showSaveImageDialog( BuildContext context, bool savingProject) => showGeneralDialog( @@ -15,8 +19,7 @@ Future showSaveImageDialog( class SaveImageDialog extends StatefulWidget { final bool savingProject; - const SaveImageDialog({Key? key, required this.savingProject}) - : super(key: key); + const SaveImageDialog({super.key, required this.savingProject}); @override State createState() => _SaveImageDialogState(); @@ -62,12 +65,13 @@ class _SaveImageDialogState extends State { dialogTitle += 'Image'; } return AlertDialog( + backgroundColor: PaintroidTheme.of(context).onSurfaceColor, title: Text( dialogTitle, - style: TextThemes.largeBoldText, + style: PaintroidTheme.of(context).titleTheme.titleMedium, ), actions: [_cancelButton, _saveButton], - contentTextStyle: TextThemes.menuItem, + contentTextStyle: PaintroidTheme.of(context).textTheme.bodyMedium, content: Form( key: formKey, child: Column( @@ -75,19 +79,28 @@ class _SaveImageDialogState extends State { mainAxisSize: MainAxisSize.min, children: [ _imageNameTextField, - const Divider(height: 16), + Divider( + height: 16, + color: PaintroidTheme.of(context).onSurfaceVariantColor, + ), if (!widget.savingProject) Column( children: [ _imageFormatDropdown, - const Divider(height: 8), + Divider( + height: 8, + color: PaintroidTheme.of(context).onSurfaceVariantColor, + ), ], ), if (!widget.savingProject && selectedFormat == ImageFormat.jpg) Column( children: [ _qualitySlider, - const Divider(height: 8), + Divider( + height: 8, + color: PaintroidTheme.of(context).onSurfaceVariantColor, + ), ], ), ImageFormatInfo(selectedFormat), @@ -100,7 +113,10 @@ class _SaveImageDialogState extends State { TextButton get _cancelButton { return TextButton( onPressed: () => Navigator.of(context).pop(), - child: const Text('Cancel'), + child: Text( + 'Cancel', + style: TextStyle(color: PaintroidTheme.of(context).primaryColor), + ), ); } @@ -112,7 +128,10 @@ class _SaveImageDialogState extends State { _dismissDialogWithData(); } }, - child: const Text('Save'), + child: Text( + 'Save', + style: TextStyle(color: PaintroidTheme.of(context).primaryColor), + ), ); } @@ -124,6 +143,10 @@ class _SaveImageDialogState extends State { children: [ Text('Quality: $imageQualityValue%'), Slider( + secondaryActiveColor: PaintroidTheme.of(context).primaryColor, + thumbColor: PaintroidTheme.of(context).primaryColor, + activeColor: PaintroidTheme.of(context).primaryColor, + inactiveColor: PaintroidTheme.of(context).secondaryContainerColor, max: 100, divisions: 100, value: imageQualityValue.toDouble(), @@ -142,9 +165,11 @@ class _SaveImageDialogState extends State { controller: nameFieldController, decoration: InputDecoration( hintText: widget.savingProject ? 'Project name' : 'Image name', - hintStyle: TextThemes.hintTextNormal, + hintStyle: PaintroidTheme.of(context).textTheme.bodySmall!.apply( + color: PaintroidTheme.of(context).onSurfaceColor, + ), filled: true, - fillColor: lightColorScheme.secondaryContainer, + fillColor: PaintroidTheme.of(context).secondaryContainerColor, border: const OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(8))), ), @@ -167,13 +192,23 @@ class _SaveImageDialogState extends State { const Text('Format:'), const VerticalDivider(width: 12), DropdownButton( + dropdownColor: PaintroidTheme.of(context).onSurfaceColor, + iconEnabledColor: PaintroidTheme.of(context).shadowColor, borderRadius: BorderRadius.circular(12), value: selectedFormat, - underline: const Divider(height: 0, color: Colors.black), + underline: Divider( + height: 0, + color: PaintroidTheme.of(context).shadowColor, + ), items: ImageFormat.values.map((fileType) { return DropdownMenuItem( value: fileType, - child: Text(fileType.extension, style: TextThemes.menuItem), + child: Text( + fileType.extension, + style: PaintroidTheme.of(context).textTheme.bodyMedium!.apply( + color: PaintroidTheme.of(context).shadowColor, + ), + ), ); }).toList(), onChanged: (selectedFileType) { diff --git a/packages/component_library/lib/src/components/icon_button_with_label.dart b/lib/ui/shared/icon_button_with_label.dart similarity index 74% rename from packages/component_library/lib/src/components/icon_button_with_label.dart rename to lib/ui/shared/icon_button_with_label.dart index ac6db6b4..3d9736a4 100644 --- a/packages/component_library/lib/src/components/icon_button_with_label.dart +++ b/lib/ui/shared/icon_button_with_label.dart @@ -1,3 +1,4 @@ +// Flutter imports: import 'package:flutter/material.dart'; class IconButtonWithLabel extends StatelessWidget { @@ -6,11 +7,11 @@ class IconButtonWithLabel extends StatelessWidget { final VoidCallback onPressed; const IconButtonWithLabel({ - Key? key, + super.key, required this.icon, required this.label, required this.onPressed, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -20,9 +21,11 @@ class IconButtonWithLabel extends StatelessWidget { icon: icon, onPressed: onPressed, ), - Text( - label, - style: const TextStyle(fontSize: 10), + FittedBox( + child: Text( + label, + style: const TextStyle(fontSize: 10), + ), ), ], ); diff --git a/packages/component_library/lib/src/components/icon_svg.dart b/lib/ui/shared/icon_svg.dart similarity index 85% rename from packages/component_library/lib/src/components/icon_svg.dart rename to lib/ui/shared/icon_svg.dart index 80e6648d..e9181fd6 100644 --- a/packages/component_library/lib/src/components/icon_svg.dart +++ b/lib/ui/shared/icon_svg.dart @@ -1,4 +1,7 @@ +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_svg/svg.dart'; class IconSvg extends StatelessWidget { @@ -8,17 +11,17 @@ class IconSvg extends StatelessWidget { final Color? color; const IconSvg({ - Key? key, + super.key, required this.path, required this.height, required this.width, this.color, - }) : super(key: key); + }); @override Widget build(BuildContext context) { return SvgPicture.asset( - 'packages/component_library/$path', + path, height: height, width: width, color: color, diff --git a/packages/io_library/lib/src/ui/image_format_info.dart b/lib/ui/shared/image_format_info.dart similarity index 66% rename from packages/io_library/lib/src/ui/image_format_info.dart rename to lib/ui/shared/image_format_info.dart index 78fbcd8e..98f42574 100644 --- a/packages/io_library/lib/src/ui/image_format_info.dart +++ b/lib/ui/shared/image_format_info.dart @@ -1,5 +1,9 @@ +// Flutter imports: import 'package:flutter/material.dart'; -import 'package:io_library/io_library.dart'; + +// Project imports: +import 'package:paintroid/core/enums/image_format.dart'; +import 'package:paintroid/ui/theme/theme.dart'; extension on ImageFormat { TextSpan get info { @@ -29,18 +33,24 @@ extension on ImageFormat { class ImageFormatInfo extends StatelessWidget { final ImageFormat format; - const ImageFormatInfo(this.format, {Key? key}) : super(key: key); + const ImageFormatInfo(this.format, {super.key}); @override Widget build(BuildContext context) { return Row( children: [ - const Icon(Icons.info_outline), - const VerticalDivider(width: 8), + Icon(Icons.info_outline, color: PaintroidTheme.of(context).shadowColor), + VerticalDivider( + width: 8, + color: PaintroidTheme.of(context).shadowColor, + ), Flexible( child: Text.rich( format.info, - style: const TextStyle(fontSize: 11), + style: TextStyle( + fontSize: 11, + color: PaintroidTheme.of(context).shadowColor, + ), ), ) ], diff --git a/lib/ui/shared/images/checkerboard.dart b/lib/ui/shared/images/checkerboard.dart new file mode 100644 index 00000000..697206d6 --- /dev/null +++ b/lib/ui/shared/images/checkerboard.dart @@ -0,0 +1,19 @@ +// Flutter imports: +import 'package:flutter/widgets.dart'; + +class CheckerboardImage extends StatelessWidget { + const CheckerboardImage({super.key}); + + @override + Widget build(BuildContext context) { + return SizedBox( + child: Image.asset( + 'assets/img/checkerboard.png', + repeat: ImageRepeat.repeat, + cacheWidth: 50, + cacheHeight: 50, + filterQuality: FilterQuality.none, + ), + ); + } +} diff --git a/lib/ui/shared/images/pocketpaint_intro_landscape.dart b/lib/ui/shared/images/pocketpaint_intro_landscape.dart new file mode 100644 index 00000000..f39fa3d8 --- /dev/null +++ b/lib/ui/shared/images/pocketpaint_intro_landscape.dart @@ -0,0 +1,16 @@ +// Flutter imports: +import 'package:flutter/widgets.dart'; + +class PocketPaintIntroLandscape extends StatelessWidget { + const PocketPaintIntroLandscape({super.key}); + + @override + Widget build(BuildContext context) { + return SizedBox( + child: Image.asset( + 'assets/img/pocketpaint_intro_landscape.png', + fit: BoxFit.contain, + ), + ); + } +} diff --git a/lib/ui/shared/images/pocketpaint_intro_portrait.dart b/lib/ui/shared/images/pocketpaint_intro_portrait.dart new file mode 100644 index 00000000..6dc39c00 --- /dev/null +++ b/lib/ui/shared/images/pocketpaint_intro_portrait.dart @@ -0,0 +1,16 @@ +// Flutter imports: +import 'package:flutter/widgets.dart'; + +class PocketPaintIntroPortrait extends StatelessWidget { + const PocketPaintIntroPortrait({super.key}); + + @override + Widget build(BuildContext context) { + return SizedBox( + child: Image.asset( + 'assets/img/pocketpaint_intro_portrait.png', + fit: BoxFit.fitHeight, + ), + ); + } +} diff --git a/lib/ui/shared/images/pocketpaint_logo_small.dart b/lib/ui/shared/images/pocketpaint_logo_small.dart new file mode 100644 index 00000000..aa589f66 --- /dev/null +++ b/lib/ui/shared/images/pocketpaint_logo_small.dart @@ -0,0 +1,15 @@ +// Flutter imports: +import 'package:flutter/widgets.dart'; + +class PocketPaintLogoSmall extends StatelessWidget { + const PocketPaintLogoSmall({super.key}); + + @override + Widget build(BuildContext context) { + return SizedBox( + child: Image.asset( + 'assets/img/pocketpaint_logo_small.png', + ), + ); + } +} diff --git a/packages/component_library/lib/src/components/loading_overlay.dart b/lib/ui/shared/loading_overlay.dart similarity index 87% rename from packages/component_library/lib/src/components/loading_overlay.dart rename to lib/ui/shared/loading_overlay.dart index 176d058c..54b03f59 100644 --- a/packages/component_library/lib/src/components/loading_overlay.dart +++ b/lib/ui/shared/loading_overlay.dart @@ -1,5 +1,11 @@ +// Flutter imports: import 'package:flutter/material.dart'; +// Project imports: +import 'package:paintroid/ui/theme/theme.dart'; + +// Project imports: + class LoadingOverlay extends StatefulWidget { final bool isLoading; final Widget? child; @@ -67,16 +73,18 @@ class _LoadingOverlayState extends State if (_overlayVisible == true) FadeTransition( opacity: _animation, - child: const Stack( + child: Stack( children: [ Opacity( opacity: 0.6, child: ModalBarrier( dismissible: false, - color: Colors.black, + color: PaintroidTheme.of(context).shadowColor, ), ), - Center(child: CircularProgressIndicator()), + const Center( + child: CircularProgressIndicator(), + ), ], ), ), diff --git a/packages/component_library/lib/src/components/pop_menu_button.dart b/lib/ui/shared/pop_menu_button.dart similarity index 65% rename from packages/component_library/lib/src/components/pop_menu_button.dart rename to lib/ui/shared/pop_menu_button.dart index 3e9b4931..6fc37541 100644 --- a/packages/component_library/lib/src/components/pop_menu_button.dart +++ b/lib/ui/shared/pop_menu_button.dart @@ -1,5 +1,9 @@ +// Flutter imports: import 'package:flutter/material.dart'; +// Project imports: +import 'package:paintroid/ui/theme/theme.dart'; + class StyledPopMenuButton extends StatelessWidget { final void Function(T) onSelected; final PopupMenuItemBuilder itemBuilder; @@ -13,15 +17,18 @@ class StyledPopMenuButton extends StatelessWidget { @override Widget build(BuildContext context) { return Theme( - data: Theme.of(context).copyWith(useMaterial3: false), + data: Theme.of(context), child: PopupMenuButton( - color: Theme.of(context).colorScheme.background, - icon: const Icon(Icons.more_vert, color: Colors.white), + color: PaintroidTheme.of(context).backgroundColor, + icon: Icon( + Icons.more_vert, + color: PaintroidTheme.of(context).onSurfaceColor, + ), elevation: 7.0, shape: RoundedRectangleBorder( side: BorderSide( width: 0, - color: Theme.of(context).colorScheme.background, + color: PaintroidTheme.of(context).backgroundColor, ), borderRadius: BorderRadius.circular(5), ), diff --git a/lib/ui/theme/data/custom_colors.dart b/lib/ui/theme/data/custom_colors.dart new file mode 100644 index 00000000..e826cdb8 --- /dev/null +++ b/lib/ui/theme/data/custom_colors.dart @@ -0,0 +1,54 @@ +// Flutter imports: +import 'package:flutter/material.dart'; + +abstract class CustomColors { + static const primary = Color(0xFF0097A7); + static const onPrimary = Color(0xFF00363D); + static const primaryContainer = Color(0xFF004F58); + static const onPrimaryContainer = Color(0xFF97F0FF); + static const secondary = Color(0xFFB1CBD0); + static const onSecondary = Color(0xFF1C3438); + static const secondaryContainer = Color(0xFF334B4F); + static const onSecondaryContainer = Color(0xFFCDE7EC); + static const tertiary = Color(0xFF4CD9DF); + static const onTertiary = Color(0xFF003739); + static const tertiaryContainer = Color(0xFF004F52); + static const onTertiaryContainer = Color(0xFF6FF6FC); + static const error = Color(0xFFFF5454); + static const orange = Color(0xFFFFAB08); + static const errorContainer = Color(0xFF93000A); + static const onError = Color(0xFF690005); + static const onErrorContainer = Color(0xFFFFDAD6); + static const background = Color(0xFFFFF6F6); + static const onBackground = Color(0xFF191C1D); + static const surface = Color(0xFF0097A7); + static const onSurface = Color(0xFFFFFFFF); + static const surfaceVariant = Color(0xFF3F484A); + static const onSurfaceVariant = Color(0xFFBFC8CA); + static const outline = Color(0xFF899294); + static const onInverseSurface = Color(0xFF191C1D); + static const inverseSurface = Color(0xFFE1E3E3); + static const inversePrimary = Color(0xFF006874); + static const shadow = Color(0xFF000000); + static const surfaceTint = Color(0xFF4FD8EB); +} + +extension ToMaterialColor on Color { + Map _toSwatch() => { + 50: withOpacity(0.1), + 100: withOpacity(0.2), + 200: withOpacity(0.3), + 300: withOpacity(0.4), + 400: withOpacity(0.5), + 500: withOpacity(0.6), + 600: withOpacity(0.7), + 700: withOpacity(0.8), + 800: withOpacity(0.9), + 900: this, + }; + + MaterialColor toMaterialColor() => MaterialColor( + value, + _toSwatch(), + ); +} diff --git a/lib/ui/theme/data/dark_paintroid_theme_data.dart b/lib/ui/theme/data/dark_paintroid_theme_data.dart new file mode 100644 index 00000000..1af6bfd0 --- /dev/null +++ b/lib/ui/theme/data/dark_paintroid_theme_data.dart @@ -0,0 +1,134 @@ +// Flutter imports: +import 'package:flutter/material.dart'; + +// Project imports: +import 'package:paintroid/ui/theme/theme.dart'; + +class DarkPaintroidThemeData extends PaintroidThemeData { + @override + ThemeData get materialThemeData => ThemeData( + brightness: Brightness.dark, + primarySwatch: CustomColors.onSurface.toMaterialColor(), + dividerTheme: dividerThemeData, + floatingActionButtonTheme: fabThemeData, + elevatedButtonTheme: buttonThemeData, + inputDecorationTheme: inputDecorationTheme, + ); + + @override + Color get primaryColor => CustomColors.primary; + + @override + Color get scaffoldBackgroundColor => CustomColors.surface; + + @override + MaterialColor get fabBackgroundColor => + CustomColors.background.toMaterialColor(); + + @override + MaterialColor get fabForegroundColor => + CustomColors.onSurface.toMaterialColor(); + + @override + Color get textFieldorderColor => CustomColors.shadow; + + @override + TextTheme get textTheme => + super.textTheme.apply(bodyColor: CustomColors.onBackground); + + @override + Color get backgroundColor => CustomColors.background; + + @override + Color get orangeColor => CustomColors.orange; + + @override + Color get errorColor => CustomColors.error; + + @override + Color get errorContainerColor => CustomColors.errorContainer; + + @override + Color get inversePrimaryColor => CustomColors.inversePrimary; + + @override + Color get inverseSurfaceColor => CustomColors.inverseSurface; + + @override + Color get onBackgroundColor => CustomColors.onBackground; + + @override + Color get onErrorColor => CustomColors.onError; + + @override + Color get onErrorContainerColor => CustomColors.onErrorContainer; + + @override + Color get onInverseSurfaceColor => CustomColors.onInverseSurface; + + @override + Color get onPrimaryColor => CustomColors.onPrimary; + + @override + Color get onPrimaryContainerColor => CustomColors.onPrimaryContainer; + + @override + Color get onSecondaryColor => CustomColors.onSecondary; + + @override + Color get onSecondaryContainerColor => CustomColors.onSecondaryContainer; + + @override + Color get onSurfaceColor => CustomColors.onSurface; + + @override + Color get onSurfaceVariantColor => CustomColors.onSurfaceVariant; + + @override + Color get onTertiaryColor => CustomColors.onTertiary; + + @override + Color get onTertiaryContainerColor => CustomColors.onTertiaryContainer; + + @override + Color get outlineColor => CustomColors.outline; + + @override + Color get primaryContainerColor => CustomColors.primaryContainer; + + @override + Color get secondaryColor => CustomColors.secondary; + + @override + Color get secondaryContainerColor => CustomColors.secondaryContainer; + + @override + Color get shadowColor => CustomColors.shadow; + + @override + Color get surfaceColor => CustomColors.surface; + + @override + Color get surfaceTintColor => CustomColors.surfaceTint; + + @override + Color get surfaceVariantColor => CustomColors.surfaceVariant; + + @override + Color get tertiaryColor => CustomColors.tertiary; + + @override + Color get tertiaryContainerColor => CustomColors.tertiaryContainer; + + @override + TextStyle get titleStyle => const TextStyle( + color: CustomColors.onSurface, + fontSize: 24.0, + ); + + @override + TextStyle get descStyle => const TextStyle( + color: CustomColors.onSurface, + fontSize: 15.0, + ); +} diff --git a/lib/ui/theme/data/font_size.dart b/lib/ui/theme/data/font_size.dart new file mode 100644 index 00000000..64bb2317 --- /dev/null +++ b/lib/ui/theme/data/font_size.dart @@ -0,0 +1,9 @@ +abstract class FontSize { + static const double small = 13; + static const double smallMedium = 14; + static const double medium = 16; + static const double mediumLarge = 18; + static const double large = 24; + static const double xLarge = 30; + static const double xxLarge = 64; +} diff --git a/lib/ui/theme/data/light_paintroid_theme_data.dart b/lib/ui/theme/data/light_paintroid_theme_data.dart new file mode 100644 index 00000000..79b4bea6 --- /dev/null +++ b/lib/ui/theme/data/light_paintroid_theme_data.dart @@ -0,0 +1,159 @@ +// Flutter imports: +import 'package:flutter/material.dart'; + +// Project imports: +import 'package:paintroid/ui/theme/theme.dart'; + +// Project imports: + +class LightPaintroidThemeData extends PaintroidThemeData { + @override + ThemeData get materialThemeData => ThemeData( + useMaterial3: true, + brightness: Brightness.light, + primarySwatch: CustomColors.shadow.toMaterialColor(), + dividerTheme: dividerThemeData, + floatingActionButtonTheme: fabThemeData, + elevatedButtonTheme: buttonThemeData, + inputDecorationTheme: inputDecorationTheme, + appBarTheme: const AppBarTheme( + backgroundColor: CustomColors.primary, + foregroundColor: CustomColors.onSurface, + ), + sliderTheme: SliderThemeData( + overlayColor: CustomColors.primary.withOpacity(.2), + activeTrackColor: CustomColors.primary, + inactiveTrackColor: CustomColors.onPrimary, + thumbColor: CustomColors.primary, + showValueIndicator: ShowValueIndicator.never, + ), + bottomSheetTheme: const BottomSheetThemeData( + constraints: BoxConstraints.tightForFinite(), + backgroundColor: CustomColors.primary, + ), + textButtonTheme: TextButtonThemeData( + style: ButtonStyle( + foregroundColor: MaterialStateProperty.all( + CustomColors.primary, + ), + ), + ), + ); + + @override + Color get primaryColor => CustomColors.primary; + + @override + Color get scaffoldBackgroundColor => CustomColors.surface; + + @override + MaterialColor get fabBackgroundColor => + CustomColors.background.toMaterialColor(); + + @override + MaterialColor get fabForegroundColor => + CustomColors.onSurface.toMaterialColor(); + + @override + Color get textFieldorderColor => CustomColors.shadow; + + @override + TextTheme get textTheme => + super.textTheme.apply(bodyColor: CustomColors.onBackground); + + @override + Color get backgroundColor => CustomColors.background; + + @override + Color get orangeColor => CustomColors.orange; + + @override + Color get errorColor => CustomColors.error; + + @override + Color get errorContainerColor => CustomColors.errorContainer; + + @override + Color get inversePrimaryColor => CustomColors.inversePrimary; + + @override + Color get inverseSurfaceColor => CustomColors.inverseSurface; + + @override + Color get onBackgroundColor => CustomColors.onBackground; + + @override + Color get onErrorColor => CustomColors.onError; + + @override + Color get onErrorContainerColor => CustomColors.onErrorContainer; + + @override + Color get onInverseSurfaceColor => CustomColors.onInverseSurface; + + @override + Color get onPrimaryColor => CustomColors.onPrimary; + + @override + Color get onPrimaryContainerColor => CustomColors.onPrimaryContainer; + + @override + Color get onSecondaryColor => CustomColors.onSecondary; + + @override + Color get onSecondaryContainerColor => CustomColors.onSecondaryContainer; + + @override + Color get onSurfaceColor => CustomColors.onSurface; + + @override + Color get onSurfaceVariantColor => CustomColors.onSurfaceVariant; + + @override + Color get onTertiaryColor => CustomColors.onTertiary; + + @override + Color get onTertiaryContainerColor => CustomColors.onTertiaryContainer; + + @override + Color get outlineColor => CustomColors.outline; + + @override + Color get primaryContainerColor => CustomColors.primaryContainer; + + @override + Color get secondaryColor => CustomColors.secondary; + + @override + Color get secondaryContainerColor => CustomColors.secondaryContainer; + + @override + Color get shadowColor => CustomColors.shadow; + + @override + Color get surfaceColor => CustomColors.surface; + + @override + Color get surfaceTintColor => CustomColors.surfaceTint; + + @override + Color get surfaceVariantColor => CustomColors.surfaceVariant; + + @override + Color get tertiaryColor => CustomColors.tertiary; + + @override + Color get tertiaryContainerColor => CustomColors.tertiaryContainer; + + @override + TextStyle get titleStyle => const TextStyle( + color: CustomColors.onSurface, + fontSize: 24.0, + ); + + @override + TextStyle get descStyle => const TextStyle( + color: CustomColors.onSurface, + fontSize: 15.0, + ); +} diff --git a/lib/ui/theme/data/paintroid_theme.dart b/lib/ui/theme/data/paintroid_theme.dart new file mode 100644 index 00000000..793c1975 --- /dev/null +++ b/lib/ui/theme/data/paintroid_theme.dart @@ -0,0 +1,35 @@ +// Flutter imports: +import 'package:flutter/material.dart'; + +// Project imports: +import 'package:paintroid/ui/theme/theme.dart'; + +// Project imports: + +class PaintroidTheme extends InheritedWidget { + const PaintroidTheme({ + required super.child, + required this.lightTheme, + required this.darkTheme, + super.key, + }); + + final PaintroidThemeData lightTheme; + final PaintroidThemeData darkTheme; + + @override + bool updateShouldNotify( + PaintroidTheme oldWidget, + ) => + oldWidget.lightTheme != lightTheme || oldWidget.darkTheme != darkTheme; + + static PaintroidThemeData of(BuildContext context) { + final PaintroidTheme? inheritedTheme = + context.dependOnInheritedWidgetOfExactType(); + assert(inheritedTheme != null, 'No PaintroidTheme found in context'); + final currentBrightness = Theme.of(context).brightness; + return currentBrightness == Brightness.dark + ? inheritedTheme!.darkTheme + : inheritedTheme!.lightTheme; + } +} diff --git a/lib/ui/theme/data/paintroid_theme_data.dart b/lib/ui/theme/data/paintroid_theme_data.dart new file mode 100644 index 00000000..fbd190cd --- /dev/null +++ b/lib/ui/theme/data/paintroid_theme_data.dart @@ -0,0 +1,150 @@ +// Flutter imports: +import 'package:flutter/material.dart'; + +// Project imports: +import 'package:paintroid/ui/theme/theme.dart'; + +// Project imports: + +abstract class PaintroidThemeData { + ThemeData get materialThemeData; + + double screenMargin = Spacing.mediumLarge; + + double searchBarMargin = Spacing.xSmall; + + double gridSpacing = Spacing.mediumLarge; + + double listSpacing = Spacing.mediumLarge; + + static String fontFamily = 'Avenir'; + + double inputDecorationBorderRadius = Spacing.medium; + + Color get primaryColor; + Color get onPrimaryColor; + Color get primaryContainerColor; + Color get onPrimaryContainerColor; + Color get secondaryColor; + Color get onSecondaryColor; + Color get secondaryContainerColor; + Color get onSecondaryContainerColor; + Color get tertiaryColor; + Color get onTertiaryColor; + Color get tertiaryContainerColor; + Color get onTertiaryContainerColor; + Color get errorColor; + Color get orangeColor; + Color get errorContainerColor; + Color get onErrorColor; + Color get onErrorContainerColor; + Color get backgroundColor; + Color get onBackgroundColor; + Color get surfaceColor; + Color get onSurfaceColor; + Color get surfaceVariantColor; + Color get onSurfaceVariantColor; + Color get outlineColor; + Color get onInverseSurfaceColor; + Color get inverseSurfaceColor; + Color get inversePrimaryColor; + Color get shadowColor; + Color get surfaceTintColor; + + Color get scaffoldBackgroundColor; + Color get textFieldorderColor; + MaterialColor get fabBackgroundColor; + MaterialColor get fabForegroundColor; + + TextStyle get titleStyle; + TextStyle get descStyle; + + TextTheme get titleTheme => TextTheme( + titleLarge: TextStyle( + fontSize: FontSize.xLarge, + fontFamily: PaintroidThemeData.fontFamily, + fontWeight: FontWeight.w600, + color: CustomColors.onSurface, + ), + titleMedium: TextStyle( + fontSize: FontSize.large, + fontFamily: PaintroidThemeData.fontFamily, + fontWeight: FontWeight.w800, + color: CustomColors.primary, + ), + titleSmall: TextStyle( + fontSize: FontSize.smallMedium, + fontFamily: PaintroidThemeData.fontFamily, + fontWeight: FontWeight.w500, + color: CustomColors.onSurface, + ), + ); + + TextTheme get textTheme => TextTheme( + bodyLarge: TextStyle( + fontSize: FontSize.large, + fontFamily: fontFamily, + fontWeight: FontWeight.normal, + ), + bodyMedium: TextStyle( + fontSize: FontSize.smallMedium, + fontFamily: fontFamily, + fontWeight: FontWeight.normal, + ), + bodySmall: TextStyle( + fontSize: FontSize.smallMedium, + fontFamily: fontFamily, + fontWeight: FontWeight.w100, + ), + ); + + FloatingActionButtonThemeData get fabThemeData => + FloatingActionButtonThemeData( + backgroundColor: fabBackgroundColor.shade600, + foregroundColor: fabForegroundColor, + ); + + InputDecorationTheme get inputDecorationTheme => InputDecorationTheme( + border: OutlineInputBorder( + borderSide: BorderSide( + color: textFieldorderColor, + ), + borderRadius: BorderRadius.all( + Radius.circular( + inputDecorationBorderRadius, + ), + ), + ), + ); + + ElevatedButtonThemeData get buttonThemeData => ElevatedButtonThemeData( + style: ButtonStyle( + shape: const StadiumBorder().materialize(), + ), + ); + + DividerThemeData get dividerThemeData => const DividerThemeData( + space: 0, + ); + + NavigationBarThemeData bottomNavBarThemeData = NavigationBarThemeData( + indicatorColor: Colors.transparent, + backgroundColor: CustomColors.primary, + labelTextStyle: MaterialStateProperty.all( + const TextStyle( + color: CustomColors.onSurface, + ), + ), + iconTheme: MaterialStateProperty.all( + const IconThemeData( + color: CustomColors.onSurface, + ), + ), + ); +} + +extension OutlinedBorderExtensions on OutlinedBorder { + MaterialStateProperty materialize() { + return MaterialStateProperty.all(this); + } +} diff --git a/lib/ui/theme/data/spacing.dart b/lib/ui/theme/data/spacing.dart new file mode 100644 index 00000000..9fa87701 --- /dev/null +++ b/lib/ui/theme/data/spacing.dart @@ -0,0 +1,10 @@ +abstract class Spacing { + static const double xSmall = 4; + static const double small = 8; + static const double medium = 12; + static const double mediumLarge = 16; + static const double large = 20; + static const double xLarge = 24; + static const double xxLarge = 48; + static const double xxxLarge = 64; +} diff --git a/lib/ui/theme/state/theme_mode_state_provider.dart b/lib/ui/theme/state/theme_mode_state_provider.dart new file mode 100644 index 00000000..30741b42 --- /dev/null +++ b/lib/ui/theme/state/theme_mode_state_provider.dart @@ -0,0 +1,58 @@ +// Dart imports: + +// Flutter imports: +import 'package:flutter/material.dart'; + +// Package imports: +import 'package:riverpod_annotation/riverpod_annotation.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +part 'theme_mode_state_provider.g.dart'; + +@riverpod +class ThemeModeState extends _$ThemeModeState { + Future getDefaultThemeMode() async { + final prefs = await SharedPreferences.getInstance(); + final String? themeMode = prefs.getString('themeMode'); + + if (themeMode == null) { + return; + } + + switch (themeMode) { + case 'light': + state = ThemeMode.light; + break; + case 'dark': + state = ThemeMode.dark; + break; + case 'system': + state = ThemeMode.system; + break; + default: + state = ThemeMode.system; + } + } + + Future setThemeMode(ThemeMode themeMode) async { + final prefs = await SharedPreferences.getInstance(); + state = ThemeMode.system; + switch (themeMode) { + case ThemeMode.light: + await prefs.setString('themeMode', 'light'); + break; + case ThemeMode.dark: + await prefs.setString('themeMode', 'dark'); + break; + case ThemeMode.system: + await prefs.setString('themeMode', 'system'); + break; + default: + } + } + + @override + ThemeMode build() { + return ThemeMode.system; + } +} diff --git a/lib/ui/theme/state/theme_mode_state_provider.g.dart b/lib/ui/theme/state/theme_mode_state_provider.g.dart new file mode 100644 index 00000000..a0899264 --- /dev/null +++ b/lib/ui/theme/state/theme_mode_state_provider.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'theme_mode_state_provider.dart'; + +// ************************************************************************** +// RiverpodGenerator +// ************************************************************************** + +String _$themeModeStateHash() => r'5ff8b7fd70f6a4645f05204cfd76920d12cd88c7'; + +/// See also [ThemeModeState]. +@ProviderFor(ThemeModeState) +final themeModeStateProvider = + AutoDisposeNotifierProvider.internal( + ThemeModeState.new, + name: r'themeModeStateProvider', + debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') + ? null + : _$themeModeStateHash, + dependencies: null, + allTransitiveDependencies: null, +); + +typedef _$ThemeModeState = AutoDisposeNotifier; +// ignore_for_file: type=lint +// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member diff --git a/lib/ui/theme/theme.dart b/lib/ui/theme/theme.dart new file mode 100644 index 00000000..26725759 --- /dev/null +++ b/lib/ui/theme/theme.dart @@ -0,0 +1,10 @@ +library theme; + +export 'data/custom_colors.dart'; +export 'data/dark_paintroid_theme_data.dart'; +export 'data/font_size.dart'; +export 'data/light_paintroid_theme_data.dart'; +export 'data/paintroid_theme.dart'; +export 'data/paintroid_theme_data.dart'; +export 'data/spacing.dart'; +export 'state/theme_mode_state_provider.dart'; diff --git a/packages/component_library/lib/src/utils/toast_utils.dart b/lib/ui/utils/toast_utils.dart similarity index 91% rename from packages/component_library/lib/src/utils/toast_utils.dart rename to lib/ui/utils/toast_utils.dart index b1c006e8..42f6ccdb 100644 --- a/packages/component_library/lib/src/utils/toast_utils.dart +++ b/lib/ui/utils/toast_utils.dart @@ -1,3 +1,4 @@ +// Package imports: import 'package:toast/toast.dart'; class ToastUtils { diff --git a/packages/command/.metadata b/packages/command/.metadata deleted file mode 100644 index 9596faee..00000000 --- a/packages/command/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: 796c8ef79279f9c774545b3771238c3098dbefab - channel: stable - -project_type: package diff --git a/packages/command/analysis_options.yaml b/packages/command/analysis_options.yaml deleted file mode 100644 index 1ee68bd9..00000000 --- a/packages/command/analysis_options.yaml +++ /dev/null @@ -1,23 +0,0 @@ -include: package:flutter_lints/flutter.yaml -linter: - rules: - always_use_package_imports: true - avoid_relative_lib_imports: true - prefer_relative_imports: false - prefer_single_quotes: true - avoid_void_async: true - constant_identifier_names: false - -analyzer: - errors: - missing_enum_constant_in_switch: error - exhaustive_cases: error - unused_element: error - type_annotate_public_apis: error - missing_required_param: error - invalid_use_of_protected_member: error - unused_import: error - - exclude: - - lib/src/**.pb*.dart - - lib/src/data/*.g.dart diff --git a/packages/command/lib/command.dart b/packages/command/lib/command.dart deleted file mode 100644 index 098170f7..00000000 --- a/packages/command/lib/command.dart +++ /dev/null @@ -1,10 +0,0 @@ -library command; - -export 'graphic_factory/graphic_factory.dart'; -export 'src/command_factory/command_factory.dart'; -export 'src/command_implementation/command.dart'; -export 'src/command_implementation/graphic/draw_path_command.dart'; -export 'src/command_implementation/graphic/graphic_command.dart'; -export 'src/command_manager/command_manager.dart'; -export 'src/command_manager/sync_command_manager.dart'; -export 'utils/path_with_action_history.dart'; diff --git a/packages/command/lib/command_providers.dart b/packages/command/lib/command_providers.dart deleted file mode 100644 index aeb71f8d..00000000 --- a/packages/command/lib/command_providers.dart +++ /dev/null @@ -1,5 +0,0 @@ -library command; - -export 'graphic_factory/graphic_factory_provider.dart'; -export 'src/command_factory/command_factory_provider.dart'; -export 'src/command_manager/command_manager_provider.dart'; diff --git a/packages/command/lib/src/command_factory/command_factory.dart b/packages/command/lib/src/command_factory/command_factory.dart deleted file mode 100644 index 328bce11..00000000 --- a/packages/command/lib/src/command_factory/command_factory.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'dart:ui'; - -import 'package:command/command.dart'; - -class CommandFactory { - const CommandFactory(); - - DrawPathCommand createDrawPathCommand( - PathWithActionHistory path, Paint paint) => - DrawPathCommand(path, paint); -} diff --git a/packages/command/lib/src/command_implementation/graphic/graphic_command.dart b/packages/command/lib/src/command_implementation/graphic/graphic_command.dart deleted file mode 100644 index 20108abc..00000000 --- a/packages/command/lib/src/command_implementation/graphic/graphic_command.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'dart:ui'; - -import 'package:command/command.dart'; -import 'package:io_library/io_library.dart'; - -abstract class GraphicCommand extends Command { - const GraphicCommand(this.paint); - - @PaintConverter() - final Paint paint; - - void call(Canvas canvas); -} diff --git a/packages/command/pubspec.yaml b/packages/command/pubspec.yaml deleted file mode 100644 index 04fd7856..00000000 --- a/packages/command/pubspec.yaml +++ /dev/null @@ -1,42 +0,0 @@ -name: command -description: Internal package for commands. -version: 0.0.1 -publish_to: "none" - -environment: - sdk: ">=3.0.5 <4.0.0" - flutter: ">=1.17.0" - -dependencies: - flutter: - sdk: flutter - - flutter_riverpod: ^2.3.6 - riverpod_annotation: ^2.1.1 - equatable: ^2.0.3 - json_annotation: ^4.8.1 - collection: ^1.17.1 - - - # Internal packages - component_library: - path: ../component_library - io_library: - path: ../io_library - -dev_dependencies: - flutter_test: - sdk: flutter - - mockito: ^5.2.0 - flutter_launcher_icons: ^0.9.3 - flutter_lints: ^2.0.1 - floor_generator: ^1.2.0 - riverpod_generator: ^2.2.3 - riverpod_lint: ^1.3.2 - build_runner: ^2.2.0 - freezed: ^2.4.1 - json_serializable: ^6.7.1 - -flutter: - uses-material-design: true diff --git a/packages/component_library/.metadata b/packages/component_library/.metadata deleted file mode 100644 index 9596faee..00000000 --- a/packages/component_library/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: 796c8ef79279f9c774545b3771238c3098dbefab - channel: stable - -project_type: package diff --git a/packages/component_library/analysis_options.yaml b/packages/component_library/analysis_options.yaml deleted file mode 100644 index 1ee68bd9..00000000 --- a/packages/component_library/analysis_options.yaml +++ /dev/null @@ -1,23 +0,0 @@ -include: package:flutter_lints/flutter.yaml -linter: - rules: - always_use_package_imports: true - avoid_relative_lib_imports: true - prefer_relative_imports: false - prefer_single_quotes: true - avoid_void_async: true - constant_identifier_names: false - -analyzer: - errors: - missing_enum_constant_in_switch: error - exhaustive_cases: error - unused_element: error - type_annotate_public_apis: error - missing_required_param: error - invalid_use_of_protected_member: error - unused_import: error - - exclude: - - lib/src/**.pb*.dart - - lib/src/data/*.g.dart diff --git a/packages/component_library/lib/component_library.dart b/packages/component_library/lib/component_library.dart deleted file mode 100644 index f3c31da0..00000000 --- a/packages/component_library/lib/component_library.dart +++ /dev/null @@ -1,13 +0,0 @@ -library component_library; - -export 'src/components/bottom_nav_bar_icon.dart'; -export 'src/components/custom_action_chip.dart'; -export 'src/components/icon_button_with_label.dart'; -export 'src/components/icon_svg.dart'; -export 'src/components/imgs.dart'; -export 'src/components/loading_overlay.dart'; -export 'src/components/pop_menu_button.dart'; -export 'src/theme/color_schemes.dart'; -export 'src/theme/styles.dart'; -export 'src/utils/open_url.dart'; -export 'src/utils/toast_utils.dart'; diff --git a/packages/component_library/lib/src/components/bottom_nav_bar_icon.dart b/packages/component_library/lib/src/components/bottom_nav_bar_icon.dart deleted file mode 100644 index e35205f1..00000000 --- a/packages/component_library/lib/src/components/bottom_nav_bar_icon.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:component_library/component_library.dart'; -import 'package:flutter/material.dart'; - -class BottomBarIcon extends StatelessWidget { - final String asset; - - const BottomBarIcon({Key? key, required this.asset}) : super(key: key); - - @override - Widget build(BuildContext context) { - return IconSvg( - path: asset, - height: 24.0, - width: 24.0, - color: Theme.of(context).colorScheme.onSurface, - ); - } -} diff --git a/packages/component_library/lib/src/components/imgs.dart b/packages/component_library/lib/src/components/imgs.dart deleted file mode 100644 index 16421d92..00000000 --- a/packages/component_library/lib/src/components/imgs.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'package:flutter/material.dart'; - -class CheckerboardImg extends StatelessWidget { - const CheckerboardImg({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - child: Image.asset( - 'packages/component_library/assets/img/checkerboard.png', - repeat: ImageRepeat.repeat, - cacheWidth: 50, - cacheHeight: 50, - filterQuality: FilterQuality.none, - ), - ); - } -} - -class PocketPaintIntroLandscape extends StatelessWidget { - const PocketPaintIntroLandscape({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - child: Image.asset( - 'packages/component_library/assets/img/pocketpaint_intro_landscape.png', - fit: BoxFit.contain, - ), - ); - } -} - -class PocketPaintIntroPortrait extends StatelessWidget { - const PocketPaintIntroPortrait({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - child: Image.asset( - 'packages/component_library/assets/img/pocketpaint_intro_portrait.png', - fit: BoxFit.fitHeight, - ), - ); - } -} - -class PocketPaintLogoSmall extends StatelessWidget { - const PocketPaintLogoSmall({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - child: Image.asset( - 'packages/component_library/assets/img/pocketpaint_logo_small.png', - ), - ); - } -} diff --git a/packages/component_library/lib/src/theme/color_schemes.dart b/packages/component_library/lib/src/theme/color_schemes.dart deleted file mode 100644 index 3a790a3d..00000000 --- a/packages/component_library/lib/src/theme/color_schemes.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:flutter/material.dart'; - -const lightColorScheme = ColorScheme( - brightness: Brightness.light, - primary: Color(0xFF0097A7), - onPrimary: Color(0xFF00363D), - primaryContainer: Color(0xFF004F58), - onPrimaryContainer: Color(0xFF97F0FF), - secondary: Color(0xFFB1CBD0), - onSecondary: Color(0xFF1C3438), - secondaryContainer: Color(0xFF334B4F), - onSecondaryContainer: Color(0xFFCDE7EC), - tertiary: Color(0xFF4CD9DF), - onTertiary: Color(0xFF003739), - tertiaryContainer: Color(0xFF004F52), - onTertiaryContainer: Color(0xFF6FF6FC), - error: Color(0xFFFF5454), - errorContainer: Color(0xFF93000A), - onError: Color(0xFF690005), - onErrorContainer: Color(0xFFFFDAD6), - background: Color(0xFFFFF6F6), - onBackground: Color(0xFF191C1D), - surface: Color(0xFF0097A7), - onSurface: Color(0xFFFFFFFF), - surfaceVariant: Color(0xFF3F484A), - onSurfaceVariant: Color(0xFFBFC8CA), - outline: Color(0xFF899294), - onInverseSurface: Color(0xFF191C1D), - inverseSurface: Color(0xFFE1E3E3), - inversePrimary: Color(0xFF006874), - shadow: Color(0xFF000000), - surfaceTint: Color(0xFF4FD8EB), -); diff --git a/packages/component_library/lib/src/theme/styles.dart b/packages/component_library/lib/src/theme/styles.dart deleted file mode 100644 index 2e822183..00000000 --- a/packages/component_library/lib/src/theme/styles.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:component_library/component_library.dart'; -import 'package:flutter/material.dart'; - -abstract class TextThemes { - static TextStyle menuItem = TextStyle( - color: lightColorScheme.onBackground, - fontWeight: FontWeight.w400, - fontSize: 14, - ); - - static TextStyle largeBoldText = TextStyle( - color: lightColorScheme.primary, - fontWeight: FontWeight.w600, - fontSize: 24, - ); - - static TextStyle hintTextNormal = TextStyle( - color: lightColorScheme.onSurfaceVariant, - fontWeight: FontWeight.w100, - fontSize: 14, - ); -} - -abstract class WidgetThemes { - static NavigationBarThemeData bottomNavBarThemeData = NavigationBarThemeData( - indicatorColor: Colors.transparent, - labelTextStyle: MaterialStateProperty.all( - TextStyle( - color: lightColorScheme.onSurface, - ), - ), - ); -} diff --git a/packages/component_library/pubspec.yaml b/packages/component_library/pubspec.yaml deleted file mode 100644 index 15a11017..00000000 --- a/packages/component_library/pubspec.yaml +++ /dev/null @@ -1,43 +0,0 @@ -name: component_library -description: Internal package for shared coponents. -version: 0.0.1 -publish_to: "none" - -environment: - sdk: ">=3.0.5 <4.0.0" - flutter: ">=1.17.0" - -dependencies: - flutter: - sdk: flutter - - flutter_riverpod: ^2.3.6 - riverpod_annotation: ^2.1.1 - freezed_annotation: ^2.4.1 - - flutter_svg: ^1.1.0 - url_launcher: ^6.1.5 - toast: ^0.3.0 - logging: ^1.0.2 - - collection: ^1.17.1 - -dev_dependencies: - flutter_test: - sdk: flutter - - mockito: ^5.2.0 - flutter_launcher_icons: ^0.9.3 - flutter_lints: ^2.0.1 - floor_generator: ^1.2.0 - riverpod_generator: ^2.2.3 - riverpod_lint: ^1.3.2 - build_runner: ^2.2.0 - freezed: ^2.4.1 - -flutter: - uses-material-design: true - - assets: - - assets/img/ - - assets/svg/ diff --git a/packages/database/.metadata b/packages/database/.metadata deleted file mode 100644 index 9596faee..00000000 --- a/packages/database/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: 796c8ef79279f9c774545b3771238c3098dbefab - channel: stable - -project_type: package diff --git a/packages/database/analysis_options.yaml b/packages/database/analysis_options.yaml deleted file mode 100644 index 7e11cc27..00000000 --- a/packages/database/analysis_options.yaml +++ /dev/null @@ -1,24 +0,0 @@ -include: package:flutter_lints/flutter.yaml -linter: - rules: - always_use_package_imports: true - avoid_relative_lib_imports: true - prefer_relative_imports: false - prefer_single_quotes: true - avoid_void_async: true - constant_identifier_names: false - -analyzer: - errors: - missing_enum_constant_in_switch: error - exhaustive_cases: error - unused_element: error - type_annotate_public_apis: error - missing_required_param: error - invalid_use_of_protected_member: error - unused_import: error - - exclude: - - lib/src/**.pb*.dart - - lib/src/data/*.g.dart - - lib/src/*.g.dart diff --git a/packages/database/lib/database.dart b/packages/database/lib/database.dart deleted file mode 100644 index 4fba40d5..00000000 --- a/packages/database/lib/database.dart +++ /dev/null @@ -1,8 +0,0 @@ -library database; - -export 'src/models/project.dart'; - -export 'src/utils/date_time_converter.dart'; - -export 'src/project_dao.dart'; -export 'src/project_database.dart'; diff --git a/packages/database/pubspec.yaml b/packages/database/pubspec.yaml deleted file mode 100644 index ebe35ad8..00000000 --- a/packages/database/pubspec.yaml +++ /dev/null @@ -1,35 +0,0 @@ -name: database -description: A new Flutter package project. -version: 0.0.1 -publish_to: "none" - -environment: - sdk: ">=3.0.5 <4.0.0" - flutter: ">=1.17.0" - -dependencies: - flutter: - sdk: flutter - - flutter_riverpod: ^2.3.6 - riverpod_annotation: ^2.1.1 - freezed_annotation: ^2.4.1 - - floor: ^1.2.0 - sqflite: - -dev_dependencies: - flutter_test: - sdk: flutter - - mockito: ^5.2.0 - flutter_launcher_icons: ^0.9.3 - flutter_lints: ^2.0.1 - floor_generator: ^1.2.0 - riverpod_generator: ^2.2.3 - riverpod_lint: ^1.3.2 - build_runner: ^2.2.0 - freezed: ^2.4.1 - -flutter: - uses-material-design: true diff --git a/packages/features/landing_page_screen/.metadata b/packages/features/landing_page_screen/.metadata deleted file mode 100644 index 9596faee..00000000 --- a/packages/features/landing_page_screen/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: 796c8ef79279f9c774545b3771238c3098dbefab - channel: stable - -project_type: package diff --git a/packages/features/landing_page_screen/analysis_options.yaml b/packages/features/landing_page_screen/analysis_options.yaml deleted file mode 100644 index 1ee68bd9..00000000 --- a/packages/features/landing_page_screen/analysis_options.yaml +++ /dev/null @@ -1,23 +0,0 @@ -include: package:flutter_lints/flutter.yaml -linter: - rules: - always_use_package_imports: true - avoid_relative_lib_imports: true - prefer_relative_imports: false - prefer_single_quotes: true - avoid_void_async: true - constant_identifier_names: false - -analyzer: - errors: - missing_enum_constant_in_switch: error - exhaustive_cases: error - unused_element: error - type_annotate_public_apis: error - missing_required_param: error - invalid_use_of_protected_member: error - unused_import: error - - exclude: - - lib/src/**.pb*.dart - - lib/src/data/*.g.dart diff --git a/packages/features/landing_page_screen/lib/landing_page_screen.dart b/packages/features/landing_page_screen/lib/landing_page_screen.dart deleted file mode 100644 index 51869a2e..00000000 --- a/packages/features/landing_page_screen/lib/landing_page_screen.dart +++ /dev/null @@ -1,9 +0,0 @@ -library landing_page_screen; - -export 'src/components/custom_action_button.dart'; -export 'src/components/image_preview.dart'; -export 'src/components/main_overflow_menu.dart'; -export 'src/components/project_list_tile.dart'; -export 'src/components/project_overflow_menu.dart'; - -export 'src/landing_page.dart'; diff --git a/packages/features/landing_page_screen/pubspec.yaml b/packages/features/landing_page_screen/pubspec.yaml deleted file mode 100644 index 09e115ea..00000000 --- a/packages/features/landing_page_screen/pubspec.yaml +++ /dev/null @@ -1,55 +0,0 @@ -name: landing_page_screen -description: A new Flutter package project. -version: 0.0.1 -publish_to: "none" - -environment: - sdk: ">=3.0.5 <4.0.0" - flutter: ">=1.17.0" - -dependencies: - flutter: - sdk: flutter - - flutter_riverpod: ^2.3.6 - riverpod_annotation: ^2.1.1 - freezed_annotation: ^2.4.1 - - intl: ^0.18.0 - toast: ^0.3.0 - oxidized: ^5.2.0 - flutter_svg: ^1.1.0 - launch_review: ^3.0.1 - package_info_plus: ^4.0.1 - filesize: ^2.0.1 - - # Internal packages - component_library: - path: ../../component_library - database: - path: ../../database - io_library: - path: ../../io_library - workspace_screen: - path: ../workspace_screen - paintroid: - path: ../../../ - -dev_dependencies: - flutter_test: - sdk: flutter - - mockito: ^5.2.0 - flutter_launcher_icons: ^0.9.3 - flutter_lints: ^2.0.1 - floor_generator: ^1.2.0 - riverpod_generator: ^2.2.3 - riverpod_lint: ^1.3.2 - build_runner: ^2.2.0 - freezed: ^2.4.1 - -flutter: - uses-material-design: true - - assets: - - test/fixture/image/ diff --git a/packages/features/onboarding_screen/.metadata b/packages/features/onboarding_screen/.metadata deleted file mode 100644 index 9596faee..00000000 --- a/packages/features/onboarding_screen/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: 796c8ef79279f9c774545b3771238c3098dbefab - channel: stable - -project_type: package diff --git a/packages/features/onboarding_screen/analysis_options.yaml b/packages/features/onboarding_screen/analysis_options.yaml deleted file mode 100644 index 1ee68bd9..00000000 --- a/packages/features/onboarding_screen/analysis_options.yaml +++ /dev/null @@ -1,23 +0,0 @@ -include: package:flutter_lints/flutter.yaml -linter: - rules: - always_use_package_imports: true - avoid_relative_lib_imports: true - prefer_relative_imports: false - prefer_single_quotes: true - avoid_void_async: true - constant_identifier_names: false - -analyzer: - errors: - missing_enum_constant_in_switch: error - exhaustive_cases: error - unused_element: error - type_annotate_public_apis: error - missing_required_param: error - invalid_use_of_protected_member: error - unused_import: error - - exclude: - - lib/src/**.pb*.dart - - lib/src/data/*.g.dart diff --git a/packages/features/onboarding_screen/lib/onboarding_screen.dart b/packages/features/onboarding_screen/lib/onboarding_screen.dart deleted file mode 100644 index a1f4acac..00000000 --- a/packages/features/onboarding_screen/lib/onboarding_screen.dart +++ /dev/null @@ -1,13 +0,0 @@ -library onboarding_screen; - -export 'src/components/bottom_nav_bar_container.dart'; -export 'src/components/onboarding_page_app_bar.dart'; -export 'src/components/onboarding_page_bottom_nav_bar.dart'; - -export 'src/screens/screen1.dart'; -export 'src/screens/screen2.dart'; -export 'src/screens/screen3.dart'; -export 'src/screens/screen4.dart'; -export 'src/screens/screen5.dart'; - -export 'src/onboarding_screen.dart'; diff --git a/packages/features/onboarding_screen/pubspec.yaml b/packages/features/onboarding_screen/pubspec.yaml deleted file mode 100644 index 491ce31e..00000000 --- a/packages/features/onboarding_screen/pubspec.yaml +++ /dev/null @@ -1,46 +0,0 @@ -name: onboarding_screen -description: A new Flutter package project. -version: 0.0.1 -publish_to: "none" - -environment: - sdk: ">=3.0.5 <4.0.0" - flutter: ">=1.17.0" - -dependencies: - flutter: - sdk: flutter - flutter_localizations: - sdk: flutter - - flutter_riverpod: ^2.3.6 - riverpod_annotation: ^2.1.1 - smooth_page_indicator: ^1.0.0+2 - shared_preferences: ^2.0.15 - toast: ^0.3.0 - flutter_svg: ^1.1.0 - flutter_localization: ^0.1.12 - - # Internal packages - component_library: - path: ../../component_library - tools: - path: ../../tools - workspace_screen: - path: ../workspace_screen - -dev_dependencies: - flutter_test: - sdk: flutter - - mockito: ^5.2.0 - flutter_launcher_icons: ^0.9.3 - flutter_lints: ^2.0.1 - floor_generator: ^1.2.0 - riverpod_generator: ^2.2.3 - riverpod_lint: ^1.3.2 - build_runner: ^2.2.0 - freezed: ^2.4.1 - -flutter: - uses-material-design: true diff --git a/packages/features/workspace_screen/.metadata b/packages/features/workspace_screen/.metadata deleted file mode 100644 index 9596faee..00000000 --- a/packages/features/workspace_screen/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: 796c8ef79279f9c774545b3771238c3098dbefab - channel: stable - -project_type: package diff --git a/packages/features/workspace_screen/analysis_options.yaml b/packages/features/workspace_screen/analysis_options.yaml deleted file mode 100644 index 1ee68bd9..00000000 --- a/packages/features/workspace_screen/analysis_options.yaml +++ /dev/null @@ -1,23 +0,0 @@ -include: package:flutter_lints/flutter.yaml -linter: - rules: - always_use_package_imports: true - avoid_relative_lib_imports: true - prefer_relative_imports: false - prefer_single_quotes: true - avoid_void_async: true - constant_identifier_names: false - -analyzer: - errors: - missing_enum_constant_in_switch: error - exhaustive_cases: error - unused_element: error - type_annotate_public_apis: error - missing_required_param: error - invalid_use_of_protected_member: error - unused_import: error - - exclude: - - lib/src/**.pb*.dart - - lib/src/data/*.g.dart diff --git a/packages/features/workspace_screen/lib/src/components/bottom_bar/tools/tool_button.dart b/packages/features/workspace_screen/lib/src/components/bottom_bar/tools/tool_button.dart deleted file mode 100644 index 3f346879..00000000 --- a/packages/features/workspace_screen/lib/src/components/bottom_bar/tools/tool_button.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:component_library/component_library.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:tools/tools.dart'; - -class ToolButton extends StatelessWidget { - final ToolData toolData; - - const ToolButton({ - Key? key, - required this.toolData, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Consumer( - builder: (context, ref, child) { - return IconButtonWithLabel( - icon: IconSvg( - path: toolData.svgAssetPath, - height: 24.0, - width: 24.0, - color: Colors.white, - ), - label: toolData.name, - onPressed: () { - Navigator.pop(context); - ref.read(toolBoxStateProvider.notifier).switchTool(toolData); - }, - ); - }, - ); - } -} diff --git a/packages/features/workspace_screen/lib/src/states/workspace_state_notifier.dart b/packages/features/workspace_screen/lib/src/states/workspace_state_notifier.dart deleted file mode 100644 index 30518c5d..00000000 --- a/packages/features/workspace_screen/lib/src/states/workspace_state_notifier.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:command/command.dart'; -import 'package:command/command_providers.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; - -part 'workspace_state.dart'; - -class WorkspaceStateNotifier extends StateNotifier { - WorkspaceStateNotifier(super.state, this._commandManager); - - final CommandManager _commandManager; - - bool get hasSavedLastWork => - state._commandCountWhenLastSaved == _commandManager.count; - - Future performIOTask(Future Function() task) async { - state = state.copyWith(isPerformingIOTask: true); - final result = await task(); - state = state.copyWith(isPerformingIOTask: false); - return result; - } - - void updateLastSavedCommandCount() => state = state.copyWith( - updatedLastSavedCommandCount: _commandManager.count, - ); - - void toggleFullscreen(bool isEnabled) => state = state.copyWith( - isFullscreen: isEnabled, - ); -} diff --git a/packages/features/workspace_screen/lib/src/workspace_screen.dart b/packages/features/workspace_screen/lib/src/workspace_screen.dart deleted file mode 100644 index 9994f891..00000000 --- a/packages/features/workspace_screen/lib/src/workspace_screen.dart +++ /dev/null @@ -1,80 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:io_library/io_library.dart'; - -import 'package:toast/toast.dart'; -import 'package:workspace_screen/workspace_screen.dart'; - -class WorkspaceScreen extends ConsumerStatefulWidget { - const WorkspaceScreen({Key? key}) : super(key: key); - - @override - ConsumerState createState() => _WorkspaceScreenState(); -} - -class _WorkspaceScreenState extends ConsumerState { - void _toggleStatusBar(bool isFullscreen) { - SystemChrome.setEnabledSystemUIMode( - isFullscreen ? SystemUiMode.immersiveSticky : SystemUiMode.manual, - overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom], - ); - } - - @override - Widget build(BuildContext context) { - ToastContext().init(context); - - final isFullscreen = ref.watch( - WorkspaceState.provider.select((state) => state.isFullscreen), - ); - ref.listen( - WorkspaceState.provider.select((state) => state.isFullscreen), - (_, isFullscreen) => _toggleStatusBar(isFullscreen), - ); - final ioHandler = ref.watch(IOHandler.provider); - - return WillPopScope( - onWillPop: () async { - var willPop = !isFullscreen; - if (isFullscreen) { - ref.read(WorkspaceState.provider.notifier).toggleFullscreen(false); - } else { - final workspaceStateNotifier = - ref.watch(WorkspaceState.provider.notifier); - if (!workspaceStateNotifier.hasSavedLastWork) { - final shouldDiscard = await showDiscardChangesDialog(context); - if (shouldDiscard != null) { - if (!shouldDiscard && mounted) { - ioHandler.saveImage(context); - } - willPop = shouldDiscard; - } else { - willPop = false; - } - } - } - return willPop; - }, - child: Scaffold( - appBar: isFullscreen ? null : TopAppBar(title: 'Pocket Paint'), - backgroundColor: Colors.grey.shade400, - resizeToAvoidBottomInset: true, - body: Stack( - children: [ - const DrawingCanvas(), - if (isFullscreen) - const Positioned( - top: 2, - right: 2, - child: SafeArea(child: ExitFullscreenButton()), - ) - else - const ToolOptions(), - ], - ), - bottomNavigationBar: isFullscreen ? null : const BottomNavBar(), - ), - ); - } -} diff --git a/packages/features/workspace_screen/lib/workspace_screen.dart b/packages/features/workspace_screen/lib/workspace_screen.dart deleted file mode 100644 index 23ebc9e6..00000000 --- a/packages/features/workspace_screen/lib/workspace_screen.dart +++ /dev/null @@ -1,27 +0,0 @@ -library workspace_screen; - -export 'src/components/bottom_bar/bottom_nav_bar.dart'; -export 'src/components/bottom_bar/bottom_nav_bar_items.dart'; -export 'src/components/bottom_bar/tool_options/stroke_cap_tool_option.dart'; -export 'src/components/bottom_bar/tool_options/stroke_tool_options.dart'; -export 'src/components/bottom_bar/tool_options/stroke_width_tool_option.dart'; -export 'src/components/bottom_bar/tool_options/tool_option.dart'; -export 'src/components/bottom_bar/tool_options/tool_options.dart'; -export 'src/components/bottom_bar/tools/tool_button.dart'; -export 'src/components/bottom_bar/tools/tools_bottom_sheet.dart'; -export 'src/components/drawing_surface/canvas_painter.dart'; -export 'src/components/drawing_surface/checkerboard_pattern.dart'; -export 'src/components/drawing_surface/command_painter.dart'; -export 'src/components/drawing_surface/drawing_canvas.dart'; -export 'src/components/drawing_surface/exit_fullscreen_button.dart'; -export 'src/components/top_bar/overflow_menu.dart'; -export 'src/components/top_bar/top_app_bar.dart'; -export 'src/models/image_with_pixel_info.dart'; -export 'src/service/device_service.dart'; -export 'src/states/canvas_dirty_state.dart'; -export 'src/states/canvas_state_data.dart'; -export 'src/states/canvas_state_provider.dart'; -export 'src/states/tool_options_visibility_state_provider.dart'; -export 'src/states/workspace_state_notifier.dart'; -export 'src/usecase/render_image_for_export.dart'; -export 'src/workspace_screen.dart'; diff --git a/packages/features/workspace_screen/pubspec.yaml b/packages/features/workspace_screen/pubspec.yaml deleted file mode 100644 index a2f5b8de..00000000 --- a/packages/features/workspace_screen/pubspec.yaml +++ /dev/null @@ -1,57 +0,0 @@ -name: workspace_screen -description: A new Flutter package project. -version: 0.0.1 -publish_to: "none" - -environment: - sdk: ">=3.0.5 <4.0.0" - flutter: ">=1.17.0" - -dependencies: - flutter: - sdk: flutter - flutter_localizations: - sdk: flutter - - flutter_localization: ^0.1.12 - intl: ^0.18.0 - flutter_riverpod: ^2.3.6 - riverpod_annotation: ^2.1.1 - freezed_annotation: ^2.4.1 - toast: ^0.3.0 - image: ^3.2.0 - oxidized: ^5.2.0 - - # Internal packages - component_library: - path: ../../component_library - l10n: - path: ../../l10n - database: - path: ../../database - command: - path: ../../command - io_library: - path: ../../io_library - tools: - path: ../../tools - colorpicker: - path: ../../colorpicker - -dev_dependencies: - flutter_test: - sdk: flutter - integration_test: - sdk: flutter - - mockito: ^5.2.0 - flutter_launcher_icons: ^0.9.3 - flutter_lints: ^2.0.1 - floor_generator: ^1.2.0 - riverpod_generator: ^2.2.3 - riverpod_lint: ^1.3.2 - build_runner: ^2.2.0 - freezed: ^2.4.1 - -flutter: - uses-material-design: true diff --git a/packages/io_library/.metadata b/packages/io_library/.metadata deleted file mode 100644 index 9596faee..00000000 --- a/packages/io_library/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: 796c8ef79279f9c774545b3771238c3098dbefab - channel: stable - -project_type: package diff --git a/packages/io_library/analysis_options.yaml b/packages/io_library/analysis_options.yaml deleted file mode 100644 index 1ee68bd9..00000000 --- a/packages/io_library/analysis_options.yaml +++ /dev/null @@ -1,23 +0,0 @@ -include: package:flutter_lints/flutter.yaml -linter: - rules: - always_use_package_imports: true - avoid_relative_lib_imports: true - prefer_relative_imports: false - prefer_single_quotes: true - avoid_void_async: true - constant_identifier_names: false - -analyzer: - errors: - missing_enum_constant_in_switch: error - exhaustive_cases: error - unused_element: error - type_annotate_public_apis: error - missing_required_param: error - invalid_use_of_protected_member: error - unused_import: error - - exclude: - - lib/src/**.pb*.dart - - lib/src/data/*.g.dart diff --git a/packages/io_library/lib/io_library.dart b/packages/io_library/lib/io_library.dart deleted file mode 100644 index beda5731..00000000 --- a/packages/io_library/lib/io_library.dart +++ /dev/null @@ -1,34 +0,0 @@ -library io_library; - -export 'src/enums/image_format.dart'; -export 'src/enums/image_location.dart'; -export 'src/failure/load_image_failure.dart'; -export 'src/failure/save_image_failure.dart'; -export 'src/io_handler.dart'; -export 'src/json_serialization/converter/paint_converter.dart'; -export 'src/json_serialization/converter/path_action_converter.dart'; -export 'src/json_serialization/converter/path_with_action_history_converter.dart'; -export 'src/json_serialization/versioning/serializer_version.dart'; -export 'src/json_serialization/versioning/version_strategy.dart'; -export 'src/models/catrobat_image.dart'; -export 'src/models/failure.dart'; -export 'src/models/image_from_file.dart'; -export 'src/models/image_meta_data.dart'; -export 'src/models/loggable_mixin.dart'; -export 'src/service/file_service.dart'; -export 'src/service/image_service.dart'; -export 'src/service/permission_service.dart'; -export 'src/service/photo_library_service.dart'; -export 'src/ui/about_dialog.dart'; -export 'src/ui/delete_project_dialog.dart'; -export 'src/ui/discard_changes_dialog.dart'; -export 'src/ui/generic_dialog.dart'; -export 'src/ui/image_format_info.dart'; -export 'src/ui/load_image_dialog.dart'; -export 'src/ui/overwrite_dialog.dart'; -export 'src/ui/project_details_dialog.dart'; -export 'src/ui/save_image_dialog.dart'; -export 'src/usecase/load_image_from_file_manager.dart'; -export 'src/usecase/load_image_from_photo_library.dart'; -export 'src/usecase/save_as_catrobat_image.dart'; -export 'src/usecase/save_as_raster_image.dart'; diff --git a/packages/io_library/pubspec.yaml b/packages/io_library/pubspec.yaml deleted file mode 100644 index 33e1fe2b..00000000 --- a/packages/io_library/pubspec.yaml +++ /dev/null @@ -1,59 +0,0 @@ -name: io_library -description: A new Flutter package project. -version: 0.0.1 -publish_to: "none" - -environment: - sdk: ">=3.0.5 <4.0.0" - flutter: ">=1.17.0" - -dependencies: - flutter: - sdk: flutter - - flutter_riverpod: ^2.3.6 - riverpod_annotation: ^2.1.1 - freezed_annotation: ^2.4.1 - logging: ^1.0.2 - protobuf: ^2.1.0 - path_provider: ^2.0.11 - file_picker: ^5.3.1 - image: ^3.2.0 - package_info_plus: ^4.0.1 - device_info_plus: ^9.0.3 - permission_handler: ^10.0.0 - image_picker: ^0.8.5+3 - filesize: ^2.0.1 - oxidized: ^5.2.0 - intl: ^0.18.0 - json_annotation: ^4.8.1 - - # Internal packages: - component_library: - path: ../component_library - command: - path: ../command - database: - path: ../database - workspace_screen: - path: ../features/workspace_screen - - -dev_dependencies: - flutter_test: - sdk: flutter - - mockito: ^5.2.0 - flutter_launcher_icons: ^0.9.3 - flutter_lints: ^2.0.1 - floor_generator: ^1.2.0 - riverpod_generator: ^2.2.3 - riverpod_lint: ^1.3.2 - build_runner: ^2.2.0 - freezed: ^2.4.1 - json_serializable: ^6.7.1 - -flutter: - uses-material-design: true - assets: - - test/fixture/image/ diff --git a/packages/io_library/test/fixture/image/test.jpg b/packages/io_library/test/fixture/image/test.jpg deleted file mode 100644 index 04ff2033529566cf1bd1277a6d96ef80e038c9c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1731 zcmbW0c~DbF9LM+NB_tpe0s%#x4Yk&-|lbs^L7^*K*oT~5i<)j z06_p8Mhig3fdh@{?h1gVCC~%_5C8^}1u*I$w15bAfE9TF)X^RQI34;LO~h9VN^i3@+vBGSqL|#o~WqLP94Mu|!?DSRflv%zh8)*PU z0?+|EFhm9zA_Nm5gaee&9pNC6MAOg)!oXOZ7@i<5u?`(jE`x3zhA~(ehZ8OX1)_0) zCE{e2wN1q2Y|h}x-XxuCu^9vv)8a;X+b*7}u8U8wxP-#`4T>Ap)VFDD*VNmycb~q2 z;lV>RGxNh1N9^p6pE&8@_~XxK&$+tM-Ope0^}EbqUhxkJ4GWLBej_q2J|QtFIVCmi zUgrI*?3~=Z-%Co%$}1`#RaG}V;WR&OX>EJf-P7CmvVUN3Xq-Fo=j+L-H`6l( z_;HE<>9ddv{hwd3(Dn=2f4GP!7Y2)kv3MaDgkcE5iCCPnwwSDm4gQR`99icYfn*w+ zQQRo5qHD{Ock$_xP*BwyS6dLGiO9YUEckzst$}^z8U_aeMkE-6o)QeBCxu0Y!{da) z6YwGt{*i=8>x7b86M`mz&>ZMwG4zuX$BVDUzS$rn=(WTmLqHOS(8~l90Tl>V?nP<< zQGL8)V&6M$p6(bfwu+z66&RUS(U0-mv#pG5t88M7Z|hh7FrMNmDff$iQDGuWDV^mj zC^GiQSh42c@yc7-&8Llzn2w(0jfQY;c^14~+FPJnQTtMn;1S^W(`JfE+kA|I84xI; zOTkE|V6J!3a^Inzg7RCgb112X6L)fEk`_)-j#9Xy8ry15v$k+K0LMGuwp|J2w=AD! zM%eSbW)t&hV;vEOl*ZD2wz^Y;dQEk*B3uk>+p=3j1lJ6p|u)bf0Hc1AI4P~}=o3E2?i5Fba1POX!7H>5Vy57)FH zK!UQ<^TVj*iUThxnoE@)GLda|lj?}bH1z9B(9V?*k63C34YUmn+^hQa8m2pikvIR5*=;QD@|#>AYiEDSbmiw#?O-?{cj)1~=5WLH)~J?k9!XG} z*M7bcZxff+|0~NI0oeJQwl|wbC5^Wio?_;3{L3E(Qy84O&3%U`IRg(gbBCVQ?3!`{ z7#(08$4+G_3)1T#eowR3vJp$6d%nCD-<0Ovligd^z9*ZP73X-*tU~Nlbh2s~L4suX z2tTz=58_fK5#VYySTiBrc$%@S(rl>3xx0m#{3Pa0S_db|`5TmT$GN-cC@++B8uQv9Mmj3aeXc`|O&BMhbGy`ql=Sr;%e!DHkft^-2#b z91Epvl6k?&-SL?^CLL1u9p95%_&u}!33*zJz4d&thhd4O29wr%@u6ZE=2m1QWA9N} z&ig0;%_P{+KoHU;SSbvzzaWk0r&%enJ4WSKr0&0(@$U#-RT-G>4{yTX8SC7`e>H3u z=S*?9ubH=H=>j<6!toGbQQ757Aro==cS_zJhaYGg kxW&G39J#@8alE0LHk+G{iPR8PX{7sKuk_1ng^|I(0T;!^UjP6A diff --git a/packages/io_library/test/fixture/image/test.png b/packages/io_library/test/fixture/image/test.png deleted file mode 100644 index a2e03a09329b7d4e7a056b28eacf63b33208aa44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1272 zcmVPx#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91GN1zh1ONa40RR91G5`Po0Cmf+s{jB19BD*PQ~&?~0ssI20000082|tP zC;$Ke82|tP82|tRcubKn-~a#uL`g(JRA>e4mS1R(Q5eTJTUbQ2WGKH(;)1IwmYNH0 zkPD(@ZY39FrM6O1a^c1WrCmtd4M|btf+XZZDJ5=}6c@9JY(g9J=kuv^>U7$cHcM~b zZ+$xFInR5}`#jHi&-=brRi(-bloco|P*$Lq z6halEyb3=cCh(qqEBsT{ad!{sOPH5MvJSfg+F&s>z&kL3A-D!-;Tf!iDV4#U1V2o9 zptBi!00!0%^`Lw_u0yQ2tySLuej9FrkCt+6{aqSUp=uW04agGQ03_K3@F*CSz}8vX6-i_rWg6b%Fu?Ry^G$uR8$xx-}B5pB;ZI+uafeSaXTqA!%nM)u;$qVvmv5a9 z;5A2bXRtl+?o?dMD&GN%RDrS7jKeu^p=PX$#vAwT@d#Yx3-}gV52>uG!8`}Ay8@~F zQ#}u}!k}xK=zVbKVp6tG;4qA~Q$69@{QeA&uNK_B;0<0wd+1-HO|=Rm2J?pg+{C$^ z{`fX@a0QQA@U8vp?R|2m1qasU7U>PbXFRPB~cC`3^d z$1(XVkp(H)OtP?$Y*?_cP!?=Rb{0OCB4H~QN(o8HN?8$>%0?m^N;VX-p;(Zj5c&H3 zr~7hyo@S`YOYhWg&bjBDd+)ht-n%mi314Lp*DJikI^;ry8SkTQNo4Q@%I&iPwU&Rx z@_%Qh5@>`?&{|iJ1CDfI$UosYqUjV8p5XQs-zLlxYa@hti`GR!2cH~5>$vCQcw zNgK?2B&%DB-5af(B#1?NNIHcj7=v5TS`82v3A3s;&_-#l9a>FH@kI!^;u`9kUWQ9( z0Y|1WG|y&%u^zLy$qp-P!zR}bdRg^?DyECU7QJ_Nv2Tn!tOONY1Z^+?H4t~{W(O6! z;<3}HiOpECZ0s%Le?;p7DS$thd@9h@tfJhvR|!5H@&=MY*XJI{cMiG~d?n89)$CE# zAwCse2hJgmu?xX>(o01ucFv=+DHFRe`UtIW(U($2RXT_|?Ur^Niird8?IEZw^87!c zb^BzNmw84x>bftV{hzdIgJk{p%KOPAKj!N9A?(M(f|`O31RV%E i5Og5uK+u8z(18ymm;N57p2}zd0000Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91GN1zh1ONa40RR91G5`Po0Cmf+s{jB19BD*PQ~&?~0ssI20000082|tP zC;$Ke82|tP82|tRcubKn-~a#uL`g(JRA>e4mS1R(Q5eTJTUbQ2WGKH(;)1IwmYNH0 zkPD(@ZY39FrM6O1a^c1WrCmtd4M|btf+XZZDJ5=}6c@9JY(g9J=kuv^>U7$cHcM~b zZ+$xFInR5}`#jHi&-=brRi(-bloco|P*$Lq z6halEyb3=cCh(qqEBsT{ad!{sOPH5MvJSfg+F&s>z&kL3A-D!-;Tf!iDV4#U1V2o9 zptBi!00!0%^`Lw_u0yQ2tySLuej9FrkCt+6{aqSUp=uW04agGQ03_K3@F*CSz}8vX6-i_rWg6b%Fu?Ry^G$uR8$xx-}B5pB;ZI+uafeSaXTqA!%nM)u;$qVvmv5a9 z;5A2bXRtl+?o?dMD&GN%RDrS7jKeu^p=PX$#vAwT@d#Yx3-}gV52>uG!8`}Ay8@~F zQ#}u}!k}xK=zVbKVp6tG;4qA~Q$69@{QeA&uNK_B;0<0wd+1-HO|=Rm2J?pg+{C$^ z{`fX@a0QQA@U8vp?R|2m1qasU7U>PbXFRPB~cC`3^d z$1(XVkp(H)OtP?$Y*?_cP!?=Rb{0OCB4H~QN(o8HN?8$>%0?m^N;VX-p;(Zj5c&H3 zr~7hyo@S`YOYhWg&bjBDd+)ht-n%mi314Lp*DJikI^;ry8SkTQNo4Q@%I&iPwU&Rx z@_%Qh5@>`?&{|iJ1CDfI$UosYqUjV8p5XQs-zLlxYa@hti`GR!2cH~5>$vCQcw zNgK?2B&%DB-5af(B#1?NNIHcj7=v5TS`82v3A3s;&_-#l9a>FH@kI!^;u`9kUWQ9( z0Y|1WG|y&%u^zLy$qp-P!zR}bdRg^?DyECU7QJ_Nv2Tn!tOONY1Z^+?H4t~{W(O6! z;<3}HiOpECZ0s%Le?;p7DS$thd@9h@tfJhvR|!5H@&=MY*XJI{cMiG~d?n89)$CE# zAwCse2hJgmu?xX>(o01ucFv=+DHFRe`UtIW(U($2RXT_|?Ur^Niird8?IEZw^87!c zb^BzNmw84x>bftV{hzdIgJk{p%KOPAKj!N9A?(M(f|`O31RV%E i5Og5uK+u8z(18ymm;N57p2}zd0000=3.0.5 <4.0.0" - flutter: ">=1.17.0" - -dependencies: - flutter: - sdk: flutter - flutter_localizations: - sdk: flutter - - flutter_localization: ^0.1.12 - intl: ^0.18.0 - -dev_dependencies: - flutter_test: - sdk: flutter - flutter_lints: ^2.0.0 - - build_runner: ^2.2.0 - -flutter: diff --git a/packages/tools/.metadata b/packages/tools/.metadata deleted file mode 100644 index 9596faee..00000000 --- a/packages/tools/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: 796c8ef79279f9c774545b3771238c3098dbefab - channel: stable - -project_type: package diff --git a/packages/tools/analysis_options.yaml b/packages/tools/analysis_options.yaml deleted file mode 100644 index 1ee68bd9..00000000 --- a/packages/tools/analysis_options.yaml +++ /dev/null @@ -1,23 +0,0 @@ -include: package:flutter_lints/flutter.yaml -linter: - rules: - always_use_package_imports: true - avoid_relative_lib_imports: true - prefer_relative_imports: false - prefer_single_quotes: true - avoid_void_async: true - constant_identifier_names: false - -analyzer: - errors: - missing_enum_constant_in_switch: error - exhaustive_cases: error - unused_element: error - type_annotate_public_apis: error - missing_required_param: error - invalid_use_of_protected_member: error - unused_import: error - - exclude: - - lib/src/**.pb*.dart - - lib/src/data/*.g.dart diff --git a/packages/tools/lib/src/brush_tool/brush_tool_provider.dart b/packages/tools/lib/src/brush_tool/brush_tool_provider.dart deleted file mode 100644 index 66d9b048..00000000 --- a/packages/tools/lib/src/brush_tool/brush_tool_provider.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:command/command_providers.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; -import 'package:tools/tools.dart'; - -part 'brush_tool_provider.g.dart'; - -@riverpod -BrushTool brushTool(BrushToolRef ref) { - return BrushTool( - paint: ref.watch(brushToolStateProvider.select((state) => state.paint)), - type: ToolType.BRUSH, - commandManager: ref.watch(commandManagerProvider), - commandFactory: ref.watch(commandFactoryProvider), - graphicFactory: ref.watch(graphicFactoryProvider), - ); -} diff --git a/packages/tools/lib/src/eraser_tool/eraser_tool_provider.dart b/packages/tools/lib/src/eraser_tool/eraser_tool_provider.dart deleted file mode 100644 index 5b28e24c..00000000 --- a/packages/tools/lib/src/eraser_tool/eraser_tool_provider.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:command/command_providers.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; -import 'package:tools/tools.dart'; - -part 'eraser_tool_provider.g.dart'; - -@riverpod -BrushTool eraserTool(EraserToolRef ref) { - return BrushTool( - paint: ref.watch(brushToolStateProvider.select((state) => state.paint)), - type: ToolType.ERASER, - commandManager: ref.watch(commandManagerProvider), - commandFactory: ref.watch(commandFactoryProvider), - graphicFactory: ref.watch(graphicFactoryProvider), - ); -} diff --git a/packages/tools/lib/src/hand_tool/hand_tool_provider.dart b/packages/tools/lib/src/hand_tool/hand_tool_provider.dart deleted file mode 100644 index 334d58e9..00000000 --- a/packages/tools/lib/src/hand_tool/hand_tool_provider.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:command/command_providers.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; -import 'package:tools/tools.dart'; - -part 'hand_tool_provider.g.dart'; - -@riverpod -HandTool handTool(HandToolRef ref) { - return HandTool( - paint: ref.watch(brushToolStateProvider.select((state) => state.paint)), - type: ToolType.HAND, - commandManager: ref.watch(commandManagerProvider), - commandFactory: ref.watch(commandFactoryProvider), - ); -} diff --git a/packages/tools/lib/tools.dart b/packages/tools/lib/tools.dart deleted file mode 100644 index 6a434f3c..00000000 --- a/packages/tools/lib/tools.dart +++ /dev/null @@ -1,19 +0,0 @@ -library tools; - -export 'src/brush_tool/brush_tool.dart'; -export 'src/brush_tool/brush_tool_provider.dart'; -export 'src/brush_tool/brush_tool_state_data.dart'; -export 'src/brush_tool/brush_tool_state_provider.dart'; - -export 'src/enums/tool_types.dart'; - -export 'src/hand_tool/hand_tool.dart'; -export 'src/hand_tool/hand_tool_provider.dart'; - -export 'src/eraser_tool/eraser_tool_provider.dart'; - -export 'src/toolbox/toolbox_state_data.dart'; -export 'src/toolbox/toolbox_state_provider.dart'; - -export 'src/tool_data.dart'; -export 'src/tool.dart'; diff --git a/packages/tools/pubspec.yaml b/packages/tools/pubspec.yaml deleted file mode 100644 index d00c2f2a..00000000 --- a/packages/tools/pubspec.yaml +++ /dev/null @@ -1,45 +0,0 @@ -name: tools -description: A new Flutter package project. -version: 0.0.1 -publish_to: "none" - -environment: - sdk: ">=3.0.5 <4.0.0" - flutter: ">=1.17.0" - -dependencies: - flutter: - sdk: flutter - - flutter_riverpod: ^2.3.6 - riverpod_annotation: ^2.1.1 - freezed_annotation: ^2.4.1 - - equatable: ^2.0.3 - toast: ^0.3.0 - - # Internal packages - component_library: - path: ../component_library - database: - path: ../database - command: - path: ../command - workspace_screen: - path: ../features/workspace_screen - -dev_dependencies: - flutter_test: - sdk: flutter - - mockito: ^5.2.0 - flutter_launcher_icons: ^0.9.3 - flutter_lints: ^2.0.1 - floor_generator: ^1.2.0 - riverpod_generator: ^2.2.3 - riverpod_lint: ^1.3.2 - build_runner: ^2.2.0 - freezed: ^2.4.1 - -flutter: - uses-material-design: true diff --git a/pubspec.lock b/pubspec.lock index 7fc77ab1..fb0f8607 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "405666cd3cf0ee0a48d21ec67e65406aad2c726d9fa58840d3375e7bdcd32a07" + sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a url: "https://pub.dev" source: hosted - version: "60.0.0" + version: "61.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "1952250bd005bacb895a01bf1b4dc00e3ba1c526cf47dca54dfe24979c65f5b3" + sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 url: "https://pub.dev" source: hosted - version: "5.12.0" + version: "5.13.0" analyzer_plugin: dependency: transitive description: @@ -25,30 +25,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.11.2" - ansi_styles: - dependency: transitive - description: - name: ansi_styles - sha256: "9c656cc12b3c27b17dd982b2cc5c0cfdfbdabd7bc8f3ae5e8542d9867b47ce8a" - url: "https://pub.dev" - source: hosted - version: "0.3.2+1" archive: dependency: transitive description: name: archive - sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b" + sha256: ecf4273855368121b1caed0d10d4513c7241dfc813f7d3c8933b36622ae9b265 url: "https://pub.dev" source: hosted - version: "3.4.9" + version: "3.5.1" args: dependency: transitive description: name: args - sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.5.0" async: dependency: transitive description: @@ -101,18 +93,18 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "67d591d602906ef9201caf93452495ad1812bea2074f04e25dbd7c133785821b" + sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22" url: "https://pub.dev" source: hosted - version: "2.4.7" + version: "2.4.9" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: c9e32d21dd6626b5c163d48b037ce906bbe428bc23ab77bcd77bb21e593b6185 + sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799" url: "https://pub.dev" source: hosted - version: "7.2.11" + version: "7.3.0" built_collection: dependency: transitive description: @@ -125,10 +117,10 @@ packages: dependency: transitive description: name: built_value - sha256: c9aabae0718ec394e5bc3c7272e6bb0dc0b32201a08fe185ec1d8401d3e39309 + sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb url: "https://pub.dev" source: hosted - version: "8.8.1" + version: "8.9.2" characters: dependency: transitive description: @@ -161,14 +153,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.0" - cli_launcher: - dependency: transitive - description: - name: cli_launcher - sha256: "5e7e0282b79e8642edd6510ee468ae2976d847a0a29b3916e85f5fa1bfe24005" - url: "https://pub.dev" - source: hosted - version: "0.3.1" cli_util: dependency: transitive description: @@ -189,12 +173,12 @@ packages: dependency: transitive description: name: code_builder - sha256: feee43a5c05e7b3199bb375a86430b8ada1b04104f2923d0e03cc01ca87b6d84 + sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 url: "https://pub.dev" source: hosted - version: "4.9.0" + version: "4.10.0" collection: - dependency: transitive + dependency: "direct main" description: name: collection sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a @@ -202,34 +186,12 @@ packages: source: hosted version: "1.18.0" colorpicker: - dependency: transitive - description: - path: "packages/colorpicker" - relative: true - source: path - version: "0.0.1" - command: dependency: "direct main" description: - path: "packages/command" - relative: true - source: path - version: "0.0.1" - component_library: - dependency: "direct main" - description: - path: "packages/component_library" + path: "packages/colorpicker" relative: true source: path version: "0.0.1" - conventional_commit: - dependency: transitive - description: - name: conventional_commit - sha256: dec15ad1118f029c618651a4359eb9135d8b88f761aa24e4016d061cd45948f2 - url: "https://pub.dev" - source: hosted - version: "0.6.0+1" convert: dependency: transitive description: @@ -242,10 +204,10 @@ packages: dependency: transitive description: name: cross_file - sha256: "2f9d2cbccb76127ba28528cb3ae2c2326a122446a83de5a056aaa3880d3882c5" + sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e url: "https://pub.dev" source: hosted - version: "0.3.3+7" + version: "0.3.3+8" crypto: dependency: transitive description: @@ -258,26 +220,26 @@ packages: dependency: transitive description: name: custom_lint - sha256: "3ce36c04d30c60cde295588c6185b3f9800e6c18f6670a7ffdb3d5eab39bb942" + sha256: "22bd87a362f433ba6aae127a7bac2838645270737f3721b180916d7c5946cb5d" url: "https://pub.dev" source: hosted - version: "0.4.0" + version: "0.5.11" custom_lint_builder: dependency: transitive description: name: custom_lint_builder - sha256: "73d09c9848e9f6d5c3e0a1809eac841a8d7ea123d0849feefa040e1ad60b6d06" + sha256: "0d48e002438950f9582e574ef806b2bea5719d8d14c0f9f754fbad729bcf3b19" url: "https://pub.dev" source: hosted - version: "0.4.0" + version: "0.5.14" custom_lint_core: dependency: transitive description: name: custom_lint_core - sha256: "9170d9db2daf774aa2251a3bc98e4ba903c7702ab07aa438bc83bd3c9a0de57f" + sha256: "2952837953022de610dacb464f045594854ced6506ac7f76af28d4a6490e189b" url: "https://pub.dev" source: hosted - version: "0.4.0" + version: "0.5.14" dart_style: dependency: transitive description: @@ -286,21 +248,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.2" - database: - dependency: transitive - description: - path: "packages/database" - relative: true - source: path - version: "0.0.1" device_info_plus: - dependency: transitive + dependency: "direct main" description: name: device_info_plus - sha256: "0042cb3b2a76413ea5f8a2b40cec2a33e01d0c937e91f0f7c211fde4f7739ba6" + sha256: "77f757b789ff68e4eaf9c56d1752309bd9f7ad557cb105b938a7f8eb89e59110" url: "https://pub.dev" source: hosted - version: "9.1.1" + version: "9.1.2" device_info_plus_platform_interface: dependency: transitive description: @@ -310,7 +265,7 @@ packages: source: hosted version: "7.0.0" equatable: - dependency: transitive + dependency: "direct main" description: name: equatable sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 @@ -342,7 +297,7 @@ packages: source: hosted version: "6.1.4" file_picker: - dependency: transitive + dependency: "direct main" description: name: file_picker sha256: be325344c1f3070354a1d84a231a1ba75ea85d413774ec4bdf444c023342e030 @@ -361,18 +316,18 @@ packages: dependency: transitive description: name: file_selector_macos - sha256: b15c3da8bd4908b9918111fa486903f5808e388b8d1c559949f584725a6594d6 + sha256: f42eacb83b318e183b1ae24eead1373ab1334084404c8c16e0354f9a3e55d385 url: "https://pub.dev" source: hosted - version: "0.9.3+3" + version: "0.9.4" file_selector_platform_interface: dependency: transitive description: name: file_selector_platform_interface - sha256: "0aa47a725c346825a2bd396343ce63ac00bda6eff2fbc43eabe99737dede8262" + sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b url: "https://pub.dev" source: hosted - version: "2.6.1" + version: "2.6.2" file_selector_windows: dependency: transitive description: @@ -382,7 +337,7 @@ packages: source: hosted version: "0.9.3+1" filesize: - dependency: transitive + dependency: "direct main" description: name: filesize sha256: f53df1f27ff60e466eefcd9df239e02d4722d5e2debee92a87dfd99ac66de2af @@ -398,7 +353,7 @@ packages: source: hosted version: "1.1.0" floor: - dependency: transitive + dependency: "direct main" description: name: floor sha256: "52a8eac2c8d274e7c0c54251226f59786bb5b749365a2d8537d8095aa5132d92" @@ -443,10 +398,10 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 + sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "3.0.2" flutter_localization: dependency: "direct main" description: @@ -464,20 +419,20 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da + sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f" url: "https://pub.dev" source: hosted - version: "2.0.17" + version: "2.0.19" flutter_riverpod: dependency: "direct main" description: name: flutter_riverpod - sha256: da9591d1f8d5881628ccd5c25c40e74fc3eef50ba45e40c3905a06e1712412d5 + sha256: "0f1974eff5bbe774bf1d870e406fc6f29e3d6f1c46bd9c58e7172ff68a785d7d" url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.5.1" flutter_svg: - dependency: transitive + dependency: "direct main" description: name: flutter_svg sha256: "6ff9fa12892ae074092de2fa6a9938fb21dbabfdaa2ff57dc697ff912fc8d4b2" @@ -498,10 +453,10 @@ packages: dependency: "direct dev" description: name: freezed - sha256: "2df89855fe181baae3b6d714dc3c4317acf4fccd495a6f36e5e00f24144c6c3b" + sha256: a434911f643466d78462625df76fd9eb13e57348ff43fe1f77bbe909522c67a1 url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.5.2" freezed_annotation: dependency: "direct main" description: @@ -514,10 +469,10 @@ packages: dependency: transitive description: name: frontend_server_client - sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "4.0.0" fuchsia_remote_debug_protocol: dependency: transitive description: flutter @@ -543,18 +498,18 @@ packages: dependency: transitive description: name: hotreloader - sha256: "728c0613556c1d153f7e7f4a367cffacc3f5a677d7f6497a1c2b35add4e6dacf" + sha256: ed56fdc1f3a8ac924e717257621d09e9ec20e308ab6352a73a50a1d7a4d9158e url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "4.2.0" http: dependency: transitive description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.0" http_multi_server: dependency: transitive description: @@ -572,7 +527,7 @@ packages: source: hosted version: "4.0.2" image: - dependency: transitive + dependency: "direct main" description: name: image sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6" @@ -580,7 +535,7 @@ packages: source: hosted version: "3.3.0" image_picker: - dependency: transitive + dependency: "direct main" description: name: image_picker sha256: b6951e25b795d053a6ba03af5f710069c99349de9341af95155d52665cb4607c @@ -591,10 +546,10 @@ packages: dependency: transitive description: name: image_picker_android - sha256: ecdc963d2aa67af5195e723a40580f802d4392e31457a12a562b3e2bd6a396fe + sha256: "844c6da4e4f2829dffdab97816bca09d0e0977e8dcef7450864aba4e07967a58" url: "https://pub.dev" source: hosted - version: "0.8.9+1" + version: "0.8.9+6" image_picker_for_web: dependency: transitive description: @@ -607,10 +562,10 @@ packages: dependency: transitive description: name: image_picker_ios - sha256: eac0a62104fa12feed213596df0321f57ce5a572562f72a68c4ff81e9e4caacf + sha256: fadafce49e8569257a0cad56d24438a6fa1f0cbd7ee0af9b631f7492818a4ca3 url: "https://pub.dev" source: hosted - version: "0.8.9" + version: "0.8.9+1" image_picker_linux: dependency: transitive description: @@ -631,10 +586,10 @@ packages: dependency: transitive description: name: image_picker_platform_interface - sha256: ed9b00e63977c93b0d2d2b343685bed9c324534ba5abafbb3dfbd6a780b1b514 + sha256: fa4e815e6fcada50e35718727d83ba1c92f1edf95c0b4436554cec301b56233b url: "https://pub.dev" source: hosted - version: "2.9.1" + version: "2.9.3" image_picker_windows: dependency: transitive description: @@ -643,6 +598,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.1+1" + import_sorter: + dependency: "direct dev" + description: + name: import_sorter + sha256: eb15738ccead84e62c31e0208ea4e3104415efcd4972b86906ca64a1187d0836 + url: "https://pub.dev" + source: hosted + version: "4.6.0" integration_test: dependency: "direct dev" description: flutter @@ -664,13 +627,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" - io_library: - dependency: "direct main" - description: - path: "packages/io_library" - relative: true - source: path - version: "0.0.1" js: dependency: transitive description: @@ -680,29 +636,23 @@ packages: source: hosted version: "0.6.7" json_annotation: - dependency: transitive + dependency: "direct main" description: name: json_annotation - sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" url: "https://pub.dev" source: hosted - version: "4.8.1" - l10n: - dependency: "direct main" - description: - path: "packages/l10n" - relative: true - source: path - version: "0.0.1" - landing_page_screen: - dependency: "direct main" + version: "4.9.0" + json_serializable: + dependency: "direct dev" description: - path: "packages/features/landing_page_screen" - relative: true - source: path - version: "0.0.1" + name: json_serializable + sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b + url: "https://pub.dev" + source: hosted + version: "6.8.0" launch_review: - dependency: transitive + dependency: "direct main" description: name: launch_review sha256: "04cdaf752033cefd53bc0fa9c22105801ef53791a93d8b6cdd00fcb3c1c1604b" @@ -713,10 +663,10 @@ packages: dependency: transitive description: name: lints - sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" + sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "3.0.0" lists: dependency: transitive description: @@ -749,14 +699,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.0" - melos: - dependency: "direct main" - description: - name: melos - sha256: "96e64bbade5712c3f010137e195bca9f1b351fac34ab1f322af492ae34032067" - url: "https://pub.dev" - source: hosted - version: "3.4.0" meta: dependency: transitive description: @@ -769,35 +711,20 @@ packages: dependency: transitive description: name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.5" mockito: dependency: "direct dev" description: name: mockito - sha256: "7d5b53bcd556c1bc7ffbe4e4d5a19c3e112b7e925e9e172dd7c6ad0630812616" - url: "https://pub.dev" - source: hosted - version: "5.4.2" - mustache_template: - dependency: transitive - description: - name: mustache_template - sha256: a46e26f91445bfb0b60519be280555b06792460b27b19e2b19ad5b9740df5d1c + sha256: "6841eed20a7befac0ce07df8116c8b8233ed1f4486a7647c7fc5a02ae6163917" url: "https://pub.dev" source: hosted - version: "2.0.0" - onboarding_screen: - dependency: "direct main" - description: - path: "packages/features/onboarding_screen" - relative: true - source: path - version: "0.0.1" + version: "5.4.4" oxidized: - dependency: transitive + dependency: "direct main" description: name: oxidized sha256: "2058b9818815546124f6d0fee813483b571ca133b4db6f63c9628897f191e6b5" @@ -813,7 +740,7 @@ packages: source: hosted version: "2.1.0" package_info_plus: - dependency: transitive + dependency: "direct main" description: name: package_info_plus sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" @@ -853,29 +780,29 @@ packages: source: hosted version: "1.0.1" path_provider: - dependency: transitive + dependency: "direct main" description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.3" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" + sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.2.4" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" path_provider_linux: dependency: transitive description: @@ -888,10 +815,10 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_windows: dependency: transitive description: @@ -901,7 +828,7 @@ packages: source: hosted version: "2.2.1" permission_handler: - dependency: transitive + dependency: "direct main" description: name: permission_handler sha256: bc56bfe9d3f44c3c612d8d393bd9b174eb796d706759f9b495ac254e4294baa5 @@ -944,10 +871,10 @@ packages: dependency: transitive description: name: petitparser - sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 url: "https://pub.dev" source: hosted - version: "5.4.0" + version: "6.0.2" platform: dependency: transitive description: @@ -960,18 +887,10 @@ packages: dependency: transitive description: name: plugin_platform_interface - sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" url: "https://pub.dev" source: hosted - version: "2.1.7" - pointycastle: - dependency: transitive - description: - name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" - url: "https://pub.dev" - source: hosted - version: "3.7.3" + version: "2.1.8" pool: dependency: transitive description: @@ -988,22 +907,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.2.4" - prompts: - dependency: transitive - description: - name: prompts - sha256: "3773b845e85a849f01e793c4fc18a45d52d7783b4cb6c0569fad19f9d0a774a1" - url: "https://pub.dev" - source: hosted - version: "2.0.0" - protobuf: - dependency: transitive - description: - name: protobuf - sha256: "01dd9bd0fa02548bf2ceee13545d4a0ec6046459d847b6b061d8a27237108a08" - url: "https://pub.dev" - source: hosted - version: "2.1.0" pub_semver: dependency: transitive description: @@ -1012,22 +915,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - pub_updater: - dependency: transitive - description: - name: pub_updater - sha256: b06600619c8c219065a548f8f7c192b3e080beff95488ed692780f48f69c0625 - url: "https://pub.dev" - source: hosted - version: "0.3.1" - pubspec: - dependency: transitive - description: - name: pubspec - sha256: f534a50a2b4d48dc3bc0ec147c8bd7c304280fff23b153f3f11803c4d49d927e - url: "https://pub.dev" - source: hosted - version: "2.3.0" pubspec_parse: dependency: transitive description: @@ -1036,54 +923,46 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.3" - quiver: - dependency: transitive - description: - name: quiver - sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 - url: "https://pub.dev" - source: hosted - version: "3.2.1" riverpod: dependency: "direct dev" description: name: riverpod - sha256: "942999ee48b899f8a46a860f1e13cee36f2f77609eb54c5b7a669bb20d550b11" + sha256: f21b32ffd26a36555e501b04f4a5dca43ed59e16343f1a30c13632b2351dfa4d url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.5.1" riverpod_analyzer_utils: dependency: transitive description: name: riverpod_analyzer_utils - sha256: "1b2632a6fc0b659c923a4dcc7cd5da42476f5b3294c70c86c971e63bdd443384" + sha256: d72d7096964baf288b55619fe48100001fc4564ab7923ed0a7f5c7650e03c0d6 url: "https://pub.dev" source: hosted - version: "0.3.1" + version: "0.3.4" riverpod_annotation: dependency: "direct main" description: name: riverpod_annotation - sha256: b70e95fbd5ca7ce42f5148092022971bb2e9843b6ab71e97d479e8ab52e98979 + sha256: e5e796c0eba4030c704e9dae1b834a6541814963292839dcf9638d53eba84f5c url: "https://pub.dev" source: hosted - version: "2.3.3" + version: "2.3.5" riverpod_generator: dependency: "direct dev" description: name: riverpod_generator - sha256: "691180275664a5420c87d72c1ed26ef8404d32b823807540172bfd1660425376" + sha256: "5b36ad2f2b562cffb37212e8d59390b25499bf045b732276e30a207b16a25f61" url: "https://pub.dev" source: hosted - version: "2.2.4" + version: "2.3.3" riverpod_lint: dependency: "direct dev" description: name: riverpod_lint - sha256: "17ad319914ac6863c64524e598913c0f17e30688aca8f5b7509e96d6e372d493" + sha256: "70198738c3047ae4f6517ef1a2011a8514a980a52576c7f629a3a08810319a02" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "2.1.1" rxdart: dependency: transitive description: @@ -1096,26 +975,26 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02" + sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180 url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.2.3" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06" + sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7" + sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c" url: "https://pub.dev" source: hosted - version: "2.3.4" + version: "2.3.5" shared_preferences_linux: dependency: transitive description: @@ -1128,18 +1007,18 @@ packages: dependency: transitive description: name: shared_preferences_platform_interface - sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a + sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf + sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" shared_preferences_windows: dependency: transitive description: @@ -1170,7 +1049,7 @@ packages: source: sdk version: "0.0.99" smooth_page_indicator: - dependency: transitive + dependency: "direct main" description: name: smooth_page_indicator sha256: "725bc638d5e79df0c84658e1291449996943f93bacbc2cec49963dbbab48d8ae" @@ -1185,6 +1064,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.0" + source_helper: + dependency: transitive + description: + name: source_helper + sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" + url: "https://pub.dev" + source: hosted + version: "1.3.4" source_span: dependency: transitive description: @@ -1193,38 +1080,46 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.0" - sqflite: + sprintf: dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + sqflite: + dependency: "direct main" description: name: sqflite - sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a" + sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6 url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.2" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6 + sha256: "28d8c66baee4968519fb8bd6cdbedad982d6e53359091f0b74544a9f32ec72d5" url: "https://pub.dev" source: hosted - version: "2.5.0+2" + version: "2.5.3" sqflite_common_ffi: dependency: transitive description: name: sqflite_common_ffi - sha256: "35d2fce1e971707c227cc4775cc017d5eafe06c2654c3435ebd5c3ad6c170f5f" + sha256: "754927d82de369a6b9e760fb60640aa81da650f35ffd468d5a992814d6022908" url: "https://pub.dev" source: hosted - version: "2.3.0+4" + version: "2.3.2+1" sqlite3: dependency: transitive description: name: sqlite3 - sha256: db65233e6b99e99b2548932f55a987961bc06d82a31a0665451fa0b4fff4c3fb + sha256: "072128763f1547e3e9b4735ce846bfd226d68019ccda54db4cd427b12dfdedc9" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.4.0" sqlparser: dependency: transitive description: @@ -1321,21 +1216,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" - toast: + tint: dependency: transitive + description: + name: tint + sha256: "9652d9a589f4536d5e392cf790263d120474f15da3cf1bee7f1fdb31b4de5f46" + url: "https://pub.dev" + source: hosted + version: "2.0.1" + toast: + dependency: "direct main" description: name: toast sha256: "12433091e3e5a25b3a25f670126e42547c9ade135de30ad9ace45d1ddccd57c9" url: "https://pub.dev" source: hosted version: "0.3.0" - tools: - dependency: "direct main" - description: - path: "packages/tools" - relative: true - source: path - version: "0.0.1" typed_data: dependency: transitive description: @@ -1352,38 +1248,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.1" - uri: - dependency: transitive - description: - name: uri - sha256: "889eea21e953187c6099802b7b4cf5219ba8f3518f604a1033064d45b1b8268a" - url: "https://pub.dev" - source: hosted - version: "1.0.0" url_launcher: - dependency: transitive + dependency: "direct main" description: name: url_launcher - sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27" + sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e" url: "https://pub.dev" source: hosted - version: "6.1.14" + version: "6.2.6" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def" + sha256: "360a6ed2027f18b73c8d98e159dda67a61b7f2e0f6ec26e86c3ada33b0621775" url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.3.1" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3 + sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03" url: "https://pub.dev" source: hosted - version: "6.2.1" + version: "6.2.4" url_launcher_linux: dependency: transitive description: @@ -1404,18 +1292,18 @@ packages: dependency: transitive description: name: url_launcher_platform_interface - sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50" + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.2" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: ba140138558fcc3eead51a1c42e92a9fb074a1b1149ed3c73e66035b2ccd94f2 + sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b url: "https://pub.dev" source: hosted - version: "2.0.19" + version: "2.2.3" url_launcher_windows: dependency: transitive description: @@ -1428,10 +1316,10 @@ packages: dependency: transitive description: name: uuid - sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" + sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8" url: "https://pub.dev" source: hosted - version: "3.0.7" + version: "4.4.0" vector_math: dependency: transitive description: @@ -1484,41 +1372,34 @@ packages: dependency: transitive description: name: win32 - sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" + sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8" url: "https://pub.dev" source: hosted - version: "5.0.9" + version: "5.2.0" win32_registry: dependency: transitive description: name: win32_registry - sha256: e4506d60b7244251bc59df15656a3093501c37fb5af02105a944d73eb95be4c9 + sha256: "41fd8a189940d8696b1b810efb9abcf60827b6cbfab90b0c43e8439e3a39d85a" url: "https://pub.dev" source: hosted - version: "1.1.1" - workspace_screen: - dependency: "direct main" - description: - path: "packages/features/workspace_screen" - relative: true - source: path - version: "0.0.1" + version: "1.1.2" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" + sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.0.4" xml: dependency: transitive description: name: xml - sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "6.5.0" yaml: dependency: transitive description: @@ -1527,14 +1408,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.2" - yaml_edit: - dependency: transitive - description: - name: yaml_edit - sha256: "1579d4a0340a83cf9e4d580ea51a16329c916973bffd5bd4b45e911b25d46bfd" - url: "https://pub.dev" - source: hosted - version: "2.1.1" sdks: - dart: ">=3.2.0-194.0.dev <4.0.0" - flutter: ">=3.10.0" + dart: ">=3.2.0 <4.0.0" + flutter: ">=3.16.0" diff --git a/pubspec.yaml b/pubspec.yaml index 5a441042..8a8894c8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -6,7 +6,7 @@ publish_to: "none" version: 1.0.0+1 environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=3.0.5 <4.0.0" dependencies: flutter: @@ -21,25 +21,28 @@ dependencies: riverpod_annotation: ^2.1.1 shared_preferences: ^2.0.15 freezed_annotation: ^2.4.1 - melos: ^3.4.0 + equatable: ^2.0.3 + json_annotation: ^4.8.1 + collection: ^1.17.1 + url_launcher: ^6.1.6 + toast: ^0.3.0 + oxidized: ^5.2.0 + flutter_svg: ^1.1.0 + launch_review: ^3.0.1 + package_info_plus: ^4.0.1 + filesize: ^2.0.1 + smooth_page_indicator: ^1.0.0+2 + image: ^3.2.0 + permission_handler: ^10.0.0 + device_info_plus: ^9.0.3 + image_picker: ^0.8.5+3 + path_provider: ^2.0.11 + file_picker: ^5.3.1 + floor: ^1.2.0 + sqflite: ^2.3.0 - # Internal packages: - component_library: - path: ./packages/component_library - l10n: - path: ./packages/l10n - command: - path: ./packages/command - io_library: - path: ./packages/io_library - tools: - path: ./packages/tools - workspace_screen: - path: ./packages/features/workspace_screen - landing_page_screen: - path: ./packages/features/landing_page_screen - onboarding_screen: - path: ./packages/features/onboarding_screen + colorpicker: + path: packages/colorpicker dev_dependencies: flutter_test: @@ -49,16 +52,23 @@ dev_dependencies: mockito: ^5.2.0 flutter_launcher_icons: ^0.9.3 - flutter_lints: ^2.0.1 - floor_generator: ^1.2.0 - riverpod_generator: ^2.2.3 - riverpod_lint: ^1.3.2 + flutter_lints: ^3.0.2 + floor_generator: ^1.4.2 + riverpod_generator: ^2.2.4 + riverpod_lint: ^2.0.0 build_runner: ^2.2.0 freezed: ^2.4.1 riverpod: ^2.3.7 + import_sorter: ^4.6.0 + json_serializable: ^6.7.1 + flutter: uses-material-design: true assets: - assets/icon/ + - assets/img/ + - assets/svg/ + - assets/lang/ + - test/assets/images/ diff --git a/packages/features/landing_page_screen/test/fixture/image/test.jpg b/test/assets/images/test.jpg similarity index 100% rename from packages/features/landing_page_screen/test/fixture/image/test.jpg rename to test/assets/images/test.jpg diff --git a/packages/features/landing_page_screen/test/fixture/image/test.png b/test/assets/images/test.png similarity index 100% rename from packages/features/landing_page_screen/test/fixture/image/test.png rename to test/assets/images/test.png diff --git a/packages/features/landing_page_screen/test/fixture/image/test1.png b/test/assets/images/test1.png similarity index 100% rename from packages/features/landing_page_screen/test/fixture/image/test1.png rename to test/assets/images/test1.png diff --git a/packages/command/test/unit/command_factory_test.dart b/test/unit/command/command_factory_test.dart similarity index 65% rename from packages/command/test/unit/command_factory_test.dart rename to test/unit/command/command_factory_test.dart index b8af3440..28fef53c 100644 --- a/packages/command/test/unit/command_factory_test.dart +++ b/test/unit/command/command_factory_test.dart @@ -1,8 +1,14 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; +// Package imports: import 'package:flutter_test/flutter_test.dart'; +// Project imports: +import 'package:paintroid/core/commands/command_factory/command_factory.dart'; +import 'package:paintroid/core/commands/command_implementation/graphic/draw_path_command.dart'; +import 'package:paintroid/core/commands/path_with_action_history.dart'; + void main() { late PathWithActionHistory testPath; late Paint testPaint; diff --git a/packages/command/test/unit/draw_path_command_test.dart b/test/unit/command/draw_path_command_test.dart similarity index 65% rename from packages/command/test/unit/draw_path_command_test.dart rename to test/unit/command/draw_path_command_test.dart index 4d34c156..6b0e3abb 100644 --- a/packages/command/test/unit/draw_path_command_test.dart +++ b/test/unit/command/draw_path_command_test.dart @@ -1,10 +1,14 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; +// Package imports: import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; +// Project imports: +import 'package:paintroid/core/commands/command_implementation/graphic/draw_path_command.dart'; +import 'package:paintroid/core/commands/path_with_action_history.dart'; import 'draw_path_command_test.mocks.dart'; @GenerateMocks([Canvas]) @@ -22,9 +26,9 @@ void main() { final testPath = PathWithActionHistory(); final testPaint = Paint(); drawPath = DrawPathCommand(testPath, testPaint); - when(mockCanvas.drawPath(testPath, testPaint)).thenReturn(null); + when(mockCanvas.drawPath(testPath.path, testPaint)).thenReturn(null); drawPath.call(mockCanvas); - verify(mockCanvas.drawPath(testPath, testPaint)); + verify(mockCanvas.drawPath(testPath.path, testPaint)); verifyNoMoreInteractions(mockCanvas); }, ); diff --git a/packages/command/test/unit/draw_path_command_test.mocks.dart b/test/unit/command/draw_path_command_test.mocks.dart similarity index 97% rename from packages/command/test/unit/draw_path_command_test.mocks.dart rename to test/unit/command/draw_path_command_test.mocks.dart index 28d796c0..f0ca97ee 100644 --- a/packages/command/test/unit/draw_path_command_test.mocks.dart +++ b/test/unit/command/draw_path_command_test.mocks.dart @@ -1,17 +1,22 @@ -// Mocks generated by Mockito 5.4.2 from annotations -// in command/test/unit/draw_path_command_test.dart. +// Mocks generated by Mockito 5.4.4 from annotations +// in paintroid/test/unit/command/draw_path_command_test.dart. // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes + +// Dart imports: import 'dart:typed_data' as _i3; import 'dart:ui' as _i2; +// Package imports: import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters // ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors diff --git a/packages/database/test/unit/project_database_test.dart b/test/unit/database/project_database_test.dart similarity index 94% rename from packages/database/test/unit/project_database_test.dart rename to test/unit/database/project_database_test.dart index dc00547a..4cd80ee1 100644 --- a/packages/database/test/unit/project_database_test.dart +++ b/test/unit/database/project_database_test.dart @@ -1,7 +1,12 @@ -import 'package:database/database.dart'; +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; +// Project imports: +import 'package:paintroid/core/database/project_database.dart'; +import 'package:paintroid/core/models/database/project.dart'; +import 'package:paintroid/core/utils/date_time_converter.dart'; + void main() async { TestWidgetsFlutterBinding.ensureInitialized(); diff --git a/packages/io_library/test/unit/service/file_service_test.dart b/test/unit/provider/file_service_test.dart similarity index 91% rename from packages/io_library/test/unit/service/file_service_test.dart rename to test/unit/provider/file_service_test.dart index 8305160f..5a9c35e9 100644 --- a/packages/io_library/test/unit/service/file_service_test.dart +++ b/test/unit/provider/file_service_test.dart @@ -1,17 +1,23 @@ +// Dart imports: import 'dart:io'; +// Flutter imports: import 'package:flutter/services.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:io_library/io_library.dart'; + +// Project imports: +import 'package:paintroid/core/providers/object/file_service.dart'; void main() async { TestWidgetsFlutterBinding.ensureInitialized(); late FileService sut; - const path = 'test/fixture/image/test.png'; + const path = 'test/assets/images/test.png'; final testPngFile = await rootBundle.load(path); - const testDirectory = './test/fixture/image'; + const testDirectory = './test/assets/images'; const channel = MethodChannel( 'plugins.flutter.io/path_provider', ); diff --git a/packages/io_library/test/unit/service/image_service_test.dart b/test/unit/provider/image_service_test.dart similarity index 81% rename from packages/io_library/test/unit/service/image_service_test.dart rename to test/unit/provider/image_service_test.dart index dc034350..5a15b355 100644 --- a/packages/io_library/test/unit/service/image_service_test.dart +++ b/test/unit/provider/image_service_test.dart @@ -1,12 +1,17 @@ +// Flutter imports: import 'package:flutter/services.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:io_library/io_library.dart'; + +// Project imports: +import 'package:paintroid/core/providers/object/image_service.dart'; void main() async { TestWidgetsFlutterBinding.ensureInitialized(); - final testPngFile = await rootBundle.load('test/fixture/image/test.png'); - final testJpgFile = await rootBundle.load('test/fixture/image/test.jpg'); + final testPngFile = await rootBundle.load('test/assets/images/test.png'); + final testJpgFile = await rootBundle.load('test/assets/images/test.jpg'); late ImageService sut; setUp(() async { @@ -36,7 +41,7 @@ void main() async { }); test('Should return project preview', () { - const path = 'test/fixture/image/test.png'; + const path = 'test/assets/images/test.png'; final result = sut.getProjectPreview(path); final imgPreview = result.unwrapOrElse((failure) => fail(failure.message)); expect(imgPreview, isA()); diff --git a/packages/io_library/test/unit/usecase/load_image_from_photo_library_test.dart b/test/unit/provider/load_image_from_photo_library_test.dart similarity index 90% rename from packages/io_library/test/unit/usecase/load_image_from_photo_library_test.dart rename to test/unit/provider/load_image_from_photo_library_test.dart index dea81939..d3b34a4d 100644 --- a/packages/io_library/test/unit/usecase/load_image_from_photo_library_test.dart +++ b/test/unit/provider/load_image_from_photo_library_test.dart @@ -1,13 +1,20 @@ +// Dart imports: import 'dart:typed_data'; import 'dart:ui'; +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:io_library/io_library.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:oxidized/oxidized.dart'; +// Project imports: +import 'package:paintroid/core/providers/object/image_service.dart'; +import 'package:paintroid/core/providers/object/load_image_from_photo_library.dart'; +import 'package:paintroid/core/providers/object/permission_service.dart'; +import 'package:paintroid/core/providers/object/photo_library_service.dart'; +import 'package:paintroid/core/utils/failure.dart'; import 'load_image_from_photo_library_test.mocks.dart'; class FakeImage extends Fake implements Image {} diff --git a/packages/io_library/test/unit/usecase/load_image_from_photo_library_test.mocks.dart b/test/unit/provider/load_image_from_photo_library_test.mocks.dart similarity index 66% rename from packages/io_library/test/unit/usecase/load_image_from_photo_library_test.mocks.dart rename to test/unit/provider/load_image_from_photo_library_test.mocks.dart index 2793e86e..11ab4975 100644 --- a/packages/io_library/test/unit/usecase/load_image_from_photo_library_test.mocks.dart +++ b/test/unit/provider/load_image_from_photo_library_test.mocks.dart @@ -1,20 +1,32 @@ -// Mocks generated by Mockito 5.4.2 from annotations -// in io_library/test/unit/usecase/load_image_from_photo_library_test.dart. +// Mocks generated by Mockito 5.4.4 from annotations +// in paintroid/test/unit/provider/load_image_from_photo_library_test.dart. // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes + +// Dart imports: import 'dart:async' as _i4; -import 'dart:typed_data' as _i6; +import 'dart:typed_data' as _i7; import 'dart:ui' as _i5; -import 'package:io_library/io_library.dart' as _i3; +// Package imports: import 'package:mockito/mockito.dart' as _i1; import 'package:oxidized/oxidized.dart' as _i2; +// Project imports: +import 'package:paintroid/core/providers/object/image_service.dart' as _i3; +import 'package:paintroid/core/providers/object/permission_service.dart' as _i8; +import 'package:paintroid/core/utils/failure.dart' as _i6; + +import 'package:paintroid/core/providers/object/photo_library_service.dart' + as _i9; + // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters // ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors @@ -42,25 +54,25 @@ class MockIImageService extends _i1.Mock implements _i3.IImageService { } @override - _i4.Future<_i2.Result<_i5.Image, _i3.Failure>> import( - _i6.Uint8List? fileData) => + _i4.Future<_i2.Result<_i5.Image, _i6.Failure>> import( + _i7.Uint8List? fileData) => (super.noSuchMethod( Invocation.method( #import, [fileData], ), - returnValue: _i4.Future<_i2.Result<_i5.Image, _i3.Failure>>.value( - _FakeResult_0<_i5.Image, _i3.Failure>( + returnValue: _i4.Future<_i2.Result<_i5.Image, _i6.Failure>>.value( + _FakeResult_0<_i5.Image, _i6.Failure>( this, Invocation.method( #import, [fileData], ), )), - ) as _i4.Future<_i2.Result<_i5.Image, _i3.Failure>>); + ) as _i4.Future<_i2.Result<_i5.Image, _i6.Failure>>); @override - _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>> exportAsJpg( + _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>> exportAsJpg( _i5.Image? image, int? quality, ) => @@ -72,8 +84,8 @@ class MockIImageService extends _i1.Mock implements _i3.IImageService { quality, ], ), - returnValue: _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>.value( - _FakeResult_0<_i6.Uint8List, _i3.Failure>( + returnValue: _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>>.value( + _FakeResult_0<_i7.Uint8List, _i6.Failure>( this, Invocation.method( #exportAsJpg, @@ -83,48 +95,48 @@ class MockIImageService extends _i1.Mock implements _i3.IImageService { ], ), )), - ) as _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>); + ) as _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>>); @override - _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>> exportAsPng( + _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>> exportAsPng( _i5.Image? image) => (super.noSuchMethod( Invocation.method( #exportAsPng, [image], ), - returnValue: _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>.value( - _FakeResult_0<_i6.Uint8List, _i3.Failure>( + returnValue: _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>>.value( + _FakeResult_0<_i7.Uint8List, _i6.Failure>( this, Invocation.method( #exportAsPng, [image], ), )), - ) as _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>); + ) as _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>>); @override - _i2.Result<_i6.Uint8List, _i3.Failure> getProjectPreview(String? path) => + _i2.Result<_i7.Uint8List, _i6.Failure> getProjectPreview(String? path) => (super.noSuchMethod( Invocation.method( #getProjectPreview, [path], ), - returnValue: _FakeResult_0<_i6.Uint8List, _i3.Failure>( + returnValue: _FakeResult_0<_i7.Uint8List, _i6.Failure>( this, Invocation.method( #getProjectPreview, [path], ), ), - ) as _i2.Result<_i6.Uint8List, _i3.Failure>); + ) as _i2.Result<_i7.Uint8List, _i6.Failure>); } /// A class which mocks [IPermissionService]. /// /// See the documentation for Mockito's code generation for more information. class MockIPermissionService extends _i1.Mock - implements _i3.IPermissionService { + implements _i8.IPermissionService { MockIPermissionService() { _i1.throwOnMissingStub(this); } @@ -161,15 +173,15 @@ class MockIPermissionService extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. class MockIPhotoLibraryService extends _i1.Mock - implements _i3.IPhotoLibraryService { + implements _i9.IPhotoLibraryService { MockIPhotoLibraryService() { _i1.throwOnMissingStub(this); } @override - _i4.Future<_i2.Result<_i2.Unit, _i3.Failure>> save( + _i4.Future<_i2.Result<_i2.Unit, _i6.Failure>> save( String? filename, - _i6.Uint8List? data, + _i7.Uint8List? data, ) => (super.noSuchMethod( Invocation.method( @@ -179,8 +191,8 @@ class MockIPhotoLibraryService extends _i1.Mock data, ], ), - returnValue: _i4.Future<_i2.Result<_i2.Unit, _i3.Failure>>.value( - _FakeResult_0<_i2.Unit, _i3.Failure>( + returnValue: _i4.Future<_i2.Result<_i2.Unit, _i6.Failure>>.value( + _FakeResult_0<_i2.Unit, _i6.Failure>( this, Invocation.method( #save, @@ -190,22 +202,22 @@ class MockIPhotoLibraryService extends _i1.Mock ], ), )), - ) as _i4.Future<_i2.Result<_i2.Unit, _i3.Failure>>); + ) as _i4.Future<_i2.Result<_i2.Unit, _i6.Failure>>); @override - _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>> pick() => + _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>> pick() => (super.noSuchMethod( Invocation.method( #pick, [], ), - returnValue: _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>.value( - _FakeResult_0<_i6.Uint8List, _i3.Failure>( + returnValue: _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>>.value( + _FakeResult_0<_i7.Uint8List, _i6.Failure>( this, Invocation.method( #pick, [], ), )), - ) as _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>); + ) as _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>>); } diff --git a/packages/io_library/test/unit/service/photo_library_service_test.dart b/test/unit/provider/photo_library_service_test.dart similarity index 95% rename from packages/io_library/test/unit/service/photo_library_service_test.dart rename to test/unit/provider/photo_library_service_test.dart index 7f0fecae..f2c0f479 100644 --- a/packages/io_library/test/unit/service/photo_library_service_test.dart +++ b/test/unit/provider/photo_library_service_test.dart @@ -1,12 +1,19 @@ +// Flutter imports: import 'package:flutter/services.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:image_picker/image_picker.dart'; -import 'package:io_library/io_library.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:oxidized/oxidized.dart'; +// Project imports: +import 'package:paintroid/core/providers/object/photo_library_service.dart'; +import 'package:paintroid/core/utils/failure.dart'; +import 'package:paintroid/core/utils/load_image_failure.dart'; +import 'package:paintroid/core/utils/save_image_failure.dart'; import 'photo_library_service_test.mocks.dart'; @GenerateMocks([ImagePicker, MethodChannel, XFile]) diff --git a/packages/io_library/test/unit/service/photo_library_service_test.mocks.dart b/test/unit/provider/photo_library_service_test.mocks.dart similarity index 90% rename from packages/io_library/test/unit/service/photo_library_service_test.mocks.dart rename to test/unit/provider/photo_library_service_test.mocks.dart index 5cc7a2d9..a983649e 100644 --- a/packages/io_library/test/unit/service/photo_library_service_test.mocks.dart +++ b/test/unit/provider/photo_library_service_test.mocks.dart @@ -1,24 +1,33 @@ -// Mocks generated by Mockito 5.4.2 from annotations -// in io_library/test/unit/service/photo_library_service_test.dart. +// Mocks generated by Mockito 5.4.4 from annotations +// in paintroid/test/unit/provider/photo_library_service_test.dart. // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes + +// Dart imports: import 'dart:async' as _i6; -import 'dart:convert' as _i8; -import 'dart:typed_data' as _i9; +import 'dart:convert' as _i9; +import 'dart:typed_data' as _i10; +// Flutter imports: import 'package:flutter/src/services/binary_messenger.dart' as _i4; import 'package:flutter/src/services/message_codec.dart' as _i3; import 'package:flutter/src/services/platform_channel.dart' as _i7; + +// Package imports: import 'package:image_picker/image_picker.dart' as _i5; +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i8; + import 'package:image_picker_platform_interface/image_picker_platform_interface.dart' as _i2; -import 'package:mockito/mockito.dart' as _i1; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters // ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors @@ -306,7 +315,10 @@ class MockMethodChannel extends _i1.Mock implements _i7.MethodChannel { @override String get name => (super.noSuchMethod( Invocation.getter(#name), - returnValue: '', + returnValue: _i8.dummyValue( + this, + Invocation.getter(#name), + ), ) as String); @override @@ -398,13 +410,19 @@ class MockXFile extends _i1.Mock implements _i2.XFile { @override String get path => (super.noSuchMethod( Invocation.getter(#path), - returnValue: '', + returnValue: _i8.dummyValue( + this, + Invocation.getter(#path), + ), ) as String); @override String get name => (super.noSuchMethod( Invocation.getter(#name), - returnValue: '', + returnValue: _i8.dummyValue( + this, + Invocation.getter(#name), + ), ) as String); @override @@ -428,27 +446,34 @@ class MockXFile extends _i1.Mock implements _i2.XFile { @override _i6.Future readAsString( - {_i8.Encoding? encoding = const _i8.Utf8Codec()}) => + {_i9.Encoding? encoding = const _i9.Utf8Codec()}) => (super.noSuchMethod( Invocation.method( #readAsString, [], {#encoding: encoding}, ), - returnValue: _i6.Future.value(''), + returnValue: _i6.Future.value(_i8.dummyValue( + this, + Invocation.method( + #readAsString, + [], + {#encoding: encoding}, + ), + )), ) as _i6.Future); @override - _i6.Future<_i9.Uint8List> readAsBytes() => (super.noSuchMethod( + _i6.Future<_i10.Uint8List> readAsBytes() => (super.noSuchMethod( Invocation.method( #readAsBytes, [], ), - returnValue: _i6.Future<_i9.Uint8List>.value(_i9.Uint8List(0)), - ) as _i6.Future<_i9.Uint8List>); + returnValue: _i6.Future<_i10.Uint8List>.value(_i10.Uint8List(0)), + ) as _i6.Future<_i10.Uint8List>); @override - _i6.Stream<_i9.Uint8List> openRead([ + _i6.Stream<_i10.Uint8List> openRead([ int? start, int? end, ]) => @@ -460,8 +485,8 @@ class MockXFile extends _i1.Mock implements _i2.XFile { end, ], ), - returnValue: _i6.Stream<_i9.Uint8List>.empty(), - ) as _i6.Stream<_i9.Uint8List>); + returnValue: _i6.Stream<_i10.Uint8List>.empty(), + ) as _i6.Stream<_i10.Uint8List>); @override _i6.Future lastModified() => (super.noSuchMethod( diff --git a/packages/io_library/test/unit/usecase/save_as_raster_image_test.dart b/test/unit/provider/save_as_raster_image_test.dart similarity index 93% rename from packages/io_library/test/unit/usecase/save_as_raster_image_test.dart rename to test/unit/provider/save_as_raster_image_test.dart index 2fb49a39..cb7dffac 100644 --- a/packages/io_library/test/unit/usecase/save_as_raster_image_test.dart +++ b/test/unit/provider/save_as_raster_image_test.dart @@ -1,13 +1,23 @@ +// Dart imports: import 'dart:typed_data'; import 'dart:ui'; +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:io_library/io_library.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:oxidized/oxidized.dart'; +// Project imports: +import 'package:paintroid/core/models/image_meta_data.dart'; +import 'package:paintroid/core/providers/object/file_service.dart'; +import 'package:paintroid/core/providers/object/image_service.dart'; +import 'package:paintroid/core/providers/object/permission_service.dart'; +import 'package:paintroid/core/providers/object/photo_library_service.dart'; +import 'package:paintroid/core/providers/object/save_as_raster_image.dart'; +import 'package:paintroid/core/utils/failure.dart'; +import 'package:paintroid/core/utils/save_image_failure.dart'; import 'save_as_raster_image_test.mocks.dart'; class FakeImage extends Fake implements Image {} diff --git a/packages/io_library/test/unit/usecase/save_as_raster_image_test.mocks.dart b/test/unit/provider/save_as_raster_image_test.mocks.dart similarity index 63% rename from packages/io_library/test/unit/usecase/save_as_raster_image_test.mocks.dart rename to test/unit/provider/save_as_raster_image_test.mocks.dart index 9916e150..588d1a84 100644 --- a/packages/io_library/test/unit/usecase/save_as_raster_image_test.mocks.dart +++ b/test/unit/provider/save_as_raster_image_test.mocks.dart @@ -1,21 +1,35 @@ -// Mocks generated by Mockito 5.4.2 from annotations -// in io_library/test/unit/usecase/save_as_raster_image_test.dart. +// Mocks generated by Mockito 5.4.4 from annotations +// in paintroid/test/unit/provider/save_as_raster_image_test.dart. // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes + +// Dart imports: import 'dart:async' as _i4; -import 'dart:io' as _i7; -import 'dart:typed_data' as _i6; +import 'dart:io' as _i10; +import 'dart:typed_data' as _i7; import 'dart:ui' as _i5; -import 'package:io_library/io_library.dart' as _i3; +// Package imports: import 'package:mockito/mockito.dart' as _i1; import 'package:oxidized/oxidized.dart' as _i2; +// Project imports: +import 'package:paintroid/core/providers/object/file_service.dart' as _i9; +import 'package:paintroid/core/providers/object/image_service.dart' as _i3; +import 'package:paintroid/core/utils/failure.dart' as _i6; + +import 'package:paintroid/core/providers/object/permission_service.dart' + as _i11; +import 'package:paintroid/core/providers/object/photo_library_service.dart' + as _i8; + // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters // ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors @@ -43,25 +57,25 @@ class MockIImageService extends _i1.Mock implements _i3.IImageService { } @override - _i4.Future<_i2.Result<_i5.Image, _i3.Failure>> import( - _i6.Uint8List? fileData) => + _i4.Future<_i2.Result<_i5.Image, _i6.Failure>> import( + _i7.Uint8List? fileData) => (super.noSuchMethod( Invocation.method( #import, [fileData], ), - returnValue: _i4.Future<_i2.Result<_i5.Image, _i3.Failure>>.value( - _FakeResult_0<_i5.Image, _i3.Failure>( + returnValue: _i4.Future<_i2.Result<_i5.Image, _i6.Failure>>.value( + _FakeResult_0<_i5.Image, _i6.Failure>( this, Invocation.method( #import, [fileData], ), )), - ) as _i4.Future<_i2.Result<_i5.Image, _i3.Failure>>); + ) as _i4.Future<_i2.Result<_i5.Image, _i6.Failure>>); @override - _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>> exportAsJpg( + _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>> exportAsJpg( _i5.Image? image, int? quality, ) => @@ -73,8 +87,8 @@ class MockIImageService extends _i1.Mock implements _i3.IImageService { quality, ], ), - returnValue: _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>.value( - _FakeResult_0<_i6.Uint8List, _i3.Failure>( + returnValue: _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>>.value( + _FakeResult_0<_i7.Uint8List, _i6.Failure>( this, Invocation.method( #exportAsJpg, @@ -84,56 +98,56 @@ class MockIImageService extends _i1.Mock implements _i3.IImageService { ], ), )), - ) as _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>); + ) as _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>>); @override - _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>> exportAsPng( + _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>> exportAsPng( _i5.Image? image) => (super.noSuchMethod( Invocation.method( #exportAsPng, [image], ), - returnValue: _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>.value( - _FakeResult_0<_i6.Uint8List, _i3.Failure>( + returnValue: _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>>.value( + _FakeResult_0<_i7.Uint8List, _i6.Failure>( this, Invocation.method( #exportAsPng, [image], ), )), - ) as _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>); + ) as _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>>); @override - _i2.Result<_i6.Uint8List, _i3.Failure> getProjectPreview(String? path) => + _i2.Result<_i7.Uint8List, _i6.Failure> getProjectPreview(String? path) => (super.noSuchMethod( Invocation.method( #getProjectPreview, [path], ), - returnValue: _FakeResult_0<_i6.Uint8List, _i3.Failure>( + returnValue: _FakeResult_0<_i7.Uint8List, _i6.Failure>( this, Invocation.method( #getProjectPreview, [path], ), ), - ) as _i2.Result<_i6.Uint8List, _i3.Failure>); + ) as _i2.Result<_i7.Uint8List, _i6.Failure>); } /// A class which mocks [IPhotoLibraryService]. /// /// See the documentation for Mockito's code generation for more information. class MockIPhotoLibraryService extends _i1.Mock - implements _i3.IPhotoLibraryService { + implements _i8.IPhotoLibraryService { MockIPhotoLibraryService() { _i1.throwOnMissingStub(this); } @override - _i4.Future<_i2.Result<_i2.Unit, _i3.Failure>> save( + _i4.Future<_i2.Result<_i2.Unit, _i6.Failure>> save( String? filename, - _i6.Uint8List? data, + _i7.Uint8List? data, ) => (super.noSuchMethod( Invocation.method( @@ -143,8 +157,8 @@ class MockIPhotoLibraryService extends _i1.Mock data, ], ), - returnValue: _i4.Future<_i2.Result<_i2.Unit, _i3.Failure>>.value( - _FakeResult_0<_i2.Unit, _i3.Failure>( + returnValue: _i4.Future<_i2.Result<_i2.Unit, _i6.Failure>>.value( + _FakeResult_0<_i2.Unit, _i6.Failure>( this, Invocation.method( #save, @@ -154,38 +168,38 @@ class MockIPhotoLibraryService extends _i1.Mock ], ), )), - ) as _i4.Future<_i2.Result<_i2.Unit, _i3.Failure>>); + ) as _i4.Future<_i2.Result<_i2.Unit, _i6.Failure>>); @override - _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>> pick() => + _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>> pick() => (super.noSuchMethod( Invocation.method( #pick, [], ), - returnValue: _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>.value( - _FakeResult_0<_i6.Uint8List, _i3.Failure>( + returnValue: _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>>.value( + _FakeResult_0<_i7.Uint8List, _i6.Failure>( this, Invocation.method( #pick, [], ), )), - ) as _i4.Future<_i2.Result<_i6.Uint8List, _i3.Failure>>); + ) as _i4.Future<_i2.Result<_i7.Uint8List, _i6.Failure>>); } /// A class which mocks [IFileService]. /// /// See the documentation for Mockito's code generation for more information. -class MockIFileService extends _i1.Mock implements _i3.IFileService { +class MockIFileService extends _i1.Mock implements _i9.IFileService { MockIFileService() { _i1.throwOnMissingStub(this); } @override - _i4.Future<_i2.Result<_i7.File, _i3.Failure>> save( + _i4.Future<_i2.Result<_i10.File, _i6.Failure>> save( String? filename, - _i6.Uint8List? data, + _i7.Uint8List? data, ) => (super.noSuchMethod( Invocation.method( @@ -195,8 +209,8 @@ class MockIFileService extends _i1.Mock implements _i3.IFileService { data, ], ), - returnValue: _i4.Future<_i2.Result<_i7.File, _i3.Failure>>.value( - _FakeResult_0<_i7.File, _i3.Failure>( + returnValue: _i4.Future<_i2.Result<_i10.File, _i6.Failure>>.value( + _FakeResult_0<_i10.File, _i6.Failure>( this, Invocation.method( #save, @@ -206,12 +220,12 @@ class MockIFileService extends _i1.Mock implements _i3.IFileService { ], ), )), - ) as _i4.Future<_i2.Result<_i7.File, _i3.Failure>>); + ) as _i4.Future<_i2.Result<_i10.File, _i6.Failure>>); @override - _i4.Future<_i2.Result<_i7.File, _i3.Failure>> saveToApplicationDirectory( + _i4.Future<_i2.Result<_i10.File, _i6.Failure>> saveToApplicationDirectory( String? filename, - _i6.Uint8List? data, + _i7.Uint8List? data, ) => (super.noSuchMethod( Invocation.method( @@ -221,8 +235,8 @@ class MockIFileService extends _i1.Mock implements _i3.IFileService { data, ], ), - returnValue: _i4.Future<_i2.Result<_i7.File, _i3.Failure>>.value( - _FakeResult_0<_i7.File, _i3.Failure>( + returnValue: _i4.Future<_i2.Result<_i10.File, _i6.Failure>>.value( + _FakeResult_0<_i10.File, _i6.Failure>( this, Invocation.method( #saveToApplicationDirectory, @@ -232,39 +246,39 @@ class MockIFileService extends _i1.Mock implements _i3.IFileService { ], ), )), - ) as _i4.Future<_i2.Result<_i7.File, _i3.Failure>>); + ) as _i4.Future<_i2.Result<_i10.File, _i6.Failure>>); @override - _i4.Future<_i2.Result<_i7.File, _i3.Failure>> pick() => (super.noSuchMethod( + _i4.Future<_i2.Result<_i10.File, _i6.Failure>> pick() => (super.noSuchMethod( Invocation.method( #pick, [], ), - returnValue: _i4.Future<_i2.Result<_i7.File, _i3.Failure>>.value( - _FakeResult_0<_i7.File, _i3.Failure>( + returnValue: _i4.Future<_i2.Result<_i10.File, _i6.Failure>>.value( + _FakeResult_0<_i10.File, _i6.Failure>( this, Invocation.method( #pick, [], ), )), - ) as _i4.Future<_i2.Result<_i7.File, _i3.Failure>>); + ) as _i4.Future<_i2.Result<_i10.File, _i6.Failure>>); @override - _i2.Result<_i7.File, _i3.Failure> getFile(String? path) => + _i2.Result<_i10.File, _i6.Failure> getFile(String? path) => (super.noSuchMethod( Invocation.method( #getFile, [path], ), - returnValue: _FakeResult_0<_i7.File, _i3.Failure>( + returnValue: _FakeResult_0<_i10.File, _i6.Failure>( this, Invocation.method( #getFile, [path], ), ), - ) as _i2.Result<_i7.File, _i3.Failure>); + ) as _i2.Result<_i10.File, _i6.Failure>); @override _i4.Future checkIfFileExistsInApplicationDirectory(String? fileName) => @@ -277,29 +291,29 @@ class MockIFileService extends _i1.Mock implements _i3.IFileService { ) as _i4.Future); @override - _i4.Future<_i2.Result<_i7.FileSystemEntity, _i3.Failure>> + _i4.Future<_i2.Result<_i10.FileSystemEntity, _i6.Failure>> deleteFileInApplicationDirectory(String? fileName) => (super.noSuchMethod( Invocation.method( #deleteFileInApplicationDirectory, [fileName], ), - returnValue: - _i4.Future<_i2.Result<_i7.FileSystemEntity, _i3.Failure>>.value( - _FakeResult_0<_i7.FileSystemEntity, _i3.Failure>( + returnValue: _i4 + .Future<_i2.Result<_i10.FileSystemEntity, _i6.Failure>>.value( + _FakeResult_0<_i10.FileSystemEntity, _i6.Failure>( this, Invocation.method( #deleteFileInApplicationDirectory, [fileName], ), )), - ) as _i4.Future<_i2.Result<_i7.FileSystemEntity, _i3.Failure>>); + ) as _i4.Future<_i2.Result<_i10.FileSystemEntity, _i6.Failure>>); } /// A class which mocks [IPermissionService]. /// /// See the documentation for Mockito's code generation for more information. class MockIPermissionService extends _i1.Mock - implements _i3.IPermissionService { + implements _i11.IPermissionService { MockIPermissionService() { _i1.throwOnMissingStub(this); } diff --git a/packages/io_library/test/unit/serialization/command/draw_path_command_serializer_test.dart b/test/unit/serialization/command/draw_path_command_serializer_test.dart similarity index 85% rename from packages/io_library/test/unit/serialization/command/draw_path_command_serializer_test.dart rename to test/unit/serialization/command/draw_path_command_serializer_test.dart index e4e86ea9..fd2b5c58 100644 --- a/packages/io_library/test/unit/serialization/command/draw_path_command_serializer_test.dart +++ b/test/unit/serialization/command/draw_path_command_serializer_test.dart @@ -1,8 +1,15 @@ -import 'package:command/command.dart'; +// Flutter imports: + +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_test/flutter_test.dart'; -import 'package:io_library/io_library.dart'; +// Project imports: +import 'package:paintroid/core/commands/command_implementation/graphic/draw_path_command.dart'; +import 'package:paintroid/core/commands/path_with_action_history.dart'; +import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart'; import '../utils/dummy_command_factory.dart'; import '../utils/dummy_paint_factory.dart'; import '../utils/dummy_path_factory.dart'; diff --git a/packages/io_library/test/unit/serialization/converter/paint_converter_test.dart b/test/unit/serialization/converter/paint_converter_test.dart similarity index 91% rename from packages/io_library/test/unit/serialization/converter/paint_converter_test.dart rename to test/unit/serialization/converter/paint_converter_test.dart index 1be43995..53ff772c 100644 --- a/packages/io_library/test/unit/serialization/converter/paint_converter_test.dart +++ b/test/unit/serialization/converter/paint_converter_test.dart @@ -1,7 +1,12 @@ +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_test/flutter_test.dart'; -import 'package:io_library/io_library.dart'; +// Project imports: +import 'package:paintroid/core/json_serialization/converter/paint_converter.dart'; +import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart'; import '../utils/dummy_paint_factory.dart'; void main() { diff --git a/packages/io_library/test/unit/serialization/converter/path_action_converter_test.dart b/test/unit/serialization/converter/path_action_converter_test.dart similarity index 86% rename from packages/io_library/test/unit/serialization/converter/path_action_converter_test.dart rename to test/unit/serialization/converter/path_action_converter_test.dart index 4fd6e0ee..75312ebb 100644 --- a/packages/io_library/test/unit/serialization/converter/path_action_converter_test.dart +++ b/test/unit/serialization/converter/path_action_converter_test.dart @@ -1,6 +1,9 @@ -import 'package:command/command.dart'; +// Package imports: import 'package:flutter_test/flutter_test.dart'; -import 'package:io_library/io_library.dart'; + +// Project imports: +import 'package:paintroid/core/commands/path_with_action_history.dart'; +import 'package:paintroid/core/json_serialization/converter/path_action_converter.dart'; void main() { const PathActionConverter converter = PathActionConverter(); diff --git a/packages/io_library/test/unit/serialization/converter/path_with_action_history_converter_test.dart b/test/unit/serialization/converter/path_with_action_history_converter_test.dart similarity index 84% rename from packages/io_library/test/unit/serialization/converter/path_with_action_history_converter_test.dart rename to test/unit/serialization/converter/path_with_action_history_converter_test.dart index 1167e2be..3b1d13b4 100644 --- a/packages/io_library/test/unit/serialization/converter/path_with_action_history_converter_test.dart +++ b/test/unit/serialization/converter/path_with_action_history_converter_test.dart @@ -1,7 +1,9 @@ -import 'package:command/command.dart'; +// Package imports: import 'package:flutter_test/flutter_test.dart'; -import 'package:io_library/io_library.dart'; +// Project imports: +import 'package:paintroid/core/commands/path_with_action_history.dart'; +import 'package:paintroid/core/json_serialization/converter/path_with_action_history_converter.dart'; import '../utils/dummy_path_factory.dart'; void main() { diff --git a/packages/io_library/test/unit/serialization/image/catrobat_image_serializer_test.dart b/test/unit/serialization/image/catrobat_image_serializer_test.dart similarity index 85% rename from packages/io_library/test/unit/serialization/image/catrobat_image_serializer_test.dart rename to test/unit/serialization/image/catrobat_image_serializer_test.dart index 10b0cbbd..e77fc830 100644 --- a/packages/io_library/test/unit/serialization/image/catrobat_image_serializer_test.dart +++ b/test/unit/serialization/image/catrobat_image_serializer_test.dart @@ -1,9 +1,14 @@ +// Dart imports: import 'dart:typed_data'; -import 'package:command/command.dart'; +// Package imports: import 'package:flutter_test/flutter_test.dart'; -import 'package:io_library/io_library.dart'; +// Project imports: +import 'package:paintroid/core/commands/command_implementation/command.dart'; +import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart'; +import 'package:paintroid/core/json_serialization/versioning/version_strategy.dart'; +import 'package:paintroid/core/models/catrobat_image.dart'; import '../utils/dummy_command_factory.dart'; import '../utils/dummy_version_strategy.dart'; diff --git a/packages/io_library/test/unit/serialization/utils/dummy_command_factory.dart b/test/unit/serialization/utils/dummy_command_factory.dart similarity index 78% rename from packages/io_library/test/unit/serialization/utils/dummy_command_factory.dart rename to test/unit/serialization/utils/dummy_command_factory.dart index 2812ce77..78bc30ed 100644 --- a/packages/io_library/test/unit/serialization/utils/dummy_command_factory.dart +++ b/test/unit/serialization/utils/dummy_command_factory.dart @@ -1,8 +1,13 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; -import 'package:io_library/io_library.dart'; - +// Project imports: +import 'package:paintroid/core/commands/command_factory/command_factory.dart'; +import 'package:paintroid/core/commands/command_implementation/command.dart'; +import 'package:paintroid/core/commands/command_implementation/graphic/draw_path_command.dart'; +import 'package:paintroid/core/commands/path_with_action_history.dart'; +import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart'; +import 'package:paintroid/core/json_serialization/versioning/version_strategy.dart'; import 'dummy_paint_factory.dart'; import 'dummy_path_factory.dart'; import 'dummy_version_strategy.dart'; diff --git a/packages/io_library/test/unit/serialization/utils/dummy_paint_factory.dart b/test/unit/serialization/utils/dummy_paint_factory.dart similarity index 90% rename from packages/io_library/test/unit/serialization/utils/dummy_paint_factory.dart rename to test/unit/serialization/utils/dummy_paint_factory.dart index dc53ffa4..3f04da4a 100644 --- a/packages/io_library/test/unit/serialization/utils/dummy_paint_factory.dart +++ b/test/unit/serialization/utils/dummy_paint_factory.dart @@ -1,5 +1,8 @@ +// Flutter imports: import 'package:flutter/material.dart'; -import 'package:io_library/io_library.dart'; + +// Project imports: +import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart'; class DummyPaintFactory { static Paint createPaint({int version = Version.v1}) { diff --git a/packages/io_library/test/unit/serialization/utils/dummy_path_factory.dart b/test/unit/serialization/utils/dummy_path_factory.dart similarity index 83% rename from packages/io_library/test/unit/serialization/utils/dummy_path_factory.dart rename to test/unit/serialization/utils/dummy_path_factory.dart index 2f19f5bb..5d595fcb 100644 --- a/packages/io_library/test/unit/serialization/utils/dummy_path_factory.dart +++ b/test/unit/serialization/utils/dummy_path_factory.dart @@ -1,4 +1,5 @@ -import 'package:command/command.dart'; +// Project imports: +import 'package:paintroid/core/commands/path_with_action_history.dart'; class DummyPathFactory { static PathWithActionHistory createPathWithActionHistory( diff --git a/packages/io_library/test/unit/serialization/utils/dummy_version_strategy.dart b/test/unit/serialization/utils/dummy_version_strategy.dart similarity index 70% rename from packages/io_library/test/unit/serialization/utils/dummy_version_strategy.dart rename to test/unit/serialization/utils/dummy_version_strategy.dart index b0ca626f..c029e83c 100644 --- a/packages/io_library/test/unit/serialization/utils/dummy_version_strategy.dart +++ b/test/unit/serialization/utils/dummy_version_strategy.dart @@ -1,4 +1,6 @@ -import 'package:io_library/io_library.dart'; +// Project imports: +import 'package:paintroid/core/json_serialization/versioning/serializer_version.dart'; +import 'package:paintroid/core/json_serialization/versioning/version_strategy.dart'; class DummyVersionStrategy implements IVersionStrategy { final int drawPathCommandVersion; diff --git a/packages/tools/test/unit/brush_tool_state_test.dart b/test/unit/tools/brush_tool_state_test.dart similarity index 89% rename from packages/tools/test/unit/brush_tool_state_test.dart rename to test/unit/tools/brush_tool_state_test.dart index 0f48b5c6..a3d2686a 100644 --- a/packages/tools/test/unit/brush_tool_state_test.dart +++ b/test/unit/tools/brush_tool_state_test.dart @@ -1,9 +1,14 @@ -import 'package:command/graphic_factory/graphic_factory.dart'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; -import 'package:tools/tools.dart'; + +// Project imports: +import 'package:paintroid/core/commands/graphic_factory/graphic_factory.dart'; +import 'package:paintroid/core/providers/state/tools/brush/brush_tool_state_provider.dart'; class MockGraphicFactory extends Mock implements GraphicFactory {} diff --git a/packages/tools/test/unit/brush_tool_test.dart b/test/unit/tools/brush_tool_test.dart similarity index 60% rename from packages/tools/test/unit/brush_tool_test.dart rename to test/unit/tools/brush_tool_test.dart index 06a21b60..8884f7ac 100644 --- a/packages/tools/test/unit/brush_tool_test.dart +++ b/test/unit/tools/brush_tool_test.dart @@ -1,14 +1,23 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; +// Package imports: import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; -import 'package:tools/tools.dart'; +// Project imports: +import 'package:paintroid/core/commands/command_factory/command_factory.dart'; +import 'package:paintroid/core/commands/command_implementation/graphic/draw_path_command.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager.dart'; +import 'package:paintroid/core/commands/graphic_factory/graphic_factory.dart'; +import 'package:paintroid/core/commands/path_with_action_history.dart'; +import 'package:paintroid/core/enums/tool_types.dart'; +import 'package:paintroid/core/tools/implementation/brush_tool.dart'; import 'brush_tool_test.mocks.dart'; @GenerateMocks([ + Path, PathWithActionHistory, Offset, DrawPathCommand, @@ -17,7 +26,8 @@ import 'brush_tool_test.mocks.dart'; GraphicFactory, ]) void main() { - late MockPathWithActionHistory mockPath; + late MockPathWithActionHistory mockPathWithActionHistory; + late MockPath mockPath; late MockOffset mockOffset; late MockDrawPathCommand mockDrawPathCommand; late MockCommandManager mockCommandManager; @@ -25,7 +35,7 @@ void main() { late MockGraphicFactory mockGraphicFactory; late Offset testOffset; - late PathWithActionHistory testPath; + late PathWithActionHistory testPathWithActionHistory; late Paint testPaint; late Paint testPaintCopied; late DrawPathCommand testDrawPathCommand; @@ -33,7 +43,8 @@ void main() { late BrushTool sut; setUp(() { - mockPath = MockPathWithActionHistory(); + mockPathWithActionHistory = MockPathWithActionHistory(); + mockPath = MockPath(); mockOffset = MockOffset(); mockDrawPathCommand = MockDrawPathCommand(); mockCommandManager = MockCommandManager(); @@ -41,14 +52,13 @@ void main() { mockGraphicFactory = MockGraphicFactory(); testOffset = const Offset(12, 13); - testPath = PathWithActionHistory(); + testPathWithActionHistory = PathWithActionHistory(); testPaint = Paint(); testPaintCopied = Paint(); - testDrawPathCommand = DrawPathCommand(testPath, testPaint); + testDrawPathCommand = DrawPathCommand(testPathWithActionHistory, testPaint); sut = BrushTool( paint: testPaint, - type: ToolType.BRUSH, commandManager: mockCommandManager, commandFactory: mockCommandFactory, graphicFactory: mockGraphicFactory, @@ -58,7 +68,7 @@ void main() { group('On tap down event', () { test('Should create one DrawPathCommand with a new Path', () { when(mockGraphicFactory.createPathWithActionHistory()) - .thenReturn(testPath); + .thenReturn(testPathWithActionHistory); when(mockGraphicFactory.copyPaint(testPaint)).thenReturn(testPaintCopied); when(mockCommandFactory.createDrawPathCommand(any, any)) .thenReturn(testDrawPathCommand); @@ -67,7 +77,7 @@ void main() { verify(mockGraphicFactory.createPathWithActionHistory()).called(1); verify(mockGraphicFactory.copyPaint(testPaint)).called(1); verify(mockCommandFactory.createDrawPathCommand( - testPath, testPaintCopied)) + testPathWithActionHistory, testPaintCopied)) .called(1); verifyNoMoreInteractions(mockCommandFactory); verifyNoMoreInteractions(mockGraphicFactory); @@ -75,19 +85,21 @@ void main() { test('Should move Path to point supplied in event', () { when(mockGraphicFactory.createPathWithActionHistory()) - .thenReturn(mockPath); + .thenReturn(mockPathWithActionHistory); when(mockGraphicFactory.copyPaint(testPaint)).thenReturn(testPaintCopied); - when(mockPath.moveTo(testOffset.dx, testOffset.dy)).thenReturn(null); + when(mockPathWithActionHistory.moveTo(testOffset.dx, testOffset.dy)) + .thenReturn(null); when(mockCommandFactory.createDrawPathCommand(any, any)) .thenReturn(testDrawPathCommand); sut.onDown(testOffset); - verify(mockPath.moveTo(testOffset.dx, testOffset.dy)).called(1); - verifyNoMoreInteractions(mockPath); + verify(mockPathWithActionHistory.moveTo(testOffset.dx, testOffset.dy)) + .called(1); + verifyNoMoreInteractions(mockPathWithActionHistory); }); test('Should not interact with DrawPathCommand', () { when(mockGraphicFactory.createPathWithActionHistory()) - .thenReturn(testPath); + .thenReturn(testPathWithActionHistory); when(mockGraphicFactory.copyPaint(testPaint)).thenReturn(testPaintCopied); when(mockCommandFactory.createDrawPathCommand(any, any)) .thenReturn(mockDrawPathCommand); @@ -98,41 +110,52 @@ void main() { group('On drag event', () { test('Should not add DrawPathCommand to CommandManager', () { - sut.pathToDraw = testPath; + sut.pathToDraw = testPathWithActionHistory; sut.onDrag(testOffset); verifyZeroInteractions(mockCommandManager); verifyZeroInteractions(mockCommandFactory); }); test('Should extend Path to coordinate passed in event', () { - sut.pathToDraw = mockPath; - when(mockPath.lineTo(testOffset.dx, testOffset.dy)).thenReturn(null); + sut.pathToDraw = mockPathWithActionHistory; + when(mockPathWithActionHistory.lineTo(testOffset.dx, testOffset.dy)) + .thenReturn(null); sut.onDrag(testOffset); - verify(mockPath.lineTo(testOffset.dx, testOffset.dy)).called(1); - verifyNoMoreInteractions(mockPath); + verify(mockPathWithActionHistory.lineTo(testOffset.dx, testOffset.dy)) + .called(1); + verifyNoMoreInteractions(mockPathWithActionHistory); }); }); group('On tap up event', () { test('Should not interact with coordinate', () { - sut.pathToDraw = testPath; + sut.pathToDraw = testPathWithActionHistory; sut.onUp(mockOffset); verifyZeroInteractions(mockOffset); }); test('Should not add DrawPathCommand to CommandManager', () { - sut.pathToDraw = testPath; + sut.pathToDraw = testPathWithActionHistory; sut.onUp(null); verifyZeroInteractions(mockCommandManager); verifyZeroInteractions(mockCommandFactory); }); test('Should close Path if bound size is zero', () { - sut.pathToDraw = mockPath; + sut.pathToDraw = mockPathWithActionHistory; + when(mockPathWithActionHistory.path).thenReturn(mockPath); when(mockPath.getBounds()).thenReturn(Rect.zero); sut.onUp(null); - verifyInOrder([mockPath.getBounds(), mockPath.close()]); - verifyNoMoreInteractions(mockPath); + verifyInOrder([ + mockPathWithActionHistory.path, + mockPath.getBounds(), + mockPathWithActionHistory.close() + ]); + verifyNoMoreInteractions(mockPathWithActionHistory); }); }); + + test('Should return Brush as ToolType', () { + expect(sut.type, ToolType.BRUSH); + }); } diff --git a/packages/tools/test/unit/brush_tool_test.mocks.dart b/test/unit/tools/brush_tool_test.mocks.dart similarity index 88% rename from packages/tools/test/unit/brush_tool_test.mocks.dart rename to test/unit/tools/brush_tool_test.mocks.dart index 381528e4..fb5bcddc 100644 --- a/packages/tools/test/unit/brush_tool_test.mocks.dart +++ b/test/unit/tools/brush_tool_test.mocks.dart @@ -1,18 +1,39 @@ -// Mocks generated by Mockito 5.4.2 from annotations -// in tools/test/unit/brush_tool_test.dart. +// Mocks generated by Mockito 5.4.4 from annotations +// in paintroid/test/unit/tools/brush_tool_test.dart. // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:typed_data' as _i4; + +// Dart imports: +import 'dart:typed_data' as _i5; import 'dart:ui' as _i2; -import 'package:command/command.dart' as _i3; +// Package imports: import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i6; + +// Project imports: +import 'package:paintroid/core/commands/path_with_action_history.dart' as _i3; + +import 'package:paintroid/core/commands/command_factory/command_factory.dart' + as _i10; +import 'package:paintroid/core/commands/command_implementation/command.dart' + as _i8; +import 'package:paintroid/core/commands/command_implementation/graphic/draw_path_command.dart' + as _i4; +import 'package:paintroid/core/commands/command_implementation/graphic/graphic_command.dart' + as _i9; +import 'package:paintroid/core/commands/command_manager/command_manager.dart' + as _i7; +import 'package:paintroid/core/commands/graphic_factory/graphic_factory.dart' + as _i11; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters // ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors @@ -82,7 +103,7 @@ class _FakePaint_5 extends _i1.SmartFake implements _i2.Paint { } class _FakeDrawPathCommand_6 extends _i1.SmartFake - implements _i3.DrawPathCommand { + implements _i4.DrawPathCommand { _FakeDrawPathCommand_6( Object parent, Invocation parentInvocation, @@ -113,21 +134,14 @@ class _FakeCanvas_8 extends _i1.SmartFake implements _i2.Canvas { ); } -/// A class which mocks [PathWithActionHistory]. +/// A class which mocks [Path]. /// /// See the documentation for Mockito's code generation for more information. -class MockPathWithActionHistory extends _i1.Mock - implements _i3.PathWithActionHistory { - MockPathWithActionHistory() { +class MockPath extends _i1.Mock implements _i2.Path { + MockPath() { _i1.throwOnMissingStub(this); } - @override - List<_i3.PathAction> get actions => (super.noSuchMethod( - Invocation.getter(#actions), - returnValue: <_i3.PathAction>[], - ) as List<_i3.PathAction>); - @override _i2.PathFillType get fillType => (super.noSuchMethod( Invocation.getter(#fillType), @@ -160,50 +174,32 @@ class MockPathWithActionHistory extends _i1.Mock ); @override - void lineTo( - double? x, - double? y, + void relativeMoveTo( + double? dx, + double? dy, ) => super.noSuchMethod( Invocation.method( - #lineTo, + #relativeMoveTo, [ - x, - y, + dx, + dy, ], ), returnValueForMissingStub: null, ); @override - void close() => super.noSuchMethod( - Invocation.method( - #close, - [], - ), - returnValueForMissingStub: null, - ); - - @override - Map toJson() => (super.noSuchMethod( - Invocation.method( - #toJson, - [], - ), - returnValue: {}, - ) as Map); - - @override - void relativeMoveTo( - double? dx, - double? dy, + void lineTo( + double? x, + double? y, ) => super.noSuchMethod( Invocation.method( - #relativeMoveTo, + #lineTo, [ - dx, - dy, + x, + y, ], ), returnValueForMissingStub: null, @@ -486,7 +482,7 @@ class MockPathWithActionHistory extends _i1.Mock void addPath( _i2.Path? path, _i2.Offset? offset, { - _i4.Float64List? matrix4, + _i5.Float64List? matrix4, }) => super.noSuchMethod( Invocation.method( @@ -504,7 +500,7 @@ class MockPathWithActionHistory extends _i1.Mock void extendWithPath( _i2.Path? path, _i2.Offset? offset, { - _i4.Float64List? matrix4, + _i5.Float64List? matrix4, }) => super.noSuchMethod( Invocation.method( @@ -518,6 +514,15 @@ class MockPathWithActionHistory extends _i1.Mock returnValueForMissingStub: null, ); + @override + void close() => super.noSuchMethod( + Invocation.method( + #close, + [], + ), + returnValueForMissingStub: null, + ); + @override void reset() => super.noSuchMethod( Invocation.method( @@ -552,7 +557,7 @@ class MockPathWithActionHistory extends _i1.Mock ) as _i2.Path); @override - _i2.Path transform(_i4.Float64List? matrix4) => (super.noSuchMethod( + _i2.Path transform(_i5.Float64List? matrix4) => (super.noSuchMethod( Invocation.method( #transform, [matrix4], @@ -600,6 +605,81 @@ class MockPathWithActionHistory extends _i1.Mock ) as _i2.PathMetrics); } +/// A class which mocks [PathWithActionHistory]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockPathWithActionHistory extends _i1.Mock + implements _i3.PathWithActionHistory { + MockPathWithActionHistory() { + _i1.throwOnMissingStub(this); + } + + @override + _i2.Path get path => (super.noSuchMethod( + Invocation.getter(#path), + returnValue: _FakePath_0( + this, + Invocation.getter(#path), + ), + ) as _i2.Path); + + @override + List<_i3.PathAction> get actions => (super.noSuchMethod( + Invocation.getter(#actions), + returnValue: <_i3.PathAction>[], + ) as List<_i3.PathAction>); + + @override + void moveTo( + double? x, + double? y, + ) => + super.noSuchMethod( + Invocation.method( + #moveTo, + [ + x, + y, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void lineTo( + double? x, + double? y, + ) => + super.noSuchMethod( + Invocation.method( + #lineTo, + [ + x, + y, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void close() => super.noSuchMethod( + Invocation.method( + #close, + [], + ), + returnValueForMissingStub: null, + ); + + @override + Map toJson() => (super.noSuchMethod( + Invocation.method( + #toJson, + [], + ), + returnValue: {}, + ) as Map); +} + /// A class which mocks [Offset]. /// /// See the documentation for Mockito's code generation for more information. @@ -860,7 +940,7 @@ class MockOffset extends _i1.Mock implements _i2.Offset { /// A class which mocks [DrawPathCommand]. /// /// See the documentation for Mockito's code generation for more information. -class MockDrawPathCommand extends _i1.Mock implements _i3.DrawPathCommand { +class MockDrawPathCommand extends _i1.Mock implements _i4.DrawPathCommand { MockDrawPathCommand() { _i1.throwOnMissingStub(this); } @@ -868,7 +948,10 @@ class MockDrawPathCommand extends _i1.Mock implements _i3.DrawPathCommand { @override String get type => (super.noSuchMethod( Invocation.getter(#type), - returnValue: '', + returnValue: _i6.dummyValue( + this, + Invocation.getter(#type), + ), ) as String); @override @@ -923,16 +1006,16 @@ class MockDrawPathCommand extends _i1.Mock implements _i3.DrawPathCommand { /// A class which mocks [CommandManager]. /// /// See the documentation for Mockito's code generation for more information. -class MockCommandManager extends _i1.Mock implements _i3.CommandManager { +class MockCommandManager extends _i1.Mock implements _i7.CommandManager { MockCommandManager() { _i1.throwOnMissingStub(this); } @override - Iterable<_i3.Command> get history => (super.noSuchMethod( + Iterable<_i8.Command> get history => (super.noSuchMethod( Invocation.getter(#history), - returnValue: <_i3.Command>[], - ) as Iterable<_i3.Command>); + returnValue: <_i8.Command>[], + ) as Iterable<_i8.Command>); @override int get count => (super.noSuchMethod( @@ -941,7 +1024,7 @@ class MockCommandManager extends _i1.Mock implements _i3.CommandManager { ) as int); @override - void addGraphicCommand(_i3.GraphicCommand? command) => super.noSuchMethod( + void addGraphicCommand(_i9.GraphicCommand? command) => super.noSuchMethod( Invocation.method( #addGraphicCommand, [command], @@ -977,7 +1060,7 @@ class MockCommandManager extends _i1.Mock implements _i3.CommandManager { ); @override - void clearHistory({Iterable<_i3.Command>? newCommands}) => super.noSuchMethod( + void clearHistory({Iterable<_i8.Command>? newCommands}) => super.noSuchMethod( Invocation.method( #clearHistory, [], @@ -990,13 +1073,13 @@ class MockCommandManager extends _i1.Mock implements _i3.CommandManager { /// A class which mocks [CommandFactory]. /// /// See the documentation for Mockito's code generation for more information. -class MockCommandFactory extends _i1.Mock implements _i3.CommandFactory { +class MockCommandFactory extends _i1.Mock implements _i10.CommandFactory { MockCommandFactory() { _i1.throwOnMissingStub(this); } @override - _i3.DrawPathCommand createDrawPathCommand( + _i4.DrawPathCommand createDrawPathCommand( _i3.PathWithActionHistory? path, _i2.Paint? paint, ) => @@ -1018,13 +1101,13 @@ class MockCommandFactory extends _i1.Mock implements _i3.CommandFactory { ], ), ), - ) as _i3.DrawPathCommand); + ) as _i4.DrawPathCommand); } /// A class which mocks [GraphicFactory]. /// /// See the documentation for Mockito's code generation for more information. -class MockGraphicFactory extends _i1.Mock implements _i3.GraphicFactory { +class MockGraphicFactory extends _i1.Mock implements _i11.GraphicFactory { MockGraphicFactory() { _i1.throwOnMissingStub(this); } diff --git a/test/unit/tools/eraser_tool_test.dart b/test/unit/tools/eraser_tool_test.dart new file mode 100644 index 00000000..3d2bec59 --- /dev/null +++ b/test/unit/tools/eraser_tool_test.dart @@ -0,0 +1,44 @@ +// Dart imports: +import 'dart:ui'; + +// Package imports: +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; + +// Project imports: +import 'package:paintroid/core/commands/command_factory/command_factory.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager.dart'; +import 'package:paintroid/core/commands/graphic_factory/graphic_factory.dart'; +import 'package:paintroid/core/enums/tool_types.dart'; +import 'package:paintroid/core/tools/implementation/eraser_tool.dart'; +import 'eraser_tool_test.mocks.dart'; + +@GenerateMocks([ + Paint, + CommandManager, + CommandFactory, + GraphicFactory, +]) +void main() { + late MockPaint mockPaint; + late MockCommandFactory mockCommandFactory; + late MockCommandManager mockCommandManager; + late MockGraphicFactory mockGraphicFactory; + late EraserTool sut; + setUp(() { + mockPaint = MockPaint(); + mockCommandFactory = MockCommandFactory(); + mockCommandManager = MockCommandManager(); + mockGraphicFactory = MockGraphicFactory(); + sut = EraserTool( + paint: mockPaint, + commandFactory: mockCommandFactory, + commandManager: mockCommandManager, + graphicFactory: mockGraphicFactory, + ); + }); + + test('Should return Eraser as ToolType', () { + expect(sut.type, ToolType.ERASER); + }); +} diff --git a/test/unit/tools/eraser_tool_test.mocks.dart b/test/unit/tools/eraser_tool_test.mocks.dart new file mode 100644 index 00000000..dad8b904 --- /dev/null +++ b/test/unit/tools/eraser_tool_test.mocks.dart @@ -0,0 +1,488 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in paintroid/test/unit/tools/eraser_tool_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes + +// Dart imports: +import 'dart:ui' as _i2; + +// Package imports: +import 'package:mockito/mockito.dart' as _i1; + +// Project imports: +import 'package:paintroid/core/commands/path_with_action_history.dart' as _i4; + +import 'package:paintroid/core/commands/command_factory/command_factory.dart' + as _i8; +import 'package:paintroid/core/commands/command_implementation/command.dart' + as _i6; +import 'package:paintroid/core/commands/command_implementation/graphic/draw_path_command.dart' + as _i3; +import 'package:paintroid/core/commands/command_implementation/graphic/graphic_command.dart' + as _i7; +import 'package:paintroid/core/commands/command_manager/command_manager.dart' + as _i5; +import 'package:paintroid/core/commands/graphic_factory/graphic_factory.dart' + as _i9; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeColor_0 extends _i1.SmartFake implements _i2.Color { + _FakeColor_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeDrawPathCommand_1 extends _i1.SmartFake + implements _i3.DrawPathCommand { + _FakeDrawPathCommand_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePaint_2 extends _i1.SmartFake implements _i2.Paint { + _FakePaint_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePathWithActionHistory_3 extends _i1.SmartFake + implements _i4.PathWithActionHistory { + _FakePathWithActionHistory_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePictureRecorder_4 extends _i1.SmartFake + implements _i2.PictureRecorder { + _FakePictureRecorder_4( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCanvas_5 extends _i1.SmartFake implements _i2.Canvas { + _FakeCanvas_5( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [Paint]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockPaint extends _i1.Mock implements _i2.Paint { + MockPaint() { + _i1.throwOnMissingStub(this); + } + + @override + bool get isAntiAlias => (super.noSuchMethod( + Invocation.getter(#isAntiAlias), + returnValue: false, + ) as bool); + + @override + set isAntiAlias(bool? value) => super.noSuchMethod( + Invocation.setter( + #isAntiAlias, + value, + ), + returnValueForMissingStub: null, + ); + + @override + _i2.Color get color => (super.noSuchMethod( + Invocation.getter(#color), + returnValue: _FakeColor_0( + this, + Invocation.getter(#color), + ), + ) as _i2.Color); + + @override + set color(_i2.Color? value) => super.noSuchMethod( + Invocation.setter( + #color, + value, + ), + returnValueForMissingStub: null, + ); + + @override + _i2.BlendMode get blendMode => (super.noSuchMethod( + Invocation.getter(#blendMode), + returnValue: _i2.BlendMode.clear, + ) as _i2.BlendMode); + + @override + set blendMode(_i2.BlendMode? value) => super.noSuchMethod( + Invocation.setter( + #blendMode, + value, + ), + returnValueForMissingStub: null, + ); + + @override + _i2.PaintingStyle get style => (super.noSuchMethod( + Invocation.getter(#style), + returnValue: _i2.PaintingStyle.fill, + ) as _i2.PaintingStyle); + + @override + set style(_i2.PaintingStyle? value) => super.noSuchMethod( + Invocation.setter( + #style, + value, + ), + returnValueForMissingStub: null, + ); + + @override + double get strokeWidth => (super.noSuchMethod( + Invocation.getter(#strokeWidth), + returnValue: 0.0, + ) as double); + + @override + set strokeWidth(double? value) => super.noSuchMethod( + Invocation.setter( + #strokeWidth, + value, + ), + returnValueForMissingStub: null, + ); + + @override + _i2.StrokeCap get strokeCap => (super.noSuchMethod( + Invocation.getter(#strokeCap), + returnValue: _i2.StrokeCap.butt, + ) as _i2.StrokeCap); + + @override + set strokeCap(_i2.StrokeCap? value) => super.noSuchMethod( + Invocation.setter( + #strokeCap, + value, + ), + returnValueForMissingStub: null, + ); + + @override + _i2.StrokeJoin get strokeJoin => (super.noSuchMethod( + Invocation.getter(#strokeJoin), + returnValue: _i2.StrokeJoin.miter, + ) as _i2.StrokeJoin); + + @override + set strokeJoin(_i2.StrokeJoin? value) => super.noSuchMethod( + Invocation.setter( + #strokeJoin, + value, + ), + returnValueForMissingStub: null, + ); + + @override + double get strokeMiterLimit => (super.noSuchMethod( + Invocation.getter(#strokeMiterLimit), + returnValue: 0.0, + ) as double); + + @override + set strokeMiterLimit(double? value) => super.noSuchMethod( + Invocation.setter( + #strokeMiterLimit, + value, + ), + returnValueForMissingStub: null, + ); + + @override + set maskFilter(_i2.MaskFilter? value) => super.noSuchMethod( + Invocation.setter( + #maskFilter, + value, + ), + returnValueForMissingStub: null, + ); + + @override + _i2.FilterQuality get filterQuality => (super.noSuchMethod( + Invocation.getter(#filterQuality), + returnValue: _i2.FilterQuality.none, + ) as _i2.FilterQuality); + + @override + set filterQuality(_i2.FilterQuality? value) => super.noSuchMethod( + Invocation.setter( + #filterQuality, + value, + ), + returnValueForMissingStub: null, + ); + + @override + set shader(_i2.Shader? value) => super.noSuchMethod( + Invocation.setter( + #shader, + value, + ), + returnValueForMissingStub: null, + ); + + @override + set colorFilter(_i2.ColorFilter? value) => super.noSuchMethod( + Invocation.setter( + #colorFilter, + value, + ), + returnValueForMissingStub: null, + ); + + @override + set imageFilter(_i2.ImageFilter? value) => super.noSuchMethod( + Invocation.setter( + #imageFilter, + value, + ), + returnValueForMissingStub: null, + ); + + @override + bool get invertColors => (super.noSuchMethod( + Invocation.getter(#invertColors), + returnValue: false, + ) as bool); + + @override + set invertColors(bool? value) => super.noSuchMethod( + Invocation.setter( + #invertColors, + value, + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [CommandManager]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCommandManager extends _i1.Mock implements _i5.CommandManager { + MockCommandManager() { + _i1.throwOnMissingStub(this); + } + + @override + Iterable<_i6.Command> get history => (super.noSuchMethod( + Invocation.getter(#history), + returnValue: <_i6.Command>[], + ) as Iterable<_i6.Command>); + + @override + int get count => (super.noSuchMethod( + Invocation.getter(#count), + returnValue: 0, + ) as int); + + @override + void addGraphicCommand(_i7.GraphicCommand? command) => super.noSuchMethod( + Invocation.method( + #addGraphicCommand, + [command], + ), + returnValueForMissingStub: null, + ); + + @override + void executeLastCommand(_i2.Canvas? canvas) => super.noSuchMethod( + Invocation.method( + #executeLastCommand, + [canvas], + ), + returnValueForMissingStub: null, + ); + + @override + void executeAllCommands(_i2.Canvas? canvas) => super.noSuchMethod( + Invocation.method( + #executeAllCommands, + [canvas], + ), + returnValueForMissingStub: null, + ); + + @override + void discardLastCommand() => super.noSuchMethod( + Invocation.method( + #discardLastCommand, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void clearHistory({Iterable<_i6.Command>? newCommands}) => super.noSuchMethod( + Invocation.method( + #clearHistory, + [], + {#newCommands: newCommands}, + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [CommandFactory]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCommandFactory extends _i1.Mock implements _i8.CommandFactory { + MockCommandFactory() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.DrawPathCommand createDrawPathCommand( + _i4.PathWithActionHistory? path, + _i2.Paint? paint, + ) => + (super.noSuchMethod( + Invocation.method( + #createDrawPathCommand, + [ + path, + paint, + ], + ), + returnValue: _FakeDrawPathCommand_1( + this, + Invocation.method( + #createDrawPathCommand, + [ + path, + paint, + ], + ), + ), + ) as _i3.DrawPathCommand); +} + +/// A class which mocks [GraphicFactory]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockGraphicFactory extends _i1.Mock implements _i9.GraphicFactory { + MockGraphicFactory() { + _i1.throwOnMissingStub(this); + } + + @override + _i2.Paint createPaint() => (super.noSuchMethod( + Invocation.method( + #createPaint, + [], + ), + returnValue: _FakePaint_2( + this, + Invocation.method( + #createPaint, + [], + ), + ), + ) as _i2.Paint); + + @override + _i4.PathWithActionHistory createPathWithActionHistory() => + (super.noSuchMethod( + Invocation.method( + #createPathWithActionHistory, + [], + ), + returnValue: _FakePathWithActionHistory_3( + this, + Invocation.method( + #createPathWithActionHistory, + [], + ), + ), + ) as _i4.PathWithActionHistory); + + @override + _i2.PictureRecorder createPictureRecorder() => (super.noSuchMethod( + Invocation.method( + #createPictureRecorder, + [], + ), + returnValue: _FakePictureRecorder_4( + this, + Invocation.method( + #createPictureRecorder, + [], + ), + ), + ) as _i2.PictureRecorder); + + @override + _i2.Canvas createCanvasWithRecorder(_i2.PictureRecorder? recorder) => + (super.noSuchMethod( + Invocation.method( + #createCanvasWithRecorder, + [recorder], + ), + returnValue: _FakeCanvas_5( + this, + Invocation.method( + #createCanvasWithRecorder, + [recorder], + ), + ), + ) as _i2.Canvas); + + @override + _i2.Paint copyPaint(_i2.Paint? original) => (super.noSuchMethod( + Invocation.method( + #copyPaint, + [original], + ), + returnValue: _FakePaint_2( + this, + Invocation.method( + #copyPaint, + [original], + ), + ), + ) as _i2.Paint); +} diff --git a/packages/tools/test/unit/hand_tool_test.dart b/test/unit/tools/hand_tool_test.dart similarity index 80% rename from packages/tools/test/unit/hand_tool_test.dart rename to test/unit/tools/hand_tool_test.dart index 8bb28a7b..65e9d17c 100644 --- a/packages/tools/test/unit/hand_tool_test.dart +++ b/test/unit/tools/hand_tool_test.dart @@ -1,11 +1,16 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; +// Package imports: import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; -import 'package:tools/tools.dart'; +// Project imports: +import 'package:paintroid/core/commands/command_factory/command_factory.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager.dart'; +import 'package:paintroid/core/enums/tool_types.dart'; +import 'package:paintroid/core/tools/implementation/hand_tool.dart'; import 'hand_tool_test.mocks.dart'; @GenerateMocks([ @@ -30,7 +35,6 @@ void main() { paint: mockPaint, commandFactory: mockCommandFactory, commandManager: mockCommandManager, - type: ToolType.HAND, ); }); @@ -67,4 +71,8 @@ void main() { verifyNoMoreInteractions(mockCommandManager); }); }); + + test('Should return Hand as ToolType', () { + expect(sut.type, ToolType.HAND); + }); } diff --git a/packages/tools/test/unit/hand_tool_test.mocks.dart b/test/unit/tools/hand_tool_test.mocks.dart similarity index 86% rename from packages/tools/test/unit/hand_tool_test.mocks.dart rename to test/unit/tools/hand_tool_test.mocks.dart index 7fc51b53..72734bfc 100644 --- a/packages/tools/test/unit/hand_tool_test.mocks.dart +++ b/test/unit/tools/hand_tool_test.mocks.dart @@ -1,17 +1,35 @@ -// Mocks generated by Mockito 5.4.2 from annotations -// in tools/test/unit/hand_tool_test.dart. +// Mocks generated by Mockito 5.4.4 from annotations +// in paintroid/test/unit/tools/hand_tool_test.dart. // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes + +// Dart imports: import 'dart:ui' as _i2; -import 'package:command/command.dart' as _i3; +// Package imports: import 'package:mockito/mockito.dart' as _i1; +// Project imports: +import 'package:paintroid/core/commands/path_with_action_history.dart' as _i8; + +import 'package:paintroid/core/commands/command_factory/command_factory.dart' + as _i7; +import 'package:paintroid/core/commands/command_implementation/command.dart' + as _i5; +import 'package:paintroid/core/commands/command_implementation/graphic/draw_path_command.dart' + as _i3; +import 'package:paintroid/core/commands/command_implementation/graphic/graphic_command.dart' + as _i6; +import 'package:paintroid/core/commands/command_manager/command_manager.dart' + as _i4; + // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters // ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors @@ -241,16 +259,16 @@ class MockPaint extends _i1.Mock implements _i2.Paint { /// A class which mocks [CommandManager]. /// /// See the documentation for Mockito's code generation for more information. -class MockCommandManager extends _i1.Mock implements _i3.CommandManager { +class MockCommandManager extends _i1.Mock implements _i4.CommandManager { MockCommandManager() { _i1.throwOnMissingStub(this); } @override - Iterable<_i3.Command> get history => (super.noSuchMethod( + Iterable<_i5.Command> get history => (super.noSuchMethod( Invocation.getter(#history), - returnValue: <_i3.Command>[], - ) as Iterable<_i3.Command>); + returnValue: <_i5.Command>[], + ) as Iterable<_i5.Command>); @override int get count => (super.noSuchMethod( @@ -259,7 +277,7 @@ class MockCommandManager extends _i1.Mock implements _i3.CommandManager { ) as int); @override - void addGraphicCommand(_i3.GraphicCommand? command) => super.noSuchMethod( + void addGraphicCommand(_i6.GraphicCommand? command) => super.noSuchMethod( Invocation.method( #addGraphicCommand, [command], @@ -295,7 +313,7 @@ class MockCommandManager extends _i1.Mock implements _i3.CommandManager { ); @override - void clearHistory({Iterable<_i3.Command>? newCommands}) => super.noSuchMethod( + void clearHistory({Iterable<_i5.Command>? newCommands}) => super.noSuchMethod( Invocation.method( #clearHistory, [], @@ -308,14 +326,14 @@ class MockCommandManager extends _i1.Mock implements _i3.CommandManager { /// A class which mocks [CommandFactory]. /// /// See the documentation for Mockito's code generation for more information. -class MockCommandFactory extends _i1.Mock implements _i3.CommandFactory { +class MockCommandFactory extends _i1.Mock implements _i7.CommandFactory { MockCommandFactory() { _i1.throwOnMissingStub(this); } @override _i3.DrawPathCommand createDrawPathCommand( - _i3.PathWithActionHistory? path, + _i8.PathWithActionHistory? path, _i2.Paint? paint, ) => (super.noSuchMethod( diff --git a/packages/features/workspace_screen/test/unit/render_image_for_export_test.dart b/test/unit/workspace/render_image_for_export_test.dart similarity index 91% rename from packages/features/workspace_screen/test/unit/render_image_for_export_test.dart rename to test/unit/workspace/render_image_for_export_test.dart index e1c8e4ff..e6f48672 100644 --- a/packages/features/workspace_screen/test/unit/render_image_for_export_test.dart +++ b/test/unit/workspace/render_image_for_export_test.dart @@ -1,13 +1,22 @@ +// Dart imports: import 'dart:ui'; -import 'package:command/command.dart'; -import 'package:command/command_providers.dart'; +// Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; -import 'package:workspace_screen/workspace_screen.dart'; +// Project imports: +import 'package:paintroid/core/commands/command_implementation/graphic/graphic_command.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager.dart'; +import 'package:paintroid/core/commands/command_manager/command_manager_provider.dart'; +import 'package:paintroid/core/commands/graphic_factory/graphic_factory.dart'; +import 'package:paintroid/core/commands/graphic_factory/graphic_factory_provider.dart'; +import 'package:paintroid/core/models/image_with_pixel_info.dart'; +import 'package:paintroid/core/providers/object/render_image_for_export.dart'; +import 'package:paintroid/core/providers/state/canvas_state_data.dart'; +import 'package:paintroid/core/providers/state/canvas_state_provider.dart'; import 'render_image_for_export_test.mocks.dart'; class FakePicture extends Fake implements Picture { diff --git a/packages/features/workspace_screen/test/unit/render_image_for_export_test.mocks.dart b/test/unit/workspace/render_image_for_export_test.mocks.dart similarity index 94% rename from packages/features/workspace_screen/test/unit/render_image_for_export_test.mocks.dart rename to test/unit/workspace/render_image_for_export_test.mocks.dart index 9bfa614d..1594780d 100644 --- a/packages/features/workspace_screen/test/unit/render_image_for_export_test.mocks.dart +++ b/test/unit/workspace/render_image_for_export_test.mocks.dart @@ -1,18 +1,29 @@ -// Mocks generated by Mockito 5.4.2 from annotations -// in workspace_screen/test/unit/render_image_for_export_test.dart. +// Mocks generated by Mockito 5.4.4 from annotations +// in paintroid/test/unit/workspace/render_image_for_export_test.dart. // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes + +// Dart imports: import 'dart:typed_data' as _i3; import 'dart:ui' as _i2; -import 'package:command/command.dart' as _i4; +// Package imports: import 'package:mockito/mockito.dart' as _i1; +import 'package:paintroid/core/commands/command_implementation/command.dart' + as _i5; +import 'package:paintroid/core/commands/command_implementation/graphic/graphic_command.dart' + as _i6; +import 'package:paintroid/core/commands/command_manager/command_manager.dart' + as _i4; + // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters // ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors @@ -625,10 +636,10 @@ class MockCommandManager extends _i1.Mock implements _i4.CommandManager { } @override - Iterable<_i4.Command> get history => (super.noSuchMethod( + Iterable<_i5.Command> get history => (super.noSuchMethod( Invocation.getter(#history), - returnValue: <_i4.Command>[], - ) as Iterable<_i4.Command>); + returnValue: <_i5.Command>[], + ) as Iterable<_i5.Command>); @override int get count => (super.noSuchMethod( @@ -637,7 +648,7 @@ class MockCommandManager extends _i1.Mock implements _i4.CommandManager { ) as int); @override - void addGraphicCommand(_i4.GraphicCommand? command) => super.noSuchMethod( + void addGraphicCommand(_i6.GraphicCommand? command) => super.noSuchMethod( Invocation.method( #addGraphicCommand, [command], @@ -673,7 +684,7 @@ class MockCommandManager extends _i1.Mock implements _i4.CommandManager { ); @override - void clearHistory({Iterable<_i4.Command>? newCommands}) => super.noSuchMethod( + void clearHistory({Iterable<_i5.Command>? newCommands}) => super.noSuchMethod( Invocation.method( #clearHistory, [], diff --git a/packages/features/landing_page_screen/test/widget/landing_page_test.dart b/test/widget/landing_page/landing_page_test.dart similarity index 79% rename from packages/features/landing_page_screen/test/widget/landing_page_test.dart rename to test/widget/landing_page/landing_page_test.dart index a9842fd2..51346425 100644 --- a/packages/features/landing_page_screen/test/widget/landing_page_test.dart +++ b/test/widget/landing_page/landing_page_test.dart @@ -1,33 +1,50 @@ +// Dart imports: import 'dart:io'; import 'dart:ui' as ui; -import 'package:database/database.dart'; -import 'package:filesize/filesize.dart'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: +import 'package:filesize/filesize.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:intl/intl.dart'; -import 'package:io_library/io_library.dart'; -import 'package:landing_page_screen/landing_page_screen.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:oxidized/oxidized.dart'; import 'package:package_info_plus/package_info_plus.dart'; -import 'package:paintroid/pocket_paint_app.dart'; -import 'package:workspace_screen/workspace_screen.dart'; +// Project imports: +import 'package:paintroid/app.dart'; +import 'package:paintroid/core/database/project_dao.dart'; +import 'package:paintroid/core/database/project_database.dart'; +import 'package:paintroid/core/models/database/project.dart'; +import 'package:paintroid/core/providers/object/device_service.dart'; +import 'package:paintroid/core/providers/object/file_service.dart'; +import 'package:paintroid/core/providers/object/image_service.dart'; +import 'package:paintroid/ui/pages/landing_page/components/main_overflow_menu.dart'; +import 'package:paintroid/ui/pages/landing_page/components/project_list_tile.dart'; +import 'package:paintroid/ui/pages/landing_page/components/project_overflow_menu.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/top_bar/overflow_menu.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/top_bar/top_app_bar.dart'; +import 'package:paintroid/ui/shared/dialogs/about_dialog.dart'; +import 'package:paintroid/ui/shared/dialogs/generic_dialog.dart'; +import 'package:paintroid/ui/shared/dialogs/project_details_dialog.dart'; import 'landing_page_test.mocks.dart'; -@GenerateMocks([ProjectDatabase, ProjectDAO, IImageService, IFileService]) +@GenerateMocks( + [ProjectDatabase, ProjectDAO, IImageService, IFileService, IDeviceService]) void main() { late Widget sut; late ProjectDatabase database; late ProjectDAO dao; late IImageService imageService; late IFileService fileService; + late IDeviceService deviceService; late List projects; final date = DateTime.now(); - const filePath = 'test/fixture/image/test.jpg'; + const filePath = 'test/assets/images/test.jpg'; final testFile = File(filePath); late ui.Image dummyImage; final DateFormat formatter = DateFormat('dd-MM-yyyy HH:mm:ss'); @@ -45,13 +62,15 @@ void main() { dao = MockProjectDAO(); imageService = MockIImageService(); fileService = MockIFileService(); + deviceService = MockIDeviceService(); sut = ProviderScope( overrides: [ ProjectDatabase.provider.overrideWith((ref) => Future.value(database)), IImageService.provider.overrideWith((ref) => imageService), IFileService.provider.overrideWith((ref) => fileService), + IDeviceService.provider.overrideWith((ref) => deviceService), ], - child: const PocketPaintApp( + child: App( showOnboardingPage: false, ), ); @@ -430,4 +449,60 @@ void main() { expect(confirmationDialogFinder, findsOneWidget); }, ); + + testWidgets( + 'Should show a CircularProgressIndicator when loading the project by clicking the edit button', + (tester) async { + String projectName = 'project.catrobat-image'; + Project project = createProject(projectName); + when(database.projectDAO).thenReturn(dao); + when(dao.getProjects()).thenAnswer((_) => Future.value([project])); + when(imageService.getProjectPreview(filePath)) + .thenReturn(Result.ok(testFile.readAsBytesSync())); + when(deviceService.getSizeInPixels()) + .thenAnswer((_) => Future.value(const Size(1080, 1920))); + when(dao.insertProject(project)).thenAnswer((_) => Future.value(1)); + when(fileService.getFile(filePath)).thenReturn(Result.ok(testFile)); + + await tester.pumpWidget(sut); + await tester.pumpAndSettle(); + verify(database.projectDAO); + verify(dao.getProjects()); + + final editButton = find.byKey(const Key('myEditIcon')); + await tester.tap(editButton); + await tester.pump(); + + expect(find.byType(CircularProgressIndicator), findsOneWidget); + }, + ); + + testWidgets( + 'Should show a CircularProgressIndicator when loading the project by clicking the project tile in list view', + (tester) async { + String projectName = 'project.catrobat-image'; + Project project1 = createProject(projectName); + Project project2 = createProject(projectName); + when(database.projectDAO).thenReturn(dao); + when(dao.getProjects()) + .thenAnswer((_) => Future.value([project1, project2])); + when(imageService.getProjectPreview(filePath)) + .thenReturn(Result.ok(testFile.readAsBytesSync())); + when(deviceService.getSizeInPixels()) + .thenAnswer((_) => Future.value(const Size(1080, 1920))); + when(dao.insertProject(project2)).thenAnswer((_) => Future.value(1)); + when(fileService.getFile(filePath)).thenReturn(Result.ok(testFile)); + + await tester.pumpWidget(sut); + await tester.pumpAndSettle(); + verify(database.projectDAO); + verify(dao.getProjects()); + + final projectTile = find.byType(ProjectListTile); + await tester.tap(projectTile); + await tester.pump(); + + expect(find.byType(CircularProgressIndicator), findsOneWidget); + }, + ); } diff --git a/packages/features/landing_page_screen/test/widget/landing_page_test.mocks.dart b/test/widget/landing_page/landing_page_test.mocks.dart similarity index 63% rename from packages/features/landing_page_screen/test/widget/landing_page_test.mocks.dart rename to test/widget/landing_page/landing_page_test.mocks.dart index 15d8c48f..2937a373 100644 --- a/packages/features/landing_page_screen/test/widget/landing_page_test.mocks.dart +++ b/test/widget/landing_page/landing_page_test.mocks.dart @@ -1,25 +1,35 @@ -// Mocks generated by Mockito 5.4.2 from annotations -// in landing_page_screen/test/widget/landing_page_test.dart. +// Mocks generated by Mockito 5.4.4 from annotations +// in paintroid/test/widget/landing_page/landing_page_test.dart. // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes + +// Dart imports: import 'dart:async' as _i3; -import 'dart:io' as _i11; -import 'dart:typed_data' as _i10; -import 'dart:ui' as _i9; - -import 'package:database/src/models/project.dart' as _i7; -import 'package:database/src/project_dao.dart' as _i2; -import 'package:database/src/project_database.dart' as _i6; -import 'package:io_library/io_library.dart' as _i8; +import 'dart:io' as _i13; +import 'dart:typed_data' as _i11; +import 'dart:ui' as _i6; + +// Package imports: import 'package:mockito/mockito.dart' as _i1; import 'package:oxidized/oxidized.dart' as _i5; import 'package:sqflite/sqflite.dart' as _i4; +// Project imports: +import 'package:paintroid/core/database/project_dao.dart' as _i2; +import 'package:paintroid/core/database/project_database.dart' as _i7; +import 'package:paintroid/core/models/database/project.dart' as _i8; +import 'package:paintroid/core/providers/object/device_service.dart' as _i14; +import 'package:paintroid/core/providers/object/file_service.dart' as _i12; +import 'package:paintroid/core/providers/object/image_service.dart' as _i9; +import 'package:paintroid/core/utils/failure.dart' as _i10; + // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values // ignore_for_file: avoid_setters_without_getters // ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package // ignore_for_file: implementation_imports // ignore_for_file: invalid_use_of_visible_for_testing_member // ignore_for_file: prefer_const_constructors @@ -70,10 +80,20 @@ class _FakeResult_3 extends _i1.SmartFake ); } +class _FakeSize_4 extends _i1.SmartFake implements _i6.Size { + _FakeSize_4( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + /// A class which mocks [ProjectDatabase]. /// /// See the documentation for Mockito's code generation for more information. -class MockProjectDatabase extends _i1.Mock implements _i6.ProjectDatabase { +class MockProjectDatabase extends _i1.Mock implements _i7.ProjectDatabase { MockProjectDatabase() { _i1.throwOnMissingStub(this); } @@ -144,7 +164,7 @@ class MockProjectDAO extends _i1.Mock implements _i2.ProjectDAO { } @override - _i3.Future insertProject(_i7.Project? project) => (super.noSuchMethod( + _i3.Future insertProject(_i8.Project? project) => (super.noSuchMethod( Invocation.method( #insertProject, [project], @@ -153,7 +173,7 @@ class MockProjectDAO extends _i1.Mock implements _i2.ProjectDAO { ) as _i3.Future); @override - _i3.Future> insertProjects(List<_i7.Project>? projects) => + _i3.Future> insertProjects(List<_i8.Project>? projects) => (super.noSuchMethod( Invocation.method( #insertProjects, @@ -173,7 +193,7 @@ class MockProjectDAO extends _i1.Mock implements _i2.ProjectDAO { ) as _i3.Future); @override - _i3.Future deleteProjects(List<_i7.Project>? projects) => + _i3.Future deleteProjects(List<_i8.Project>? projects) => (super.noSuchMethod( Invocation.method( #deleteProjects, @@ -184,54 +204,54 @@ class MockProjectDAO extends _i1.Mock implements _i2.ProjectDAO { ) as _i3.Future); @override - _i3.Future> getProjects() => (super.noSuchMethod( + _i3.Future> getProjects() => (super.noSuchMethod( Invocation.method( #getProjects, [], ), - returnValue: _i3.Future>.value(<_i7.Project>[]), - ) as _i3.Future>); + returnValue: _i3.Future>.value(<_i8.Project>[]), + ) as _i3.Future>); @override - _i3.Future<_i7.Project?> getProjectByName(String? name) => + _i3.Future<_i8.Project?> getProjectByName(String? name) => (super.noSuchMethod( Invocation.method( #getProjectByName, [name], ), - returnValue: _i3.Future<_i7.Project?>.value(), - ) as _i3.Future<_i7.Project?>); + returnValue: _i3.Future<_i8.Project?>.value(), + ) as _i3.Future<_i8.Project?>); } /// A class which mocks [IImageService]. /// /// See the documentation for Mockito's code generation for more information. -class MockIImageService extends _i1.Mock implements _i8.IImageService { +class MockIImageService extends _i1.Mock implements _i9.IImageService { MockIImageService() { _i1.throwOnMissingStub(this); } @override - _i3.Future<_i5.Result<_i9.Image, _i8.Failure>> import( - _i10.Uint8List? fileData) => + _i3.Future<_i5.Result<_i6.Image, _i10.Failure>> import( + _i11.Uint8List? fileData) => (super.noSuchMethod( Invocation.method( #import, [fileData], ), - returnValue: _i3.Future<_i5.Result<_i9.Image, _i8.Failure>>.value( - _FakeResult_3<_i9.Image, _i8.Failure>( + returnValue: _i3.Future<_i5.Result<_i6.Image, _i10.Failure>>.value( + _FakeResult_3<_i6.Image, _i10.Failure>( this, Invocation.method( #import, [fileData], ), )), - ) as _i3.Future<_i5.Result<_i9.Image, _i8.Failure>>); + ) as _i3.Future<_i5.Result<_i6.Image, _i10.Failure>>); @override - _i3.Future<_i5.Result<_i10.Uint8List, _i8.Failure>> exportAsJpg( - _i9.Image? image, + _i3.Future<_i5.Result<_i11.Uint8List, _i10.Failure>> exportAsJpg( + _i6.Image? image, int? quality, ) => (super.noSuchMethod( @@ -242,8 +262,8 @@ class MockIImageService extends _i1.Mock implements _i8.IImageService { quality, ], ), - returnValue: _i3.Future<_i5.Result<_i10.Uint8List, _i8.Failure>>.value( - _FakeResult_3<_i10.Uint8List, _i8.Failure>( + returnValue: _i3.Future<_i5.Result<_i11.Uint8List, _i10.Failure>>.value( + _FakeResult_3<_i11.Uint8List, _i10.Failure>( this, Invocation.method( #exportAsJpg, @@ -253,55 +273,55 @@ class MockIImageService extends _i1.Mock implements _i8.IImageService { ], ), )), - ) as _i3.Future<_i5.Result<_i10.Uint8List, _i8.Failure>>); + ) as _i3.Future<_i5.Result<_i11.Uint8List, _i10.Failure>>); @override - _i3.Future<_i5.Result<_i10.Uint8List, _i8.Failure>> exportAsPng( - _i9.Image? image) => + _i3.Future<_i5.Result<_i11.Uint8List, _i10.Failure>> exportAsPng( + _i6.Image? image) => (super.noSuchMethod( Invocation.method( #exportAsPng, [image], ), - returnValue: _i3.Future<_i5.Result<_i10.Uint8List, _i8.Failure>>.value( - _FakeResult_3<_i10.Uint8List, _i8.Failure>( + returnValue: _i3.Future<_i5.Result<_i11.Uint8List, _i10.Failure>>.value( + _FakeResult_3<_i11.Uint8List, _i10.Failure>( this, Invocation.method( #exportAsPng, [image], ), )), - ) as _i3.Future<_i5.Result<_i10.Uint8List, _i8.Failure>>); + ) as _i3.Future<_i5.Result<_i11.Uint8List, _i10.Failure>>); @override - _i5.Result<_i10.Uint8List, _i8.Failure> getProjectPreview(String? path) => + _i5.Result<_i11.Uint8List, _i10.Failure> getProjectPreview(String? path) => (super.noSuchMethod( Invocation.method( #getProjectPreview, [path], ), - returnValue: _FakeResult_3<_i10.Uint8List, _i8.Failure>( + returnValue: _FakeResult_3<_i11.Uint8List, _i10.Failure>( this, Invocation.method( #getProjectPreview, [path], ), ), - ) as _i5.Result<_i10.Uint8List, _i8.Failure>); + ) as _i5.Result<_i11.Uint8List, _i10.Failure>); } /// A class which mocks [IFileService]. /// /// See the documentation for Mockito's code generation for more information. -class MockIFileService extends _i1.Mock implements _i8.IFileService { +class MockIFileService extends _i1.Mock implements _i12.IFileService { MockIFileService() { _i1.throwOnMissingStub(this); } @override - _i3.Future<_i5.Result<_i11.File, _i8.Failure>> save( + _i3.Future<_i5.Result<_i13.File, _i10.Failure>> save( String? filename, - _i10.Uint8List? data, + _i11.Uint8List? data, ) => (super.noSuchMethod( Invocation.method( @@ -311,8 +331,8 @@ class MockIFileService extends _i1.Mock implements _i8.IFileService { data, ], ), - returnValue: _i3.Future<_i5.Result<_i11.File, _i8.Failure>>.value( - _FakeResult_3<_i11.File, _i8.Failure>( + returnValue: _i3.Future<_i5.Result<_i13.File, _i10.Failure>>.value( + _FakeResult_3<_i13.File, _i10.Failure>( this, Invocation.method( #save, @@ -322,12 +342,12 @@ class MockIFileService extends _i1.Mock implements _i8.IFileService { ], ), )), - ) as _i3.Future<_i5.Result<_i11.File, _i8.Failure>>); + ) as _i3.Future<_i5.Result<_i13.File, _i10.Failure>>); @override - _i3.Future<_i5.Result<_i11.File, _i8.Failure>> saveToApplicationDirectory( + _i3.Future<_i5.Result<_i13.File, _i10.Failure>> saveToApplicationDirectory( String? filename, - _i10.Uint8List? data, + _i11.Uint8List? data, ) => (super.noSuchMethod( Invocation.method( @@ -337,8 +357,8 @@ class MockIFileService extends _i1.Mock implements _i8.IFileService { data, ], ), - returnValue: _i3.Future<_i5.Result<_i11.File, _i8.Failure>>.value( - _FakeResult_3<_i11.File, _i8.Failure>( + returnValue: _i3.Future<_i5.Result<_i13.File, _i10.Failure>>.value( + _FakeResult_3<_i13.File, _i10.Failure>( this, Invocation.method( #saveToApplicationDirectory, @@ -348,39 +368,39 @@ class MockIFileService extends _i1.Mock implements _i8.IFileService { ], ), )), - ) as _i3.Future<_i5.Result<_i11.File, _i8.Failure>>); + ) as _i3.Future<_i5.Result<_i13.File, _i10.Failure>>); @override - _i3.Future<_i5.Result<_i11.File, _i8.Failure>> pick() => (super.noSuchMethod( + _i3.Future<_i5.Result<_i13.File, _i10.Failure>> pick() => (super.noSuchMethod( Invocation.method( #pick, [], ), - returnValue: _i3.Future<_i5.Result<_i11.File, _i8.Failure>>.value( - _FakeResult_3<_i11.File, _i8.Failure>( + returnValue: _i3.Future<_i5.Result<_i13.File, _i10.Failure>>.value( + _FakeResult_3<_i13.File, _i10.Failure>( this, Invocation.method( #pick, [], ), )), - ) as _i3.Future<_i5.Result<_i11.File, _i8.Failure>>); + ) as _i3.Future<_i5.Result<_i13.File, _i10.Failure>>); @override - _i5.Result<_i11.File, _i8.Failure> getFile(String? path) => + _i5.Result<_i13.File, _i10.Failure> getFile(String? path) => (super.noSuchMethod( Invocation.method( #getFile, [path], ), - returnValue: _FakeResult_3<_i11.File, _i8.Failure>( + returnValue: _FakeResult_3<_i13.File, _i10.Failure>( this, Invocation.method( #getFile, [path], ), ), - ) as _i5.Result<_i11.File, _i8.Failure>); + ) as _i5.Result<_i13.File, _i10.Failure>); @override _i3.Future checkIfFileExistsInApplicationDirectory(String? fileName) => @@ -393,20 +413,44 @@ class MockIFileService extends _i1.Mock implements _i8.IFileService { ) as _i3.Future); @override - _i3.Future<_i5.Result<_i11.FileSystemEntity, _i8.Failure>> + _i3.Future<_i5.Result<_i13.FileSystemEntity, _i10.Failure>> deleteFileInApplicationDirectory(String? fileName) => (super.noSuchMethod( Invocation.method( #deleteFileInApplicationDirectory, [fileName], ), returnValue: _i3 - .Future<_i5.Result<_i11.FileSystemEntity, _i8.Failure>>.value( - _FakeResult_3<_i11.FileSystemEntity, _i8.Failure>( + .Future<_i5.Result<_i13.FileSystemEntity, _i10.Failure>>.value( + _FakeResult_3<_i13.FileSystemEntity, _i10.Failure>( this, Invocation.method( #deleteFileInApplicationDirectory, [fileName], ), )), - ) as _i3.Future<_i5.Result<_i11.FileSystemEntity, _i8.Failure>>); + ) as _i3.Future<_i5.Result<_i13.FileSystemEntity, _i10.Failure>>); +} + +/// A class which mocks [IDeviceService]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockIDeviceService extends _i1.Mock implements _i14.IDeviceService { + MockIDeviceService() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.Future<_i6.Size> getSizeInPixels() => (super.noSuchMethod( + Invocation.method( + #getSizeInPixels, + [], + ), + returnValue: _i3.Future<_i6.Size>.value(_FakeSize_4( + this, + Invocation.method( + #getSizeInPixels, + [], + ), + )), + ) as _i3.Future<_i6.Size>); } diff --git a/packages/features/onboarding_screen/test/widget/onboarding_screen_test.dart b/test/widget/onboarding_page/onboarding_page_test.dart similarity index 90% rename from packages/features/onboarding_screen/test/widget/onboarding_screen_test.dart rename to test/widget/onboarding_page/onboarding_page_test.dart index 773ea4a4..6b414836 100644 --- a/packages/features/onboarding_screen/test/widget/onboarding_screen_test.dart +++ b/test/widget/onboarding_page/onboarding_page_test.dart @@ -1,9 +1,17 @@ +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:onboarding_screen/onboarding_screen.dart'; import 'package:smooth_page_indicator/smooth_page_indicator.dart'; -import 'package:flutter_localizations/flutter_localizations.dart'; + +// Project imports: +import 'package:paintroid/ui/pages/onboarding_page/components/onboarding_page_app_bar.dart'; +import 'package:paintroid/ui/pages/onboarding_page/components/onboarding_page_bottom_nav_bar.dart'; +import 'package:paintroid/ui/pages/onboarding_page/onboarding_page.dart'; +import 'package:paintroid/ui/theme/theme.dart'; void main() { late Widget sut; @@ -45,12 +53,21 @@ void main() { ]; setUp(() { - sut = const ProviderScope( - child: MaterialApp( - home: OnboardingPage(), - localizationsDelegates: [ - GlobalMaterialLocalizations.delegate, - ], + final lightTheme = LightPaintroidThemeData(); + final darkTheme = DarkPaintroidThemeData(); + + sut = ProviderScope( + child: PaintroidTheme( + lightTheme: lightTheme, + darkTheme: darkTheme, + child: MaterialApp( + theme: lightTheme.materialThemeData, + darkTheme: darkTheme.materialThemeData, + home: const OnboardingPage(), + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + ], + ), ), ); }); diff --git a/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart b/test/widget/workspace_page/bottom_control_navigation_bar_test.dart similarity index 84% rename from packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart rename to test/widget/workspace_page/bottom_control_navigation_bar_test.dart index 6c0327b6..ea51e6f3 100644 --- a/packages/features/workspace_screen/test/widget/bottom_control_navigation_bar_test.dart +++ b/test/widget/workspace_page/bottom_control_navigation_bar_test.dart @@ -1,12 +1,19 @@ +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:l10n/l10n.dart'; -import 'package:tools/tools.dart'; -import 'package:workspace_screen/workspace_screen.dart'; +// Project imports: +import 'package:paintroid/core/localization/app_localizations.dart'; +import 'package:paintroid/core/tools/tool_data.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/bottom_bar/tool_options/stroke_cap_tool_option.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/bottom_bar/tool_options/stroke_width_tool_option.dart'; +import 'package:paintroid/ui/pages/workspace_page/workspace_page.dart'; +import 'package:paintroid/ui/theme/theme.dart'; import 'bottom_nav_bar_interactions.dart'; void main() { @@ -17,13 +24,22 @@ void main() { late Widget sut; setUp(() { - sut = const ProviderScope( - child: MaterialApp( - home: WorkspaceScreen(), - localizationsDelegates: [ - AppLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - ], + final lightTheme = LightPaintroidThemeData(); + final darkTheme = DarkPaintroidThemeData(); + + sut = ProviderScope( + child: PaintroidTheme( + lightTheme: lightTheme, + darkTheme: darkTheme, + child: MaterialApp( + theme: lightTheme.materialThemeData, + darkTheme: darkTheme.materialThemeData, + home: const WorkspacePage(), + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + ], + ), ), ); }); diff --git a/packages/features/workspace_screen/test/widget/bottom_nav_bar_interactions.dart b/test/widget/workspace_page/bottom_nav_bar_interactions.dart similarity index 94% rename from packages/features/workspace_screen/test/widget/bottom_nav_bar_interactions.dart rename to test/widget/workspace_page/bottom_nav_bar_interactions.dart index 718cd99b..679520de 100644 --- a/packages/features/workspace_screen/test/widget/bottom_nav_bar_interactions.dart +++ b/test/widget/workspace_page/bottom_nav_bar_interactions.dart @@ -1,7 +1,13 @@ -import 'package:component_library/component_library.dart'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_test/flutter_test.dart'; -import 'package:tools/tools.dart'; + +// Project imports: +import 'package:paintroid/core/tools/tool_data.dart'; +import 'package:paintroid/ui/shared/bottom_nav_bar_icon.dart'; +import 'package:paintroid/ui/shared/icon_button_with_label.dart'; class BottomNavBarInteractions { final WidgetTester _tester; @@ -36,22 +42,6 @@ class BottomNavBarInteractions { return this; } - Future checkActiveToolIconAndLabel( - ToolData toolData) async { - final secondNavDestination = find.byType(NavigationDestination).at(1); - final activeToolIcon = find.descendant( - of: secondNavDestination, - matching: find.byWidgetPredicate((Widget widget) => - widget is BottomBarIcon && widget.asset == toolData.svgAssetPath)); - - final activeToolLabel = find.descendant( - of: secondNavDestination, matching: find.text(toolData.name)); - - expect(activeToolIcon, findsOneWidget); - expect(activeToolLabel, findsOneWidget); - return this; - } - Future openColorPicker() async { final thirdNavDestination = find.byType(NavigationDestination).at(2); expect(thirdNavDestination, findsOneWidget); @@ -109,6 +99,22 @@ class BottomNavBarInteractions { ); } + Future checkActiveToolIconAndLabel( + ToolData toolData) async { + final secondNavDestination = find.byType(NavigationDestination).at(1); + final activeToolIcon = find.descendant( + of: secondNavDestination, + matching: find.byWidgetPredicate((Widget widget) => + widget is BottomBarIcon && widget.asset == toolData.svgAssetPath)); + + final activeToolLabel = find.descendant( + of: secondNavDestination, matching: find.text(toolData.name)); + + expect(activeToolIcon, findsOneWidget); + expect(activeToolLabel, findsOneWidget); + return this; + } + Finder _findIconButtonWithLabel(String targetLabel) { return find.descendant( of: find.byWidgetPredicate( diff --git a/packages/features/workspace_screen/test/widget/canvas_interactions.dart b/test/widget/workspace_page/canvas_interactions.dart similarity index 90% rename from packages/features/workspace_screen/test/widget/canvas_interactions.dart rename to test/widget/workspace_page/canvas_interactions.dart index bccc2904..034effd7 100644 --- a/packages/features/workspace_screen/test/widget/canvas_interactions.dart +++ b/test/widget/workspace_page/canvas_interactions.dart @@ -1,11 +1,17 @@ +// Dart imports: import 'dart:math' as math; import 'dart:typed_data'; import 'dart:ui' as ui; +// Flutter imports: import 'package:flutter/rendering.dart'; + +// Package imports: import 'package:flutter_test/flutter_test.dart'; import 'package:image/image.dart' as img; -import 'package:workspace_screen/workspace_screen.dart'; + +// Project imports: +import 'package:paintroid/ui/pages/workspace_page/components/drawing_surface/canvas_painter.dart'; class CanvasInteractions { final WidgetTester _tester; diff --git a/packages/features/workspace_screen/test/widget/eraser_tool_test.dart b/test/widget/workspace_page/eraser_tool_test.dart similarity index 61% rename from packages/features/workspace_screen/test/widget/eraser_tool_test.dart rename to test/widget/workspace_page/eraser_tool_test.dart index 79610ee7..4a3e2e43 100644 --- a/packages/features/workspace_screen/test/widget/eraser_tool_test.dart +++ b/test/widget/workspace_page/eraser_tool_test.dart @@ -1,18 +1,27 @@ +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:l10n/l10n.dart'; -import 'package:tools/tools.dart'; -import 'package:workspace_screen/workspace_screen.dart'; -import 'package:flutter_localizations/flutter_localizations.dart'; +// Project imports: +import 'package:paintroid/core/localization/app_localizations.dart'; +import 'package:paintroid/core/providers/object/device_service.dart'; +import 'package:paintroid/core/tools/tool_data.dart'; +import 'package:paintroid/ui/pages/workspace_page/workspace_page.dart'; +import 'package:paintroid/ui/theme/theme.dart'; import 'bottom_nav_bar_interactions.dart'; import 'canvas_interactions.dart'; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + final lightTheme = LightPaintroidThemeData(); + final darkTheme = DarkPaintroidThemeData(); + testWidgets( 'Pixel value changes after drawing and erasing', (WidgetTester tester) async { @@ -22,12 +31,18 @@ void main() { IDeviceService.sizeProvider .overrideWith((ref) => Future.value(const Size(600, 600))) ], - child: const MaterialApp( - home: WorkspaceScreen(), - localizationsDelegates: [ - AppLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - ], + child: PaintroidTheme( + lightTheme: lightTheme, + darkTheme: darkTheme, + child: MaterialApp( + theme: lightTheme.materialThemeData, + darkTheme: darkTheme.materialThemeData, + home: const WorkspacePage(), + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + ], + ), ), ), ); diff --git a/packages/features/workspace_screen/test/widget/hand_tool_test.dart b/test/widget/workspace_page/hand_tool_test.dart similarity index 72% rename from packages/features/workspace_screen/test/widget/hand_tool_test.dart rename to test/widget/workspace_page/hand_tool_test.dart index 8230eccd..efd88b07 100644 --- a/packages/features/workspace_screen/test/widget/hand_tool_test.dart +++ b/test/widget/workspace_page/hand_tool_test.dart @@ -1,12 +1,18 @@ +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:l10n/l10n.dart'; -import 'package:tools/tools.dart'; -import 'package:workspace_screen/workspace_screen.dart'; +// Project imports: +import 'package:paintroid/core/localization/app_localizations.dart'; +import 'package:paintroid/core/providers/object/device_service.dart'; +import 'package:paintroid/core/tools/tool_data.dart'; +import 'package:paintroid/ui/pages/workspace_page/workspace_page.dart'; +import 'package:paintroid/ui/theme/theme.dart'; import 'bottom_nav_bar_interactions.dart'; import 'interactive_viewer_interactions.dart'; @@ -16,17 +22,26 @@ void main() { late Widget sut; setUp(() { + final lightTheme = LightPaintroidThemeData(); + final darkTheme = DarkPaintroidThemeData(); + sut = ProviderScope( overrides: [ IDeviceService.sizeProvider .overrideWith((ref) => Future.value(const Size(600, 600))) ], - child: const MaterialApp( - home: WorkspaceScreen(), - localizationsDelegates: [ - AppLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - ], + child: PaintroidTheme( + lightTheme: lightTheme, + darkTheme: darkTheme, + child: MaterialApp( + theme: lightTheme.materialThemeData, + darkTheme: darkTheme.materialThemeData, + home: const WorkspacePage(), + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + ], + ), ), ); }); diff --git a/packages/features/workspace_screen/test/widget/interactive_viewer_interactions.dart b/test/widget/workspace_page/interactive_viewer_interactions.dart similarity index 96% rename from packages/features/workspace_screen/test/widget/interactive_viewer_interactions.dart rename to test/widget/workspace_page/interactive_viewer_interactions.dart index 9bff062e..fa7cd645 100644 --- a/packages/features/workspace_screen/test/widget/interactive_viewer_interactions.dart +++ b/test/widget/workspace_page/interactive_viewer_interactions.dart @@ -1,4 +1,7 @@ +// Flutter imports: import 'package:flutter/widgets.dart'; + +// Package imports: import 'package:flutter_test/flutter_test.dart'; class InterActiveViewerInteractions { diff --git a/packages/features/workspace_screen/test/widget/workspace_screen_test.dart b/test/widget/workspace_page/workspace_page_test.dart similarity index 63% rename from packages/features/workspace_screen/test/widget/workspace_screen_test.dart rename to test/widget/workspace_page/workspace_page_test.dart index bd05bca4..5598697e 100644 --- a/packages/features/workspace_screen/test/widget/workspace_screen_test.dart +++ b/test/widget/workspace_page/workspace_page_test.dart @@ -1,24 +1,45 @@ -import 'package:command/command.dart'; +// Flutter imports: import 'package:flutter/material.dart'; + +// Package imports: +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:l10n/l10n.dart'; -import 'package:workspace_screen/workspace_screen.dart'; -import 'package:flutter_localizations/flutter_localizations.dart'; -class FakeCommandManager extends Fake implements CommandManager {} +// Project imports: +import 'package:paintroid/core/commands/command_manager/command_manager.dart'; +import 'package:paintroid/core/localization/app_localizations.dart'; +import 'package:paintroid/core/providers/state/workspace_state_notifier.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/top_bar/overflow_menu.dart'; +import 'package:paintroid/ui/pages/workspace_page/components/top_bar/top_app_bar.dart'; +import 'package:paintroid/ui/pages/workspace_page/workspace_page.dart'; +import 'package:paintroid/ui/theme/theme.dart'; + +class FakeCommandManager extends Fake implements CommandManager { + @override + int get count => 0; +} void main() { late Widget sut; setUp(() { - sut = const ProviderScope( - child: MaterialApp( - home: WorkspaceScreen(), - localizationsDelegates: [ - AppLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - ], + final lightTheme = LightPaintroidThemeData(); + final darkTheme = DarkPaintroidThemeData(); + + sut = ProviderScope( + child: PaintroidTheme( + lightTheme: lightTheme, + darkTheme: darkTheme, + child: MaterialApp( + theme: lightTheme.materialThemeData, + darkTheme: darkTheme.materialThemeData, + home: const WorkspacePage(), + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + ], + ), ), ); }); @@ -54,17 +75,27 @@ void main() { setUp(() { testWorkspaceState = WorkspaceState.initial.copyWith(isFullscreen: true); fakeCommandManager = FakeCommandManager(); + + final lightTheme = LightPaintroidThemeData(); + final darkTheme = DarkPaintroidThemeData(); + sut = ProviderScope( overrides: [ WorkspaceState.provider.overrideWith((ref) => WorkspaceStateNotifier(testWorkspaceState, fakeCommandManager)) ], - child: const MaterialApp( - home: WorkspaceScreen(), - localizationsDelegates: [ - AppLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - ], + child: PaintroidTheme( + lightTheme: lightTheme, + darkTheme: darkTheme, + child: MaterialApp( + theme: lightTheme.materialThemeData, + darkTheme: darkTheme.materialThemeData, + home: const WorkspacePage(), + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + ], + ), ), ); }); From c47fef8ab397122c2d14c4bb244081383e67f722 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Sat, 18 May 2024 17:46:56 +0530 Subject: [PATCH 27/39] sort imports, remove duplicates --- .../components/bottom_bar/bottom_nav_bar.dart | 2 +- pubspec.lock | 211 ++---------------- pubspec.yaml | 12 - 3 files changed, 16 insertions(+), 209 deletions(-) diff --git a/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart b/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart index 13b23ac5..4d49ae48 100644 --- a/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart +++ b/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart @@ -1,9 +1,9 @@ // Flutter imports: -import 'package:colorpicker/colorpicker.dart'; import 'package:flutter/material.dart'; // Package imports: import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:colorpicker/colorpicker.dart'; // Project imports: import 'package:paintroid/core/enums/tool_types.dart'; diff --git a/pubspec.lock b/pubspec.lock index 549dd000..5b6fccad 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -6,21 +6,17 @@ packages: description: name: _fe_analyzer_shared sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a - sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a url: "https://pub.dev" source: hosted version: "61.0.0" - version: "61.0.0" analyzer: dependency: transitive description: name: analyzer sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 - sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 url: "https://pub.dev" source: hosted version: "5.13.0" - version: "5.13.0" analyzer_plugin: dependency: transitive description: @@ -34,21 +30,17 @@ packages: description: name: archive sha256: ecf4273855368121b1caed0d10d4513c7241dfc813f7d3c8933b36622ae9b265 - sha256: ecf4273855368121b1caed0d10d4513c7241dfc813f7d3c8933b36622ae9b265 url: "https://pub.dev" source: hosted version: "3.5.1" - version: "3.5.1" args: dependency: transitive description: name: args sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" - sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" url: "https://pub.dev" source: hosted version: "2.5.0" - version: "2.5.0" async: dependency: transitive description: @@ -102,21 +94,17 @@ packages: description: name: build_runner sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22" - sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22" url: "https://pub.dev" source: hosted version: "2.4.9" - version: "2.4.9" build_runner_core: dependency: transitive description: name: build_runner_core sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799" - sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799" url: "https://pub.dev" source: hosted version: "7.3.0" - version: "7.3.0" built_collection: dependency: transitive description: @@ -130,11 +118,9 @@ packages: description: name: built_value sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb - sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb url: "https://pub.dev" source: hosted version: "8.9.2" - version: "8.9.2" characters: dependency: transitive description: @@ -188,18 +174,14 @@ packages: description: name: code_builder sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 - sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 url: "https://pub.dev" source: hosted version: "4.10.0" - version: "4.10.0" collection: - dependency: "direct main" dependency: "direct main" description: name: collection sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted version: "1.18.0" @@ -239,31 +221,25 @@ packages: description: name: custom_lint sha256: "22bd87a362f433ba6aae127a7bac2838645270737f3721b180916d7c5946cb5d" - sha256: "22bd87a362f433ba6aae127a7bac2838645270737f3721b180916d7c5946cb5d" url: "https://pub.dev" source: hosted version: "0.5.11" - version: "0.5.11" custom_lint_builder: dependency: transitive description: name: custom_lint_builder sha256: "0d48e002438950f9582e574ef806b2bea5719d8d14c0f9f754fbad729bcf3b19" - sha256: "0d48e002438950f9582e574ef806b2bea5719d8d14c0f9f754fbad729bcf3b19" url: "https://pub.dev" source: hosted version: "0.5.14" - version: "0.5.14" custom_lint_core: dependency: transitive description: name: custom_lint_core sha256: "2952837953022de610dacb464f045594854ced6506ac7f76af28d4a6490e189b" - sha256: "2952837953022de610dacb464f045594854ced6506ac7f76af28d4a6490e189b" url: "https://pub.dev" source: hosted version: "0.5.14" - version: "0.5.14" dart_style: dependency: transitive description: @@ -273,16 +249,13 @@ packages: source: hosted version: "2.3.2" device_info_plus: - dependency: "direct main" dependency: "direct main" description: name: device_info_plus sha256: "77f757b789ff68e4eaf9c56d1752309bd9f7ad557cb105b938a7f8eb89e59110" - sha256: "77f757b789ff68e4eaf9c56d1752309bd9f7ad557cb105b938a7f8eb89e59110" url: "https://pub.dev" source: hosted version: "9.1.2" - version: "9.1.2" device_info_plus_platform_interface: dependency: transitive description: @@ -292,7 +265,6 @@ packages: source: hosted version: "7.0.0" equatable: - dependency: "direct main" dependency: "direct main" description: name: equatable @@ -312,20 +284,19 @@ packages: dependency: transitive description: name: ffi - sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.0" file: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "6.1.4" file_picker: - dependency: "direct main" dependency: "direct main" description: name: file_picker @@ -346,21 +317,17 @@ packages: description: name: file_selector_macos sha256: f42eacb83b318e183b1ae24eead1373ab1334084404c8c16e0354f9a3e55d385 - sha256: f42eacb83b318e183b1ae24eead1373ab1334084404c8c16e0354f9a3e55d385 url: "https://pub.dev" source: hosted version: "0.9.4" - version: "0.9.4" file_selector_platform_interface: dependency: transitive description: name: file_selector_platform_interface sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b - sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b url: "https://pub.dev" source: hosted version: "2.6.2" - version: "2.6.2" file_selector_windows: dependency: transitive description: @@ -370,7 +337,6 @@ packages: source: hosted version: "0.9.3+1" filesize: - dependency: "direct main" dependency: "direct main" description: name: filesize @@ -387,7 +353,6 @@ packages: source: hosted version: "1.1.0" floor: - dependency: "direct main" dependency: "direct main" description: name: floor @@ -434,11 +399,9 @@ packages: description: name: flutter_lints sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" - sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" url: "https://pub.dev" source: hosted version: "3.0.2" - version: "3.0.2" flutter_localization: dependency: "direct main" description: @@ -457,23 +420,18 @@ packages: description: name: flutter_plugin_android_lifecycle sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f" - sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f" url: "https://pub.dev" source: hosted version: "2.0.19" - version: "2.0.19" flutter_riverpod: dependency: "direct main" description: name: flutter_riverpod sha256: "0f1974eff5bbe774bf1d870e406fc6f29e3d6f1c46bd9c58e7172ff68a785d7d" - sha256: "0f1974eff5bbe774bf1d870e406fc6f29e3d6f1c46bd9c58e7172ff68a785d7d" url: "https://pub.dev" source: hosted version: "2.5.1" - version: "2.5.1" flutter_svg: - dependency: "direct main" dependency: "direct main" description: name: flutter_svg @@ -496,11 +454,9 @@ packages: description: name: freezed sha256: a434911f643466d78462625df76fd9eb13e57348ff43fe1f77bbe909522c67a1 - sha256: a434911f643466d78462625df76fd9eb13e57348ff43fe1f77bbe909522c67a1 url: "https://pub.dev" source: hosted version: "2.5.2" - version: "2.5.2" freezed_annotation: dependency: "direct main" description: @@ -514,11 +470,9 @@ packages: description: name: frontend_server_client sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 - sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 url: "https://pub.dev" source: hosted version: "4.0.0" - version: "4.0.0" fuchsia_remote_debug_protocol: dependency: transitive description: flutter @@ -545,11 +499,9 @@ packages: description: name: hotreloader sha256: ed56fdc1f3a8ac924e717257621d09e9ec20e308ab6352a73a50a1d7a4d9158e - sha256: ed56fdc1f3a8ac924e717257621d09e9ec20e308ab6352a73a50a1d7a4d9158e url: "https://pub.dev" source: hosted version: "4.2.0" - version: "4.2.0" http: dependency: transitive description: @@ -575,7 +527,6 @@ packages: source: hosted version: "4.0.2" image: - dependency: "direct main" dependency: "direct main" description: name: image @@ -584,7 +535,6 @@ packages: source: hosted version: "3.3.0" image_picker: - dependency: "direct main" dependency: "direct main" description: name: image_picker @@ -656,14 +606,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.6.0" - import_sorter: - dependency: "direct dev" - description: - name: import_sorter - sha256: eb15738ccead84e62c31e0208ea4e3104415efcd4972b86906ca64a1187d0836 - url: "https://pub.dev" - source: hosted - version: "4.6.0" integration_test: dependency: "direct dev" description: flutter @@ -674,11 +616,9 @@ packages: description: name: intl sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" url: "https://pub.dev" source: hosted version: "0.18.1" - version: "0.18.1" io: dependency: transitive description: @@ -691,23 +631,18 @@ packages: dependency: transitive description: name: js - sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.7.1" + version: "0.6.7" json_annotation: - dependency: "direct main" dependency: "direct main" description: name: json_annotation sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" - sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" url: "https://pub.dev" source: hosted version: "4.9.0" - json_serializable: - dependency: "direct dev" - version: "4.9.0" json_serializable: dependency: "direct dev" description: @@ -716,12 +651,6 @@ packages: url: "https://pub.dev" source: hosted version: "6.8.0" - launch_review: - name: json_serializable - sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b - url: "https://pub.dev" - source: hosted - version: "6.8.0" launch_review: dependency: "direct main" description: @@ -730,40 +659,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.1" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" - url: "https://pub.dev" - source: hosted - version: "10.0.0" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 - url: "https://pub.dev" - source: hosted - version: "2.0.1" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 - url: "https://pub.dev" - source: hosted - version: "2.0.1" lints: dependency: transitive description: name: lints sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 - sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 url: "https://pub.dev" source: hosted version: "3.0.0" - version: "3.0.0" lists: dependency: transitive description: @@ -809,22 +712,17 @@ packages: description: name: mime sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" - sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" url: "https://pub.dev" source: hosted version: "1.0.5" - version: "1.0.5" mockito: dependency: "direct dev" description: name: mockito sha256: "6841eed20a7befac0ce07df8116c8b8233ed1f4486a7647c7fc5a02ae6163917" - sha256: "6841eed20a7befac0ce07df8116c8b8233ed1f4486a7647c7fc5a02ae6163917" url: "https://pub.dev" source: hosted version: "5.4.4" - oxidized: - version: "5.4.4" oxidized: dependency: "direct main" description: @@ -842,7 +740,6 @@ packages: source: hosted version: "2.1.0" package_info_plus: - dependency: "direct main" dependency: "direct main" description: name: package_info_plus @@ -862,10 +759,10 @@ packages: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.8.3" path_drawing: dependency: transitive description: @@ -883,36 +780,29 @@ packages: source: hosted version: "1.0.1" path_provider: - dependency: "direct main" dependency: "direct main" description: name: path_provider sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161 - sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161 url: "https://pub.dev" source: hosted version: "2.1.3" - version: "2.1.3" path_provider_android: dependency: transitive description: name: path_provider_android sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d - sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d url: "https://pub.dev" source: hosted version: "2.2.4" - version: "2.2.4" path_provider_foundation: dependency: transitive description: name: path_provider_foundation sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" - sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" url: "https://pub.dev" source: hosted version: "2.3.2" - version: "2.3.2" path_provider_linux: dependency: transitive description: @@ -926,11 +816,9 @@ packages: description: name: path_provider_platform_interface sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" - sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted version: "2.1.2" - version: "2.1.2" path_provider_windows: dependency: transitive description: @@ -940,7 +828,6 @@ packages: source: hosted version: "2.2.1" permission_handler: - dependency: "direct main" dependency: "direct main" description: name: permission_handler @@ -985,11 +872,9 @@ packages: description: name: petitparser sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 - sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 url: "https://pub.dev" source: hosted version: "6.0.2" - version: "6.0.2" platform: dependency: transitive description: @@ -1003,11 +888,9 @@ packages: description: name: plugin_platform_interface sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" url: "https://pub.dev" source: hosted version: "2.1.8" - version: "2.1.8" pool: dependency: transitive description: @@ -1020,7 +903,7 @@ packages: dependency: transitive description: name: process - sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" + sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" url: "https://pub.dev" source: hosted version: "4.2.4" @@ -1045,51 +928,41 @@ packages: description: name: riverpod sha256: f21b32ffd26a36555e501b04f4a5dca43ed59e16343f1a30c13632b2351dfa4d - sha256: f21b32ffd26a36555e501b04f4a5dca43ed59e16343f1a30c13632b2351dfa4d url: "https://pub.dev" source: hosted version: "2.5.1" - version: "2.5.1" riverpod_analyzer_utils: dependency: transitive description: name: riverpod_analyzer_utils sha256: d72d7096964baf288b55619fe48100001fc4564ab7923ed0a7f5c7650e03c0d6 - sha256: d72d7096964baf288b55619fe48100001fc4564ab7923ed0a7f5c7650e03c0d6 url: "https://pub.dev" source: hosted version: "0.3.4" - version: "0.3.4" riverpod_annotation: dependency: "direct main" description: name: riverpod_annotation sha256: e5e796c0eba4030c704e9dae1b834a6541814963292839dcf9638d53eba84f5c - sha256: e5e796c0eba4030c704e9dae1b834a6541814963292839dcf9638d53eba84f5c url: "https://pub.dev" source: hosted version: "2.3.5" - version: "2.3.5" riverpod_generator: dependency: "direct dev" description: name: riverpod_generator sha256: "5b36ad2f2b562cffb37212e8d59390b25499bf045b732276e30a207b16a25f61" - sha256: "5b36ad2f2b562cffb37212e8d59390b25499bf045b732276e30a207b16a25f61" url: "https://pub.dev" source: hosted version: "2.3.3" - version: "2.3.3" riverpod_lint: dependency: "direct dev" description: name: riverpod_lint sha256: "70198738c3047ae4f6517ef1a2011a8514a980a52576c7f629a3a08810319a02" - sha256: "70198738c3047ae4f6517ef1a2011a8514a980a52576c7f629a3a08810319a02" url: "https://pub.dev" source: hosted version: "2.1.1" - version: "2.1.1" rxdart: dependency: transitive description: @@ -1103,21 +976,17 @@ packages: description: name: shared_preferences sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180 - sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180 url: "https://pub.dev" source: hosted version: "2.2.3" - version: "2.2.3" shared_preferences_android: dependency: transitive description: name: shared_preferences_android sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2" - sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2" url: "https://pub.dev" source: hosted version: "2.2.2" - version: "2.2.2" shared_preferences_foundation: dependency: transitive description: @@ -1139,11 +1008,9 @@ packages: description: name: shared_preferences_platform_interface sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" - sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" url: "https://pub.dev" source: hosted version: "2.3.2" - version: "2.3.2" shared_preferences_web: dependency: transitive description: @@ -1182,7 +1049,6 @@ packages: source: sdk version: "0.0.99" smooth_page_indicator: - dependency: "direct main" dependency: "direct main" description: name: smooth_page_indicator @@ -1206,25 +1072,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.4" - source_helper: - dependency: transitive - description: - name: source_helper - sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" - url: "https://pub.dev" - source: hosted - version: "1.3.4" source_span: dependency: transitive description: name: source_span sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted version: "1.10.0" - sprintf: - version: "1.10.0" sprintf: dependency: transitive description: @@ -1233,14 +1088,6 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" - sqflite: - dependency: "direct main" - description: - name: sprintf - sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" - url: "https://pub.dev" - source: hosted - version: "7.0.0" sqflite: dependency: "direct main" description: @@ -1286,11 +1133,9 @@ packages: description: name: stack_trace sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted version: "1.11.1" - version: "1.11.1" state_notifier: dependency: transitive description: @@ -1304,11 +1149,9 @@ packages: description: name: stream_channel sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted version: "2.1.2" - version: "2.1.2" stream_transform: dependency: transitive description: @@ -1362,11 +1205,9 @@ packages: description: name: test_api sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted version: "0.6.1" - version: "0.6.1" timing: dependency: transitive description: @@ -1375,7 +1216,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" - tint: tint: dependency: transitive description: @@ -1384,14 +1224,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" - toast: - dependency: "direct main" - description: - name: tint - sha256: "9652d9a589f4536d5e392cf790263d120474f15da3cf1bee7f1fdb31b4de5f46" - url: "https://pub.dev" - source: hosted - version: "2.0.1" toast: dependency: "direct main" description: @@ -1417,26 +1249,21 @@ packages: source: hosted version: "0.3.1" url_launcher: - dependency: "direct main" dependency: "direct main" description: name: url_launcher sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e" - sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e" url: "https://pub.dev" source: hosted version: "6.2.6" - version: "6.2.6" url_launcher_android: dependency: transitive description: name: url_launcher_android sha256: "360a6ed2027f18b73c8d98e159dda67a61b7f2e0f6ec26e86c3ada33b0621775" - sha256: "360a6ed2027f18b73c8d98e159dda67a61b7f2e0f6ec26e86c3ada33b0621775" url: "https://pub.dev" source: hosted version: "6.3.1" - version: "6.3.1" url_launcher_ios: dependency: transitive description: @@ -1457,20 +1284,18 @@ packages: dependency: transitive description: name: url_launcher_macos - sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234 + sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.2.0" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" - sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" url: "https://pub.dev" source: hosted version: "2.3.2" - version: "2.3.2" url_launcher_web: dependency: transitive description: @@ -1492,11 +1317,9 @@ packages: description: name: uuid sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8" - sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8" url: "https://pub.dev" source: hosted version: "4.4.0" - version: "4.4.0" vector_math: dependency: transitive description: @@ -1533,18 +1356,18 @@ packages: dependency: transitive description: name: web_socket_channel - sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42" + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b url: "https://pub.dev" source: hosted - version: "2.4.5" + version: "2.4.0" webdriver: dependency: transitive description: name: webdriver - sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" + sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.2" win32: dependency: transitive description: @@ -1566,21 +1389,17 @@ packages: description: name: xdg_directories sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d - sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d url: "https://pub.dev" source: hosted version: "1.0.4" - version: "1.0.4" xml: dependency: transitive description: name: xml sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 - sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 url: "https://pub.dev" source: hosted version: "6.5.0" - version: "6.5.0" yaml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index db386f2b..938025c7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -40,7 +40,6 @@ dependencies: file_picker: ^5.3.1 floor: ^1.2.0 sqflite: ^2.3.0 - colorpicker: path: packages/colorpicker @@ -56,19 +55,12 @@ dev_dependencies: floor_generator: ^1.4.2 riverpod_generator: ^2.2.4 riverpod_lint: ^2.0.0 - flutter_lints: ^3.0.2 - floor_generator: ^1.4.2 - riverpod_generator: ^2.2.4 - riverpod_lint: ^2.0.0 build_runner: ^2.2.0 freezed: ^2.4.1 riverpod: ^2.3.7 import_sorter: ^4.6.0 json_serializable: ^6.7.1 - import_sorter: ^4.6.0 - json_serializable: ^6.7.1 - flutter: uses-material-design: true @@ -79,7 +71,3 @@ flutter: - assets/svg/ - assets/lang/ - test/assets/images/ - - assets/img/ - - assets/svg/ - - assets/lang/ - - test/assets/images/ From 096ac430444c13bd48137c92052e13c789cfb232 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Sat, 18 May 2024 18:13:10 +0530 Subject: [PATCH 28/39] fix lint errors --- .../color_picker_state_data.freezed.dart | 2 +- pubspec.lock | 60 +++++++++++++------ 2 files changed, 43 insertions(+), 19 deletions(-) diff --git a/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart b/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart index c217e94e..ad1d7b3c 100644 --- a/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart +++ b/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart @@ -118,7 +118,7 @@ class _$_ColorPickerStateData implements _ColorPickerStateData { } @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && other is _$_ColorPickerStateData && diff --git a/pubspec.lock b/pubspec.lock index 5b6fccad..be39912d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -292,10 +292,10 @@ packages: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.0" file_picker: dependency: "direct main" description: @@ -659,6 +659,30 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" lints: dependency: transitive description: @@ -687,26 +711,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mime: dependency: transitive description: @@ -759,10 +783,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_drawing: dependency: transitive description: @@ -879,10 +903,10 @@ packages: dependency: transitive description: name: platform - sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.4" plugin_platform_interface: dependency: transitive description: @@ -903,10 +927,10 @@ packages: dependency: transitive description: name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" url: "https://pub.dev" source: hosted - version: "4.2.4" + version: "5.0.2" pub_semver: dependency: transitive description: @@ -1332,10 +1356,10 @@ packages: dependency: transitive description: name: vm_service - sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583 + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 url: "https://pub.dev" source: hosted - version: "11.10.0" + version: "13.0.0" watcher: dependency: transitive description: @@ -1364,10 +1388,10 @@ packages: dependency: transitive description: name: webdriver - sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49" + sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" win32: dependency: transitive description: From fb23944af7c499a83b0c642af327b6e96d69a2de Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Thu, 30 May 2024 00:46:53 +0530 Subject: [PATCH 29/39] use paintroid theme colors --- .../components/project_list_tile.dart | 3 +- .../components/bottom_bar/bottom_nav_bar.dart | 8 +-- lib/ui/theme/data/custom_colors.dart | 1 + .../theme/data/dark_paintroid_theme_data.dart | 3 + .../data/light_paintroid_theme_data.dart | 3 + lib/ui/theme/data/paintroid_theme_data.dart | 1 + pubspec.lock | 60 ++++++------------- 7 files changed, 32 insertions(+), 47 deletions(-) diff --git a/lib/ui/pages/landing_page/components/project_list_tile.dart b/lib/ui/pages/landing_page/components/project_list_tile.dart index 5795be24..d6c80fbc 100644 --- a/lib/ui/pages/landing_page/components/project_list_tile.dart +++ b/lib/ui/pages/landing_page/components/project_list_tile.dart @@ -9,6 +9,7 @@ import 'package:paintroid/core/models/database/project.dart'; import 'package:paintroid/core/providers/object/image_service.dart'; import 'package:paintroid/ui/pages/landing_page/components/image_preview.dart'; import 'package:paintroid/ui/pages/landing_page/components/project_overflow_menu.dart'; +import 'package:paintroid/ui/theme/theme.dart'; class ProjectListTile extends StatelessWidget { final Project project; @@ -34,7 +35,7 @@ class ProjectListTile extends StatelessWidget { project: project, imageService: imageService, width: 80, - color: Colors.white, + color: PaintroidTheme.of(context).onSurfaceColor, ), dense: false, title: Text( diff --git a/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart b/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart index 4d49ae48..17bbc9f0 100644 --- a/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart +++ b/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart @@ -52,7 +52,7 @@ class BottomNavBar extends ConsumerWidget { decoration: BoxDecoration( color: currentPaint.color, border: Border.all( - color: Colors.white, + color: PaintroidTheme.of(context).onSurfaceColor, width: 1.4, ), borderRadius: BorderRadius.circular(2.0), @@ -121,9 +121,9 @@ void _showColorPicker(BuildContext context, WidgetRef ref) { builder: (BuildContext context) => Container( height: MediaQuery.of(context).size.height * 0.7, alignment: Alignment.center, - decoration: const BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( + decoration: BoxDecoration( + color: PaintroidTheme.of(context).surfaceColor, + borderRadius: const BorderRadius.only( topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0), )), diff --git a/lib/ui/theme/data/custom_colors.dart b/lib/ui/theme/data/custom_colors.dart index e826cdb8..d823ee6d 100644 --- a/lib/ui/theme/data/custom_colors.dart +++ b/lib/ui/theme/data/custom_colors.dart @@ -31,6 +31,7 @@ abstract class CustomColors { static const inversePrimary = Color(0xFF006874); static const shadow = Color(0xFF000000); static const surfaceTint = Color(0xFF4FD8EB); + static const transparentColor = Color(0x00000000); } extension ToMaterialColor on Color { diff --git a/lib/ui/theme/data/dark_paintroid_theme_data.dart b/lib/ui/theme/data/dark_paintroid_theme_data.dart index 1af6bfd0..7f95b028 100644 --- a/lib/ui/theme/data/dark_paintroid_theme_data.dart +++ b/lib/ui/theme/data/dark_paintroid_theme_data.dart @@ -120,6 +120,9 @@ class DarkPaintroidThemeData extends PaintroidThemeData { @override Color get tertiaryContainerColor => CustomColors.tertiaryContainer; + @override + Color get transparentColor => CustomColors.transparentColor; + @override TextStyle get titleStyle => const TextStyle( color: CustomColors.onSurface, diff --git a/lib/ui/theme/data/light_paintroid_theme_data.dart b/lib/ui/theme/data/light_paintroid_theme_data.dart index 79b4bea6..9b0850db 100644 --- a/lib/ui/theme/data/light_paintroid_theme_data.dart +++ b/lib/ui/theme/data/light_paintroid_theme_data.dart @@ -145,6 +145,9 @@ class LightPaintroidThemeData extends PaintroidThemeData { @override Color get tertiaryContainerColor => CustomColors.tertiaryContainer; + @override + Color get transparentColor => CustomColors.transparentColor; + @override TextStyle get titleStyle => const TextStyle( color: CustomColors.onSurface, diff --git a/lib/ui/theme/data/paintroid_theme_data.dart b/lib/ui/theme/data/paintroid_theme_data.dart index fbd190cd..bfe72a6d 100644 --- a/lib/ui/theme/data/paintroid_theme_data.dart +++ b/lib/ui/theme/data/paintroid_theme_data.dart @@ -50,6 +50,7 @@ abstract class PaintroidThemeData { Color get inversePrimaryColor; Color get shadowColor; Color get surfaceTintColor; + Color get transparentColor; Color get scaffoldBackgroundColor; Color get textFieldorderColor; diff --git a/pubspec.lock b/pubspec.lock index be39912d..5b6fccad 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -292,10 +292,10 @@ packages: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "6.1.4" file_picker: dependency: "direct main" description: @@ -659,30 +659,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.1" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" - url: "https://pub.dev" - source: hosted - version: "10.0.0" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 - url: "https://pub.dev" - source: hosted - version: "2.0.1" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 - url: "https://pub.dev" - source: hosted - version: "2.0.1" lints: dependency: transitive description: @@ -711,26 +687,26 @@ packages: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.5.0" meta: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.10.0" mime: dependency: transitive description: @@ -783,10 +759,10 @@ packages: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.8.3" path_drawing: dependency: transitive description: @@ -903,10 +879,10 @@ packages: dependency: transitive description: name: platform - sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "3.1.2" plugin_platform_interface: dependency: transitive description: @@ -927,10 +903,10 @@ packages: dependency: transitive description: name: process - sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" + sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" url: "https://pub.dev" source: hosted - version: "5.0.2" + version: "4.2.4" pub_semver: dependency: transitive description: @@ -1356,10 +1332,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583 url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "11.10.0" watcher: dependency: transitive description: @@ -1388,10 +1364,10 @@ packages: dependency: transitive description: name: webdriver - sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" + sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.2" win32: dependency: transitive description: From 2aabe54f260827b5891b66467a4bf9c8d131f2e7 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Sat, 1 Jun 2024 18:29:55 +0530 Subject: [PATCH 30/39] fix minor issues --- packages/colorpicker/lib/src/colorpicker.dart | 16 +++++++++--- .../src/state/color_picker_state_data.dart | 2 +- .../color_picker_state_data.freezed.dart | 26 +++++++++---------- .../state/color_picker_state_provider.dart | 4 +-- .../state/color_picker_state_provider.g.dart | 2 +- 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index 9f7ebd56..dc342ed8 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -21,6 +21,13 @@ class ColorPicker extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + Future.delayed(Duration.zero, () { + if (ref.read(colorPickerStateProvider).currentColor == null) { + final data = ref.read(colorPickerStateProvider.notifier); + data.updateColor(currentColor); + data.updateOpacity(currentColor.opacity); + } + }); final colorPickerStateData = ref.watch(colorPickerStateProvider); return Container( margin: const EdgeInsets.all(26.0), @@ -34,8 +41,9 @@ class ColorPicker extends ConsumerWidget { children: [ ColorComparison( currentColor: currentColor, - newColor: colorPickerStateData.currentColor - .withOpacity(colorPickerStateData.currentOpacity), + newColor: colorPickerStateData.currentColor!.withOpacity( + colorPickerStateData.currentOpacity, + ), ), const SizedBox(height: 10.0), GridView.count( @@ -60,7 +68,7 @@ class ColorPicker extends ConsumerWidget { ), const SizedBox(height: 20.0), OpacitySlider( - gradientColor: colorPickerStateData.currentColor, + gradientColor: colorPickerStateData.currentColor!, ), const SizedBox(height: 20.0), Row( @@ -75,7 +83,7 @@ class ColorPicker extends ConsumerWidget { const SizedBox(width: 10.0), TextButton( onPressed: () { - onColorChanged(colorPickerStateData.currentColor + onColorChanged(colorPickerStateData.currentColor! .withOpacity(colorPickerStateData.currentOpacity)); Navigator.pop(context); }, diff --git a/packages/colorpicker/lib/src/state/color_picker_state_data.dart b/packages/colorpicker/lib/src/state/color_picker_state_data.dart index 0410d1a9..206bb2e5 100644 --- a/packages/colorpicker/lib/src/state/color_picker_state_data.dart +++ b/packages/colorpicker/lib/src/state/color_picker_state_data.dart @@ -7,7 +7,7 @@ part 'color_picker_state_data.freezed.dart'; @freezed class ColorPickerStateData with _$ColorPickerStateData { const factory ColorPickerStateData({ - required Color currentColor, + required Color? currentColor, required double currentOpacity, }) = _ColorPickerStateData; } diff --git a/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart b/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart index ad1d7b3c..29036323 100644 --- a/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart +++ b/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart @@ -16,7 +16,7 @@ final _privateConstructorUsedError = UnsupportedError( /// @nodoc mixin _$ColorPickerStateData { - Color get currentColor => throw _privateConstructorUsedError; + Color? get currentColor => throw _privateConstructorUsedError; double get currentOpacity => throw _privateConstructorUsedError; @JsonKey(ignore: true) @@ -30,7 +30,7 @@ abstract class $ColorPickerStateDataCopyWith<$Res> { $Res Function(ColorPickerStateData) then) = _$ColorPickerStateDataCopyWithImpl<$Res, ColorPickerStateData>; @useResult - $Res call({Color currentColor, double currentOpacity}); + $Res call({Color? currentColor, double currentOpacity}); } /// @nodoc @@ -47,14 +47,14 @@ class _$ColorPickerStateDataCopyWithImpl<$Res, @pragma('vm:prefer-inline') @override $Res call({ - Object? currentColor = null, + Object? currentColor = freezed, Object? currentOpacity = null, }) { return _then(_value.copyWith( - currentColor: null == currentColor + currentColor: freezed == currentColor ? _value.currentColor : currentColor // ignore: cast_nullable_to_non_nullable - as Color, + as Color?, currentOpacity: null == currentOpacity ? _value.currentOpacity : currentOpacity // ignore: cast_nullable_to_non_nullable @@ -71,7 +71,7 @@ abstract class _$$_ColorPickerStateDataCopyWith<$Res> __$$_ColorPickerStateDataCopyWithImpl<$Res>; @override @useResult - $Res call({Color currentColor, double currentOpacity}); + $Res call({Color? currentColor, double currentOpacity}); } /// @nodoc @@ -85,14 +85,14 @@ class __$$_ColorPickerStateDataCopyWithImpl<$Res> @pragma('vm:prefer-inline') @override $Res call({ - Object? currentColor = null, + Object? currentColor = freezed, Object? currentOpacity = null, }) { return _then(_$_ColorPickerStateData( - currentColor: null == currentColor + currentColor: freezed == currentColor ? _value.currentColor : currentColor // ignore: cast_nullable_to_non_nullable - as Color, + as Color?, currentOpacity: null == currentOpacity ? _value.currentOpacity : currentOpacity // ignore: cast_nullable_to_non_nullable @@ -108,7 +108,7 @@ class _$_ColorPickerStateData implements _ColorPickerStateData { {required this.currentColor, required this.currentOpacity}); @override - final Color currentColor; + final Color? currentColor; @override final double currentOpacity; @@ -118,7 +118,7 @@ class _$_ColorPickerStateData implements _ColorPickerStateData { } @override - bool operator ==(Object other) { + bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && other is _$_ColorPickerStateData && @@ -141,11 +141,11 @@ class _$_ColorPickerStateData implements _ColorPickerStateData { abstract class _ColorPickerStateData implements ColorPickerStateData { const factory _ColorPickerStateData( - {required final Color currentColor, + {required final Color? currentColor, required final double currentOpacity}) = _$_ColorPickerStateData; @override - Color get currentColor; + Color? get currentColor; @override double get currentOpacity; @override diff --git a/packages/colorpicker/lib/src/state/color_picker_state_provider.dart b/packages/colorpicker/lib/src/state/color_picker_state_provider.dart index 32deda4f..7cd21022 100644 --- a/packages/colorpicker/lib/src/state/color_picker_state_provider.dart +++ b/packages/colorpicker/lib/src/state/color_picker_state_provider.dart @@ -11,8 +11,8 @@ class ColorPickerState extends _$ColorPickerState { final colors = DisplayColors.colors; @override ColorPickerStateData build() { - return ColorPickerStateData( - currentColor: colors[0], + return const ColorPickerStateData( + currentColor: null, currentOpacity: 1.0, ); } diff --git a/packages/colorpicker/lib/src/state/color_picker_state_provider.g.dart b/packages/colorpicker/lib/src/state/color_picker_state_provider.g.dart index 522ae199..2ac4146f 100644 --- a/packages/colorpicker/lib/src/state/color_picker_state_provider.g.dart +++ b/packages/colorpicker/lib/src/state/color_picker_state_provider.g.dart @@ -6,7 +6,7 @@ part of 'color_picker_state_provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$colorPickerStateHash() => r'383e6e54ba4cd4c039beda38499e4fc4cf8deb74'; +String _$colorPickerStateHash() => r'd9193012d8a7cbf6b50a034ba7f1b9483095df9f'; /// See also [ColorPickerState]. @ProviderFor(ColorPickerState) From f0d97d550b6fda135c7bfa247923a1ba80a8077d Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Sat, 1 Jun 2024 18:34:40 +0530 Subject: [PATCH 31/39] fix lint errors --- .../lib/src/state/color_picker_state_data.freezed.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart b/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart index 29036323..165b8aa7 100644 --- a/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart +++ b/packages/colorpicker/lib/src/state/color_picker_state_data.freezed.dart @@ -118,7 +118,7 @@ class _$_ColorPickerStateData implements _ColorPickerStateData { } @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && other is _$_ColorPickerStateData && From 22c993dd508f3b15fdf99faf71688b0a56d57232 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Sat, 1 Jun 2024 18:36:43 +0530 Subject: [PATCH 32/39] fix background color --- .../workspace_page/components/bottom_bar/bottom_nav_bar.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart b/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart index 17bbc9f0..0817fe4a 100644 --- a/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart +++ b/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart @@ -122,7 +122,7 @@ void _showColorPicker(BuildContext context, WidgetRef ref) { height: MediaQuery.of(context).size.height * 0.7, alignment: Alignment.center, decoration: BoxDecoration( - color: PaintroidTheme.of(context).surfaceColor, + color: PaintroidTheme.of(context).onSurfaceColor, borderRadius: const BorderRadius.only( topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0), From e3353b575900ef0c3dade2b60b4e04f90a41622b Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Tue, 4 Jun 2024 16:06:54 +0530 Subject: [PATCH 33/39] fix test error, minor refactoring --- .../components/bottom_bar/bottom_nav_bar.dart | 6 ++-- packages/colorpicker/lib/src/colorpicker.dart | 30 ++++++++----------- .../lib/src/components/color_square.dart | 2 -- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart b/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart index 0817fe4a..bc75dff7 100644 --- a/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart +++ b/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart @@ -118,11 +118,11 @@ void _showColorPicker(BuildContext context, WidgetRef ref) { showModalBottomSheet( context: context, isScrollControlled: true, - builder: (BuildContext context) => Container( - height: MediaQuery.of(context).size.height * 0.7, + builder: (BuildContext dialogContext) => Container( + height: MediaQuery.of(dialogContext).size.height * 0.7, alignment: Alignment.center, decoration: BoxDecoration( - color: PaintroidTheme.of(context).onSurfaceColor, + color: PaintroidTheme.of(dialogContext).onSurfaceColor, borderRadius: const BorderRadius.only( topLeft: Radius.circular(16.0), topRight: Radius.circular(16.0), diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index dc342ed8..b02c8c16 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -21,13 +21,6 @@ class ColorPicker extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - Future.delayed(Duration.zero, () { - if (ref.read(colorPickerStateProvider).currentColor == null) { - final data = ref.read(colorPickerStateProvider.notifier); - data.updateColor(currentColor); - data.updateOpacity(currentColor.opacity); - } - }); final colorPickerStateData = ref.watch(colorPickerStateProvider); return Container( margin: const EdgeInsets.all(26.0), @@ -41,9 +34,11 @@ class ColorPicker extends ConsumerWidget { children: [ ColorComparison( currentColor: currentColor, - newColor: colorPickerStateData.currentColor!.withOpacity( - colorPickerStateData.currentOpacity, - ), + newColor: colorPickerStateData.currentColor != null + ? colorPickerStateData.currentColor!.withOpacity( + colorPickerStateData.currentOpacity, + ) + : currentColor, ), const SizedBox(height: 10.0), GridView.count( @@ -58,17 +53,16 @@ class ColorPicker extends ConsumerWidget { if (index == colors.length) { return const CheckerboardSquare(); } else { - return ColorSquare( - color: colors[index], - opacity: colorPickerStateData.currentOpacity, - ); + return ColorSquare(color: colors[index]); } }, ), ), const SizedBox(height: 20.0), OpacitySlider( - gradientColor: colorPickerStateData.currentColor!, + gradientColor: colorPickerStateData.currentColor != null + ? colorPickerStateData.currentColor! + : currentColor, ), const SizedBox(height: 20.0), Row( @@ -83,8 +77,10 @@ class ColorPicker extends ConsumerWidget { const SizedBox(width: 10.0), TextButton( onPressed: () { - onColorChanged(colorPickerStateData.currentColor! - .withOpacity(colorPickerStateData.currentOpacity)); + if (colorPickerStateData.currentColor != null) { + onColorChanged(colorPickerStateData.currentColor! + .withOpacity(colorPickerStateData.currentOpacity)); + } Navigator.pop(context); }, child: const Text('APPLY'), diff --git a/packages/colorpicker/lib/src/components/color_square.dart b/packages/colorpicker/lib/src/components/color_square.dart index 8ef8bf95..54838680 100644 --- a/packages/colorpicker/lib/src/components/color_square.dart +++ b/packages/colorpicker/lib/src/components/color_square.dart @@ -6,11 +6,9 @@ class ColorSquare extends ConsumerWidget { const ColorSquare({ super.key, required this.color, - required this.opacity, }); final Color color; - final double opacity; @override Widget build(BuildContext context, WidgetRef ref) { From 5bab29ace285b8c75e6befc82aed83938b859e01 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Thu, 6 Jun 2024 21:27:14 +0530 Subject: [PATCH 34/39] add pipette tool --- .../components/bottom_bar/bottom_nav_bar.dart | 2 + .../colorpicker/assets/img/checkerboard.png | Bin 10096 -> 103386 bytes .../lib/pages/pipette_tool_page.dart | 144 ++++++++++++++++++ packages/colorpicker/lib/src/colorpicker.dart | 44 +++++- .../src/components/checkerboard_square.dart | 15 +- .../lib/src/components/color_comparison.dart | 24 +-- .../lib/src/components/opacity_slider.dart | 82 +++++----- .../src/components/pipette_tool_button.dart | 44 ++++++ .../lib/src/components/top_bar.dart | 39 +++++ .../state/color_picker_state_provider.dart | 2 +- .../state/color_picker_state_provider.g.dart | 8 +- 11 files changed, 334 insertions(+), 70 deletions(-) create mode 100644 packages/colorpicker/lib/pages/pipette_tool_page.dart create mode 100644 packages/colorpicker/lib/src/components/pipette_tool_button.dart create mode 100644 packages/colorpicker/lib/src/components/top_bar.dart diff --git a/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart b/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart index bc75dff7..1c4ca547 100644 --- a/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart +++ b/lib/ui/pages/workspace_page/components/bottom_bar/bottom_nav_bar.dart @@ -8,6 +8,7 @@ import 'package:colorpicker/colorpicker.dart'; // Project imports: import 'package:paintroid/core/enums/tool_types.dart'; import 'package:paintroid/core/localization/app_localizations.dart'; +import 'package:paintroid/core/providers/state/canvas_state_provider.dart'; import 'package:paintroid/core/providers/state/tool_options_visibility_state_provider.dart'; import 'package:paintroid/core/providers/state/tools/brush/brush_tool_state_provider.dart'; import 'package:paintroid/core/providers/state/tools/toolbox/toolbox_state_provider.dart'; @@ -132,6 +133,7 @@ void _showColorPicker(BuildContext context, WidgetRef ref) { onColorChanged: (newColor) { ref.read(brushToolStateProvider.notifier).updateColor(newColor); }, + image: ref.read(canvasStateProvider).cachedImage, ), ), ); diff --git a/packages/colorpicker/assets/img/checkerboard.png b/packages/colorpicker/assets/img/checkerboard.png index 92f8909d5962f1ed4d9f3d6b7ac39262c86eaa7e..ecc4202152720c6c84ef5dfe5314bad3f1e885a9 100644 GIT binary patch literal 103386 zcmeHQe{56b8t&;LL@8~#9kFETKlPa9?_A0a;#(=DhWfe{4Lg~OXFq(Y z<&mj5yc|S>SB)me~1PN~gd zjJhYeyw#B^-jgkzrS8ZoJKFdE*Qgyt3Vj-SICp5T^wynZ_hh3+)Uh*_Z7cca*cs{=u|d=Hko$dgUllu}!ow@o?^u+aZISPg z)899!7l*5euP$4sef^?kZNb{Movc^8{-?OB4)n>(540z$)UP^8pWLQHnVN~ckw?`X z(%W1TF1_*(+#1{(L=B>b#RH9gXkxCxTq7Y3K!%144aqZ-XJxrZFCDP1!IG1V0W3Lz z1^}p0AQS*Kz|bgk5AY`7O(4%eo>3G)y$1Cfl+s9n6;)1DIZ=QvK#@>@1~&k-4bV2g zr~%mt7#etJHc$jX5d?b^?9Dvo7sOg{p22wr4-Gst@X)|R0}l;6G#jK(ETm7(P^CdI z2*DsV2B77HmJ>2tD4?N$Cfa;O%lVfD>zZbI0RT@!4*@M(Ko5ax2Xvk2yn)UeXo`ZS zC~6xY=sM9#=&CUQT_<#%&~-xBiQZ@&IB95GhmL|AIBCGpfT00H%lB^uCk>o5aMHj@ z11AlfG;q=!;H2^3q@jsDn%L800Gu>%(tZ^uZGY|dOQ)aMzM!b1I{nc>=K<>pr+L7* zVNE<$yyK|07@ccv3sx-;`t6E~hv+}dl;_&W)hk2Tw^uRbD4H8DHp``5H6<4^>%ZfNdO6#`Qn|K% z52G1?3`AI8;$33np==iPO1j6z(agg9O0sr;FzYJw#&~t-p3T(9!n>u!nBGCkEKk{A z%b^e%`*fyziRxY<`dNP2(=#3=Lg-vN{%=0$SC87q(;GQ^*uZGpmsf^r=O_nDRDNEcnVYbKOp~_OYZaM=`qdpY>z*I<=L4hu(DC(SGZrRc?v1=r ziD$?(9igZP%usvJ70nSvx$rHT8B2*R_IBP7#o3+G9ZUw6dK`)9#@wwpyGy!iEk$eHwb%gBGDyFTPIq(9$P zV{*>xd@eiiqnhbAQkTsC!~F5x_II>F5qqBHk{S0m#p-0nps!IIobi4$82Edd+pIm@+sMy?9|`Q~Rmwylk+ z(iXMD772cRcs3@O;T?}Zqm8JDyny;z(L?3aJ1(GW*p2om~l9yYDm=-G#9B_ z&cD%$H4fG|SmOX3061`MBnsdFP&J@xK-GY%0geV74LJHbtmEAOS+8xT7XT^Ep{7Hs zmq^=?wjpgp+J>|ZX&cfuq;1z>+J;oETBTDWRYR(VR1K*bQZ=M%NY#+4AyorY8cbiqh@S&?*Y8qR?ZFv~r~b0hAk1Za}#KgW7Tr1Lp1hk%On9)>c5mNQ&YK0czX|3ORwsHp#ga&V*qHtt`F3#ilv_!K%P;r0fvSpCzhO8a;iwVt#$KNU>%m6SaM>? zi6tjWY0VB6$uqrr0NDuzXjD1%W(kE@Jt%^xaw2&~@{Hse$up8?B+mi|r2xoIViaU2 zqbA~!psz7a54nLn19{#Xc~mXI(8LAM(II_;U=Sh>&^CJQUm|&iQh;wp^89-fr~k`T z^WID^0L|Ne7C33(q=AzLP8v9AKn8#e02xr)_|Uir1RW4`K+sVV_d(F18Tz5DhO!!v zf!`Z405m{ra|DttNVXu^f@BMxz&OwVpaDPwY@$EKqp@&dn_RSa02%-^KjsG~al(Lv_{>j|fMz_?*eJXO5os9<0e zuD`V{ShYOpw=4E)qW>^co_F7{idANJIB+tNUazRc2#lLuaCtV_gus77fz`;Oe8Q)g zQBCETu`%+Mbc+vXd0-zog1RGN-(KzD@nW-F+Er6>A+!EFeyCS5c#~`E_b}?2RS!g1 zU*cWDFH|-QdL_M0@6pV{yc0<6{$SQs=8f^{&OMu{kA-(ji80;r!z@qPUt6q!ml^wX zrh7@w{Dh@VR6^&{KkvOVM>$xsvh@q)Vvz6hJY!#*)mxX-_A~4tJSgEo2@lE})q@hg zlW|_P;)3rad?%Tq_MR)6Mi9P}@STM3Bzz}tG~dahQ?9Rbz6_>%- z0%vPu3W0;balILxI;LC($1s(5wD$bqU81HVL>dN(0VD>H7*HAuNDLq`fW!b2gRiCL zL-U{WB}!R^JD8?f>F)6GXi&9bA(~{iji`_{jWz-YfrG$7;Gq8iv^fy9fhis5z?248 z4a@-)KvBm591S=caI~gnw=`3Fk*-C~a!vY9KzbTXXnxjXLmkI1wjgj2I0&3Rt)X+6 z0wO&_rs)Xfgn&8@>NxZaB5ZM-Lf{~9)bwJREcEC-V3$X_=SQSUt>w-cfqrtJ0E#*e z>Nu$5ppJ9h)N#T$O{NWon>N(ft!Pj>c7yN<-kQ!j08lWu8m)1Wwjpgp+IFL*ZJ8f0 zp5{8tTt{QJ>BtLw*DZ~b$+cP>DT^2PrG)5_yK|MJY(e|eYiiOjwkBJr0P20vt@pv*e(0>wjint<|OSVQs9%qB{S}CiZuh3YmJSju0^>Tt&c5z Z^4%{Q{=Rh883XyR{^3=1{SSFM{s$oSe3k$J literal 10096 zcmb_>2Q*z>xAsEN1|9x}6ara>CdFFc7Gw0cJ&1Ws!)xy;(0992~Q3Q~XfZx~E8ZxDdoSdb$ zu9l*Ty28x>GR|FFxBJLY0C02n_R>|7r8P1(p+#Q?kN`3O1z-b2t!?jn$Y^V;|3&iO z+>Yl#GC}wi9T>Y+P^bpljO; zOc3;^UfYhp?eZJUZ@cRTqpvFmVqSx`wBx_nHveM(6&Hj6D7O69xBuJA+uk3{9{?0( z0pR+X{$~ICS^e!pApuhm0089jzkT;g0YKyk^r!yqv&jR1&L{wYFaGUgECvAlNC4<~ zW9#GP`#T0e4&KL+Mp0}b=@_oq$51I^9ST9Z1GZFtxOloEM90s3*VW?zB(6C>sNVVc zL&VE%-m9ytB|r{9MM1g#K}A7@prS(1u+Y)K3l|d$0}CG)3dP68$0Hzu!w3jT3GwiW zDTztR$S5c%pfD;LDsmb)IR*LE0Dz4F#&$wNq6e-9uQNeG0ZZ?}A}%Vw?DiP_l;s^A zjg)!bI;pdq_|rcA={Kj|Y~P9Fsk@ZOCwm(HeKTMAU9Z-<9G@j#L)5$A9zJWzv#~DM zrTCKU$CwjK^3R2u?EWB^Kgd_`)%=U!fs%%90-f&68@#kwHo$2+)j08;rfY~y-Aj#~ zoNP+9Y@Eu~+WRIW^?koK&t}{mzE;r*w~0D{Y)l9$PfYWT+`j@cP7ie-Dn6Yvs*ur} zen6jMXxzVp=k+qW{PD2nVeDt@hgcg}$MAJ5M@ibgz7o2CTQv-x?#)aFK0PctqDC?AJ53{SJ<$Wm(Ge#0 zXuAqUf=?WKUBmQmOzP)X`#U2+5?FIRZ-WgVOP~F%rM- zU_#DzF(WVcQHibq?z5U~&W?}C?53X4td>vr|3)(Po zfeC#0&y2IVevb9PwR^W}`S9?v=zT0Xf*Vxs{@*MfA+Uv+z`X$#9qd)Gk^gFAWE4~+ z2oy#vAjrp0K*Yer_*XY0L6FNk_Y(GT#GKB{g|^B^Jb31qgLNcqY)g|wBPLzceh&21 zaDGoaRP&uTJyAG`rV@NOLw=}h+eP{%LyEPinQvOLu>Z3V)31-_`q=@>XG~8O1=q8!=-h9cLPn31h9)u%M}%ik z^UK$duf;my|EwO#75iM?sVqFfR5Yy-Zr+!CCMTJ%E{1IC%zqs9O}*XFzVVN6*ii}t zC7B@s4KpO$5JT2oHX}|> z65Mfnicbn>z%H@=F*d5MfZPXqo-}M)KXxNdqPwN&ee#y{q>L8i{nlt|vcg-~pX5@` z6~YJlJ?_L2lD>+X845Ns2iQ zW1Ea7u|cj^mk$CY`cdX&HvS9IK~ z9h~U12Bdc?ZEpCVM{1xL4a_6bDAu@t^+TQx4L>MY;ln;6KpK4zst>ewMc` zvNfr7PJd8#M5x3_tGO{-O!Z-Am!yk~Qo`OLCD9J2Dr~1EE3eiKef2Dd&!C7Vh z{Wi&PJw&F4@hO>~nRhtVRvGuwf0WWLnG>rR^t19tE3Y$pqBZ&8IHQ{M*YhipF@%?) zPYtIU5%XPhlaSqT+i4-Ci?D$`ot1qt{qSRq290<0Gg$5(wxt-fzBOH&@mS;VXRAz$d)ZxGEhld~dnZ*P`AFXX6A|G-8g-|6OH z36ql!nNT$Ae=EVXDAVW6c^rS2aQDz}hU{?0dWvvKC8v!i+_turC!VfYYO{>mYNsfD zh4zDBcA&y7Oy4u{ZJaY_-YrbG^6^E|e*Rg0c`|ww3R=D@I3iYpop%&U<}VR_tyy9ve7>hT+Hqua5wUMmc)vVnG|GIttA(m?4) z?J=maxOb$sDx^!_j2(UjcwS2wl|5}>l$?Nqz1s{;3GGL@%JzYhmKdFoDRAtzppM~3 zZG}v}T~PVZpAQIQB}BCN5{|bn$8Z#Y6`=PaI+?3LWSY&sTvc+F>s9e+hcFFgsPW;aOi-!wVEuwZ_ z-_Ze@_{q7AfIaFJ4aQ=ESr9J zZoJsq?t4t5iOrA`7twTn#363z`vg1R%s587MbzJ9X66bwtlu?W?A4?@a8+Mjp;t6~jG=Du@GyW3w43+}cp*=-^`ZIw<*${KUu_I8)AVVbzL zAly=6T8ZArF0(#Uzmj_pZrKHQ^FIE1`0(5Vq@49ZsMxA79D*D`|{o>V(BSy%nf@GT8lUj(Kia#;qGfql#Rr&H24V$%RjJr@OEyk}?-S9fH&(?K%SHLGLjO}O+ zzBa@^6zW#=_sh(a{2+O%!PZUogB-6IHz7%;^W57Gl?R%^rDU%(BodQKddqlQUUMdd zqv=otNWdkst?d?l@C~1$gpawm6coQ% zU!4)VoVT{0>ax88hB8;|g*C2#H`{wBSAe0leXcRO2z3>WPv%MhtJU5!Dc9>bQL1Hi zEBo<*eLc>)BrBY{jPk z@W}?)0a2Tk2)(qh=A2&&lDhACh4VxBCn6tK7ES9ppTk3lgoFwGVh)mojh%Z&H#^r+ zt(V&=e5#kKy6ZhrS08W*8~YhRlD78@%iP;3yg%zY2Wp*>6x8Q_ZfY-HQ#MKJnRS~I zR7&+eaY6W`?r6;4co4UxGOC_~p6r79d|btF^j()*I~{TRewJ2kEB2K;%(u!S%q03j zY@lZT*MV{KH~07%DctJrnorcl4UvSjR;bfTYz8ej}GSi+VIJo)c9pB7DKYa3^j8 zkisjufjHJvdK#1W_zDwW1IpfhI5#G55%ME_Iu}2=v0=S0xlo^EOx`=`=^QM9Jh`#y znvfth&?02#^1b(%#y!l@YaicpcgW7=)!f`=@|&5-jYs2EwjRdhPieMxM<9<7dd@Yk zUM!4X(m!Uq2d9{j%5xZyL})qHv|S`h#pM^oiN8F(0#yHt==$D>uFARGXtE6;rJ~0;!%M0fmR`nv*X!n>N^W8~&nknvF zbHKCQzb+&kfBy(NDeL^z&JA~i+`R|k^VU^@s%x#C!oGTmhs>ENmrK~(KUW<8x$bWl zc9`cqa8)$+YB)nqeN2*CX5Dg=gS)vWilQ-y<>+5XPVxu$LQlhs}OD}X>NvojHQ^YQCeYZ~XOHvPrmVVc1SjloABe}zySOv%hjh* zP<3_Qf@@f_Xl0?{);s5p(HHt2z$G~QsVnvI;j!0^o);~;b2%L&xrl8iRj+M6_PE&$ z?3a|Yg{zuCL3g^pEF;x^BhdmcPtVSeSKFz4s&{_#RmL6^J^v9t>$6$(ALX_H%e`A! zHTe8KdgAPRwl}kKqL@|9X>EU2ZyN9*zziM)kRho5^707@fD+J^d^_Ni(Xpm&?)MD) znD!rkwo1{t-0OULf1N`!KkpSm#P2zTsa$7u(Cl_4mCY(P+ z2`{a5A7oW&Cpg2&toqn-hnqs_;Amf*OaA!mwXsN`<6R+x&9>cU1)F$LqJCC2 z+!N#CRvBWoPf&Z}cy{E{RkHditNdX1%@&9 z*N!pK7&F_Sr`J3vih8`^x6&sd#K3*|mTM1XE)t`m6N57?YU+wj{17n}UOY=wK1Q^1 zMY?<$Q#=Puf1guufTm86#EEBL18WH8#e!7E6Ieg>V880AC-`L-tB=jm8tKZkFL>vS zx?QS9dbaCQN>6AStUiy!6gzeXTDSKK{l^d;wGufpb+JyfQtCp6+$J>#dp$1eThB&z zj6}Z=L0#Q@seiy;U^r>K|Bm918Y=LDVQMJWuMf>8Y!x-{8-pe-hF|YzY_e3$gxid& zm_YY_R!@=Kv(;f_m07Dd_{cDsu!v^|i)XZIx7{A7qH4VV`K&sE2rXbgGF%WY{+^F0 z(SvFq1E3}8Euk;gK%qfLJbbqFn9Rg`*0JkryZGWtZ7_ws*T=RH8jBw-vs(A+hcaS1 zd|w(^xN0t88mThoi9-tOqoAy1a7IJIk_8NS*sP&fYbGj`j|i8sDU*L_h(N`WL)7G# zB9|Jbj5d8-mK}$v0>-^7z-GV@IYOR5pxSsWo=}vo#F_(B0g402w`OYS(pnj*4(J|15nke5-bL25TJaNBm@4RF{JzhLFDCj~{ zNnS_FrGI*2F64P=v3^uf`O_wLe#PJLp~O-OnThY5Qp=W*CoXx+c69B~xPhd^TMe^^ zq+J)T=#oaILY*3k_4X>f%FC@;xy29|TR91T=_woz%#z%ErzQd_hvrPNjeh9$cT!yQ zM0GJ5!wQAr)X^D_VPFSJK@#gBB(bzrv-KO&cLO4~jK+p_6j2DFoEt>2et0&2a~33H z8l{+X1I20dk?f!$e<%?ON>giAYN;m%@ItjY)2!l!Fz3d0-}~J+i49^d0?WQ8k9OVX zq;OlhJr<=>o&>yeVd?c!2mb}oyyM-m&vUCQ2hlXpcY z$sN8lu-T}6OubXtD4DPv+#d0mQwI%Pp^U!9rL78zYAtb`+VcD|oKP0b zdJs_MFVo0(aZMeE6KKyXc_w%sfBO$UqaW2i{PM62g@65W~Xhz=l zer+dO+TpYNxcjJS?oK|UBkZH}w~8dThtA|JaX?I*GS3b+4{C$#HB$m}m-!9%n!D3)nZLLS`@~n+1F)F@(gb74mDl+9(`Dj;T({ zl(YYT(F(ACE)`mbZ~t|vUd~fTl4BtIFt!}!l+Xt-4%SOZbBE(#jn7+@4zngRPFR0o z-hP3>!DIXY`^5k=9VDg<0~6@?I?Aaja9ZV*u-@t_2FOtjEmB@3@zK*a9VL{3{R5C# z#OGAf<79I;9Wl4_S<$x~ikF~L$#UQuJrKc^4!{QKL@?QCxv9fbn=-0tTTU9!0z0Ys z+jeVH?5AAT$c69`xCZ~FcHkDk(O0zlkKIPTRQaF(_kq%}aR9n$m?}odna#=f)ve*O zgtO2#dT4fWR0$NwilnuQEU!mWl`dz+M3$z*biptoz);hcor;rHPDg8!)inevxS5O) zg^JL~c2q8mNTzB!Cus;9Ei%>(bI#@E=a9gOz+sk!;TvW;O`kYjiPX%jP&Q?dna;)h zGu0cu%zt5i4xSrWpx|2rG^F1LhreDRfaeB2oo_PMo@ult2hAV*!>0f9-~c^!Qo?NO z#?{&mA-n%*b+E6`e$v8zz(t9NV91$UN|&fLb0#Rq*^5FZVz4VoCF1pc3j5LBpa0IJ zQ*%#NZmYz+WKp}My9zH54I4gElFd48E{l#-GOTe7Ou8#fUN9F7bQw2+WD-by<}<@> zrqM_$YhzGR(@cKuv#ye!y=}`(^Ko@-Q`Cy0H;bvEGG^^%HC839e@hwE7)m6Bc46o7 z>x)jwEa|pDqwd)W@l5ZZTfSXOX;16lPNZfUb62Of&0jRL__R%9`b%9V&SoP(RD*7O(`<88 zBuI&@#^bzC*SoN=g8+U~(%Rm_&DIT^d5Y$#z}w8ip~i;v2K z)z(WWnP)x;Nmcx^pY)3$Jo}j=8jyooL)oiDT;6q|tU0Nt^4+}Rl^Ys9;hGRLKHqD% z9G1@2mj3DobrFWcToTcYubJ3%$`Vv;x!^*f%>lbjTi+<0YA41Mv&n^N!-}6ubO7-P zZT+^gcZ|)uY0*t{mkJ81TpM>uA&sHMY-S(R=OWoVVz~=3kQ6T!O$h)(2r*P zgYazbI~kcXlwh;n&4?NF%+JAp`mtk@RiuDOanp?}wmXA2o-pjrt?d3qUROG=A4^t; zPQE$@OB?o0&~8{`7PppLV#T&%TZ2VESAkU|M4=1@W6REJwm=grjdvuoZ%0!7q~iSv zE6Oy$zPUVgmc2GJh-k@W{9vG6orIHcVXL|+9)VlHdHn9jWCb>i)wGW5aUNkPmf(&T z8v9%OyYh2*$Q8pLYS!e!Yr+Oj(UBcQnG@BuSvBv1P5+(N&)F$Enwm|3u-0IKi$)Cp zVCs88dWHOh#NZy9Ef;4sVn3SXlo4t3vCULmqHg62Z-U0&Zu1AwkZ91WFAA#_)N3GG z4(=h@mfb?}C2tVerb&**ozIwy;!rnCslMR(;63N`NPs3e%&Ay#YGKDlN`s~`>cUn`H;Fpi_FxJc@TC;E)ueL;^hlWlZ4SKs zwRZ$-Xp%#9cD8X}vnH=KpKTStpwd8*c`zeIb?~G7)Bmoxi(qj#s#N;N-9uc@e(4;y zh)D2740dabf?{f_mazPYVJ9RmmXFiy2@6}fXwZ1!I~M%dbs=sVzZdIqI`@juf#B43ml=XF#mWN-rf>Z)*_dIB{nm)bU7q$ z+g4T6c=Xe*Jfh|U)tZPt8+27-^h>0Ux^~YqgWUBLoGC1u@DJrh5_!tRV(AwSp0CDD zWutNTO-I*RHINO_+lvD~XL`mo#JnfJ0@k$f?;gj=>gzXrF}+k?bC|2mDFI*Pva~To zE}BJG9X?O&p8RHG3AOS}k7|Be3SoCU7Ldo+B zYc4twr8vH)oKkg3*{reV zV#%F*U3HzyD42xNDLVEPA&2o#9}b!Ktd+T*T!SY!<{LDa}*g#|YEuBXmDdH$N!=?KOaF)OC)eD8qR_dH75WDrT6x)cmx zRnZ<0W#0F(+mgkO&T!ZVCio!1c}XdqefI=w`f1V&z9Q~vkgy}^X;5k7hY+fNYpWtu z#=)%Dro=2y^@ug&V8>TeRruOe4LK|coK!*iknaZEo7W{6F3x;V5}ZM(uzA>oQhH&R zM*d=|qt4}G2-~_Xj^_v#RZbX;oK9tk$%?+^Y?Ve)U28+i`jYRY<2t=Oq)9t9=_#=kUd%qJj?A?k4L^ zVY$H^=~1ATI(wOOkR$pYM{Q@*Y-7`mx!mi3(lCAfh)!HogJsk=hpr9WV`FE*J(jP- ztms2_qzA>HOtSLNA*kX1Yf@-9BrLsHAD7?I1_RGDzqIz5F^05CqU>@_cPxEXyh9%3 zPFth{rDzKg&LDxGdOVCAd!}wrR>UI}Ri+HWU=~Jbud1ZmUg2p%2$iR7;vQH8LUDCv zQI}0IGM$c|?%6mA4-^WLBgJ9FWpZN`B)iLSq2dP>)i;<>-BngZd7}fwmB(YN&?Yv! q^UIeaL{qaLc`)Q=k?P87%S+alls;k)ibVW7yU4#KG~Umz-u*vkK16u{ diff --git a/packages/colorpicker/lib/pages/pipette_tool_page.dart b/packages/colorpicker/lib/pages/pipette_tool_page.dart new file mode 100644 index 00000000..239fa207 --- /dev/null +++ b/packages/colorpicker/lib/pages/pipette_tool_page.dart @@ -0,0 +1,144 @@ +import 'dart:async'; +import 'dart:typed_data'; +import 'dart:ui' as ui; + +import 'package:colorpicker/src/components/top_bar.dart'; +import 'package:colorpicker/src/state/color_picker_state_provider.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class PipetteToolPage extends ConsumerStatefulWidget { + const PipetteToolPage({ + super.key, + required this.snapshot, + }); + + final ui.Image? snapshot; + + @override + ConsumerState createState() => + _PipetteToolPageState(); +} + +class _PipetteToolPageState extends ConsumerState { + GlobalKey imageKey = GlobalKey(); + ui.Image? displayImage; + + Future _loadImage() async { + final ByteData? bytedata = + await widget.snapshot!.toByteData(format: ui.ImageByteFormat.png); + if (bytedata == null) { + return Future.error('An error occurred while loading the snapshot'); + } + final Uint8List headedIntList = Uint8List.view(bytedata.buffer); + ImageProvider? image = MemoryImage(headedIntList); + final ImageStream imageStream = image.resolve(const ImageConfiguration()); + final Completer completer = Completer(); + + void imageListener(ImageInfo info, bool synchronousCall) { + completer.complete(info.image); + imageStream.removeListener(ImageStreamListener(imageListener)); + } + + imageStream.addListener(ImageStreamListener(imageListener)); + displayImage = await completer.future; + + setState(() {}); + } + + Future _updateColor(TapUpDetails details) async { + RenderBox box = imageKey.currentContext!.findRenderObject() as RenderBox; + Offset localPosition = box.globalToLocal(details.globalPosition); + + double xRatio = localPosition.dx / box.size.width; + double yRatio = localPosition.dy / box.size.height; + + int x = (xRatio * displayImage!.width).toInt(); + int y = (yRatio * displayImage!.height).toInt(); + + ByteData? byteData = + await displayImage!.toByteData(format: ui.ImageByteFormat.rawRgba); + if (byteData == null) return; + + int offset = (y * displayImage!.width + x) * 4; + + int red = byteData.getUint8(offset); + int green = byteData.getUint8(offset + 1); + int blue = byteData.getUint8(offset + 2); + int alpha = byteData.getUint8(offset + 3); + + Color color = Color.fromARGB(alpha, red, green, blue); + + final colorData = ref.read(colorPickerStateProvider.notifier); + colorData.updateColor(color.withOpacity(1)); + colorData.updateOpacity(color.opacity); + } + + @override + void initState() { + super.initState(); + _loadImage(); + } + + @override + Widget build(BuildContext context) { + final screenSize = MediaQuery.of(context).size; + final colorData = ref.watch(colorPickerStateProvider); + return Scaffold( + backgroundColor: Colors.white, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(60.0), + child: TopBar( + color: colorData.currentColor != null + ? colorData.currentColor!.withOpacity(colorData.currentOpacity) + : Colors.transparent), + ), + body: Center( + child: Stack( + children: [ + Positioned.fill( + child: Image.asset( + 'packages/colorpicker/assets/img/checkerboard.png', + repeat: ImageRepeat.repeat, + cacheHeight: 16, + cacheWidth: 16, + filterQuality: FilterQuality.none, + ), + ), + if (displayImage != null) + GestureDetector( + onTapUp: _updateColor, + child: SizedBox( + height: screenSize.height, + width: screenSize.width, + child: CustomPaint( + key: imageKey, + painter: ImagePainter(displayImage!), + ), + ), + ), + ], + ), + ), + ); + } +} + +class ImagePainter extends CustomPainter { + final ui.Image image; + + ImagePainter(this.image); + + @override + void paint(Canvas canvas, Size size) { + final Rect srcRect = + Rect.fromLTWH(0, 0, image.width.toDouble(), image.height.toDouble()); + final Rect dstRect = Rect.fromLTWH(0, 0, size.width, size.height); + canvas.drawImageRect(image, srcRect, dstRect, Paint()); + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) { + return false; + } +} diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index b02c8c16..4727c902 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -1,21 +1,26 @@ +import 'package:colorpicker/pages/pipette_tool_page.dart'; import 'package:colorpicker/src/components/checkerboard_square.dart'; import 'package:colorpicker/src/components/color_square.dart'; +import 'package:colorpicker/src/components/pipette_tool_button.dart'; import 'package:colorpicker/src/constants/colors.dart'; import 'package:colorpicker/src/components/color_comparison.dart'; import 'package:colorpicker/src/components/opacity_slider.dart'; import 'package:colorpicker/src/state/color_picker_state_provider.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'dart:ui' as ui; class ColorPicker extends ConsumerWidget { const ColorPicker({ super.key, required this.currentColor, required this.onColorChanged, + required this.image, }); final Color currentColor; final void Function(Color) onColorChanged; + final ui.Image? image; final colors = DisplayColors.colors; @@ -32,13 +37,32 @@ class ColorPicker extends ConsumerWidget { child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - ColorComparison( - currentColor: currentColor, - newColor: colorPickerStateData.currentColor != null - ? colorPickerStateData.currentColor!.withOpacity( - colorPickerStateData.currentOpacity, - ) - : currentColor, + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ColorComparison( + currentColor: currentColor, + newColor: colorPickerStateData.currentColor != null + ? colorPickerStateData.currentColor!.withOpacity( + colorPickerStateData.currentOpacity, + ) + : currentColor + .withOpacity(1.0) + .withOpacity(colorPickerStateData.currentOpacity), + ), + const Spacer(), + GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => PipetteToolPage(snapshot: image), + ), + ); + }, + child: const PipetteToolButton(), + ), + ], ), const SizedBox(height: 10.0), GridView.count( @@ -62,7 +86,7 @@ class ColorPicker extends ConsumerWidget { OpacitySlider( gradientColor: colorPickerStateData.currentColor != null ? colorPickerStateData.currentColor! - : currentColor, + : currentColor.withOpacity(1.0), ), const SizedBox(height: 20.0), Row( @@ -80,6 +104,10 @@ class ColorPicker extends ConsumerWidget { if (colorPickerStateData.currentColor != null) { onColorChanged(colorPickerStateData.currentColor! .withOpacity(colorPickerStateData.currentOpacity)); + } else { + onColorChanged(currentColor + .withOpacity(1.0) + .withOpacity(colorPickerStateData.currentOpacity)); } Navigator.pop(context); }, diff --git a/packages/colorpicker/lib/src/components/checkerboard_square.dart b/packages/colorpicker/lib/src/components/checkerboard_square.dart index 0f23d44d..4037e195 100644 --- a/packages/colorpicker/lib/src/components/checkerboard_square.dart +++ b/packages/colorpicker/lib/src/components/checkerboard_square.dart @@ -1,4 +1,3 @@ -import 'package:colorpicker/utils/assets.dart'; import 'package:flutter/material.dart'; class CheckerboardSquare extends StatelessWidget { @@ -6,13 +5,13 @@ class CheckerboardSquare extends StatelessWidget { @override Widget build(BuildContext context) { - return Container( - decoration: BoxDecoration( - image: DecorationImage( - image: PackageAssets.getCheckerboardImgAsset(), - fit: BoxFit.contain, - repeat: ImageRepeat.repeat, - ), + return Positioned.fill( + child: Image.asset( + 'packages/colorpicker/assets/img/checkerboard.png', + repeat: ImageRepeat.repeat, + cacheHeight: 16, + cacheWidth: 16, + filterQuality: FilterQuality.none, ), ); } diff --git a/packages/colorpicker/lib/src/components/color_comparison.dart b/packages/colorpicker/lib/src/components/color_comparison.dart index e7f33438..e323d80b 100644 --- a/packages/colorpicker/lib/src/components/color_comparison.dart +++ b/packages/colorpicker/lib/src/components/color_comparison.dart @@ -1,4 +1,3 @@ -import 'package:colorpicker/utils/assets.dart'; import 'package:flutter/material.dart'; class ColorComparison extends StatelessWidget { @@ -51,18 +50,21 @@ class ColorDescription extends StatelessWidget { return Column( children: [ Expanded( - child: Container( - decoration: BoxDecoration( - image: DecorationImage( - image: PackageAssets.getCheckerboardImgAsset(), - repeat: ImageRepeat.repeat, + child: Stack( + children: [ + Positioned.fill( + child: Image.asset( + 'packages/colorpicker/assets/img/checkerboard.png', + repeat: ImageRepeat.repeat, + cacheHeight: 16, + cacheWidth: 16, + filterQuality: FilterQuality.none, + ), ), - ), - child: Container( - decoration: BoxDecoration( - color: color, + Positioned.fill( + child: Container(color: color), ), - ), + ], ), ), const SizedBox(width: 8.0), diff --git a/packages/colorpicker/lib/src/components/opacity_slider.dart b/packages/colorpicker/lib/src/components/opacity_slider.dart index 27064f1b..8f75ca77 100644 --- a/packages/colorpicker/lib/src/components/opacity_slider.dart +++ b/packages/colorpicker/lib/src/components/opacity_slider.dart @@ -1,6 +1,6 @@ import 'package:colorpicker/src/components/slider_indicator_shape.dart'; import 'package:colorpicker/src/state/color_picker_state_provider.dart'; -import 'package:colorpicker/utils/assets.dart'; +// import 'package:colorpicker/utils/assets.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -15,47 +15,53 @@ class OpacitySlider extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final colorPickerStateData = ref.watch(colorPickerStateProvider); - return Container( - height: 25.0, - decoration: BoxDecoration( - image: DecorationImage( - image: PackageAssets.getCheckerboardImgAsset(), - fit: BoxFit.fitHeight, - repeat: ImageRepeat.repeat, - ), - ), - child: Container( - decoration: BoxDecoration( - gradient: LinearGradient( - colors: [ - gradientColor.withOpacity(1.0), - gradientColor.withOpacity(0.0), - ], - begin: Alignment.centerLeft, - end: Alignment.centerRight, + return Stack( + children: [ + Positioned.fill( + child: Image.asset( + 'packages/colorpicker/assets/img/checkerboard.png', + repeat: ImageRepeat.repeat, + cacheHeight: 16, + cacheWidth: 16, + filterQuality: FilterQuality.none, ), ), - child: SliderTheme( - data: SliderTheme.of(context).copyWith( - trackHeight: 25.0, - trackShape: CustomTrackShape(), - thumbShape: SliderIndicatorShape(), - inactiveTrackColor: Colors.transparent, - activeTrackColor: Colors.transparent, - overlayColor: Colors.transparent, - ), - child: Slider( - min: 0.0, - max: 1.0, - value: 1.0 - colorPickerStateData.currentOpacity, - onChanged: (position) { - ref - .read(colorPickerStateProvider.notifier) - .updateOpacity(1.0 - position); - }, + SizedBox( + height: 25.0, + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + colors: [ + gradientColor.withOpacity(1.0), + gradientColor.withOpacity(0.0), + ], + begin: Alignment.centerLeft, + end: Alignment.centerRight, + ), + ), + child: SliderTheme( + data: SliderTheme.of(context).copyWith( + trackHeight: 25.0, + trackShape: CustomTrackShape(), + thumbShape: SliderIndicatorShape(), + inactiveTrackColor: Colors.transparent, + activeTrackColor: Colors.transparent, + overlayColor: Colors.transparent, + ), + child: Slider( + min: 0.0, + max: 1.0, + value: 1.0 - colorPickerStateData.currentOpacity, + onChanged: (position) { + ref + .read(colorPickerStateProvider.notifier) + .updateOpacity(1.0 - position); + }, + ), + ), ), ), - ), + ], ); } } diff --git a/packages/colorpicker/lib/src/components/pipette_tool_button.dart b/packages/colorpicker/lib/src/components/pipette_tool_button.dart new file mode 100644 index 00000000..8035192b --- /dev/null +++ b/packages/colorpicker/lib/src/components/pipette_tool_button.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; + +class PipetteToolButton extends StatelessWidget { + const PipetteToolButton({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + height: 50.0, + width: 130.0, + padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 4.0), + decoration: BoxDecoration( + color: const Color.fromARGB(255, 204, 204, 204), + borderRadius: const BorderRadius.all(Radius.circular(6.0)), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.2), + offset: const Offset(0, 1), + blurRadius: 1.0, + ), + ], + ), + child: const Row( + children: [ + Icon( + Icons.auto_fix_normal, + color: Colors.black, + ), + Spacer(), + Text( + 'PIPETTE', + style: TextStyle( + color: Colors.black, + letterSpacing: 1.0, + fontWeight: FontWeight.w500, + fontSize: 15.0, + ), + ), + Spacer(), + ], + ), + ); + } +} diff --git a/packages/colorpicker/lib/src/components/top_bar.dart b/packages/colorpicker/lib/src/components/top_bar.dart new file mode 100644 index 00000000..b73568bf --- /dev/null +++ b/packages/colorpicker/lib/src/components/top_bar.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class TopBar extends ConsumerWidget { + const TopBar({ + super.key, + required this.color, + }); + + final Color color; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return AppBar( + title: Container( + height: 36.0, + width: 36.0, + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(2.0), + border: Border.all( + color: Colors.white, + width: 0.4, + ), + ), + ), + centerTitle: true, + actions: [ + IconButton( + icon: const Icon(Icons.check), + onPressed: () { + Navigator.pop(context); + }, + ), + const SizedBox(width: 10.0), + ], + ); + } +} diff --git a/packages/colorpicker/lib/src/state/color_picker_state_provider.dart b/packages/colorpicker/lib/src/state/color_picker_state_provider.dart index 7cd21022..454ef1f5 100644 --- a/packages/colorpicker/lib/src/state/color_picker_state_provider.dart +++ b/packages/colorpicker/lib/src/state/color_picker_state_provider.dart @@ -6,7 +6,7 @@ import 'package:colorpicker/src/constants/colors.dart'; part 'color_picker_state_provider.g.dart'; -@riverpod +@Riverpod(keepAlive: true) class ColorPickerState extends _$ColorPickerState { final colors = DisplayColors.colors; @override diff --git a/packages/colorpicker/lib/src/state/color_picker_state_provider.g.dart b/packages/colorpicker/lib/src/state/color_picker_state_provider.g.dart index 2ac4146f..5855d576 100644 --- a/packages/colorpicker/lib/src/state/color_picker_state_provider.g.dart +++ b/packages/colorpicker/lib/src/state/color_picker_state_provider.g.dart @@ -6,12 +6,12 @@ part of 'color_picker_state_provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$colorPickerStateHash() => r'd9193012d8a7cbf6b50a034ba7f1b9483095df9f'; +String _$colorPickerStateHash() => r'c98665b37a54dc06c6687b8ebd57bb72800f7571'; /// See also [ColorPickerState]. @ProviderFor(ColorPickerState) -final colorPickerStateProvider = AutoDisposeNotifierProvider.internal( +final colorPickerStateProvider = + NotifierProvider.internal( ColorPickerState.new, name: r'colorPickerStateProvider', debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product') @@ -21,6 +21,6 @@ final colorPickerStateProvider = AutoDisposeNotifierProvider; +typedef _$ColorPickerState = Notifier; // ignore_for_file: type=lint // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member From 5215c12eecb9cf48add4afecdf1440b2ec7b4b31 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Fri, 7 Jun 2024 22:08:05 +0530 Subject: [PATCH 35/39] fix dependencies --- pubspec.lock | 98 +++++++++++++++++++++------------------------------- 1 file changed, 40 insertions(+), 58 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index dcbd1735..60b1e5e6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,34 +5,34 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" + sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a url: "https://pub.dev" source: hosted - version: "67.0.0" + version: "61.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" + sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 url: "https://pub.dev" source: hosted - version: "6.4.1" + version: "5.13.0" analyzer_plugin: dependency: transitive description: name: analyzer_plugin - sha256: "9661b30b13a685efaee9f02e5d01ed9f2b423bd889d28a304d02d704aee69161" + sha256: c1d5f167683de03d5ab6c3b53fc9aeefc5d59476e7810ba7bbddff50c6f4392d url: "https://pub.dev" source: hosted - version: "0.11.3" + version: "0.11.2" archive: dependency: transitive description: name: archive - sha256: ecf4273855368121b1caed0d10d4513c7241dfc813f7d3c8933b36622ae9b265 + sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d url: "https://pub.dev" source: hosted - version: "3.5.1" + version: "3.6.1" args: dependency: transitive description: @@ -220,42 +220,34 @@ packages: dependency: transitive description: name: custom_lint - sha256: "7c0aec12df22f9082146c354692056677f1e70bc43471644d1fdb36c6fdda799" + sha256: "22bd87a362f433ba6aae127a7bac2838645270737f3721b180916d7c5946cb5d" url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.5.11" custom_lint_builder: dependency: transitive description: name: custom_lint_builder - sha256: d7dc41e709dde223806660268678be7993559e523eb3164e2a1425fd6f7615a9 + sha256: "0d48e002438950f9582e574ef806b2bea5719d8d14c0f9f754fbad729bcf3b19" url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.5.14" custom_lint_core: dependency: transitive description: name: custom_lint_core - sha256: a85e8f78f4c52f6c63cdaf8c872eb573db0231dcdf3c3a5906d493c1f8bc20e6 + sha256: "2952837953022de610dacb464f045594854ced6506ac7f76af28d4a6490e189b" url: "https://pub.dev" source: hosted - version: "0.6.3" + version: "0.5.14" dart_style: dependency: transitive description: name: dart_style - sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" + sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" url: "https://pub.dev" source: hosted - version: "2.3.6" - dev_build: - dependency: transitive - description: - name: dev_build - sha256: "2fa3bf81b5e92504f8d7a412df2c69b61a24ceca468466e5e777cbb59c30af96" - url: "https://pub.dev" - source: hosted - version: "0.16.5" + version: "2.3.2" device_info_plus: dependency: "direct main" description: @@ -364,34 +356,26 @@ packages: dependency: "direct main" description: name: floor - sha256: c1b06023912b5b8e49deb6a9d867863c535ae1a232d991c3582bba3ee8687867 + sha256: "52a8eac2c8d274e7c0c54251226f59786bb5b749365a2d8537d8095aa5132d92" url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.4.2" floor_annotation: dependency: transitive description: name: floor_annotation - sha256: a40949580a7ab0eee572686e2d3b1638fd6bd6a753e661d792ab4236b365b23b - url: "https://pub.dev" - source: hosted - version: "1.5.0" - floor_common: - dependency: transitive - description: - name: floor_common - sha256: "41c9914862f83a821815e1b1ffd47a1e1ae2130c35ff882ba2d000a67713ba64" + sha256: fa3fa4f198cdd1d922a69ceb06e54663fe59256bf1cb3c036eff206b445a6960 url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.4.2" floor_generator: dependency: "direct dev" description: name: floor_generator - sha256: "1499b3ab878a807e6fbe6f140dc014124845cd1df3090a113aae5fa7577a1e77" + sha256: "40aaf1b619adc03367ce4b7c79161e3198d43b572b5ec9cc99a4a89de27b08d2" url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.4.2" flutter: dependency: "direct main" description: flutter @@ -815,10 +799,10 @@ packages: dependency: transitive description: name: path_provider_foundation - sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 + sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.3.2" path_provider_linux: dependency: transitive description: @@ -935,10 +919,10 @@ packages: dependency: transitive description: name: pubspec_parse - sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 url: "https://pub.dev" source: hosted - version: "1.2.3" + version: "1.3.0" riverpod: dependency: "direct dev" description: @@ -951,10 +935,10 @@ packages: dependency: transitive description: name: riverpod_analyzer_utils - sha256: "8b71f03fc47ae27d13769496a1746332df4cec43918aeba9aff1e232783a780f" + sha256: d72d7096964baf288b55619fe48100001fc4564ab7923ed0a7f5c7650e03c0d6 url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.3.4" riverpod_annotation: dependency: "direct main" description: @@ -967,18 +951,18 @@ packages: dependency: "direct dev" description: name: riverpod_generator - sha256: d451608bf17a372025fc36058863737636625dfdb7e3cbf6142e0dfeb366ab22 + sha256: "5b36ad2f2b562cffb37212e8d59390b25499bf045b732276e30a207b16a25f61" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.3.3" riverpod_lint: dependency: "direct dev" description: name: riverpod_lint - sha256: "3c67c14ccd16f0c9d53e35ef70d06cd9d072e2fb14557326886bbde903b230a5" + sha256: "70198738c3047ae4f6517ef1a2011a8514a980a52576c7f629a3a08810319a02" url: "https://pub.dev" source: hosted - version: "2.3.10" + version: "2.1.1" rxdart: dependency: transitive description: @@ -1140,10 +1124,10 @@ packages: dependency: transitive description: name: sqlparser - sha256: "7b20045d1ccfb7bc1df7e8f9fee5ae58673fce6ff62cefbb0e0fd7214e90e5a0" + sha256: "91f47610aa54d8abf9d795a7b4e49b2a788f65d7493d5a68fbf180c3cbcc6f38" url: "https://pub.dev" source: hosted - version: "0.34.1" + version: "0.27.0" stack_trace: dependency: transitive description: @@ -1188,10 +1172,10 @@ packages: dependency: transitive description: name: strings - sha256: b33f40c4dd3e597bf6d9e7f4f4dc282dad0f19b07d9f320cb5c2183859cbccf5 + sha256: "5af86299505c299640f5564e187c1a2ee9d6308c540e8d65f6385f5c67019122" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "0.2.2" sync_http: dependency: transitive description: @@ -1268,18 +1252,18 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e" + sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3" url: "https://pub.dev" source: hosted - version: "6.2.6" + version: "6.3.0" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "360a6ed2027f18b73c8d98e159dda67a61b7f2e0f6ec26e86c3ada33b0621775" + sha256: "17cd5e205ea615e2c6ea7a77323a11712dffa0720a8a90540db57a01347f9ad9" url: "https://pub.dev" source: hosted - version: "6.3.1" + version: "6.3.2" url_launcher_ios: dependency: transitive description: @@ -1301,11 +1285,9 @@ packages: description: name: url_launcher_macos sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de" - sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de" url: "https://pub.dev" source: hosted version: "3.2.0" - version: "3.2.0" url_launcher_platform_interface: dependency: transitive description: From 3e64b1f9b71a23b1976e565e436e5f11dccf8c9b Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Sun, 9 Jun 2024 23:45:06 +0530 Subject: [PATCH 36/39] fix test error --- packages/colorpicker/lib/src/colorpicker.dart | 2 +- .../lib/src/components/color_comparison.dart | 2 +- .../src/components/pipette_tool_button.dart | 7 ++- pubspec.lock | 60 +++++++++++++------ 4 files changed, 48 insertions(+), 23 deletions(-) diff --git a/packages/colorpicker/lib/src/colorpicker.dart b/packages/colorpicker/lib/src/colorpicker.dart index 4727c902..d44d9b1e 100644 --- a/packages/colorpicker/lib/src/colorpicker.dart +++ b/packages/colorpicker/lib/src/colorpicker.dart @@ -75,7 +75,7 @@ class ColorPicker extends ConsumerWidget { colors.length + 1, (index) { if (index == colors.length) { - return const CheckerboardSquare(); + return const Stack(children: [CheckerboardSquare()]); } else { return ColorSquare(color: colors[index]); } diff --git a/packages/colorpicker/lib/src/components/color_comparison.dart b/packages/colorpicker/lib/src/components/color_comparison.dart index e323d80b..3ac0d2c9 100644 --- a/packages/colorpicker/lib/src/components/color_comparison.dart +++ b/packages/colorpicker/lib/src/components/color_comparison.dart @@ -13,7 +13,7 @@ class ColorComparison extends StatelessWidget { @override Widget build(BuildContext context) { return SizedBox( - width: 130.0, + width: 120.0, height: 70.0, child: Row( children: [ diff --git a/packages/colorpicker/lib/src/components/pipette_tool_button.dart b/packages/colorpicker/lib/src/components/pipette_tool_button.dart index 8035192b..81151d02 100644 --- a/packages/colorpicker/lib/src/components/pipette_tool_button.dart +++ b/packages/colorpicker/lib/src/components/pipette_tool_button.dart @@ -7,7 +7,7 @@ class PipetteToolButton extends StatelessWidget { Widget build(BuildContext context) { return Container( height: 50.0, - width: 130.0, + width: 148.0, padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 4.0), decoration: BoxDecoration( color: const Color.fromARGB(255, 204, 204, 204), @@ -21,19 +21,20 @@ class PipetteToolButton extends StatelessWidget { ], ), child: const Row( + mainAxisAlignment: MainAxisAlignment.center, children: [ + Spacer(), Icon( Icons.auto_fix_normal, color: Colors.black, + size: 20, ), Spacer(), Text( 'PIPETTE', style: TextStyle( color: Colors.black, - letterSpacing: 1.0, fontWeight: FontWeight.w500, - fontSize: 15.0, ), ), Spacer(), diff --git a/pubspec.lock b/pubspec.lock index 60b1e5e6..b9644491 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -292,10 +292,10 @@ packages: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.0" file_picker: dependency: "direct main" description: @@ -659,6 +659,30 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.1" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" lints: dependency: transitive description: @@ -687,26 +711,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mime: dependency: transitive description: @@ -759,10 +783,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_drawing: dependency: transitive description: @@ -879,10 +903,10 @@ packages: dependency: transitive description: name: platform - sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.4" plugin_platform_interface: dependency: transitive description: @@ -903,10 +927,10 @@ packages: dependency: transitive description: name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" url: "https://pub.dev" source: hosted - version: "4.2.4" + version: "5.0.2" pub_semver: dependency: transitive description: @@ -1332,10 +1356,10 @@ packages: dependency: transitive description: name: vm_service - sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583 + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 url: "https://pub.dev" source: hosted - version: "11.10.0" + version: "13.0.0" watcher: dependency: transitive description: @@ -1364,10 +1388,10 @@ packages: dependency: transitive description: name: webdriver - sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49" + sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" win32: dependency: transitive description: From 3677ed4000f6b31a26aac34a133f6cb80ffee850 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Mon, 10 Jun 2024 00:18:57 +0530 Subject: [PATCH 37/39] update makefile to run pub get in packages --- Makefile | 7 +++++++ packages/colorpicker/pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e659c228..5d61410c 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,7 @@ FVM_PRESENT := $(shell command -v fvm 2> /dev/null) # Use fvm if installed; otherwise use flutter directly FLUTTER_CMD := $(if $(FVM_PRESENT),fvm flutter,flutter) DART_CMD := $(if $(FVM_PRESENT),fvm dart,dart) +PACKAGES_DIR := packages @@ -14,6 +15,12 @@ clean: get: $(FLUTTER_CMD) pub get + @for dir in $(shell find $(PACKAGES_DIR) -maxdepth 1 -type d); do \ + if [ "$$dir" != "$(PACKAGES_DIR)" ]; then \ + echo "Running $(FLUTTER_CMD) pub get in $$dir"; \ + (cd $$dir && $(FLUTTER_CMD) pub get); \ + fi \ + done run: $(FLUTTER_CMD) run diff --git a/packages/colorpicker/pubspec.yaml b/packages/colorpicker/pubspec.yaml index fa1b8386..cbd18409 100644 --- a/packages/colorpicker/pubspec.yaml +++ b/packages/colorpicker/pubspec.yaml @@ -21,7 +21,7 @@ dev_dependencies: flutter_lints: ^2.0.0 build_runner: ^2.2.0 riverpod_generator: ^2.2.3 - riverpod_lint: ^1.3.2 + riverpod_lint: ^2.1.1 freezed: ^2.4.1 flutter: From d6d8c929394e76afeabf4a74f3474e66e8057373 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Sun, 23 Jun 2024 12:04:24 +0530 Subject: [PATCH 38/39] add basic color match test --- .../lib/src/components/opacity_slider.dart | 1 + packages/colorpicker/pubspec.yaml | 1 + .../test/widget/pipette_tool_test.dart | 58 ++++++++++++++ test/utils/bottom_nav_bar_interactions.dart | 30 +++++++ .../workspace_page/color_match_test.dart | 78 +++++++++++++++++++ 5 files changed, 168 insertions(+) create mode 100644 packages/colorpicker/test/widget/pipette_tool_test.dart create mode 100644 test/widget/workspace_page/color_match_test.dart diff --git a/packages/colorpicker/lib/src/components/opacity_slider.dart b/packages/colorpicker/lib/src/components/opacity_slider.dart index 8f75ca77..267ff76b 100644 --- a/packages/colorpicker/lib/src/components/opacity_slider.dart +++ b/packages/colorpicker/lib/src/components/opacity_slider.dart @@ -49,6 +49,7 @@ class OpacitySlider extends ConsumerWidget { overlayColor: Colors.transparent, ), child: Slider( + key: const Key('opacity_slider'), min: 0.0, max: 1.0, value: 1.0 - colorPickerStateData.currentOpacity, diff --git a/packages/colorpicker/pubspec.yaml b/packages/colorpicker/pubspec.yaml index cbd18409..06f85e82 100644 --- a/packages/colorpicker/pubspec.yaml +++ b/packages/colorpicker/pubspec.yaml @@ -18,6 +18,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + mockito: ^5.2.0 flutter_lints: ^2.0.0 build_runner: ^2.2.0 riverpod_generator: ^2.2.3 diff --git a/packages/colorpicker/test/widget/pipette_tool_test.dart b/packages/colorpicker/test/widget/pipette_tool_test.dart new file mode 100644 index 00000000..f1d22e6e --- /dev/null +++ b/packages/colorpicker/test/widget/pipette_tool_test.dart @@ -0,0 +1,58 @@ +import 'dart:ui' as ui; +import 'package:colorpicker/pages/pipette_tool_page.dart'; +import 'package:colorpicker/src/state/color_picker_state_data.dart'; +import 'package:colorpicker/src/state/color_picker_state_provider.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_test/flutter_test.dart'; + +// Helper function to create a sample image for testing +Future createTestImage() async { + final pictureRecorder = ui.PictureRecorder(); + final canvas = Canvas(pictureRecorder); + final paint = Paint()..color = const Color(0xFFFF0000); + canvas.drawRect(const Rect.fromLTWH(0, 0, 100, 100), paint); + final picture = pictureRecorder.endRecording(); + return picture.toImage(100, 100); +} + +void main() { + testWidgets('PipetteToolPage displays image and updates color on tap', + (WidgetTester tester) async { + // Create a sample image for testing + final image = await createTestImage(); + + // Override the provider for testing + final container = ProviderContainer(overrides: [ + colorPickerStateProvider.overrideWith( + () => ColorPickerState() + ..state = const ColorPickerStateData( + currentColor: Colors.red, currentOpacity: 1.0), + ), + ]); + + // Build the widget + await tester.pumpWidget( + UncontrolledProviderScope( + container: container, + child: MaterialApp( + home: PipetteToolPage(snapshot: image), + ), + ), + ); + + // Wait for the image to load + await tester.pumpAndSettle(); + + // Verify that the image is displayed + expect(find.byType(CustomPaint), findsOneWidget); + + // Tap on the image to update the color + await tester.tap(find.byType(CustomPaint)); + await tester.pumpAndSettle(); + + // Verify that the color update was called + final colorState = container.read(colorPickerStateProvider); + expect(colorState.currentColor, isNotNull); + }); +} diff --git a/test/utils/bottom_nav_bar_interactions.dart b/test/utils/bottom_nav_bar_interactions.dart index 679520de..c11b8899 100644 --- a/test/utils/bottom_nav_bar_interactions.dart +++ b/test/utils/bottom_nav_bar_interactions.dart @@ -72,6 +72,36 @@ class BottomNavBarInteractions { return this; } + Future selectColorWithOpacity(Color color) async { + await openColorPicker(); + + final colorButton = _findButtonWithColor(color); + expect(colorButton, findsOneWidget); + await _tester.tap(colorButton); + await _tester.pumpAndSettle(); + + final opacitySliderWidget = find.descendant( + of: find.byType(SliderTheme), + matching: find.byKey(const Key('opacity_slider')), + ); + expect(opacitySliderWidget, findsOneWidget); + final sliderCenter = _tester.getCenter(opacitySliderWidget); + await _tester.tapAt(sliderCenter); + await _tester.pumpAndSettle(); + + final applyButton = find.descendant( + of: find.byWidgetPredicate((Widget widget) => widget is Row), + matching: find.text('APPLY'), + ); + expect(applyButton, findsWidgets); + await _tester.dragUntilVisible( + applyButton, find.byType(SingleChildScrollView), const Offset(0, 50)); + await _tester.pumpAndSettle(); + await _tester.tap(applyButton); + await _tester.pumpAndSettle(); + return this; + } + Future checkActiveColor(Color color) async { final thirdNavDestination = find.byType(NavigationDestination).at(2); final activeColor = find.descendant( diff --git a/test/widget/workspace_page/color_match_test.dart b/test/widget/workspace_page/color_match_test.dart new file mode 100644 index 00000000..71272650 --- /dev/null +++ b/test/widget/workspace_page/color_match_test.dart @@ -0,0 +1,78 @@ +// Flutter imports: +import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +// Package imports: +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:integration_test/integration_test.dart'; +import 'package:paintroid/app.dart'; +import 'package:paintroid/core/localization/app_localizations.dart'; +import 'package:paintroid/ui/pages/workspace_page/workspace_page.dart'; +import 'package:paintroid/ui/theme/data/dark_paintroid_theme_data.dart'; +import 'package:paintroid/ui/theme/data/light_paintroid_theme_data.dart'; +import 'package:paintroid/ui/theme/data/paintroid_theme.dart'; +// Project imports: +import '../../utils/test_utils.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + late Widget sut1, sut2; + + setUp(() async { + sut1 = ProviderScope( + child: App( + showOnboardingPage: false, + ), + ); + + final lightTheme = LightPaintroidThemeData(); + final darkTheme = DarkPaintroidThemeData(); + + sut2 = ProviderScope( + child: PaintroidTheme( + lightTheme: lightTheme, + darkTheme: darkTheme, + child: MaterialApp( + theme: lightTheme.materialThemeData, + darkTheme: darkTheme.materialThemeData, + home: const WorkspacePage(), + localizationsDelegates: const [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + ], + ), + ), + ); + }); + + group('Color displays correctly', () { + testWidgets( + 'Color and opacity remain same on two successive uses', + (WidgetTester tester) async { + UIInteraction.initialize(tester); + await tester.pumpWidget(sut1); + await UIInteraction.createNewImage(); + + const blueColor = Color(0xff0073cc); + + await tester.pumpWidget(sut2); + final bottomNavBarInteractions = BottomNavBarInteractions(tester); + await bottomNavBarInteractions + .selectColorWithOpacity(blueColor) + .then((_) async { + UIInteraction.initialize(tester); + await tester.pumpWidget(sut1); + await tester.tapAt(const Offset(20, 20)); + await tester.pumpAndSettle(); + await tester.tapAt(const Offset(10, 10)); + await tester.pumpAndSettle(); + + final colorAtFirstTap = await UIInteraction.getPixelColor(20, 20); + final colorAtSecondTap = await UIInteraction.getPixelColor(10, 10); + + expect(colorAtFirstTap, equals(colorAtSecondTap)); + }); + }); + }); +} \ No newline at end of file From 6fb279ee3d69f6c8ae28fe7cb7e9166572b900b7 Mon Sep 17 00:00:00 2001 From: Bhav Khurana Date: Mon, 19 Aug 2024 17:45:48 +0530 Subject: [PATCH 39/39] fix errors --- .../workspace_page/color_match_test.dart | 78 ------------------- 1 file changed, 78 deletions(-) delete mode 100644 test/widget/workspace_page/color_match_test.dart diff --git a/test/widget/workspace_page/color_match_test.dart b/test/widget/workspace_page/color_match_test.dart deleted file mode 100644 index 71272650..00000000 --- a/test/widget/workspace_page/color_match_test.dart +++ /dev/null @@ -1,78 +0,0 @@ -// Flutter imports: -import 'package:flutter/material.dart'; -import 'package:flutter_localizations/flutter_localizations.dart'; -// Package imports: -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:integration_test/integration_test.dart'; -import 'package:paintroid/app.dart'; -import 'package:paintroid/core/localization/app_localizations.dart'; -import 'package:paintroid/ui/pages/workspace_page/workspace_page.dart'; -import 'package:paintroid/ui/theme/data/dark_paintroid_theme_data.dart'; -import 'package:paintroid/ui/theme/data/light_paintroid_theme_data.dart'; -import 'package:paintroid/ui/theme/data/paintroid_theme.dart'; -// Project imports: -import '../../utils/test_utils.dart'; - -void main() { - IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - - late Widget sut1, sut2; - - setUp(() async { - sut1 = ProviderScope( - child: App( - showOnboardingPage: false, - ), - ); - - final lightTheme = LightPaintroidThemeData(); - final darkTheme = DarkPaintroidThemeData(); - - sut2 = ProviderScope( - child: PaintroidTheme( - lightTheme: lightTheme, - darkTheme: darkTheme, - child: MaterialApp( - theme: lightTheme.materialThemeData, - darkTheme: darkTheme.materialThemeData, - home: const WorkspacePage(), - localizationsDelegates: const [ - AppLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - ], - ), - ), - ); - }); - - group('Color displays correctly', () { - testWidgets( - 'Color and opacity remain same on two successive uses', - (WidgetTester tester) async { - UIInteraction.initialize(tester); - await tester.pumpWidget(sut1); - await UIInteraction.createNewImage(); - - const blueColor = Color(0xff0073cc); - - await tester.pumpWidget(sut2); - final bottomNavBarInteractions = BottomNavBarInteractions(tester); - await bottomNavBarInteractions - .selectColorWithOpacity(blueColor) - .then((_) async { - UIInteraction.initialize(tester); - await tester.pumpWidget(sut1); - await tester.tapAt(const Offset(20, 20)); - await tester.pumpAndSettle(); - await tester.tapAt(const Offset(10, 10)); - await tester.pumpAndSettle(); - - final colorAtFirstTap = await UIInteraction.getPixelColor(20, 20); - final colorAtSecondTap = await UIInteraction.getPixelColor(10, 10); - - expect(colorAtFirstTap, equals(colorAtSecondTap)); - }); - }); - }); -} \ No newline at end of file