diff --git a/.VSCodeCounter/2025-08-24_12-43-46/details.md b/.VSCodeCounter/2025-08-24_12-43-46/details.md new file mode 100644 index 0000000..9809de8 --- /dev/null +++ b/.VSCodeCounter/2025-08-24_12-43-46/details.md @@ -0,0 +1,148 @@ +# Details + +Date : 2025-08-24 12:43:46 + +Directory /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer + +Total : 133 files, 6259 codes, 411 comments, 1006 blanks, all 7676 lines + +[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md) + +## Files +| filename | language | code | comment | blank | total | +| :--- | :--- | ---: | ---: | ---: | ---: | +| [.github/workflows/script.yml](/.github/workflows/script.yml) | YAML | 24 | 0 | 7 | 31 | +| [README.md](/README.md) | Markdown | 53 | 0 | 10 | 63 | +| [analysis\_options.yaml](/analysis_options.yaml) | YAML | 3 | 22 | 4 | 29 | +| [android/app/build.gradle](/android/app/build.gradle) | Groovy | 44 | 6 | 9 | 59 | +| [android/app/src/debug/AndroidManifest.xml](/android/app/src/debug/AndroidManifest.xml) | XML | 3 | 4 | 1 | 8 | +| [android/app/src/main/AndroidManifest.xml](/android/app/src/main/AndroidManifest.xml) | XML | 34 | 11 | 1 | 46 | +| [android/app/src/main/res/drawable-v21/launch\_background.xml](/android/app/src/main/res/drawable-v21/launch_background.xml) | XML | 4 | 7 | 2 | 13 | +| [android/app/src/main/res/drawable/launch\_background.xml](/android/app/src/main/res/drawable/launch_background.xml) | XML | 4 | 7 | 2 | 13 | +| [android/app/src/main/res/values-night/styles.xml](/android/app/src/main/res/values-night/styles.xml) | XML | 9 | 9 | 1 | 19 | +| [android/app/src/main/res/values/styles.xml](/android/app/src/main/res/values/styles.xml) | XML | 9 | 9 | 1 | 19 | +| [android/app/src/profile/AndroidManifest.xml](/android/app/src/profile/AndroidManifest.xml) | XML | 3 | 4 | 1 | 8 | +| [android/build.gradle](/android/build.gradle) | Groovy | 16 | 0 | 3 | 19 | +| [android/gradle.properties](/android/gradle.properties) | Properties | 3 | 0 | 1 | 4 | +| [android/gradle/wrapper/gradle-wrapper.properties](/android/gradle/wrapper/gradle-wrapper.properties) | Properties | 5 | 0 | 1 | 6 | +| [android/settings.gradle](/android/settings.gradle) | Groovy | 21 | 0 | 5 | 26 | +| [ios/Podfile](/ios/Podfile) | Ruby | 32 | 3 | 10 | 45 | +| [ios/Runner/AppDelegate.swift](/ios/Runner/AppDelegate.swift) | Swift | 12 | 0 | 2 | 14 | +| [ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json](/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json) | JSON | 122 | 0 | 1 | 123 | +| [ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json](/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json) | JSON | 23 | 0 | 1 | 24 | +| [ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md](/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md) | Markdown | 3 | 0 | 2 | 5 | +| [ios/Runner/Base.lproj/LaunchScreen.storyboard](/ios/Runner/Base.lproj/LaunchScreen.storyboard) | XML | 36 | 1 | 1 | 38 | +| [ios/Runner/Base.lproj/Main.storyboard](/ios/Runner/Base.lproj/Main.storyboard) | XML | 25 | 1 | 1 | 27 | +| [ios/Runner/Runner-Bridging-Header.h](/ios/Runner/Runner-Bridging-Header.h) | C++ | 1 | 0 | 1 | 2 | +| [ios/RunnerTests/RunnerTests.swift](/ios/RunnerTests/RunnerTests.swift) | Swift | 7 | 2 | 4 | 13 | +| [lib/config/routes/route\_app.dart](/lib/config/routes/route_app.dart) | Dart | 125 | 1 | 9 | 135 | +| [lib/config/themes/app\_theme.dart](/lib/config/themes/app_theme.dart) | Dart | 239 | 2 | 14 | 255 | +| [lib/core/draggable\_progress.dart](/lib/core/draggable_progress.dart) | Dart | 42 | 0 | 4 | 46 | +| [lib/core/enums/app\_settings\_enum.dart](/lib/core/enums/app_settings_enum.dart) | Dart | 1 | 0 | 2 | 3 | +| [lib/core/extensions/language.dart](/lib/core/extensions/language.dart) | Dart | 20 | 0 | 5 | 25 | +| [lib/core/extensions/navigators.dart](/lib/core/extensions/navigators.dart) | Dart | 126 | 3 | 16 | 145 | +| [lib/core/helpers/app\_bar/app\_bar.dart](/lib/core/helpers/app_bar/app_bar.dart) | Dart | 127 | 2 | 13 | 142 | +| [lib/core/helpers/app\_bar/back\_button.dart](/lib/core/helpers/app_bar/back_button.dart) | Dart | 21 | 0 | 6 | 27 | +| [lib/core/helpers/current\_device.dart](/lib/core/helpers/current_device.dart) | Dart | 7 | 0 | 2 | 9 | +| [lib/core/helpers/custom\_alert\_dialog.dart](/lib/core/helpers/custom_alert_dialog.dart) | Dart | 123 | 0 | 8 | 131 | +| [lib/core/helpers/random\_int.dart](/lib/core/helpers/random_int.dart) | Dart | 9 | 0 | 4 | 13 | +| [lib/core/helpers/random\_text.dart](/lib/core/helpers/random_text.dart) | Dart | 13 | 0 | 7 | 20 | +| [lib/core/helpers/screen\_size.dart](/lib/core/helpers/screen_size.dart) | Dart | 7 | 0 | 2 | 9 | +| [lib/core/helpers/storage/app\_settings/app\_settings\_cubit.dart](/lib/core/helpers/storage/app_settings/app_settings_cubit.dart) | Dart | 62 | 10 | 21 | 93 | +| [lib/core/helpers/storage/app\_settings/app\_settings\_state.dart](/lib/core/helpers/storage/app_settings/app_settings_state.dart) | Dart | 18 | 0 | 5 | 23 | +| [lib/core/helpers/svg\_picture.dart](/lib/core/helpers/svg_picture.dart) | Dart | 31 | 0 | 3 | 34 | +| [lib/core/helpers/system\_overlay\_style.dart](/lib/core/helpers/system_overlay_style.dart) | Dart | 51 | 0 | 6 | 57 | +| [lib/core/material\_app/my\_app.dart](/lib/core/material_app/my_app.dart) | Dart | 74 | 5 | 9 | 88 | +| [lib/core/resources/color\_manager.dart](/lib/core/resources/color_manager.dart) | Dart | 79 | 23 | 8 | 110 | +| [lib/core/resources/font\_manager.dart](/lib/core/resources/font_manager.dart) | Dart | 26 | 11 | 4 | 41 | +| [lib/core/resources/strings\_manager.dart](/lib/core/resources/strings_manager.dart) | Dart | 41 | 2 | 5 | 48 | +| [lib/core/resources/styles\_manager.dart](/lib/core/resources/styles_manager.dart) | Dart | 77 | 0 | 7 | 84 | +| [lib/core/resources/theme\_manager.dart](/lib/core/resources/theme_manager.dart) | Dart | 86 | 2 | 10 | 98 | +| [lib/core/widgets/adapt\_widget\_size.dart](/lib/core/widgets/adapt_widget_size.dart) | Dart | 18 | 0 | 4 | 22 | +| [lib/core/widgets/adaptive/padding/adaptive\_padding.dart](/lib/core/widgets/adaptive/padding/adaptive_padding.dart) | Dart | 20 | 0 | 2 | 22 | +| [lib/core/widgets/adaptive/padding/all\_padding.dart](/lib/core/widgets/adaptive/padding/all_padding.dart) | Dart | 11 | 0 | 2 | 13 | +| [lib/core/widgets/adaptive/padding/bottom\_padding.dart](/lib/core/widgets/adaptive/padding/bottom_padding.dart) | Dart | 11 | 0 | 3 | 14 | +| [lib/core/widgets/adaptive/padding/end\_padding.dart](/lib/core/widgets/adaptive/padding/end_padding.dart) | Dart | 11 | 0 | 2 | 13 | +| [lib/core/widgets/adaptive/padding/horizontal\_padding.dart](/lib/core/widgets/adaptive/padding/horizontal_padding.dart) | Dart | 12 | 0 | 2 | 14 | +| [lib/core/widgets/adaptive/padding/only\_padding.dart](/lib/core/widgets/adaptive/padding/only_padding.dart) | Dart | 28 | 0 | 3 | 31 | +| [lib/core/widgets/adaptive/padding/start\_padding.dart](/lib/core/widgets/adaptive/padding/start_padding.dart) | Dart | 12 | 0 | 1 | 13 | +| [lib/core/widgets/adaptive/padding/symmetric\_padding.dart](/lib/core/widgets/adaptive/padding/symmetric_padding.dart) | Dart | 17 | 0 | 2 | 19 | +| [lib/core/widgets/adaptive/padding/top\_padding.dart](/lib/core/widgets/adaptive/padding/top_padding.dart) | Dart | 12 | 0 | 1 | 13 | +| [lib/core/widgets/adaptive/padding/vertical\_padding.dart](/lib/core/widgets/adaptive/padding/vertical_padding.dart) | Dart | 12 | 0 | 2 | 14 | +| [lib/core/widgets/adaptive/text/adaptive\_text.dart](/lib/core/widgets/adaptive/text/adaptive_text.dart) | Dart | 91 | 5 | 13 | 109 | +| [lib/core/widgets/adaptive/text/bold\_text.dart](/lib/core/widgets/adaptive/text/bold_text.dart) | Dart | 15 | 0 | 2 | 17 | +| [lib/core/widgets/adaptive/text/light\_text.dart](/lib/core/widgets/adaptive/text/light_text.dart) | Dart | 14 | 0 | 2 | 16 | +| [lib/core/widgets/adaptive/text/medium\_text.dart](/lib/core/widgets/adaptive/text/medium_text.dart) | Dart | 16 | 0 | 2 | 18 | +| [lib/core/widgets/adaptive/text/regular\_text.dart](/lib/core/widgets/adaptive/text/regular_text.dart) | Dart | 14 | 0 | 2 | 16 | +| [lib/core/widgets/adaptive/text/semi\_bold\_text.dart](/lib/core/widgets/adaptive/text/semi_bold_text.dart) | Dart | 15 | 0 | 2 | 17 | +| [lib/core/widgets/custom\_widgets/check\_box.dart](/lib/core/widgets/custom_widgets/check_box.dart) | Dart | 51 | 0 | 2 | 53 | +| [lib/core/widgets/custom\_widgets/custom\_bottom\_sheet.dart](/lib/core/widgets/custom_widgets/custom_bottom_sheet.dart) | Dart | 197 | 0 | 8 | 205 | +| [lib/core/widgets/custom\_widgets/custom\_circulars\_progress.dart](/lib/core/widgets/custom_widgets/custom_circulars_progress.dart) | Dart | 215 | 0 | 24 | 239 | +| [lib/core/widgets/custom\_widgets/custom\_dialog.dart](/lib/core/widgets/custom_widgets/custom_dialog.dart) | Dart | 91 | 0 | 6 | 97 | +| [lib/core/widgets/custom\_widgets/custom\_divider.dart](/lib/core/widgets/custom_widgets/custom_divider.dart) | Dart | 29 | 0 | 4 | 33 | +| [lib/core/widgets/custom\_widgets/custom\_icon.dart](/lib/core/widgets/custom_widgets/custom_icon.dart) | Dart | 25 | 0 | 2 | 27 | +| [lib/core/widgets/custom\_widgets/custom\_rounded\_elevated\_button.dart](/lib/core/widgets/custom_widgets/custom_rounded_elevated_button.dart) | Dart | 45 | 0 | 4 | 49 | +| [lib/core/widgets/custom\_widgets/custom\_switch.dart](/lib/core/widgets/custom_widgets/custom_switch.dart) | Dart | 35 | 2 | 4 | 41 | +| [lib/core/widgets/custom\_widgets/error\_screen.dart](/lib/core/widgets/custom_widgets/error_screen.dart) | Dart | 26 | 0 | 2 | 28 | +| [lib/core/widgets/custom\_widgets/hero\_widget.dart](/lib/core/widgets/custom_widgets/hero_widget.dart) | Dart | 15 | 0 | 3 | 18 | +| [lib/core/widgets/custom\_widgets/keyboard\_detected.dart](/lib/core/widgets/custom_widgets/keyboard_detected.dart) | Dart | 47 | 0 | 9 | 56 | +| [lib/core/widgets/custom\_widgets/rounded\_outlined\_button.dart](/lib/core/widgets/custom_widgets/rounded_outlined_button.dart) | Dart | 44 | 0 | 4 | 48 | +| [lib/core/widgets/custom\_widgets/scale\_transition.dart](/lib/core/widgets/custom_widgets/scale_transition.dart) | Dart | 34 | 0 | 6 | 40 | +| [lib/core/widgets/custom\_widgets/vertical\_animation\_hero\_page.dart](/lib/core/widgets/custom_widgets/vertical_animation_hero_page.dart) | Dart | 39 | 0 | 4 | 43 | +| [lib/features/base/view/base\_page.dart](/lib/features/base/view/base_page.dart) | Dart | 52 | 0 | 5 | 57 | +| [lib/features/searching/view/grid\_page.dart](/lib/features/searching/view/grid_page.dart) | Dart | 290 | 0 | 35 | 325 | +| [lib/features/searching/view\_model/grid\_notifier.dart](/lib/features/searching/view_model/grid_notifier.dart) | Dart | 384 | 18 | 109 | 511 | +| [lib/features/searching/view\_model/grid\_notifier\_state.dart](/lib/features/searching/view_model/grid_notifier_state.dart) | Dart | 50 | 1 | 7 | 58 | +| [lib/features/searching/widgets/searcher\_grid.dart](/lib/features/searching/widgets/searcher_grid.dart) | Dart | 79 | 3 | 14 | 96 | +| [lib/features/sorting/base/helper/sortable\_item.dart](/lib/features/sorting/base/helper/sortable_item.dart) | Dart | 45 | 1 | 8 | 54 | +| [lib/features/sorting/base/helper/sorting\_enums.dart](/lib/features/sorting/base/helper/sorting_enums.dart) | Dart | 9 | 6 | 4 | 19 | +| [lib/features/sorting/base/view/sorting\_list\_page.dart](/lib/features/sorting/base/view/sorting_list_page.dart) | Dart | 60 | 0 | 3 | 63 | +| [lib/features/sorting/base/view/sorting\_page.dart](/lib/features/sorting/base/view/sorting_page.dart) | Dart | 205 | 1 | 19 | 225 | +| [lib/features/sorting/base/view\_model/sorting\_notifier.dart](/lib/features/sorting/base/view_model/sorting_notifier.dart) | Dart | 143 | 4 | 48 | 195 | +| [lib/features/sorting/base/view\_model/sorting\_state.dart](/lib/features/sorting/base/view_model/sorting_state.dart) | Dart | 31 | 0 | 3 | 34 | +| [lib/features/sorting/base/widgets/control\_buttons.dart](/lib/features/sorting/base/widgets/control_buttons.dart) | Dart | 47 | 0 | 3 | 50 | +| [lib/features/sorting/base/widgets/sorting\_app\_bar.dart](/lib/features/sorting/base/widgets/sorting_app_bar.dart) | Dart | 1 | 43 | 1 | 45 | +| [lib/features/sorting/bubble/view/bubble\_sort\_page.dart](/lib/features/sorting/bubble/view/bubble_sort_page.dart) | Dart | 25 | 0 | 6 | 31 | +| [lib/features/sorting/bubble/view\_model/bubble\_sort\_notifier.dart](/lib/features/sorting/bubble/view_model/bubble_sort_notifier.dart) | Dart | 25 | 0 | 10 | 35 | +| [lib/features/sorting/insertion/view/insertion\_sort\_page.dart](/lib/features/sorting/insertion/view/insertion_sort_page.dart) | Dart | 25 | 0 | 6 | 31 | +| [lib/features/sorting/insertion/view\_model/insertion\_sort\_notifier.dart](/lib/features/sorting/insertion/view_model/insertion_sort_notifier.dart) | Dart | 22 | 0 | 7 | 29 | +| [lib/features/sorting/merge/view/merge\_sort\_page.dart](/lib/features/sorting/merge/view/merge_sort_page.dart) | Dart | 25 | 0 | 6 | 31 | +| [lib/features/sorting/merge/view\_model/merge\_sort\_notifier.dart](/lib/features/sorting/merge/view_model/merge_sort_notifier.dart) | Dart | 7 | 1 | 2 | 10 | +| [lib/features/sorting/selection/view/selection\_sort\_page.dart](/lib/features/sorting/selection/view/selection_sort_page.dart) | Dart | 25 | 0 | 6 | 31 | +| [lib/features/sorting/selection/view\_model/selection\_sort\_notifier.dart](/lib/features/sorting/selection/view_model/selection_sort_notifier.dart) | Dart | 31 | 1 | 11 | 43 | +| [lib/main.dart](/lib/main.dart) | Dart | 6 | 0 | 2 | 8 | +| [linux/CMakeLists.txt](/linux/CMakeLists.txt) | CMake | 118 | 0 | 28 | 146 | +| [linux/flutter/CMakeLists.txt](/linux/flutter/CMakeLists.txt) | CMake | 79 | 0 | 10 | 89 | +| [linux/flutter/generated\_plugin\_registrant.cc](/linux/flutter/generated_plugin_registrant.cc) | C++ | 3 | 4 | 5 | 12 | +| [linux/flutter/generated\_plugin\_registrant.h](/linux/flutter/generated_plugin_registrant.h) | C++ | 5 | 5 | 6 | 16 | +| [linux/flutter/generated\_plugins.cmake](/linux/flutter/generated_plugins.cmake) | CMake | 18 | 0 | 6 | 24 | +| [linux/main.cc](/linux/main.cc) | C++ | 5 | 0 | 2 | 7 | +| [linux/my\_application.cc](/linux/my_application.cc) | C++ | 82 | 17 | 26 | 125 | +| [linux/my\_application.h](/linux/my_application.h) | C++ | 7 | 7 | 5 | 19 | +| [macos/Flutter/GeneratedPluginRegistrant.swift](/macos/Flutter/GeneratedPluginRegistrant.swift) | Swift | 6 | 3 | 4 | 13 | +| [macos/Podfile](/macos/Podfile) | Ruby | 33 | 1 | 10 | 44 | +| [macos/Runner/AppDelegate.swift](/macos/Runner/AppDelegate.swift) | Swift | 8 | 0 | 2 | 10 | +| [macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json](/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json) | JSON | 68 | 0 | 1 | 69 | +| [macos/Runner/Base.lproj/MainMenu.xib](/macos/Runner/Base.lproj/MainMenu.xib) | XML | 343 | 0 | 1 | 344 | +| [macos/Runner/MainFlutterWindow.swift](/macos/Runner/MainFlutterWindow.swift) | Swift | 12 | 0 | 4 | 16 | +| [macos/RunnerTests/RunnerTests.swift](/macos/RunnerTests/RunnerTests.swift) | Swift | 7 | 2 | 4 | 13 | +| [pubspec.yaml](/pubspec.yaml) | YAML | 26 | 0 | 11 | 37 | +| [test/widget\_test.dart](/test/widget_test.dart) | Dart | 0 | 30 | 1 | 31 | +| [web/index.html](/web/index.html) | HTML | 19 | 15 | 5 | 39 | +| [web/manifest.json](/web/manifest.json) | JSON | 35 | 0 | 1 | 36 | +| [windows/CMakeLists.txt](/windows/CMakeLists.txt) | CMake | 89 | 0 | 20 | 109 | +| [windows/flutter/CMakeLists.txt](/windows/flutter/CMakeLists.txt) | CMake | 98 | 0 | 12 | 110 | +| [windows/flutter/generated\_plugin\_registrant.cc](/windows/flutter/generated_plugin_registrant.cc) | C++ | 3 | 4 | 5 | 12 | +| [windows/flutter/generated\_plugin\_registrant.h](/windows/flutter/generated_plugin_registrant.h) | C++ | 5 | 5 | 6 | 16 | +| [windows/flutter/generated\_plugins.cmake](/windows/flutter/generated_plugins.cmake) | CMake | 18 | 0 | 6 | 24 | +| [windows/runner/CMakeLists.txt](/windows/runner/CMakeLists.txt) | CMake | 34 | 0 | 7 | 41 | +| [windows/runner/flutter\_window.cpp](/windows/runner/flutter_window.cpp) | C++ | 49 | 7 | 16 | 72 | +| [windows/runner/flutter\_window.h](/windows/runner/flutter_window.h) | C++ | 20 | 5 | 9 | 34 | +| [windows/runner/main.cpp](/windows/runner/main.cpp) | C++ | 30 | 4 | 10 | 44 | +| [windows/runner/resource.h](/windows/runner/resource.h) | C++ | 9 | 6 | 2 | 17 | +| [windows/runner/utils.cpp](/windows/runner/utils.cpp) | C++ | 54 | 2 | 10 | 66 | +| [windows/runner/utils.h](/windows/runner/utils.h) | C++ | 8 | 6 | 6 | 20 | +| [windows/runner/win32\_window.cpp](/windows/runner/win32_window.cpp) | C++ | 210 | 24 | 55 | 289 | +| [windows/runner/win32\_window.h](/windows/runner/win32_window.h) | C++ | 48 | 31 | 24 | 103 | + +[Summary](results.md) / Details / [Diff Summary](diff.md) / [Diff Details](diff-details.md) \ No newline at end of file diff --git a/.VSCodeCounter/2025-08-24_12-43-46/diff-details.md b/.VSCodeCounter/2025-08-24_12-43-46/diff-details.md new file mode 100644 index 0000000..b2b31db --- /dev/null +++ b/.VSCodeCounter/2025-08-24_12-43-46/diff-details.md @@ -0,0 +1,15 @@ +# Diff Details + +Date : 2025-08-24 12:43:46 + +Directory /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer + +Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines + +[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details + +## Files +| filename | language | code | comment | blank | total | +| :--- | :--- | ---: | ---: | ---: | ---: | + +[Summary](results.md) / [Details](details.md) / [Diff Summary](diff.md) / Diff Details \ No newline at end of file diff --git a/.VSCodeCounter/2025-08-24_12-43-46/diff.csv b/.VSCodeCounter/2025-08-24_12-43-46/diff.csv new file mode 100644 index 0000000..b7d8d75 --- /dev/null +++ b/.VSCodeCounter/2025-08-24_12-43-46/diff.csv @@ -0,0 +1,2 @@ +"filename", "language", "", "comment", "blank", "total" +"Total", "-", , 0, 0, 0 \ No newline at end of file diff --git a/.VSCodeCounter/2025-08-24_12-43-46/diff.md b/.VSCodeCounter/2025-08-24_12-43-46/diff.md new file mode 100644 index 0000000..9626b53 --- /dev/null +++ b/.VSCodeCounter/2025-08-24_12-43-46/diff.md @@ -0,0 +1,19 @@ +# Diff Summary + +Date : 2025-08-24 12:43:46 + +Directory /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer + +Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines + +[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md) + +## Languages +| language | files | code | comment | blank | total | +| :--- | ---: | ---: | ---: | ---: | ---: | + +## Directories +| path | files | code | comment | blank | total | +| :--- | ---: | ---: | ---: | ---: | ---: | + +[Summary](results.md) / [Details](details.md) / Diff Summary / [Diff Details](diff-details.md) \ No newline at end of file diff --git a/.VSCodeCounter/2025-08-24_12-43-46/diff.txt b/.VSCodeCounter/2025-08-24_12-43-46/diff.txt new file mode 100644 index 0000000..5aa31d6 --- /dev/null +++ b/.VSCodeCounter/2025-08-24_12-43-46/diff.txt @@ -0,0 +1,22 @@ +Date : 2025-08-24 12:43:46 +Directory : /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer +Total : 0 files, 0 codes, 0 comments, 0 blanks, all 0 lines + +Languages ++----------+------------+------------+------------+------------+------------+ +| language | files | code | comment | blank | total | ++----------+------------+------------+------------+------------+------------+ ++----------+------------+------------+------------+------------+------------+ + +Directories ++------+------------+------------+------------+------------+------------+ +| path | files | code | comment | blank | total | ++------+------------+------------+------------+------------+------------+ ++------+------------+------------+------------+------------+------------+ + +Files ++----------+----------+------------+------------+------------+------------+ +| filename | language | code | comment | blank | total | ++----------+----------+------------+------------+------------+------------+ +| Total | | 0 | 0 | 0 | 0 | ++----------+----------+------------+------------+------------+------------+ \ No newline at end of file diff --git a/.VSCodeCounter/2025-08-24_12-43-46/results.csv b/.VSCodeCounter/2025-08-24_12-43-46/results.csv new file mode 100644 index 0000000..51c748a --- /dev/null +++ b/.VSCodeCounter/2025-08-24_12-43-46/results.csv @@ -0,0 +1,135 @@ +"filename", "language", "Dart", "CMake", "C++", "YAML", "Markdown", "Ruby", "Swift", "JSON", "XML", "Groovy", "Properties", "HTML", "comment", "blank", "total" +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/.github/workflows/script.yml", "YAML", 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 31 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/README.md", "Markdown", 0, 0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 10, 63 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/analysis_options.yaml", "YAML", 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 22, 4, 29 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/build.gradle", "Groovy", 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 6, 9, 59 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/debug/AndroidManifest.xml", "XML", 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 1, 8 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/AndroidManifest.xml", "XML", 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 11, 1, 46 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/res/drawable-v21/launch_background.xml", "XML", 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 7, 2, 13 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/res/drawable/launch_background.xml", "XML", 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 7, 2, 13 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/res/values-night/styles.xml", "XML", 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 9, 1, 19 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/res/values/styles.xml", "XML", 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 9, 1, 19 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/profile/AndroidManifest.xml", "XML", 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 1, 8 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/build.gradle", "Groovy", 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 3, 19 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/gradle.properties", "Properties", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 4 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/gradle/wrapper/gradle-wrapper.properties", "Properties", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 1, 6 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/settings.gradle", "Groovy", 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 5, 26 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Podfile", "Ruby", 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 3, 10, 45 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/AppDelegate.swift", "Swift", 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 2, 14 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json", "JSON", 0, 0, 0, 0, 0, 0, 0, 122, 0, 0, 0, 0, 0, 1, 123 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json", "JSON", 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 1, 24 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md", "Markdown", 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Base.lproj/LaunchScreen.storyboard", "XML", 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 1, 1, 38 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Base.lproj/Main.storyboard", "XML", 0, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 1, 1, 27 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Runner-Bridging-Header.h", "C++", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/RunnerTests/RunnerTests.swift", "Swift", 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 2, 4, 13 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/config/routes/route_app.dart", "Dart", 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 135 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/config/themes/app_theme.dart", "Dart", 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 14, 255 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/draggable_progress.dart", "Dart", 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 46 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/enums/app_settings_enum.dart", "Dart", 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/extensions/language.dart", "Dart", 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 25 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/extensions/navigators.dart", "Dart", 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 16, 145 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/app_bar/app_bar.dart", "Dart", 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 13, 142 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/app_bar/back_button.dart", "Dart", 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 27 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/current_device.dart", "Dart", 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 9 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/custom_alert_dialog.dart", "Dart", 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 131 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/random_int.dart", "Dart", 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 13 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/random_text.dart", "Dart", 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 20 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/screen_size.dart", "Dart", 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 9 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/storage/app_settings/app_settings_cubit.dart", "Dart", 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 21, 93 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/storage/app_settings/app_settings_state.dart", "Dart", 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 23 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/svg_picture.dart", "Dart", 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 34 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/system_overlay_style.dart", "Dart", 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 57 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/material_app/my_app.dart", "Dart", 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 9, 88 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/color_manager.dart", "Dart", 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 8, 110 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/font_manager.dart", "Dart", 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 4, 41 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/strings_manager.dart", "Dart", 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 48 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/styles_manager.dart", "Dart", 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 84 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/theme_manager.dart", "Dart", 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 10, 98 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adapt_widget_size.dart", "Dart", 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 22 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/adaptive_padding.dart", "Dart", 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 22 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/all_padding.dart", "Dart", 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 13 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/bottom_padding.dart", "Dart", 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 14 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/end_padding.dart", "Dart", 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 13 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/horizontal_padding.dart", "Dart", 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 14 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/only_padding.dart", "Dart", 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 31 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/start_padding.dart", "Dart", 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 13 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/symmetric_padding.dart", "Dart", 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 19 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/top_padding.dart", "Dart", 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 13 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/vertical_padding.dart", "Dart", 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 14 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/adaptive_text.dart", "Dart", 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 13, 109 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/bold_text.dart", "Dart", 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 17 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/light_text.dart", "Dart", 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/medium_text.dart", "Dart", 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 18 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/regular_text.dart", "Dart", 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 16 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/semi_bold_text.dart", "Dart", 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 17 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/check_box.dart", "Dart", 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 53 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_bottom_sheet.dart", "Dart", 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 205 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_circulars_progress.dart", "Dart", 215, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 239 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_dialog.dart", "Dart", 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 97 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_divider.dart", "Dart", 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 33 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_icon.dart", "Dart", 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 27 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_rounded_elevated_button.dart", "Dart", 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 49 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_switch.dart", "Dart", 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 41 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/error_screen.dart", "Dart", 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 28 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/hero_widget.dart", "Dart", 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 18 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/keyboard_detected.dart", "Dart", 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 56 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/rounded_outlined_button.dart", "Dart", 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 48 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/scale_transition.dart", "Dart", 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 40 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/vertical_animation_hero_page.dart", "Dart", 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 43 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/base/view/base_page.dart", "Dart", 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 57 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/searching/view/grid_page.dart", "Dart", 290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 325 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/searching/view_model/grid_notifier.dart", "Dart", 384, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 109, 511 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/searching/view_model/grid_notifier_state.dart", "Dart", 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 58 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/searching/widgets/searcher_grid.dart", "Dart", 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 14, 96 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/helper/sortable_item.dart", "Dart", 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 54 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/helper/sorting_enums.dart", "Dart", 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 19 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/view/sorting_list_page.dart", "Dart", 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 63 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/view/sorting_page.dart", "Dart", 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 19, 225 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/view_model/sorting_notifier.dart", "Dart", 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 48, 195 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/view_model/sorting_state.dart", "Dart", 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 34 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/widgets/control_buttons.dart", "Dart", 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 50 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/widgets/sorting_app_bar.dart", "Dart", 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 1, 45 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/bubble/view/bubble_sort_page.dart", "Dart", 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 31 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/bubble/view_model/bubble_sort_notifier.dart", "Dart", 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 35 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/insertion/view/insertion_sort_page.dart", "Dart", 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 31 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/insertion/view_model/insertion_sort_notifier.dart", "Dart", 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 29 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/merge/view/merge_sort_page.dart", "Dart", 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 31 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/merge/view_model/merge_sort_notifier.dart", "Dart", 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 10 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/selection/view/selection_sort_page.dart", "Dart", 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 31 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/selection/view_model/selection_sort_notifier.dart", "Dart", 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 11, 43 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/main.dart", "Dart", 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/CMakeLists.txt", "CMake", 0, 118, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 146 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/flutter/CMakeLists.txt", "CMake", 0, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 89 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/flutter/generated_plugin_registrant.cc", "C++", 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 12 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/flutter/generated_plugin_registrant.h", "C++", 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 16 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/flutter/generated_plugins.cmake", "CMake", 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 24 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/main.cc", "C++", 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 7 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/my_application.cc", "C++", 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 26, 125 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/my_application.h", "C++", 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 5, 19 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Flutter/GeneratedPluginRegistrant.swift", "Swift", 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 3, 4, 13 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Podfile", "Ruby", 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 1, 10, 44 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Runner/AppDelegate.swift", "Swift", 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 2, 10 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json", "JSON", 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 1, 69 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Runner/Base.lproj/MainMenu.xib", "XML", 0, 0, 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, 0, 1, 344 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Runner/MainFlutterWindow.swift", "Swift", 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 4, 16 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/RunnerTests/RunnerTests.swift", "Swift", 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 2, 4, 13 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/pubspec.yaml", "YAML", 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 37 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/test/widget_test.dart", "Dart", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 1, 31 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/web/index.html", "HTML", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 15, 5, 39 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/web/manifest.json", "JSON", 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 1, 36 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/CMakeLists.txt", "CMake", 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 109 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/flutter/CMakeLists.txt", "CMake", 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 110 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/flutter/generated_plugin_registrant.cc", "C++", 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 12 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/flutter/generated_plugin_registrant.h", "C++", 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 16 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/flutter/generated_plugins.cmake", "CMake", 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 24 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/CMakeLists.txt", "CMake", 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 41 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/flutter_window.cpp", "C++", 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 16, 72 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/flutter_window.h", "C++", 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 9, 34 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/main.cpp", "C++", 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 10, 44 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/resource.h", "C++", 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 2, 17 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/utils.cpp", "C++", 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 10, 66 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/utils.h", "C++", 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 20 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/win32_window.cpp", "C++", 0, 0, 210, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 55, 289 +"/Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/win32_window.h", "C++", 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 24, 103 +"Total", "-", 4214, 454, 539, 53, 56, 65, 52, 248, 470, 81, 8, 19, 411, 1006, 7676 \ No newline at end of file diff --git a/.VSCodeCounter/2025-08-24_12-43-46/results.json b/.VSCodeCounter/2025-08-24_12-43-46/results.json new file mode 100644 index 0000000..150a703 --- /dev/null +++ b/.VSCodeCounter/2025-08-24_12-43-46/results.json @@ -0,0 +1 @@ +{"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/test/widget_test.dart":{"language":"Dart","code":0,"comment":30,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/flutter/generated_plugins.cmake":{"language":"CMake","code":18,"comment":0,"blank":6},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/flutter/generated_plugin_registrant.cc":{"language":"C++","code":3,"comment":4,"blank":5},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/flutter/CMakeLists.txt":{"language":"CMake","code":98,"comment":0,"blank":12},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/flutter/generated_plugin_registrant.h":{"language":"C++","code":5,"comment":5,"blank":6},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/main.cpp":{"language":"C++","code":30,"comment":4,"blank":10},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/flutter_window.h":{"language":"C++","code":20,"comment":5,"blank":9},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/resource.h":{"language":"C++","code":9,"comment":6,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/win32_window.h":{"language":"C++","code":48,"comment":31,"blank":24},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/CMakeLists.txt":{"language":"CMake","code":34,"comment":0,"blank":7},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/flutter_window.cpp":{"language":"C++","code":49,"comment":7,"blank":16},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/config/routes/route_app.dart":{"language":"Dart","code":125,"comment":1,"blank":9},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/widgets/sorting_app_bar.dart":{"language":"Dart","code":1,"comment":43,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/utils.h":{"language":"C++","code":8,"comment":6,"blank":6},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/analysis_options.yaml":{"language":"YAML","code":3,"comment":22,"blank":4},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/main.dart":{"language":"Dart","code":6,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/widgets/control_buttons.dart":{"language":"Dart","code":47,"comment":0,"blank":3},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_switch.dart":{"language":"Dart","code":35,"comment":2,"blank":4},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/base/view/base_page.dart":{"language":"Dart","code":52,"comment":0,"blank":5},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/error_screen.dart":{"language":"Dart","code":26,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/keyboard_detected.dart":{"language":"Dart","code":47,"comment":0,"blank":9},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_bottom_sheet.dart":{"language":"Dart","code":197,"comment":0,"blank":8},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adapt_widget_size.dart":{"language":"Dart","code":18,"comment":0,"blank":4},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/only_padding.dart":{"language":"Dart","code":28,"comment":0,"blank":3},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/all_padding.dart":{"language":"Dart","code":11,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/top_padding.dart":{"language":"Dart","code":12,"comment":0,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/bold_text.dart":{"language":"Dart","code":15,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/view_model/sorting_state.dart":{"language":"Dart","code":31,"comment":0,"blank":3},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/end_padding.dart":{"language":"Dart","code":11,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/view_model/sorting_notifier.dart":{"language":"Dart","code":143,"comment":4,"blank":48},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/view/sorting_page.dart":{"language":"Dart","code":205,"comment":1,"blank":19},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/helper/sortable_item.dart":{"language":"Dart","code":45,"comment":1,"blank":8},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/semi_bold_text.dart":{"language":"Dart","code":15,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/view/sorting_list_page.dart":{"language":"Dart","code":60,"comment":0,"blank":3},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/adaptive_text.dart":{"language":"Dart","code":91,"comment":5,"blank":13},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/light_text.dart":{"language":"Dart","code":14,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/medium_text.dart":{"language":"Dart","code":16,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/regular_text.dart":{"language":"Dart","code":14,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/helper/sorting_enums.dart":{"language":"Dart","code":9,"comment":6,"blank":4},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/selection/view/selection_sort_page.dart":{"language":"Dart","code":25,"comment":0,"blank":6},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/insertion/view_model/insertion_sort_notifier.dart":{"language":"Dart","code":22,"comment":0,"blank":7},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/insertion/view/insertion_sort_page.dart":{"language":"Dart","code":25,"comment":0,"blank":6},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/draggable_progress.dart":{"language":"Dart","code":42,"comment":0,"blank":4},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/extensions/navigators.dart":{"language":"Dart","code":126,"comment":3,"blank":16},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/extensions/language.dart":{"language":"Dart","code":20,"comment":0,"blank":5},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/selection/view_model/selection_sort_notifier.dart":{"language":"Dart","code":31,"comment":1,"blank":11},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/random_text.dart":{"language":"Dart","code":13,"comment":0,"blank":7},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/check_box.dart":{"language":"Dart","code":51,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/bubble/view_model/bubble_sort_notifier.dart":{"language":"Dart","code":25,"comment":0,"blank":10},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/system_overlay_style.dart":{"language":"Dart","code":51,"comment":0,"blank":6},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/hero_widget.dart":{"language":"Dart","code":15,"comment":0,"blank":3},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/bubble/view/bubble_sort_page.dart":{"language":"Dart","code":25,"comment":0,"blank":6},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/merge/view_model/merge_sort_notifier.dart":{"language":"Dart","code":7,"comment":1,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_divider.dart":{"language":"Dart","code":29,"comment":0,"blank":4},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_dialog.dart":{"language":"Dart","code":91,"comment":0,"blank":6},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_circulars_progress.dart":{"language":"Dart","code":215,"comment":0,"blank":24},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/vertical_animation_hero_page.dart":{"language":"Dart","code":39,"comment":0,"blank":4},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_icon.dart":{"language":"Dart","code":25,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/rounded_outlined_button.dart":{"language":"Dart","code":44,"comment":0,"blank":4},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/scale_transition.dart":{"language":"Dart","code":34,"comment":0,"blank":6},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/merge/view/merge_sort_page.dart":{"language":"Dart","code":25,"comment":0,"blank":6},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_rounded_elevated_button.dart":{"language":"Dart","code":45,"comment":0,"blank":4},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/color_manager.dart":{"language":"Dart","code":79,"comment":23,"blank":8},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/strings_manager.dart":{"language":"Dart","code":41,"comment":2,"blank":5},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/config/themes/app_theme.dart":{"language":"Dart","code":239,"comment":2,"blank":14},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/styles_manager.dart":{"language":"Dart","code":77,"comment":0,"blank":7},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/pubspec.yaml":{"language":"YAML","code":26,"comment":0,"blank":11},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/font_manager.dart":{"language":"Dart","code":26,"comment":11,"blank":4},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/horizontal_padding.dart":{"language":"Dart","code":12,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/theme_manager.dart":{"language":"Dart","code":86,"comment":2,"blank":10},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/win32_window.cpp":{"language":"C++","code":210,"comment":24,"blank":55},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/enums/app_settings_enum.dart":{"language":"Dart","code":1,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/current_device.dart":{"language":"Dart","code":7,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/custom_alert_dialog.dart":{"language":"Dart","code":123,"comment":0,"blank":8},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/screen_size.dart":{"language":"Dart","code":7,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/random_int.dart":{"language":"Dart","code":9,"comment":0,"blank":4},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/svg_picture.dart":{"language":"Dart","code":31,"comment":0,"blank":3},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/searching/widgets/searcher_grid.dart":{"language":"Dart","code":79,"comment":3,"blank":14},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/searching/view/grid_page.dart":{"language":"Dart","code":290,"comment":0,"blank":35},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/start_padding.dart":{"language":"Dart","code":12,"comment":0,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/searching/view_model/grid_notifier_state.dart":{"language":"Dart","code":50,"comment":1,"blank":7},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/searching/view_model/grid_notifier.dart":{"language":"Dart","code":384,"comment":18,"blank":109},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/bottom_padding.dart":{"language":"Dart","code":11,"comment":0,"blank":3},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/symmetric_padding.dart":{"language":"Dart","code":17,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/vertical_padding.dart":{"language":"Dart","code":12,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/utils.cpp":{"language":"C++","code":54,"comment":2,"blank":10},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/adaptive_padding.dart":{"language":"Dart","code":20,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/storage/app_settings/app_settings_state.dart":{"language":"Dart","code":18,"comment":0,"blank":5},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/storage/app_settings/app_settings_cubit.dart":{"language":"Dart","code":62,"comment":10,"blank":21},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/README.md":{"language":"Markdown","code":53,"comment":0,"blank":10},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Podfile":{"language":"Ruby","code":32,"comment":3,"blank":10},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/AppDelegate.swift":{"language":"Swift","code":12,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json":{"language":"JSON","code":23,"comment":0,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Base.lproj/LaunchScreen.storyboard":{"language":"XML","code":36,"comment":1,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/CMakeLists.txt":{"language":"CMake","code":89,"comment":0,"blank":20},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md":{"language":"Markdown","code":3,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Base.lproj/Main.storyboard":{"language":"XML","code":25,"comment":1,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/build.gradle":{"language":"Groovy","code":16,"comment":0,"blank":3},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/settings.gradle":{"language":"Groovy","code":21,"comment":0,"blank":5},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/.github/workflows/script.yml":{"language":"YAML","code":24,"comment":0,"blank":7},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json":{"language":"JSON","code":122,"comment":0,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/app_bar/app_bar.dart":{"language":"Dart","code":127,"comment":2,"blank":13},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Runner-Bridging-Header.h":{"language":"C++","code":1,"comment":0,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/profile/AndroidManifest.xml":{"language":"XML","code":3,"comment":4,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/debug/AndroidManifest.xml":{"language":"XML","code":3,"comment":4,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/app_bar/back_button.dart":{"language":"Dart","code":21,"comment":0,"blank":6},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/AndroidManifest.xml":{"language":"XML","code":34,"comment":11,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/gradle.properties":{"language":"Properties","code":3,"comment":0,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/RunnerTests/RunnerTests.swift":{"language":"Swift","code":7,"comment":2,"blank":4},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/flutter/CMakeLists.txt":{"language":"CMake","code":79,"comment":0,"blank":10},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/gradle/wrapper/gradle-wrapper.properties":{"language":"Properties","code":5,"comment":0,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/build.gradle":{"language":"Groovy","code":44,"comment":6,"blank":9},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/res/drawable-v21/launch_background.xml":{"language":"XML","code":4,"comment":7,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/flutter/generated_plugin_registrant.h":{"language":"C++","code":5,"comment":5,"blank":6},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/flutter/generated_plugin_registrant.cc":{"language":"C++","code":3,"comment":4,"blank":5},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/flutter/generated_plugins.cmake":{"language":"CMake","code":18,"comment":0,"blank":6},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/material_app/my_app.dart":{"language":"Dart","code":74,"comment":5,"blank":9},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/res/values-night/styles.xml":{"language":"XML","code":9,"comment":9,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/my_application.h":{"language":"C++","code":7,"comment":7,"blank":5},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/res/drawable/launch_background.xml":{"language":"XML","code":4,"comment":7,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/my_application.cc":{"language":"C++","code":82,"comment":17,"blank":26},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/CMakeLists.txt":{"language":"CMake","code":118,"comment":0,"blank":28},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/web/manifest.json":{"language":"JSON","code":35,"comment":0,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/main.cc":{"language":"C++","code":5,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Podfile":{"language":"Ruby","code":33,"comment":1,"blank":10},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Runner/AppDelegate.swift":{"language":"Swift","code":8,"comment":0,"blank":2},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/RunnerTests/RunnerTests.swift":{"language":"Swift","code":7,"comment":2,"blank":4},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Runner/MainFlutterWindow.swift":{"language":"Swift","code":12,"comment":0,"blank":4},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json":{"language":"JSON","code":68,"comment":0,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/web/index.html":{"language":"HTML","code":19,"comment":15,"blank":5},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Runner/Base.lproj/MainMenu.xib":{"language":"XML","code":343,"comment":0,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/res/values/styles.xml":{"language":"XML","code":9,"comment":9,"blank":1},"file:///Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Flutter/GeneratedPluginRegistrant.swift":{"language":"Swift","code":6,"comment":3,"blank":4}} \ No newline at end of file diff --git a/.VSCodeCounter/2025-08-24_12-43-46/results.md b/.VSCodeCounter/2025-08-24_12-43-46/results.md new file mode 100644 index 0000000..5d45dac --- /dev/null +++ b/.VSCodeCounter/2025-08-24_12-43-46/results.md @@ -0,0 +1,125 @@ +# Summary + +Date : 2025-08-24 12:43:46 + +Directory /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer + +Total : 133 files, 6259 codes, 411 comments, 1006 blanks, all 7676 lines + +Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md) + +## Languages +| language | files | code | comment | blank | total | +| :--- | ---: | ---: | ---: | ---: | ---: | +| Dart | 77 | 4,214 | 177 | 615 | 5,006 | +| C++ | 16 | 539 | 127 | 188 | 854 | +| XML | 10 | 470 | 53 | 12 | 535 | +| CMake | 7 | 454 | 0 | 89 | 543 | +| JSON | 4 | 248 | 0 | 4 | 252 | +| Groovy | 3 | 81 | 6 | 17 | 104 | +| Ruby | 2 | 65 | 4 | 20 | 89 | +| Markdown | 2 | 56 | 0 | 12 | 68 | +| YAML | 3 | 53 | 22 | 22 | 97 | +| Swift | 6 | 52 | 7 | 20 | 79 | +| HTML | 1 | 19 | 15 | 5 | 39 | +| Properties | 2 | 8 | 0 | 2 | 10 | + +## Directories +| path | files | code | comment | blank | total | +| :--- | ---: | ---: | ---: | ---: | ---: | +| . | 133 | 6,259 | 411 | 1,006 | 7,676 | +| . (Files) | 3 | 82 | 22 | 25 | 129 | +| .github | 1 | 24 | 0 | 7 | 31 | +| .github/workflows | 1 | 24 | 0 | 7 | 31 | +| android | 12 | 155 | 57 | 28 | 240 | +| android (Files) | 3 | 40 | 0 | 9 | 49 | +| android/app | 8 | 110 | 57 | 18 | 185 | +| android/app (Files) | 1 | 44 | 6 | 9 | 59 | +| android/app/src | 7 | 66 | 51 | 9 | 126 | +| android/app/src/debug | 1 | 3 | 4 | 1 | 8 | +| android/app/src/main | 5 | 60 | 43 | 7 | 110 | +| android/app/src/main (Files) | 1 | 34 | 11 | 1 | 46 | +| android/app/src/main/res | 4 | 26 | 32 | 6 | 64 | +| android/app/src/main/res/drawable | 1 | 4 | 7 | 2 | 13 | +| android/app/src/main/res/drawable-v21 | 1 | 4 | 7 | 2 | 13 | +| android/app/src/main/res/values | 1 | 9 | 9 | 1 | 19 | +| android/app/src/main/res/values-night | 1 | 9 | 9 | 1 | 19 | +| android/app/src/profile | 1 | 3 | 4 | 1 | 8 | +| android/gradle | 1 | 5 | 0 | 1 | 6 | +| android/gradle/wrapper | 1 | 5 | 0 | 1 | 6 | +| ios | 9 | 261 | 7 | 23 | 291 | +| ios (Files) | 1 | 32 | 3 | 10 | 45 | +| ios/Runner | 7 | 222 | 2 | 9 | 233 | +| ios/Runner (Files) | 2 | 13 | 0 | 3 | 16 | +| ios/Runner/Assets.xcassets | 3 | 148 | 0 | 4 | 152 | +| ios/Runner/Assets.xcassets/AppIcon.appiconset | 1 | 122 | 0 | 1 | 123 | +| ios/Runner/Assets.xcassets/LaunchImage.imageset | 2 | 26 | 0 | 3 | 29 | +| ios/Runner/Base.lproj | 2 | 61 | 2 | 2 | 65 | +| ios/RunnerTests | 1 | 7 | 2 | 4 | 13 | +| lib | 76 | 4,214 | 147 | 614 | 4,975 | +| lib (Files) | 1 | 6 | 0 | 2 | 8 | +| lib/config | 2 | 364 | 3 | 23 | 390 | +| lib/config/routes | 1 | 125 | 1 | 9 | 135 | +| lib/config/themes | 1 | 239 | 2 | 14 | 255 | +| lib/core | 52 | 2,263 | 65 | 276 | 2,604 | +| lib/core (Files) | 1 | 42 | 0 | 4 | 46 | +| lib/core/enums | 1 | 1 | 0 | 2 | 3 | +| lib/core/extensions | 2 | 146 | 3 | 21 | 170 | +| lib/core/helpers | 11 | 469 | 12 | 77 | 558 | +| lib/core/helpers (Files) | 7 | 241 | 0 | 32 | 273 | +| lib/core/helpers/app_bar | 2 | 148 | 2 | 19 | 169 | +| lib/core/helpers/storage | 2 | 80 | 10 | 26 | 116 | +| lib/core/helpers/storage/app_settings | 2 | 80 | 10 | 26 | 116 | +| lib/core/material_app | 1 | 74 | 5 | 9 | 88 | +| lib/core/resources | 5 | 309 | 38 | 34 | 381 | +| lib/core/widgets | 31 | 1,222 | 7 | 129 | 1,358 | +| lib/core/widgets (Files) | 1 | 18 | 0 | 4 | 22 | +| lib/core/widgets/adaptive | 16 | 311 | 5 | 43 | 359 | +| lib/core/widgets/adaptive/padding | 10 | 146 | 0 | 20 | 166 | +| lib/core/widgets/adaptive/text | 6 | 165 | 5 | 23 | 193 | +| lib/core/widgets/custom_widgets | 14 | 893 | 2 | 82 | 977 | +| lib/features | 21 | 1,581 | 79 | 313 | 1,973 | +| lib/features/base | 1 | 52 | 0 | 5 | 57 | +| lib/features/base/view | 1 | 52 | 0 | 5 | 57 | +| lib/features/searching | 4 | 803 | 22 | 165 | 990 | +| lib/features/searching/view | 1 | 290 | 0 | 35 | 325 | +| lib/features/searching/view_model | 2 | 434 | 19 | 116 | 569 | +| lib/features/searching/widgets | 1 | 79 | 3 | 14 | 96 | +| lib/features/sorting | 16 | 726 | 57 | 143 | 926 | +| lib/features/sorting/base | 8 | 541 | 55 | 89 | 685 | +| lib/features/sorting/base/helper | 2 | 54 | 7 | 12 | 73 | +| lib/features/sorting/base/view | 2 | 265 | 1 | 22 | 288 | +| lib/features/sorting/base/view_model | 2 | 174 | 4 | 51 | 229 | +| lib/features/sorting/base/widgets | 2 | 48 | 43 | 4 | 95 | +| lib/features/sorting/bubble | 2 | 50 | 0 | 16 | 66 | +| lib/features/sorting/bubble/view | 1 | 25 | 0 | 6 | 31 | +| lib/features/sorting/bubble/view_model | 1 | 25 | 0 | 10 | 35 | +| lib/features/sorting/insertion | 2 | 47 | 0 | 13 | 60 | +| lib/features/sorting/insertion/view | 1 | 25 | 0 | 6 | 31 | +| lib/features/sorting/insertion/view_model | 1 | 22 | 0 | 7 | 29 | +| lib/features/sorting/merge | 2 | 32 | 1 | 8 | 41 | +| lib/features/sorting/merge/view | 1 | 25 | 0 | 6 | 31 | +| lib/features/sorting/merge/view_model | 1 | 7 | 1 | 2 | 10 | +| lib/features/sorting/selection | 2 | 56 | 1 | 17 | 74 | +| lib/features/sorting/selection/view | 1 | 25 | 0 | 6 | 31 | +| lib/features/sorting/selection/view_model | 1 | 31 | 1 | 11 | 43 | +| linux | 8 | 317 | 33 | 88 | 438 | +| linux (Files) | 4 | 212 | 24 | 61 | 297 | +| linux/flutter | 4 | 105 | 9 | 27 | 141 | +| macos | 7 | 477 | 6 | 26 | 509 | +| macos (Files) | 1 | 33 | 1 | 10 | 44 | +| macos/Flutter | 1 | 6 | 3 | 4 | 13 | +| macos/Runner | 4 | 431 | 0 | 8 | 439 | +| macos/Runner (Files) | 2 | 20 | 0 | 6 | 26 | +| macos/Runner/Assets.xcassets | 1 | 68 | 0 | 1 | 69 | +| macos/Runner/Assets.xcassets/AppIcon.appiconset | 1 | 68 | 0 | 1 | 69 | +| macos/Runner/Base.lproj | 1 | 343 | 0 | 1 | 344 | +| macos/RunnerTests | 1 | 7 | 2 | 4 | 13 | +| test | 1 | 0 | 30 | 1 | 31 | +| web | 2 | 54 | 15 | 6 | 75 | +| windows | 14 | 675 | 94 | 188 | 957 | +| windows (Files) | 1 | 89 | 0 | 20 | 109 | +| windows/flutter | 4 | 124 | 9 | 29 | 162 | +| windows/runner | 9 | 462 | 85 | 139 | 686 | + +Summary / [Details](details.md) / [Diff Summary](diff.md) / [Diff Details](diff-details.md) \ No newline at end of file diff --git a/.VSCodeCounter/2025-08-24_12-43-46/results.txt b/.VSCodeCounter/2025-08-24_12-43-46/results.txt new file mode 100644 index 0000000..fc545f1 --- /dev/null +++ b/.VSCodeCounter/2025-08-24_12-43-46/results.txt @@ -0,0 +1,261 @@ +Date : 2025-08-24 12:43:46 +Directory : /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer +Total : 133 files, 6259 codes, 411 comments, 1006 blanks, all 7676 lines + +Languages ++------------+------------+------------+------------+------------+------------+ +| language | files | code | comment | blank | total | ++------------+------------+------------+------------+------------+------------+ +| Dart | 77 | 4,214 | 177 | 615 | 5,006 | +| C++ | 16 | 539 | 127 | 188 | 854 | +| XML | 10 | 470 | 53 | 12 | 535 | +| CMake | 7 | 454 | 0 | 89 | 543 | +| JSON | 4 | 248 | 0 | 4 | 252 | +| Groovy | 3 | 81 | 6 | 17 | 104 | +| Ruby | 2 | 65 | 4 | 20 | 89 | +| Markdown | 2 | 56 | 0 | 12 | 68 | +| YAML | 3 | 53 | 22 | 22 | 97 | +| Swift | 6 | 52 | 7 | 20 | 79 | +| HTML | 1 | 19 | 15 | 5 | 39 | +| Properties | 2 | 8 | 0 | 2 | 10 | ++------------+------------+------------+------------+------------+------------+ + +Directories ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+ +| path | files | code | comment | blank | total | ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+ +| . | 133 | 6,259 | 411 | 1,006 | 7,676 | +| . (Files) | 3 | 82 | 22 | 25 | 129 | +| .github | 1 | 24 | 0 | 7 | 31 | +| .github/workflows | 1 | 24 | 0 | 7 | 31 | +| android | 12 | 155 | 57 | 28 | 240 | +| android (Files) | 3 | 40 | 0 | 9 | 49 | +| android/app | 8 | 110 | 57 | 18 | 185 | +| android/app (Files) | 1 | 44 | 6 | 9 | 59 | +| android/app/src | 7 | 66 | 51 | 9 | 126 | +| android/app/src/debug | 1 | 3 | 4 | 1 | 8 | +| android/app/src/main | 5 | 60 | 43 | 7 | 110 | +| android/app/src/main (Files) | 1 | 34 | 11 | 1 | 46 | +| android/app/src/main/res | 4 | 26 | 32 | 6 | 64 | +| android/app/src/main/res/drawable | 1 | 4 | 7 | 2 | 13 | +| android/app/src/main/res/drawable-v21 | 1 | 4 | 7 | 2 | 13 | +| android/app/src/main/res/values | 1 | 9 | 9 | 1 | 19 | +| android/app/src/main/res/values-night | 1 | 9 | 9 | 1 | 19 | +| android/app/src/profile | 1 | 3 | 4 | 1 | 8 | +| android/gradle | 1 | 5 | 0 | 1 | 6 | +| android/gradle/wrapper | 1 | 5 | 0 | 1 | 6 | +| ios | 9 | 261 | 7 | 23 | 291 | +| ios (Files) | 1 | 32 | 3 | 10 | 45 | +| ios/Runner | 7 | 222 | 2 | 9 | 233 | +| ios/Runner (Files) | 2 | 13 | 0 | 3 | 16 | +| ios/Runner/Assets.xcassets | 3 | 148 | 0 | 4 | 152 | +| ios/Runner/Assets.xcassets/AppIcon.appiconset | 1 | 122 | 0 | 1 | 123 | +| ios/Runner/Assets.xcassets/LaunchImage.imageset | 2 | 26 | 0 | 3 | 29 | +| ios/Runner/Base.lproj | 2 | 61 | 2 | 2 | 65 | +| ios/RunnerTests | 1 | 7 | 2 | 4 | 13 | +| lib | 76 | 4,214 | 147 | 614 | 4,975 | +| lib (Files) | 1 | 6 | 0 | 2 | 8 | +| lib/config | 2 | 364 | 3 | 23 | 390 | +| lib/config/routes | 1 | 125 | 1 | 9 | 135 | +| lib/config/themes | 1 | 239 | 2 | 14 | 255 | +| lib/core | 52 | 2,263 | 65 | 276 | 2,604 | +| lib/core (Files) | 1 | 42 | 0 | 4 | 46 | +| lib/core/enums | 1 | 1 | 0 | 2 | 3 | +| lib/core/extensions | 2 | 146 | 3 | 21 | 170 | +| lib/core/helpers | 11 | 469 | 12 | 77 | 558 | +| lib/core/helpers (Files) | 7 | 241 | 0 | 32 | 273 | +| lib/core/helpers/app_bar | 2 | 148 | 2 | 19 | 169 | +| lib/core/helpers/storage | 2 | 80 | 10 | 26 | 116 | +| lib/core/helpers/storage/app_settings | 2 | 80 | 10 | 26 | 116 | +| lib/core/material_app | 1 | 74 | 5 | 9 | 88 | +| lib/core/resources | 5 | 309 | 38 | 34 | 381 | +| lib/core/widgets | 31 | 1,222 | 7 | 129 | 1,358 | +| lib/core/widgets (Files) | 1 | 18 | 0 | 4 | 22 | +| lib/core/widgets/adaptive | 16 | 311 | 5 | 43 | 359 | +| lib/core/widgets/adaptive/padding | 10 | 146 | 0 | 20 | 166 | +| lib/core/widgets/adaptive/text | 6 | 165 | 5 | 23 | 193 | +| lib/core/widgets/custom_widgets | 14 | 893 | 2 | 82 | 977 | +| lib/features | 21 | 1,581 | 79 | 313 | 1,973 | +| lib/features/base | 1 | 52 | 0 | 5 | 57 | +| lib/features/base/view | 1 | 52 | 0 | 5 | 57 | +| lib/features/searching | 4 | 803 | 22 | 165 | 990 | +| lib/features/searching/view | 1 | 290 | 0 | 35 | 325 | +| lib/features/searching/view_model | 2 | 434 | 19 | 116 | 569 | +| lib/features/searching/widgets | 1 | 79 | 3 | 14 | 96 | +| lib/features/sorting | 16 | 726 | 57 | 143 | 926 | +| lib/features/sorting/base | 8 | 541 | 55 | 89 | 685 | +| lib/features/sorting/base/helper | 2 | 54 | 7 | 12 | 73 | +| lib/features/sorting/base/view | 2 | 265 | 1 | 22 | 288 | +| lib/features/sorting/base/view_model | 2 | 174 | 4 | 51 | 229 | +| lib/features/sorting/base/widgets | 2 | 48 | 43 | 4 | 95 | +| lib/features/sorting/bubble | 2 | 50 | 0 | 16 | 66 | +| lib/features/sorting/bubble/view | 1 | 25 | 0 | 6 | 31 | +| lib/features/sorting/bubble/view_model | 1 | 25 | 0 | 10 | 35 | +| lib/features/sorting/insertion | 2 | 47 | 0 | 13 | 60 | +| lib/features/sorting/insertion/view | 1 | 25 | 0 | 6 | 31 | +| lib/features/sorting/insertion/view_model | 1 | 22 | 0 | 7 | 29 | +| lib/features/sorting/merge | 2 | 32 | 1 | 8 | 41 | +| lib/features/sorting/merge/view | 1 | 25 | 0 | 6 | 31 | +| lib/features/sorting/merge/view_model | 1 | 7 | 1 | 2 | 10 | +| lib/features/sorting/selection | 2 | 56 | 1 | 17 | 74 | +| lib/features/sorting/selection/view | 1 | 25 | 0 | 6 | 31 | +| lib/features/sorting/selection/view_model | 1 | 31 | 1 | 11 | 43 | +| linux | 8 | 317 | 33 | 88 | 438 | +| linux (Files) | 4 | 212 | 24 | 61 | 297 | +| linux/flutter | 4 | 105 | 9 | 27 | 141 | +| macos | 7 | 477 | 6 | 26 | 509 | +| macos (Files) | 1 | 33 | 1 | 10 | 44 | +| macos/Flutter | 1 | 6 | 3 | 4 | 13 | +| macos/Runner | 4 | 431 | 0 | 8 | 439 | +| macos/Runner (Files) | 2 | 20 | 0 | 6 | 26 | +| macos/Runner/Assets.xcassets | 1 | 68 | 0 | 1 | 69 | +| macos/Runner/Assets.xcassets/AppIcon.appiconset | 1 | 68 | 0 | 1 | 69 | +| macos/Runner/Base.lproj | 1 | 343 | 0 | 1 | 344 | +| macos/RunnerTests | 1 | 7 | 2 | 4 | 13 | +| test | 1 | 0 | 30 | 1 | 31 | +| web | 2 | 54 | 15 | 6 | 75 | +| windows | 14 | 675 | 94 | 188 | 957 | +| windows (Files) | 1 | 89 | 0 | 20 | 109 | +| windows/flutter | 4 | 124 | 9 | 29 | 162 | +| windows/runner | 9 | 462 | 85 | 139 | 686 | ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+ + +Files ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+ +| filename | language | code | comment | blank | total | ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+ +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/.github/workflows/script.yml | YAML | 24 | 0 | 7 | 31 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/README.md | Markdown | 53 | 0 | 10 | 63 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/analysis_options.yaml | YAML | 3 | 22 | 4 | 29 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/build.gradle | Groovy | 44 | 6 | 9 | 59 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/debug/AndroidManifest.xml | XML | 3 | 4 | 1 | 8 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/AndroidManifest.xml | XML | 34 | 11 | 1 | 46 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/res/drawable-v21/launch_background.xml | XML | 4 | 7 | 2 | 13 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/res/drawable/launch_background.xml | XML | 4 | 7 | 2 | 13 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/res/values-night/styles.xml | XML | 9 | 9 | 1 | 19 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/main/res/values/styles.xml | XML | 9 | 9 | 1 | 19 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/app/src/profile/AndroidManifest.xml | XML | 3 | 4 | 1 | 8 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/build.gradle | Groovy | 16 | 0 | 3 | 19 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/gradle.properties | Properties | 3 | 0 | 1 | 4 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/gradle/wrapper/gradle-wrapper.properties | Properties | 5 | 0 | 1 | 6 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/android/settings.gradle | Groovy | 21 | 0 | 5 | 26 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Podfile | Ruby | 32 | 3 | 10 | 45 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/AppDelegate.swift | Swift | 12 | 0 | 2 | 14 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json | JSON | 122 | 0 | 1 | 123 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json | JSON | 23 | 0 | 1 | 24 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md | Markdown | 3 | 0 | 2 | 5 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Base.lproj/LaunchScreen.storyboard | XML | 36 | 1 | 1 | 38 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Base.lproj/Main.storyboard | XML | 25 | 1 | 1 | 27 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/Runner/Runner-Bridging-Header.h | C++ | 1 | 0 | 1 | 2 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/ios/RunnerTests/RunnerTests.swift | Swift | 7 | 2 | 4 | 13 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/config/routes/route_app.dart | Dart | 125 | 1 | 9 | 135 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/config/themes/app_theme.dart | Dart | 239 | 2 | 14 | 255 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/draggable_progress.dart | Dart | 42 | 0 | 4 | 46 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/enums/app_settings_enum.dart | Dart | 1 | 0 | 2 | 3 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/extensions/language.dart | Dart | 20 | 0 | 5 | 25 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/extensions/navigators.dart | Dart | 126 | 3 | 16 | 145 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/app_bar/app_bar.dart | Dart | 127 | 2 | 13 | 142 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/app_bar/back_button.dart | Dart | 21 | 0 | 6 | 27 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/current_device.dart | Dart | 7 | 0 | 2 | 9 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/custom_alert_dialog.dart | Dart | 123 | 0 | 8 | 131 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/random_int.dart | Dart | 9 | 0 | 4 | 13 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/random_text.dart | Dart | 13 | 0 | 7 | 20 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/screen_size.dart | Dart | 7 | 0 | 2 | 9 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/storage/app_settings/app_settings_cubit.dart | Dart | 62 | 10 | 21 | 93 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/storage/app_settings/app_settings_state.dart | Dart | 18 | 0 | 5 | 23 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/svg_picture.dart | Dart | 31 | 0 | 3 | 34 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/helpers/system_overlay_style.dart | Dart | 51 | 0 | 6 | 57 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/material_app/my_app.dart | Dart | 74 | 5 | 9 | 88 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/color_manager.dart | Dart | 79 | 23 | 8 | 110 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/font_manager.dart | Dart | 26 | 11 | 4 | 41 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/strings_manager.dart | Dart | 41 | 2 | 5 | 48 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/styles_manager.dart | Dart | 77 | 0 | 7 | 84 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/resources/theme_manager.dart | Dart | 86 | 2 | 10 | 98 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adapt_widget_size.dart | Dart | 18 | 0 | 4 | 22 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/adaptive_padding.dart | Dart | 20 | 0 | 2 | 22 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/all_padding.dart | Dart | 11 | 0 | 2 | 13 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/bottom_padding.dart | Dart | 11 | 0 | 3 | 14 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/end_padding.dart | Dart | 11 | 0 | 2 | 13 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/horizontal_padding.dart | Dart | 12 | 0 | 2 | 14 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/only_padding.dart | Dart | 28 | 0 | 3 | 31 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/start_padding.dart | Dart | 12 | 0 | 1 | 13 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/symmetric_padding.dart | Dart | 17 | 0 | 2 | 19 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/top_padding.dart | Dart | 12 | 0 | 1 | 13 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/padding/vertical_padding.dart | Dart | 12 | 0 | 2 | 14 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/adaptive_text.dart | Dart | 91 | 5 | 13 | 109 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/bold_text.dart | Dart | 15 | 0 | 2 | 17 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/light_text.dart | Dart | 14 | 0 | 2 | 16 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/medium_text.dart | Dart | 16 | 0 | 2 | 18 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/regular_text.dart | Dart | 14 | 0 | 2 | 16 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/adaptive/text/semi_bold_text.dart | Dart | 15 | 0 | 2 | 17 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/check_box.dart | Dart | 51 | 0 | 2 | 53 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_bottom_sheet.dart | Dart | 197 | 0 | 8 | 205 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_circulars_progress.dart | Dart | 215 | 0 | 24 | 239 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_dialog.dart | Dart | 91 | 0 | 6 | 97 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_divider.dart | Dart | 29 | 0 | 4 | 33 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_icon.dart | Dart | 25 | 0 | 2 | 27 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_rounded_elevated_button.dart | Dart | 45 | 0 | 4 | 49 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/custom_switch.dart | Dart | 35 | 2 | 4 | 41 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/error_screen.dart | Dart | 26 | 0 | 2 | 28 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/hero_widget.dart | Dart | 15 | 0 | 3 | 18 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/keyboard_detected.dart | Dart | 47 | 0 | 9 | 56 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/rounded_outlined_button.dart | Dart | 44 | 0 | 4 | 48 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/scale_transition.dart | Dart | 34 | 0 | 6 | 40 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/core/widgets/custom_widgets/vertical_animation_hero_page.dart | Dart | 39 | 0 | 4 | 43 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/base/view/base_page.dart | Dart | 52 | 0 | 5 | 57 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/searching/view/grid_page.dart | Dart | 290 | 0 | 35 | 325 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/searching/view_model/grid_notifier.dart | Dart | 384 | 18 | 109 | 511 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/searching/view_model/grid_notifier_state.dart | Dart | 50 | 1 | 7 | 58 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/searching/widgets/searcher_grid.dart | Dart | 79 | 3 | 14 | 96 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/helper/sortable_item.dart | Dart | 45 | 1 | 8 | 54 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/helper/sorting_enums.dart | Dart | 9 | 6 | 4 | 19 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/view/sorting_list_page.dart | Dart | 60 | 0 | 3 | 63 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/view/sorting_page.dart | Dart | 205 | 1 | 19 | 225 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/view_model/sorting_notifier.dart | Dart | 143 | 4 | 48 | 195 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/view_model/sorting_state.dart | Dart | 31 | 0 | 3 | 34 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/widgets/control_buttons.dart | Dart | 47 | 0 | 3 | 50 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/base/widgets/sorting_app_bar.dart | Dart | 1 | 43 | 1 | 45 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/bubble/view/bubble_sort_page.dart | Dart | 25 | 0 | 6 | 31 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/bubble/view_model/bubble_sort_notifier.dart | Dart | 25 | 0 | 10 | 35 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/insertion/view/insertion_sort_page.dart | Dart | 25 | 0 | 6 | 31 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/insertion/view_model/insertion_sort_notifier.dart | Dart | 22 | 0 | 7 | 29 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/merge/view/merge_sort_page.dart | Dart | 25 | 0 | 6 | 31 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/merge/view_model/merge_sort_notifier.dart | Dart | 7 | 1 | 2 | 10 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/selection/view/selection_sort_page.dart | Dart | 25 | 0 | 6 | 31 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/features/sorting/selection/view_model/selection_sort_notifier.dart | Dart | 31 | 1 | 11 | 43 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/lib/main.dart | Dart | 6 | 0 | 2 | 8 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/CMakeLists.txt | CMake | 118 | 0 | 28 | 146 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/flutter/CMakeLists.txt | CMake | 79 | 0 | 10 | 89 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/flutter/generated_plugin_registrant.cc | C++ | 3 | 4 | 5 | 12 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/flutter/generated_plugin_registrant.h | C++ | 5 | 5 | 6 | 16 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/flutter/generated_plugins.cmake | CMake | 18 | 0 | 6 | 24 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/main.cc | C++ | 5 | 0 | 2 | 7 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/my_application.cc | C++ | 82 | 17 | 26 | 125 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/linux/my_application.h | C++ | 7 | 7 | 5 | 19 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Flutter/GeneratedPluginRegistrant.swift | Swift | 6 | 3 | 4 | 13 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Podfile | Ruby | 33 | 1 | 10 | 44 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Runner/AppDelegate.swift | Swift | 8 | 0 | 2 | 10 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json | JSON | 68 | 0 | 1 | 69 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Runner/Base.lproj/MainMenu.xib | XML | 343 | 0 | 1 | 344 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/Runner/MainFlutterWindow.swift | Swift | 12 | 0 | 4 | 16 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/macos/RunnerTests/RunnerTests.swift | Swift | 7 | 2 | 4 | 13 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/pubspec.yaml | YAML | 26 | 0 | 11 | 37 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/test/widget_test.dart | Dart | 0 | 30 | 1 | 31 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/web/index.html | HTML | 19 | 15 | 5 | 39 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/web/manifest.json | JSON | 35 | 0 | 1 | 36 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/CMakeLists.txt | CMake | 89 | 0 | 20 | 109 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/flutter/CMakeLists.txt | CMake | 98 | 0 | 12 | 110 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/flutter/generated_plugin_registrant.cc | C++ | 3 | 4 | 5 | 12 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/flutter/generated_plugin_registrant.h | C++ | 5 | 5 | 6 | 16 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/flutter/generated_plugins.cmake | CMake | 18 | 0 | 6 | 24 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/CMakeLists.txt | CMake | 34 | 0 | 7 | 41 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/flutter_window.cpp | C++ | 49 | 7 | 16 | 72 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/flutter_window.h | C++ | 20 | 5 | 9 | 34 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/main.cpp | C++ | 30 | 4 | 10 | 44 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/resource.h | C++ | 9 | 6 | 2 | 17 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/utils.cpp | C++ | 54 | 2 | 10 | 66 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/utils.h | C++ | 8 | 6 | 6 | 20 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/win32_window.cpp | C++ | 210 | 24 | 55 | 289 | +| /Users/ahmedelhawary/Documents/side_projects/flutter_projects/projects/algorithm-visualizer/windows/runner/win32_window.h | C++ | 48 | 31 | 24 | 103 | +| Total | | 6,259 | 411 | 1,006 | 7,676 | ++--------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------+------------+------------+------------+------------+ \ No newline at end of file diff --git a/android/.gitignore b/android/.gitignore index 6f56801..be3943c 100644 --- a/android/.gitignore +++ b/android/.gitignore @@ -5,9 +5,10 @@ gradle-wrapper.jar /gradlew.bat /local.properties GeneratedPluginRegistrant.java +.cxx/ # Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +# See https://flutter.dev/to/reference-keystore key.properties **/*.keystore **/*.jks diff --git a/android/app/build.gradle b/android/app/build.gradle deleted file mode 100644 index f1cb206..0000000 --- a/android/app/build.gradle +++ /dev/null @@ -1,58 +0,0 @@ -plugins { - id "com.android.application" - id "kotlin-android" - // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. - id "dev.flutter.flutter-gradle-plugin" -} - -def localProperties = new Properties() -def localPropertiesFile = rootProject.file("local.properties") -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader("UTF-8") { reader -> - localProperties.load(reader) - } -} - -def flutterVersionCode = localProperties.getProperty("flutter.versionCode") -if (flutterVersionCode == null) { - flutterVersionCode = "1" -} - -def flutterVersionName = localProperties.getProperty("flutter.versionName") -if (flutterVersionName == null) { - flutterVersionName = "1.0" -} - -android { - namespace = "com.example.algorithm_visualizer" - compileSdk = flutter.compileSdkVersion - ndkVersion = flutter.ndkVersion - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId = "com.example.algorithm_visualizer" - // You can update the following values to match your application needs. - // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdk = flutter.minSdkVersion - targetSdk = flutter.targetSdkVersion - versionCode = flutterVersionCode.toInteger() - versionName = flutterVersionName - } - - buildTypes { - release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig = signingConfigs.debug - } - } -} - -flutter { - source = "../.." -} diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts new file mode 100644 index 0000000..84922bf --- /dev/null +++ b/android/app/build.gradle.kts @@ -0,0 +1,44 @@ +plugins { + id("com.android.application") + id("kotlin-android") + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id("dev.flutter.flutter-gradle-plugin") +} + +android { + namespace = "com.example.algorithm_visualizer" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_11.toString() + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId = "com.example.algorithm_visualizer" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + minSdk = flutter.minSdkVersion + targetSdk = flutter.targetSdkVersion + versionCode = flutter.versionCode + versionName = flutter.versionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig = signingConfigs.getByName("debug") + } + } +} + +flutter { + source = "../.." +} diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index f6cc2c8..b0a2f84 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ ("clean") { + delete(rootProject.layout.buildDirectory) +} diff --git a/android/gradle.properties b/android/gradle.properties index 3b5b324..f018a61 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,3 +1,3 @@ -org.gradle.jvmargs=-Xmx4G -XX:+HeapDumpOnOutOfMemoryError +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 7bb2df6..ac3b479 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip diff --git a/android/settings.gradle b/android/settings.gradle deleted file mode 100644 index 536165d..0000000 --- a/android/settings.gradle +++ /dev/null @@ -1,25 +0,0 @@ -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 - }() - - includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") - - repositories { - google() - mavenCentral() - gradlePluginPortal() - } -} - -plugins { - id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "7.3.0" apply false - id "org.jetbrains.kotlin.android" version "1.7.10" apply false -} - -include ":app" diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts new file mode 100644 index 0000000..ab39a10 --- /dev/null +++ b/android/settings.gradle.kts @@ -0,0 +1,25 @@ +pluginManagement { + val flutterSdkPath = run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id("dev.flutter.flutter-plugin-loader") version "1.0.0" + id("com.android.application") version "8.7.3" apply false + id("org.jetbrains.kotlin.android") version "2.1.0" apply false +} + +include(":app") diff --git a/lib/config/routes/route_app.dart b/lib/config/routes/route_app.dart index 5978d35..7679ee7 100644 --- a/lib/config/routes/route_app.dart +++ b/lib/config/routes/route_app.dart @@ -5,9 +5,16 @@ import 'package:algorithm_visualizer/features/base/view/base_page.dart'; import 'package:algorithm_visualizer/features/searching/view/grid_page.dart'; import 'package:algorithm_visualizer/features/sorting/base/view/sorting_list_page.dart'; import 'package:algorithm_visualizer/features/sorting/bubble/view/bubble_sort_page.dart'; +import 'package:algorithm_visualizer/features/sorting/bucket/view/bucket_sort_page.dart'; +import 'package:algorithm_visualizer/features/sorting/comparison/view/comparison_sort_page.dart'; +import 'package:algorithm_visualizer/features/sorting/counting/view/counting_sort_page.dart'; +import 'package:algorithm_visualizer/features/sorting/heap/view/heap_sort_page.dart'; import 'package:algorithm_visualizer/features/sorting/insertion/view/insertion_sort_page.dart'; import 'package:algorithm_visualizer/features/sorting/merge/view/merge_sort_page.dart'; +import 'package:algorithm_visualizer/features/sorting/quick/view/quick_sort_page.dart'; +import 'package:algorithm_visualizer/features/sorting/radix/view/radix_sort_page.dart'; import 'package:algorithm_visualizer/features/sorting/selection/view/selection_sort_page.dart'; +import 'package:algorithm_visualizer/features/sorting/shell/view/shell_sort_page.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; @@ -41,6 +48,34 @@ class Routes { name: 'mergeSort', path: 'mergeSort', ); + static const RouteConfig heapSort = RouteConfig( + name: 'heapSort', + path: 'heapSort', + ); + static const RouteConfig quickSort = RouteConfig( + name: 'quickSort', + path: 'quickSort', + ); + static const RouteConfig radixSort = RouteConfig( + name: 'radixSort', + path: 'radixSort', + ); + static const RouteConfig shellSort = RouteConfig( + name: 'shellSort', + path: 'shellSort', + ); + static const RouteConfig countingSort = RouteConfig( + name: 'countingSort', + path: 'countingSort', + ); + static const RouteConfig bucketSort = RouteConfig( + name: 'bucketSort', + path: 'bucketSort', + ); + static const RouteConfig comparisonSort = RouteConfig( + name: 'comparisonSort', + path: 'comparisonSort', + ); } class RouteConfig { @@ -111,6 +146,55 @@ class AppRoutes { return const MergeSortPage(); }, ), + GoRoute( + path: Routes.heapSort.path, + name: Routes.heapSort.name, + builder: (context, state) { + return const HeapSortPage(); + }, + ), + GoRoute( + path: Routes.quickSort.path, + name: Routes.quickSort.name, + builder: (context, state) { + return const QuickSortPage(); + }, + ), + GoRoute( + path: Routes.radixSort.path, + name: Routes.radixSort.name, + builder: (context, state) { + return const RadixSortPage(); + }, + ), + GoRoute( + path: Routes.shellSort.path, + name: Routes.shellSort.name, + builder: (context, state) { + return const ShellSortPage(); + }, + ), + GoRoute( + path: Routes.countingSort.path, + name: Routes.countingSort.name, + builder: (context, state) { + return const CountingSortPage(); + }, + ), + GoRoute( + path: Routes.bucketSort.path, + name: Routes.bucketSort.name, + builder: (context, state) { + return const BucketSortPage(); + }, + ), + GoRoute( + path: Routes.comparisonSort.path, + name: Routes.comparisonSort.name, + builder: (context, state) { + return const ComparisonSortPage(); + }, + ), ], ), ], diff --git a/lib/config/themes/app_theme.dart b/lib/config/themes/app_theme.dart index 258791c..d7e10b9 100644 --- a/lib/config/themes/app_theme.dart +++ b/lib/config/themes/app_theme.dart @@ -44,7 +44,7 @@ class AppTheme { tabBarTheme: _tabBarTheme(), textTheme: _textTheme(), dividerTheme: const DividerThemeData(color: ColorManager.whiteD5), - bottomAppBarTheme: const BottomAppBarTheme(color: ColorManager.blackOp30), + bottomAppBarTheme: const BottomAppBarThemeData(color: ColorManager.blackOp30), textSelectionTheme: const TextSelectionThemeData( cursorColor: ColorManager.teal, selectionColor: ColorManager.blackOp10, @@ -125,7 +125,7 @@ class AppTheme { elevation: 0, titleSpacing: 5.w, surfaceTintColor: ColorManager.white, - color: ColorManager.white, + backgroundColor: ColorManager.white, shadowColor: ColorManager.blackOp20, scrolledUnderElevation: 1.5.r, iconTheme: const IconThemeData(color: ColorManager.black), @@ -169,7 +169,7 @@ class AppTheme { tabBarTheme: _tabBarDarkTheme(), textTheme: _textDarkTheme(), dividerTheme: const DividerThemeData(color: ColorManager.blackL5), - bottomAppBarTheme: const BottomAppBarTheme(color: ColorManager.whiteOp30), + bottomAppBarTheme: const BottomAppBarThemeData(color: ColorManager.whiteOp30), textSelectionTheme: const TextSelectionThemeData( cursorColor: ColorManager.teal, selectionColor: ColorManager.greyD6, @@ -244,7 +244,7 @@ class AppTheme { elevation: 0, titleSpacing: 5.w, surfaceTintColor: ColorManager.blackBlue, - color: ColorManager.blackBlue, + backgroundColor: ColorManager.blackBlue, shadowColor: ColorManager.greyD8, scrolledUnderElevation: 1.5.r, iconTheme: const IconThemeData(color: ColorManager.white), diff --git a/lib/core/draggable_progress.dart b/lib/core/draggable_progress.dart index 00629fe..e13a5c7 100644 --- a/lib/core/draggable_progress.dart +++ b/lib/core/draggable_progress.dart @@ -2,19 +2,37 @@ import 'package:algorithm_visualizer/core/resources/theme_manager.dart'; import 'package:flutter/material.dart'; class DraggableProgressBar extends StatefulWidget { - const DraggableProgressBar({required this.onChanged, super.key}); + const DraggableProgressBar({ + this.runOnChangedInitially = false, + required this.onChanged, + this.sliderValue = 0.3, + this.isActive = true, + super.key, + }); final void Function(double persent) onChanged; + final bool runOnChangedInitially; + final double sliderValue; + final bool isActive; @override LinearSliderState createState() => LinearSliderState(); } class LinearSliderState extends State { - double sliderValue = 0.3; + late double sliderValue = widget.sliderValue; + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (widget.runOnChangedInitially) widget.onChanged(sliderValue); + }); + super.initState(); + } @override Widget build(BuildContext context) { return Slider( - activeColor: context.getColor(ThemeEnum.blueColor), + activeColor: widget.isActive + ? context.getColor(ThemeEnum.mediumBlueColor) + : context.getColor(ThemeEnum.whiteD7Color), value: sliderValue, onChanged: (v) { setState(() { diff --git a/lib/core/helpers/current_device.dart b/lib/core/helpers/current_device.dart index 1fc7f3c..bb75fe6 100644 --- a/lib/core/helpers/current_device.dart +++ b/lib/core/helpers/current_device.dart @@ -5,4 +5,9 @@ extension CurrentDevice on BuildContext { final ThemeData theme = Theme.of(this); return theme.platform == TargetPlatform.android; } + + bool get isIOS { + final ThemeData theme = Theme.of(this); + return theme.platform == TargetPlatform.iOS; + } } diff --git a/lib/core/material_app/my_app.dart b/lib/core/material_app/my_app.dart index 3cc4aad..0fba7c5 100644 --- a/lib/core/material_app/my_app.dart +++ b/lib/core/material_app/my_app.dart @@ -14,21 +14,12 @@ class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { - const defaultSize = Size(360, 690); + final defaultSize = MediaQuery.sizeOf(context); return ScreenUtilInit( designSize: defaultSize, minTextAdapt: true, splitScreenMode: true, - fontSizeResolver: (fontSize, instance) { - final size = fontSize; - final width = MediaQuery.of(context).size.width; - // Size(501.7, 669.0) - - if (width <= 450) return size.toDouble() * (instance.scaleText); - - return size.toDouble() * (instance.scaleText / 1.35); - }, builder: (context, child) { return Consumer( builder: (context, ref, child) { @@ -39,9 +30,8 @@ class MyApp extends StatelessWidget { return LayoutBuilder( builder: (context, constraints) { - final padding = constraints.maxWidth < 450 - ? 0.0 - : ((constraints.maxWidth - defaultSize.width) / 2.3); + final padding = + constraints.maxWidth < 450 ? 0.0 : ((constraints.maxWidth - defaultSize.width) / 2.3); return SystemOverlay( isBlackTheme: isDarkMode, @@ -62,12 +52,9 @@ class MyApp extends StatelessWidget { themeMode: themeMode, debugShowCheckedModeBanner: false, routerDelegate: AppRoutes.router.routerDelegate, - backButtonDispatcher: - AppRoutes.router.backButtonDispatcher, - routeInformationParser: - AppRoutes.router.routeInformationParser, - routeInformationProvider: - AppRoutes.router.routeInformationProvider, + backButtonDispatcher: AppRoutes.router.backButtonDispatcher, + routeInformationParser: AppRoutes.router.routeInformationParser, + routeInformationProvider: AppRoutes.router.routeInformationProvider, ), ), ), diff --git a/lib/core/resources/strings_manager.dart b/lib/core/resources/strings_manager.dart index e6cfad1..ffcea1e 100644 --- a/lib/core/resources/strings_manager.dart +++ b/lib/core/resources/strings_manager.dart @@ -24,18 +24,36 @@ class StringsManager { static const String unknownPage = "Unknown page"; static const String notInitializeGridYet = "Not initialize grid yet."; static const String clear = "Clear"; + static const String dijkstra = "Dijkstra"; + static const String aStarSearch = "A* Search"; + static const String bFS = "BFS"; + static const String dFS = "DFS"; static const String clearAll = "Clear all"; static const String clearPath = "Clear path"; - static const String generateMaze = "Generate maze"; + static const String recursiveBacktrackerMaze = "Recursive Backtracker Maze"; + static const String recursiveDivisionMaze = "Recursive Division Maze"; static const String searching = "Searching"; static const String sorting = "Sorting"; static const String bubbleSort = "Bubble sort"; static const String insertionSort = "Insertion sort"; static const String selectionSort = "Selection sort"; static const String mergeSort = "Merge sort"; + static const String heapSort = "Heap sort"; + static const String quickSort = "Quick sort"; + static const String radixSort = "Radix sort"; + static const String shellSort = "Shell sort"; + static const String countingSort = "Counting sort"; + static const String bucketSort = "Bucket sort"; + static const String comparisonSort = "Comparison sort"; + static const String comparisonAlgorithms = "Comparison algorithms"; + static const String generateMaze = "Generate Maze"; + static const String visualize = "Visualize"; + static const String maze = "Maze"; static const String stop = "Stop"; static const String play = "Play"; static const String reset = "Reset"; static const String sort = "Sort"; + static const String speed = "Speed"; + static const String size = "Size"; } diff --git a/lib/core/resources/theme_manager.dart b/lib/core/resources/theme_manager.dart index 4d7d443..0bfab25 100644 --- a/lib/core/resources/theme_manager.dart +++ b/lib/core/resources/theme_manager.dart @@ -33,6 +33,7 @@ enum ThemeEnum { blueColor, darkBlueColor, + mediumBlueColor, lightBlueColor, greenColor, redColor, @@ -82,7 +83,8 @@ extension ThemeExtension on BuildContext { Theme.of(this).textTheme.bodyLarge?.color ?? ColorManager.greyD3, ThemeEnum.blueColor: ColorManager.blue, ThemeEnum.darkBlueColor: ColorManager.darkBlue, - ThemeEnum.lightBlueColor: ColorManager.lightBlue, + ThemeEnum.mediumBlueColor: ColorManager.mediumBlue, + ThemeEnum.lightBlueColor: ColorManager.finishedSearcherBlue, ThemeEnum.greenColor: ColorManager.green, ThemeEnum.redColor: ColorManager.red, ThemeEnum.orangeColor: ColorManager.orange, diff --git a/lib/core/widgets/adaptive/padding/symmetric_padding.dart b/lib/core/widgets/adaptive/padding/symmetric_padding.dart index 785a0d4..133deb5 100644 --- a/lib/core/widgets/adaptive/padding/symmetric_padding.dart +++ b/lib/core/widgets/adaptive/padding/symmetric_padding.dart @@ -2,8 +2,8 @@ part of '../../../../core/widgets/adaptive/padding/adaptive_padding.dart'; class SymmetricPadding extends StatelessWidget { const SymmetricPadding({ - required this.horizontal, - required this.vertical, + this.horizontal = 0, + this.vertical = 0, required this.child, super.key, }); @@ -13,8 +13,6 @@ class SymmetricPadding extends StatelessWidget { @override Widget build(BuildContext context) { return _RPadding( - padding: - REdgeInsets.symmetric(horizontal: horizontal, vertical: vertical), - child: child); + padding: REdgeInsets.symmetric(horizontal: horizontal, vertical: vertical), child: child); } } diff --git a/lib/core/widgets/custom_widgets/custom_rounded_elevated_button.dart b/lib/core/widgets/custom_widgets/custom_rounded_elevated_button.dart index 2dbb418..ccdbb5e 100644 --- a/lib/core/widgets/custom_widgets/custom_rounded_elevated_button.dart +++ b/lib/core/widgets/custom_widgets/custom_rounded_elevated_button.dart @@ -34,7 +34,7 @@ class CustomRoundedElevatedButton extends StatelessWidget { style: ElevatedButton.styleFrom( backgroundColor: background, shadowColor: shadow ?? ColorManager.transparent, - fixedSize: fitToContent ? Size.fromHeight(fixedSize.r) : null, + fixedSize: fitToContent ? Size.fromHeight(fixedSize.r) : Size.fromWidth(fixedSize.r), padding: EdgeInsets.symmetric(horizontal: 15.r), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(roundedRadius).r), diff --git a/lib/features/base/view/base_page.dart b/lib/features/base/view/base_page.dart index 077c1c7..1323f83 100644 --- a/lib/features/base/view/base_page.dart +++ b/lib/features/base/view/base_page.dart @@ -7,6 +7,9 @@ import 'package:algorithm_visualizer/core/widgets/adaptive/text/adaptive_text.da import 'package:algorithm_visualizer/core/widgets/custom_widgets/custom_rounded_elevated_button.dart'; import 'package:flutter/material.dart'; +import 'movable_animated_button.dart'; +import 'movable_pins.dart'; + class BasePage extends StatefulWidget { const BasePage({super.key}); @@ -28,26 +31,29 @@ class _BasePageState extends State { return Scaffold( body: SafeArea( child: Center( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - CustomRoundedElevatedButton( - roundedRadius: 3, - backgroundColor: ThemeEnum.whiteD5Color, - child: const RegularText(StringsManager.searching), - onPressed: () { - context.pushTo(Routes.searching); - }, - ), - CustomRoundedElevatedButton( - roundedRadius: 3, - backgroundColor: ThemeEnum.whiteD5Color, - child: const RegularText(StringsManager.sorting), - onPressed: () { - context.pushTo(Routes.sortingList); - }, - ), - ], + child: MovablePinsBackground( + pinColor: ThemeEnum.whiteD4Color, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + FloatingAnimatedButton( + child: CustomRoundedElevatedButton( + roundedRadius: 3, + backgroundColor: ThemeEnum.whiteD5Color, + child: const RegularText(StringsManager.searching), + onPressed: () => context.pushTo(Routes.searching), + ), + ), + FloatingAnimatedButton( + child: CustomRoundedElevatedButton( + roundedRadius: 3, + backgroundColor: ThemeEnum.whiteD5Color, + child: const RegularText(StringsManager.sorting), + onPressed: () => context.pushTo(Routes.sortingList), + ), + ), + ], + ), ), ), ), diff --git a/lib/features/base/view/movable_animated_button.dart b/lib/features/base/view/movable_animated_button.dart new file mode 100644 index 0000000..eb91a49 --- /dev/null +++ b/lib/features/base/view/movable_animated_button.dart @@ -0,0 +1,91 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +class FloatingAnimatedButton extends StatefulWidget { + final Widget child; + final Duration stepDuration; + + const FloatingAnimatedButton({ + super.key, + required this.child, + this.stepDuration = const Duration(seconds: 3), + }); + + @override + State createState() => _FloatingAnimatedButtonState(); +} + +class _FloatingAnimatedButtonState extends State with SingleTickerProviderStateMixin { + late AnimationController _controller; + late Animation _scale; + late Animation _offset; + + final Random _random = Random(); + double _currentScale = 1.0; + Offset _currentOffset = Offset.zero; + + @override + void initState() { + super.initState(); + + _controller = AnimationController(vsync: this); + + _setNewRandomAnimation(); + + // when one random animation finishes → schedule the next one + _controller.addStatusListener((status) { + if (status == AnimationStatus.completed) { + _currentScale = _scale.value; + _currentOffset = _offset.value; + _setNewRandomAnimation(); + } + }); + } + + void _setNewRandomAnimation() { + // generate new random target scale and offset + final newScale = 0.95 + _random.nextDouble() * 0.1; + final newOffset = Offset( + (_random.nextDouble() * 40 - 35) / 100, + (_random.nextDouble() * 40 - 35) / 100, + ); + + _scale = Tween( + begin: _currentScale, + end: newScale, + ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeInOut)); + + _offset = Tween( + begin: _currentOffset, + end: newOffset, + ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeInOut)); + + _controller.duration = widget.stepDuration + Duration(milliseconds: _random.nextInt(2000)); + + _controller.reset(); + _controller.forward(); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return AnimatedBuilder( + animation: _controller, + builder: (_, __) { + return Transform.translate( + offset: _offset.value * 25, + child: Transform.scale( + scale: _scale.value, + child: widget.child, + ), + ); + }, + ); + } +} diff --git a/lib/features/base/view/movable_pins.dart b/lib/features/base/view/movable_pins.dart new file mode 100644 index 0000000..322163d --- /dev/null +++ b/lib/features/base/view/movable_pins.dart @@ -0,0 +1,210 @@ +import 'dart:math'; + +import 'package:algorithm_visualizer/core/resources/theme_manager.dart'; +import 'package:flutter/material.dart'; + +class MovablePinsBackground extends StatefulWidget { + const MovablePinsBackground({this.pinColor = ThemeEnum.whiteD5Color, required this.child, super.key}); + final ThemeEnum pinColor; + final Widget child; + @override + State createState() => _MovablePinsBackgroundState(); +} + +class _MovablePinsBackgroundState extends State with SingleTickerProviderStateMixin { + late AnimationController _controller; + final List _particles = []; + final Random _random = Random(); + + /// 🔧 Adjustable parameters + double speedFactor = 0.3; + double densityFactor = 0.45; + final int maxPins = 150; + + @override + void initState() { + super.initState(); + _controller = AnimationController( + vsync: this, + duration: const Duration(hours: 1), + )..addListener(_update); + + _controller.repeat(); + } + + void _createParticles(Size size) { + if (_particles.isNotEmpty) return; + + final baseCount = (size.width * size.height / 2500).round(); + final count = (baseCount * densityFactor).round(); + + for (int i = 0; i < count; i++) { + _particles.add(Particle.random(_random, size, speedFactor)); + } + } + + void _update() { + final size = MediaQuery.of(context).size; + + setState(() { + for (int i = _particles.length - 1; i >= 0; i--) { + final p = _particles[i]; + p.randomWalk(); + p.update(); + + // remove if outside screen + if (!p.isInside(size)) { + _particles.removeAt(i); + _particles.add(Particle.random(_random, size, speedFactor)); + } + } + }); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final size = MediaQuery.of(context).size; + _createParticles(size); + + return GestureDetector( + // set max pins limit + + onTapDown: (d) { + setState(() { + // add new pin + _particles.add(Particle( + d.localPosition, + Offset((_random.nextDouble() * 2 - 1) * 0.5, (_random.nextDouble() * 2 - 1) * 0.5), + _random, + size, + speedFactor, + )); + + // if exceeded maxPins → remove the oldest one (index 0) + if (_particles.length > maxPins) { + _particles.removeAt(0); + } + }); + }, + onPanUpdate: (d) { + setState(() { + const influenceRadius = 100.0; // 👈 adjust how far the finger affects pins + for (var p in _particles) { + final distance = (p.position - d.localPosition).distance; + if (distance < influenceRadius) { + // push away + final direction = (p.position - d.localPosition).normalize(); + p.velocity += direction * 0.5; // 👈 adjust strength + } + } + }); + }, + + child: Stack( + alignment: AlignmentDirectional.center, + children: [ + CustomPaint( + painter: ParticlePainter(_particles, context.getColor(widget.pinColor)), + child: const SizedBox.expand(), + ), + widget.child + ], + ), + ); + } +} + +class Particle { + Offset position; + Offset velocity; + final Size screenSize; + final Random random; + final double speedFactor; + + Particle(this.position, this.velocity, this.random, this.screenSize, this.speedFactor); + + factory Particle.random(Random random, Size screenSize, double speedFactor) { + return Particle( + Offset( + random.nextDouble() * screenSize.width, + random.nextDouble() * screenSize.height, + ), + Offset( + (random.nextDouble() * 2 - 1) * 0.5, + (random.nextDouble() * 2 - 1) * 0.5, + ), + random, + screenSize, + speedFactor, + ); + } + + void randomWalk() { + final dx = (random.nextDouble() * 0.2 - 0.1) * speedFactor; + final dy = (random.nextDouble() * 0.2 - 0.1) * speedFactor; + velocity += Offset(dx, dy); + + final maxSpeed = 1.5 * speedFactor; + if (velocity.distance > maxSpeed) { + velocity = (velocity / velocity.distance) * maxSpeed; + } + } + + void update() { + position += velocity; + } + + bool isInside(Size size) { + return position.dx >= -20 && + position.dx <= size.width + 20 && + position.dy >= -20 && + position.dy <= size.height + 20; + } +} + +class ParticlePainter extends CustomPainter { + final List particles; + final Color pinColor; + + ParticlePainter(this.particles, this.pinColor); + + @override + void paint(Canvas canvas, Size size) { + final circlePaint = Paint()..color = pinColor; + final linePaint = Paint() + ..color = pinColor.withOpacity(0.2) + ..strokeWidth = 0.5; + + const maxDistance = 150.0; + + for (var p in particles) { + canvas.drawCircle(p.position, 3, circlePaint); + + for (var other in particles) { + if (p == other) continue; + final dist = (p.position - other.position).distance; + if (dist < maxDistance) { + linePaint.color = pinColor.withOpacity(1 - dist / maxDistance); + canvas.drawLine(p.position, other.position, linePaint); + } + } + } + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) => true; +} + +extension OffsetX on Offset { + Offset normalize() { + final len = distance; + if (len == 0) return Offset.zero; + return this / len; + } +} diff --git a/lib/features/searching/view/grid_page.dart b/lib/features/searching/view/grid_page.dart index 37e9ad6..2e21d1b 100644 --- a/lib/features/searching/view/grid_page.dart +++ b/lib/features/searching/view/grid_page.dart @@ -2,7 +2,6 @@ import 'package:algorithm_visualizer/core/resources/color_manager.dart'; import 'package:algorithm_visualizer/core/resources/strings_manager.dart'; import 'package:algorithm_visualizer/core/resources/theme_manager.dart'; import 'package:algorithm_visualizer/core/widgets/adaptive/text/adaptive_text.dart'; -import 'package:algorithm_visualizer/core/widgets/custom_widgets/custom_dialog.dart'; import 'package:algorithm_visualizer/core/widgets/custom_widgets/custom_icon.dart'; import 'package:algorithm_visualizer/features/searching/view_model/grid_notifier.dart'; import 'package:flutter/material.dart'; @@ -26,68 +25,165 @@ BorderDirectional _thineVerticalBorder() => BorderDirectional( bottom: _borderSide(true), ); -class SearchingPage extends StatelessWidget { +class SearchingPage extends ConsumerWidget { const SearchingPage({super.key}); + @override + Widget build(BuildContext context, WidgetRef ref) { + return PopScope( + onPopInvokedWithResult: (didPop, result) async { + if (didPop) { + await ref.read(_gridNotifierProvider.notifier).cancelSearching(); + ref.invalidate(_gridNotifierProvider); + } + }, + child: Scaffold( + appBar: AppBar( + title: const _ControlButtons(), + centerTitle: true, + ), + body: SafeArea( + child: LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + return _BuildLayout(constraints.biggest); + }, + ), + ), + ), + ); + } +} + +class _ControlButtons extends StatefulWidget { + const _ControlButtons(); + + @override + State<_ControlButtons> createState() => _ControlButtonsState(); +} + +class _ControlButtonsState extends State<_ControlButtons> { + PopupMenuItem buildPopupMenuItem(String value, [ThemeEnum? color]) { + final isLargeScreen = MediaQuery.sizeOf(context).width > 500; + return PopupMenuItem( + value: value, child: RegularText(value, fontSize: isLargeScreen ? 16 : 14, color: color)); + } + @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - actions: [ - Consumer( - builder: (context, ref, _) { - return TextButton( - onPressed: () { - CustomAlertDialog(context).solidDialog( - parameters: [ - ListDialogParameters( - text: StringsManager.generateMaze, - onTap: () { - ref.read(_gridNotifierProvider.notifier).generateMaze(); - }, - ), - ListDialogParameters( - text: "Dijkstra", - onTap: () { + return Consumer( + builder: (context, ref, _) { + return Row( + children: [ + Expanded( + flex: 8, + child: SizedBox( + width: double.infinity, + height: 40.r, + child: Center( + child: FittedBox( + fit: BoxFit.scaleDown, + child: PopupMenuButton( + position: PopupMenuPosition.under, + onSelected: (value) { + if (value == StringsManager.recursiveBacktrackerMaze) { + ref.read(_gridNotifierProvider.notifier).generateRecursiveBacktrackerMaze(); + } else if (value == StringsManager.recursiveDivisionMaze) { + ref.read(_gridNotifierProvider.notifier).generateRecursiveDivisionMaze(); + } + }, + itemBuilder: (context) => [ + buildPopupMenuItem(StringsManager.recursiveBacktrackerMaze), + buildPopupMenuItem(StringsManager.recursiveDivisionMaze), + ], + icon: const Row( + mainAxisSize: MainAxisSize.min, + children: [ + MediumText(StringsManager.maze, fontSize: 16), + CustomIcon( + Icons.keyboard_arrow_down_rounded, + size: 20, + ), + ], + ), // 3-dot menu + ), + ), + ), + ), + ), + Expanded( + flex: 10, + child: SizedBox( + width: double.infinity, + height: 40.r, + child: FittedBox( + fit: BoxFit.scaleDown, + child: Center( + child: PopupMenuButton( + position: PopupMenuPosition.under, + style: const ButtonStyle( + backgroundColor: WidgetStatePropertyAll(ColorManager.finishedSearcherBlue)), + onSelected: (value) { + if (value == StringsManager.dijkstra) { ref.read(_gridNotifierProvider.notifier).performDijkstra(); - }, - ), - ListDialogParameters( - text: "BFS", - onTap: () { + } else if (value == StringsManager.aStarSearch) { + ref.read(_gridNotifierProvider.notifier).performAStar(); + } else if (value == StringsManager.bFS) { ref.read(_gridNotifierProvider.notifier).performBFS(); - }, - ), - ListDialogParameters( - text: StringsManager.clearPath, - color: ThemeEnum.redColor, - onTap: () { + } + }, + itemBuilder: (context) => [ + buildPopupMenuItem(StringsManager.dijkstra), + buildPopupMenuItem(StringsManager.aStarSearch), + buildPopupMenuItem(StringsManager.bFS), + ], + icon: const Row( + mainAxisSize: MainAxisSize.min, + children: [ + MediumText(StringsManager.visualize, fontSize: 16), + CustomIcon(Icons.keyboard_arrow_down_rounded, size: 22), + ], + ), // 3-dot menu + ), + ), + ), + ), + ), + Expanded( + flex: 10, + child: SizedBox( + width: double.infinity, + height: 40.r, + child: FittedBox( + fit: BoxFit.scaleDown, + child: Center( + child: PopupMenuButton( + position: PopupMenuPosition.under, + onSelected: (value) { + if (value == StringsManager.clearPath) { ref.read(_gridNotifierProvider.notifier).clearTheGrid(keepWall: true); - }, - ), - ListDialogParameters( - text: StringsManager.clearAll, - color: ThemeEnum.redColor, - onTap: () { + } else if (value == StringsManager.clearAll) { ref.read(_gridNotifierProvider.notifier).clearTheGrid(); - }, - ), - ], - ); - }, - child: const CustomIcon(Icons.menu_rounded), - ); - }, - ), - ], - ), - body: SafeArea( - child: LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - return _BuildLayout(constraints.biggest); - }, - ), - ), + } + }, + itemBuilder: (context) => [ + buildPopupMenuItem(StringsManager.clearPath, ThemeEnum.redColor), + buildPopupMenuItem(StringsManager.clearAll, ThemeEnum.redColor), + ], + icon: const Row( + mainAxisSize: MainAxisSize.min, + children: [ + MediumText(StringsManager.clear, fontSize: 16, color: ThemeEnum.redColor), + CustomIcon(Icons.keyboard_arrow_down_rounded, size: 20, color: ColorManager.red), + ], + ), // 3-dot menu + ), + ), + ), + ), + ), + ], + ); + }, ); } } @@ -169,7 +265,8 @@ class _Square extends ConsumerStatefulWidget { class _SquareState extends ConsumerState<_Square> { @override Widget build(BuildContext context) { - final isSelected = ref.watch(_gridNotifierProvider.select((it) => it.gridData[widget.index])); + final isSelected = ref.watch(_gridNotifierProvider + .select((it) => it.gridData.length > widget.index ? it.gridData[widget.index] : GridStatus.empty)); final isColored = isSelected != GridStatus.empty; final showBorder = isSelected != GridStatus.empty && diff --git a/lib/features/searching/view_model/grid_notifier.dart b/lib/features/searching/view_model/grid_notifier.dart index 1498ea5..5c63c64 100644 --- a/lib/features/searching/view_model/grid_notifier.dart +++ b/lib/features/searching/view_model/grid_notifier.dart @@ -1,5 +1,6 @@ import 'dart:collection'; import 'dart:math'; +import 'package:async/async.dart'; import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; @@ -20,25 +21,33 @@ class MazeDirection { class SearchingNotifier extends StateNotifier { SearchingNotifier() : super(GridNotifierState()); - final int columnSquares = 25; + + /// [_gridSquareSize] + final double _gridSquareSize = 25; static const Duration scaleAppearDurationForWall = Duration(milliseconds: 700); static const Duration clearDuration = Duration(microseconds: 1); - static const Duration drawFindingPathDuration = Duration(milliseconds: 2); - static const Duration drawSearcherDuration = Duration(milliseconds: 5); + static const Duration drawSearcherDuration = Duration(milliseconds: 25); static const Duration mazeDuration = Duration(milliseconds: 10); int tapDownIndex = -1; GridStatus tapDownGridStatus = GridStatus.empty; + CancelableOperation? _cancelableSearch; + + /// [_isBuildingGrid] if build maze or search or even clear grid + bool _isBuildingGrid = false; + bool _isSearched = false; + + Future cancelSearching() async { + await _cancelableSearch?.cancel(); + // _cancelableSearch=null; + } void updateGridLayout(Size size) { final screenWidth = size.width; final screenHeight = size.height; - final double gridSize = - (screenWidth < screenHeight) ? screenWidth / columnSquares : screenHeight / columnSquares; - - final columnCrossAxisCount = (screenWidth / gridSize).floor(); - final rowMainAxisCount = (screenHeight / gridSize).floor(); + final columnCrossAxisCount = (screenWidth / _gridSquareSize).floor(); + final rowMainAxisCount = (screenHeight / _gridSquareSize).floor(); final count = columnCrossAxisCount * rowMainAxisCount; @@ -46,7 +55,7 @@ class SearchingNotifier extends StateNotifier { columnCrossAxisCount: columnCrossAxisCount, rowMainAxisCount: rowMainAxisCount, gridCount: count, - gridSize: gridSize, + gridSize: _gridSquareSize, screenWidth: screenWidth, screenHeight: screenHeight, ); @@ -123,10 +132,29 @@ class SearchingNotifier extends StateNotifier { } } - void clearTheGrid({bool keepWall = false}) { - _clearTheGrid(addState: state, keepWall: keepWall); + Future clearTheGrid({bool keepWall = false, bool clearAnyway = false}) async { + if (!clearAnyway && _isBuildingGrid) return; + _isBuildingGrid = true; + + await cancelSearching(); + + _cancelableSearch = + CancelableOperation.fromFuture(_clearTheGridFun(clearAnyway: clearAnyway, keepWall: keepWall)); + + try { + await _cancelableSearch?.value; + } catch (e) { + debugPrint("something wrong with clearTheGrid: $e"); + } + } + + Future _clearTheGridFun({bool keepWall = false, bool clearAnyway = false}) async { + await _clearTheGrid(addState: state, keepWall: keepWall); state = state.copyWith(currentTappedIndex: -1); + + _isSearched = false; + _isBuildingGrid = false; } void onPointerDownOnGrid(PointerDownEvent event) { @@ -138,10 +166,26 @@ class SearchingNotifier extends StateNotifier { } void onFingerMoveOnGrid(PointerMoveEvent event) { - final index = _getIndex(addState: state, localPosition: event.localPosition); + if (_isBuildingGrid) return; + _isBuildingGrid = true; + + int index = _getIndex(addState: state, localPosition: event.localPosition); + + /// when you try to draw on the right border if you make the arrow closly to the border it will draw the wall in the left side (the next index) + /// those two lines to prevent that + final calcIndex = (event.localPosition.dx / _gridSquareSize).floor(); + if (calcIndex != 0 && + calcIndex % state.columnCrossAxisCount == 0 && + index % state.columnCrossAxisCount == 0) { + index--; + } /// to handle multi calls from listener widget - if (index == state.currentTappedIndex) return; + if (index == state.currentTappedIndex) { + _isBuildingGrid = false; + + return; + } if (index >= 0 && index < state.gridData.length) { final updatedGridData = List.from(state.gridData); @@ -165,6 +209,8 @@ class SearchingNotifier extends StateNotifier { state = state.copyWith(gridData: updatedGridData, currentTappedIndex: index); } + + _isBuildingGrid = false; } int _getIndex({ @@ -183,11 +229,30 @@ class SearchingNotifier extends StateNotifier { } Future performBFS() async { + if (_isBuildingGrid) return; + _isBuildingGrid = true; + await cancelSearching(); + + _cancelableSearch = CancelableOperation.fromFuture(_performBFSFun()); + + try { + await _cancelableSearch?.value; + } catch (e) { + debugPrint("something wrong with performBFS: $e"); + } + } + + Future _performBFSFun() async { + if (_isSearched) await clearTheGrid(keepWall: true, clearAnyway: true); + final gridData = List.from(state.gridData); final startPointIndex = gridData.indexOf(GridStatus.startPoint); final targetPointIndex = gridData.indexOf(GridStatus.targetPoint); - if (startPointIndex == -1 || targetPointIndex == -1) return; + if (startPointIndex == -1 || targetPointIndex == -1) { + _isBuildingGrid = false; + return; + } final queue = Queue(); final Set visited = {}; @@ -204,10 +269,10 @@ class SearchingNotifier extends StateNotifier { const right = 1; final directions = [ - up, // up - down, // down - left, // left - right, // right + up, + down, + left, + right, ]; while (queue.isNotEmpty) { @@ -215,6 +280,9 @@ class SearchingNotifier extends StateNotifier { if (currentIndex == targetPointIndex) { _tracePath(previous, currentIndex); + _isBuildingGrid = false; + _isSearched = true; + return; } @@ -231,7 +299,7 @@ class SearchingNotifier extends StateNotifier { } } - // for marking the current grid as visited + /// for marking the current grid as visited if (gridData[currentIndex] != GridStatus.startPoint && gridData[currentIndex] != GridStatus.targetPoint) { gridData[currentIndex] = GridStatus.searcher; @@ -239,14 +307,36 @@ class SearchingNotifier extends StateNotifier { await Future.delayed(drawSearcherDuration); } } + + _isBuildingGrid = false; + _isSearched = true; } Future performDijkstra() async { + if (_isBuildingGrid) return; + _isBuildingGrid = true; + await cancelSearching(); + + _cancelableSearch = CancelableOperation.fromFuture(_performDijkstraFun()); + + try { + await _cancelableSearch?.value; + } catch (e) { + debugPrint("something wrong with performDijkstra: $e"); + } + } + + Future _performDijkstraFun() async { + if (_isSearched) await clearTheGrid(keepWall: true, clearAnyway: true); + final gridData = List.from(state.gridData); final startPointIndex = gridData.indexOf(GridStatus.startPoint); final targetPointIndex = gridData.indexOf(GridStatus.targetPoint); - if (startPointIndex == -1 || targetPointIndex == -1) return; + if (startPointIndex == -1 || targetPointIndex == -1) { + _isBuildingGrid = false; + return; + } final distance = List.filled(gridData.length, double.infinity); final previous = List.filled(gridData.length, null); @@ -255,7 +345,6 @@ class SearchingNotifier extends StateNotifier { distance[startPointIndex] = 0; - // priority queue to get the minimum distance vertex final pq = PriorityQueue((a, b) => distance[a].compareTo(distance[b])); pq.add(startPointIndex); @@ -269,12 +358,13 @@ class SearchingNotifier extends StateNotifier { while (pq.isNotEmpty) { final currentIndex = pq.removeFirst(); - // Mark the current node as visited + /// mark the current node as visited visited[currentIndex] = true; - // If we reached the target, we trace back the path if (currentIndex == targetPointIndex) { _tracePath(previous, currentIndex); + _isBuildingGrid = false; + _isSearched = true; return; } @@ -285,14 +375,15 @@ class SearchingNotifier extends StateNotifier { continue; } - final tentativeDistance = distance[currentIndex] + 1; // Assume weight of 1 for each move + final tentativeDistance = distance[currentIndex] + 1; + + /// assume weight of 1 for each move if (tentativeDistance < distance[neighborIndex]) { distance[neighborIndex] = tentativeDistance; previous[neighborIndex] = currentIndex; pq.add(neighborIndex); - // Visualize the search process if (gridData[neighborIndex] != GridStatus.startPoint && gridData[neighborIndex] != GridStatus.targetPoint) { gridData[neighborIndex] = GridStatus.searcher; @@ -302,6 +393,8 @@ class SearchingNotifier extends StateNotifier { } } } + _isBuildingGrid = false; + _isSearched = true; } bool _isValidNeighbor( @@ -309,8 +402,8 @@ class SearchingNotifier extends StateNotifier { final isFirstLeftInRowIndex = neighborIndex % cross == 0; final isEndRightInRowIndex = (neighborIndex + 1) % cross == 0; - if (direction == 1 && isFirstLeftInRowIndex) return false; // avoid exiting the boundaries - if (direction == -1 && isEndRightInRowIndex) return false; // avoid exiting the boundaries + if (direction == 1 && isFirstLeftInRowIndex) return false; + if (direction == -1 && isEndRightInRowIndex) return false; return neighborIndex >= 0 && neighborIndex < gridData.length && @@ -331,27 +424,189 @@ class SearchingNotifier extends StateNotifier { } } - void generateMaze() async { + Future performAStar() async { + if (_isBuildingGrid) return; + _isBuildingGrid = true; + await cancelSearching(); + + _cancelableSearch = CancelableOperation.fromFuture(_performAStarFun()); + + try { + await _cancelableSearch?.value; + } catch (e) { + debugPrint("something wrong with performAStar: $e"); + } + } + + Future _performAStarFun() async { + if (_isSearched) await clearTheGrid(keepWall: true, clearAnyway: true); + + final gridData = List.from(state.gridData); + final startPointIndex = gridData.indexOf(GridStatus.startPoint); + final targetPointIndex = gridData.indexOf(GridStatus.targetPoint); + + if (startPointIndex == -1 || targetPointIndex == -1) { + _isBuildingGrid = false; + + return; + } + + final cross = state.columnCrossAxisCount; + + final gScore = List.filled(gridData.length, double.infinity); + final fScore = List.filled(gridData.length, double.infinity); + final previous = List.filled(gridData.length, null); + final visited = {}; + + gScore[startPointIndex] = 0; + fScore[startPointIndex] = _heuristic(startPointIndex, targetPointIndex, cross); + + // priority queue based on fScore (g + h) + final pq = PriorityQueue((a, b) => fScore[a].compareTo(fScore[b])); + pq.add(startPointIndex); + + final directions = [ + -cross, // up + cross, // down + -1, // left + 1, // right + ]; + + while (pq.isNotEmpty) { + final currentIndex = pq.removeFirst(); + + if (currentIndex == targetPointIndex) { + await _tracePath(previous, currentIndex); + _isBuildingGrid = false; + _isSearched = true; + + return; + } + + visited.add(currentIndex); + + for (final direction in directions) { + final neighborIndex = currentIndex + direction; + + if (!_isValidNeighbor(currentIndex, neighborIndex, direction, cross, gridData)) { + continue; + } + + if (visited.contains(neighborIndex)) continue; + + final tentativeG = gScore[currentIndex] + 1; // weight = 1 + + if (tentativeG < gScore[neighborIndex]) { + gScore[neighborIndex] = tentativeG; + fScore[neighborIndex] = tentativeG + _heuristic(neighborIndex, targetPointIndex, cross); + previous[neighborIndex] = currentIndex; + + if (!pq.contains(neighborIndex)) { + pq.add(neighborIndex); + } + + if (gridData[neighborIndex] != GridStatus.startPoint && + gridData[neighborIndex] != GridStatus.targetPoint) { + gridData[neighborIndex] = GridStatus.searcher; + state = state.copyWith(gridData: List.from(gridData)); + await Future.delayed(drawSearcherDuration); + } + } + } + } + _isBuildingGrid = false; + _isSearched = true; + } + + double _heuristic(int index, int targetIndex, int cross) { + final x1 = index % cross; + final y1 = index ~/ cross; + final x2 = targetIndex % cross; + final y2 = targetIndex ~/ cross; + + return ((x1 - x2).abs() + (y1 - y2).abs()).toDouble(); + } + + Future generateRecursiveBacktrackerMaze() async { + if (_isBuildingGrid) return; + _isBuildingGrid = true; + await cancelSearching(); + + _cancelableSearch = CancelableOperation.fromFuture(_generateRecursiveBacktrackerMazeFun()); + + try { + await _cancelableSearch?.value; + } catch (e) { + debugPrint("something wrong with generateRecursiveBacktrackerMaze: $e"); + } + } + + Future _generateRecursiveBacktrackerMazeFun() async { + if (_isSearched) await clearTheGrid(clearAnyway: true); + final gridData = List.from(state.gridData); - // Clear the maze but keep start and target points + /// clear the maze but keep start and target points for (int i = 0; i < gridData.length; i++) { if (gridData[i] != GridStatus.startPoint && gridData[i] != GridStatus.targetPoint) { gridData[i] = GridStatus.empty; } } - // Random starting point + await _drawBorders(gridData); + + _makeSafeCorridor(gridData); + final random = Random(); - int startRow = (random.nextInt(state.rowMainAxisCount - 2) ~/ 2) * 2 + 1; - int startCol = (random.nextInt(state.columnCrossAxisCount - 2) ~/ 2) * 2 + 1; + int startRow = (random.nextInt((state.rowMainAxisCount - 3) ~/ 2) * 2) + 2; // >= 2 + int startCol = (random.nextInt((state.columnCrossAxisCount - 3) ~/ 2) * 2) + 2; // >= 2 - await _cravePassage(startRow, startCol, gridData); + await _drawWalls(startRow, startCol, gridData); state = state.copyWith(gridData: gridData); + _isBuildingGrid = false; + _isSearched = true; + } + + Future _drawBorders(List gridData) async { + for (int c = 0; c < state.columnCrossAxisCount; c++) { + for (final r in [0, state.rowMainAxisCount - 1]) { + final idx = r * state.columnCrossAxisCount + c; + if (gridData[idx] != GridStatus.startPoint && gridData[idx] != GridStatus.targetPoint) { + gridData[idx] = GridStatus.wall; + state = state.copyWith(gridData: List.from(gridData)); + await Future.delayed(mazeDuration); + } + } + } + + for (int r = 1; r < state.rowMainAxisCount - 1; r++) { + for (final c in [0, state.columnCrossAxisCount - 1]) { + final idx = r * state.columnCrossAxisCount + c; + if (gridData[idx] != GridStatus.startPoint && gridData[idx] != GridStatus.targetPoint) { + gridData[idx] = GridStatus.wall; + state = state.copyWith(gridData: List.from(gridData)); + await Future.delayed(mazeDuration); + } + } + } + } + + /// Make the second layer inside the borders always a safe corridor (roads). + void _makeSafeCorridor(List gridData) { + for (int r = 1; r < state.rowMainAxisCount - 1; r++) { + for (int c = 1; c < state.columnCrossAxisCount - 1; c++) { + if (r == 1 || r == state.rowMainAxisCount - 2 || c == 1 || c == state.columnCrossAxisCount - 2) { + final idx = r * state.columnCrossAxisCount + c; + if (gridData[idx] != GridStatus.startPoint && gridData[idx] != GridStatus.targetPoint) { + gridData[idx] = GridStatus.empty; // always keep clear + } + } + } + } } - Future _cravePassage(int row, int col, List gridData) async { + Future _drawWalls(int row, int col, List gridData) async { final directions = [MazeDirection.up, MazeDirection.down, MazeDirection.left, MazeDirection.right]; directions.shuffle(); @@ -359,25 +614,124 @@ class SearchingNotifier extends StateNotifier { final newRow = row + direction.rowDelta * 2; final newCol = col + direction.colDelta * 2; - final currentGrid = gridData[newRow * state.columnCrossAxisCount + newCol]; if (_isValidCell(newRow, newCol) && - currentGrid == GridStatus.empty && - currentGrid != GridStatus.startPoint && - currentGrid != GridStatus.targetPoint) { - gridData[(row + direction.rowDelta) * state.columnCrossAxisCount + (col + direction.colDelta)] = - GridStatus.wall; - gridData[newRow * state.columnCrossAxisCount + newCol] = GridStatus.wall; + gridData[newRow * state.columnCrossAxisCount + newCol] == GridStatus.empty) { + final betweenRow = row + direction.rowDelta; + final betweenCol = col + direction.colDelta; - state = state.copyWith(gridData: List.from(gridData)); + final betweenIdx = betweenRow * state.columnCrossAxisCount + betweenCol; + final newIdx = newRow * state.columnCrossAxisCount + newCol; + if (gridData[betweenIdx] != GridStatus.startPoint && gridData[betweenIdx] != GridStatus.targetPoint) { + gridData[betweenIdx] = GridStatus.wall; + } + + if (gridData[newIdx] != GridStatus.startPoint && gridData[newIdx] != GridStatus.targetPoint) { + gridData[newIdx] = GridStatus.wall; + } + + state = state.copyWith(gridData: List.from(gridData)); await Future.delayed(mazeDuration); - await _cravePassage(newRow, newCol, gridData); + await _drawWalls(newRow, newCol, gridData); } } } bool _isValidCell(int row, int col) { - return row > 0 && col > 0 && row < state.rowMainAxisCount && col < state.columnCrossAxisCount; + // must be inside the "safe corridor" + return row > 1 && col > 1 && row < state.rowMainAxisCount - 2 && col < state.columnCrossAxisCount - 2; + } + + Future generateRecursiveDivisionMaze() async { + if (_isBuildingGrid) return; + _isBuildingGrid = true; + await cancelSearching(); + + _cancelableSearch = CancelableOperation.fromFuture(_generateRecursiveDivisionMazeFun()); + + try { + await _cancelableSearch?.value; + } catch (e) { + debugPrint("something wrong with generateRecursiveDivisionMaze: $e"); + } + } + + Future _generateRecursiveDivisionMazeFun() async { + if (_isSearched) await clearTheGrid(clearAnyway: true); + + final gridData = List.from(state.gridData); + + // Step 1: Start with all empty + for (int i = 0; i < gridData.length; i++) { + if (gridData[i] != GridStatus.startPoint && gridData[i] != GridStatus.targetPoint) { + gridData[i] = GridStatus.empty; + } + } + + // Step 2: Add outer borders as walls + for (int r = 0; r < state.rowMainAxisCount; r++) { + for (int c = 0; c < state.columnCrossAxisCount; c++) { + if (r == 0 || c == 0 || r == state.rowMainAxisCount - 1 || c == state.columnCrossAxisCount - 1) { + if (gridData[r * state.columnCrossAxisCount + c] != GridStatus.startPoint && + gridData[r * state.columnCrossAxisCount + c] != GridStatus.targetPoint) { + gridData[r * state.columnCrossAxisCount + c] = GridStatus.wall; + state = state.copyWith(gridData: List.from(gridData)); + await Future.delayed(mazeDuration); + } + } + } + } + + state = state.copyWith(gridData: List.from(gridData)); + + await _divide(1, 1, state.rowMainAxisCount - 2, state.columnCrossAxisCount - 2, gridData); + + state = state.copyWith(gridData: gridData); + _isBuildingGrid = false; + _isSearched = true; + } + + Future _divide(int row, int col, int height, int width, List gridData) async { + if (height < 2 || width < 2) return; + + final random = Random(); + final horizontal = random.nextBool(); + + if (horizontal) { + /// horizontal wall + int wallRow = row + (random.nextInt(height ~/ 2)) * 2 + 1; + int passageCol = col + (random.nextInt(width ~/ 2)) * 2; + + for (int c = col; c < col + width; c++) { + if (c == passageCol) continue; + if (gridData[wallRow * state.columnCrossAxisCount + c] != GridStatus.startPoint && + gridData[wallRow * state.columnCrossAxisCount + c] != GridStatus.targetPoint) { + gridData[wallRow * state.columnCrossAxisCount + c] = GridStatus.wall; + state = state.copyWith(gridData: List.from(gridData)); + await Future.delayed(mazeDuration); + } + } + + await _divide(row, col, wallRow - row, width, gridData); + await _divide(wallRow + 1, col, row + height - wallRow - 1, width, gridData); + } else { + /// vertical wall + int wallCol = col + (random.nextInt(width ~/ 2)) * 2 + 1; + int passageRow = row + (random.nextInt(height ~/ 2)) * 2; + + for (int r = row; r < row + height; r++) { + if (r == passageRow) continue; + if (gridData[r * state.columnCrossAxisCount + wallCol] != GridStatus.startPoint && + gridData[r * state.columnCrossAxisCount + wallCol] != GridStatus.targetPoint) { + gridData[r * state.columnCrossAxisCount + wallCol] = GridStatus.wall; + state = state.copyWith(gridData: List.from(gridData)); + await Future.delayed(mazeDuration); + } + } + + await _divide(row, col, height, wallCol - col, gridData); + await _divide(row, wallCol + 1, height, col + width - wallCol - 1, gridData); + } } } diff --git a/lib/features/searching/widgets/searcher_grid.dart b/lib/features/searching/widgets/searcher_grid.dart index ddda9fa..bcaf3b7 100644 --- a/lib/features/searching/widgets/searcher_grid.dart +++ b/lib/features/searching/widgets/searcher_grid.dart @@ -26,7 +26,6 @@ class _SearcherGridState extends State<_SearcherGrid> with SingleTickerProviderS vsync: this, ); - // Define the scale animation from 0.1 to 1.2 then back to 1.0 _scaleAnimation = TweenSequence([ TweenSequenceItem(tween: Tween(begin: 0.1, end: 1.4), weight: 60), TweenSequenceItem(tween: Tween(begin: 1.4, end: 1.0), weight: 40), @@ -37,7 +36,6 @@ class _SearcherGridState extends State<_SearcherGrid> with SingleTickerProviderS ), ); - // Define the color animation _colorAnimation = TweenSequence([ TweenSequenceItem(tween: ColorTween(begin: startColor, end: mediumColor), weight: 40), TweenSequenceItem(tween: ColorTween(begin: mediumColor, end: finishedSearcherColor), weight: 60), diff --git a/lib/features/sorting/base/helper/sorting_enums.dart b/lib/features/sorting/base/helper/sorting_enums.dart index 4f406c1..b68aedd 100644 --- a/lib/features/sorting/base/helper/sorting_enums.dart +++ b/lib/features/sorting/base/helper/sorting_enums.dart @@ -1,18 +1,5 @@ part of '../view_model/sorting_notifier.dart'; -enum SortingAlgorithm { - bubble, - selection, - insertion, - merge, - // quick, - // shell, - // heap, - // count, - // radix, - // bucket, -} - enum SortingEnum { played, stopped, none } enum SortingStatus { unSorted, compared, swapping, swapped, sorted, none } diff --git a/lib/features/sorting/base/view/sorting_list_page.dart b/lib/features/sorting/base/view/sorting_list_page.dart index fa420f5..b9c8d38 100644 --- a/lib/features/sorting/base/view/sorting_list_page.dart +++ b/lib/features/sorting/base/view/sorting_list_page.dart @@ -16,43 +16,22 @@ class SortingListPage extends StatelessWidget { elevation: 1, title: const InkWell(child: RegularText(StringsManager.sorting)), ), - body: SafeArea( + body: const SafeArea( child: Center( child: Column( - mainAxisAlignment: MainAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - CustomRoundedElevatedButton( - roundedRadius: 3, - backgroundColor: ThemeEnum.whiteD5Color, - child: const RegularText(StringsManager.bubbleSort), - onPressed: () { - context.pushTo(Routes.bubbleSort); - }, - ), - CustomRoundedElevatedButton( - roundedRadius: 3, - backgroundColor: ThemeEnum.whiteD5Color, - child: const RegularText(StringsManager.insertionSort), - onPressed: () { - context.pushTo(Routes.insertionSort); - }, - ), - CustomRoundedElevatedButton( - roundedRadius: 3, - backgroundColor: ThemeEnum.whiteD5Color, - child: const RegularText(StringsManager.selectionSort), - onPressed: () { - context.pushTo(Routes.selectionSort); - }, - ), - CustomRoundedElevatedButton( - roundedRadius: 3, - backgroundColor: ThemeEnum.whiteD5Color, - child: const RegularText(StringsManager.mergeSort), - onPressed: () { - context.pushTo(Routes.mergeSort); - }, - ), + _CustomButton(text: StringsManager.bubbleSort, route: Routes.bubbleSort), + _CustomButton(text: StringsManager.insertionSort, route: Routes.insertionSort), + _CustomButton(text: StringsManager.selectionSort, route: Routes.selectionSort), + _CustomButton(text: StringsManager.mergeSort, route: Routes.mergeSort), + _CustomButton(text: StringsManager.heapSort, route: Routes.heapSort), + _CustomButton(text: StringsManager.quickSort, route: Routes.quickSort), + _CustomButton(text: StringsManager.radixSort, route: Routes.radixSort), + _CustomButton(text: StringsManager.shellSort, route: Routes.shellSort), + _CustomButton(text: StringsManager.countingSort, route: Routes.countingSort), + _CustomButton(text: StringsManager.bucketSort, route: Routes.bucketSort), + _CustomButton(text: StringsManager.comparisonSort, route: Routes.comparisonSort), ], ), ), @@ -60,3 +39,22 @@ class SortingListPage extends StatelessWidget { ); } } + +class _CustomButton extends StatelessWidget { + const _CustomButton({required this.text, required this.route}); + final String text; + final RouteConfig route; + @override + Widget build(BuildContext context) { + return CustomRoundedElevatedButton( + fixedSize: 160, + fitToContent: false, + roundedRadius: 3, + backgroundColor: ThemeEnum.whiteD5Color, + child: FittedBox(child: RegularText(text)), + onPressed: () { + context.pushTo(route); + }, + ); + } +} diff --git a/lib/features/sorting/base/view/sorting_page.dart b/lib/features/sorting/base/view/sorting_page.dart index 7f7588b..57a32c8 100644 --- a/lib/features/sorting/base/view/sorting_page.dart +++ b/lib/features/sorting/base/view/sorting_page.dart @@ -1,6 +1,8 @@ import 'package:algorithm_visualizer/core/draggable_progress.dart' show DraggableProgressBar; +import 'package:algorithm_visualizer/core/resources/color_manager.dart'; import 'package:algorithm_visualizer/core/resources/strings_manager.dart'; import 'package:algorithm_visualizer/core/resources/theme_manager.dart'; +import 'package:algorithm_visualizer/core/widgets/adaptive/padding/adaptive_padding.dart'; import 'package:algorithm_visualizer/core/widgets/adaptive/text/adaptive_text.dart'; import 'package:algorithm_visualizer/core/widgets/custom_widgets/custom_rounded_elevated_button.dart'; import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; @@ -9,50 +11,26 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; part '../widgets/sorting_app_bar.dart'; part '../widgets/control_buttons.dart'; +part '../widgets/size_draggable.dart'; +part '../widgets/speed_draggable.dart'; class SortingPage extends ConsumerWidget { const SortingPage({required this.instance, required this.title, super.key}); final StateNotifierProvider instance; final String title; + @override - Widget build(BuildContext context, ref) { - return Scaffold( - appBar: appBar(), - body: SafeArea( - child: Stack( - alignment: AlignmentDirectional.bottomCenter, - children: [ - Align(alignment: AlignmentDirectional.topCenter, child: _BuildList(instance)), - // _ControlButtons(), - Padding( - padding: REdgeInsets.symmetric(horizontal: 0), - child: Align( - alignment: AlignmentDirectional.bottomCenter, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - spacing: 10, - children: [ - _ControlButtons(instance), - Row( - children: [ - DraggableProgressBar( - onChanged: (persent) { - ref.read(instance.notifier).changeSpeed(persent); - }, - ), - DraggableProgressBar( - onChanged: (persent) { - ref.read(instance.notifier).changeSize(persent); - }, - ), - ], - ), - ], - ), - ), - ), - ], - ), + Widget build(BuildContext context, WidgetRef ref) { + return PopScope( + onPopInvokedWithResult: (didPop, result) async { + if (didPop) { + await ref.read(instance.notifier).cancelSorting(); + ref.invalidate(instance); // deletes current instance and resets + } + }, + child: Scaffold( + appBar: appBar(), + body: _BuildBody(instance: instance), ), ); } @@ -60,43 +38,82 @@ class SortingPage extends ConsumerWidget { AppBar appBar() { return AppBar( elevation: 1, - title: Consumer( - builder: (context, ref, _) { - return InkWell(child: RegularText(title)); - }, - ), + title: SortingAppBar(title: title), ); } } -class Item extends StatelessWidget { - final String text; +class SortingAppBar extends StatelessWidget { + const SortingAppBar({super.key, required this.title}); - const Item({super.key, required this.text}); + final String title; @override Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.all(10), - color: context.getColor(ThemeEnum.whiteD7Color), - child: RegularText(text, color: ThemeEnum.primaryColor), + return Consumer( + builder: (context, ref, _) { + return InkWell(child: RegularText(title)); + }, ); } } -class _BuildList extends ConsumerWidget { - const _BuildList(this.instance); +class _BuildBody extends StatelessWidget { + const _BuildBody({required this.instance}); + final StateNotifierProvider instance; + @override + Widget build(BuildContext context) { + return SafeArea( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Align(alignment: AlignmentDirectional.topCenter, child: ShowUpSortingList(instance)), + Flexible( + child: Align( + alignment: AlignmentDirectional.bottomCenter, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + spacing: 10, + children: [ + Flexible(child: _SortingControlButtons(instance)), + Flexible( + child: SymmetricPadding( + horizontal: 15, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _SpeedDraggable(instance: instance), + _SizeDraggable(instance: instance), + ], + ), + ), + ), + ], + ), + ), + ), + ], + ), + ); + } +} + +class ShowUpSortingList extends ConsumerWidget { + const ShowUpSortingList(this.instance, {this.selectedAlgorithmLength = 1, super.key}); + final StateNotifierProvider instance; + final int selectedAlgorithmLength; @override Widget build(BuildContext context, ref) { final items = ref.watch(instance.select((state) => state.list)); final speedDuration = ref.watch(instance.select((state) => state.swipeDuration)); + final maxHeight = SortingNotifier.calculateMaxListItemHeight(context); return Padding( padding: const EdgeInsets.only(top: 5), - child: SizedBox( - height: SortingNotifier.maxListItemHeight * 1.3, + child: RSizedBox( + height: selectedAlgorithmLength == 1 ? maxHeight * 1.01 : null, width: double.infinity, child: Stack( alignment: AlignmentDirectional.bottomCenter, @@ -104,14 +121,19 @@ class _BuildList extends ConsumerWidget { items.length, (index) { final item = items[index]; - final position = ref.watch(instance.select((state) => state.positions[item.id]!)); + final position = ref.watch(instance.select((state) => state.positions[item.id])); return AnimatedPositioned( key: ValueKey(item.id), - left: position.dx, - bottom: position.dy, + left: position?.dx, + bottom: position?.dy, duration: speedDuration, child: _BuildItem( - item: item, index: index, speedDuration: speedDuration * 0.5, instance: instance), + item: item, + index: index, + instance: instance, + speedDuration: speedDuration * 0.5, + selectedAlgorithmLength: selectedAlgorithmLength, + ), ); }, ), @@ -127,27 +149,30 @@ class _BuildItem extends ConsumerWidget { required this.index, required this.speedDuration, required this.instance, + required this.selectedAlgorithmLength, }); final int index; final SortableItem item; final Duration speedDuration; final StateNotifierProvider instance; + final int selectedAlgorithmLength; @override Widget build(BuildContext context, ref) { final size = ref.watch(instance.select((state) => state.size)); final itemWidth = SortingNotifier.calculateItemWidth(context, size); - final currentItem = ref.watch(instance.select((state) => state.list[index])); + final currentItem = + ref.watch(instance.select((state) => index < state.list.length ? state.list[index] : null)); return Padding( padding: EdgeInsets.symmetric(horizontal: SortingNotifier.itemsPadding / 2), child: AnimatedContainer( duration: speedDuration, - height: SortingNotifier.calculateItemHeight(item.value, size), + height: SortingNotifier.calculateItemHeight(context, item.value, size, selectedAlgorithmLength), width: itemWidth, decoration: BoxDecoration( - color: context.getColor(currentItem.getColor), + color: context.getColor(currentItem?.getColor ?? SortingNotifier.itemColor), borderRadius: const BorderRadius.vertical(top: Radius.circular(1)), ), ), diff --git a/lib/features/sorting/base/view_model/sorting_notifier.dart b/lib/features/sorting/base/view_model/sorting_notifier.dart index f518d92..8802656 100644 --- a/lib/features/sorting/base/view_model/sorting_notifier.dart +++ b/lib/features/sorting/base/view_model/sorting_notifier.dart @@ -11,15 +11,14 @@ part '../helper/sorting_enums.dart'; part '../helper/sortable_item.dart'; abstract class SortingNotifier extends StateNotifier { - SortingNotifier() : super(SortingNotifierState(list: generateList(_defaultSize))) { + SortingNotifier() : super(SortingNotifierState(list: _generateList(_defaultSize))) { _initializePositions(); } - static double maxListItemHeight = 250.h; static double itemsPadding = 1.w; static const ThemeEnum swappingColor = ThemeEnum.redColor; - static const ThemeEnum comparedColor = ThemeEnum.comparedColor; - static const ThemeEnum itemColor = ThemeEnum.blueColor; + static const ThemeEnum comparedColor = ThemeEnum.lightBlueColor; + static const ThemeEnum itemColor = ThemeEnum.darkBlueColor; static const ThemeEnum doneSortingColor = ThemeEnum.greenColor; static const int _defaultSize = 20; @@ -27,16 +26,10 @@ abstract class SortingNotifier extends StateNotifier { static const int _minSize = 10; static const Duration _defaultSpeedDuration = Duration(milliseconds: 300); - // static const Duration _maxSpeedDuration = Duration(milliseconds: 3000); - // static const Duration _minSpeedDuration = Duration(milliseconds: 20); - SortingEnum operation = SortingEnum.none; - CancelableOperation? cancelableSort; + CancelableOperation? _cancelableSort; - int i = 0; - int j = 0; - - static List generateList(int size) { + static List _generateList(int size) { return List.generate(size, (index) => SortableItem(id: index, value: index + 1))..shuffle(); } @@ -44,18 +37,43 @@ abstract class SortingNotifier extends StateNotifier { final screenWidth = MediaQuery.of(context).size.width; final availableWidth = screenWidth - (itemsPadding * (size - 1)); - // Ensure a positive width return availableWidth / size > 0 ? availableWidth / size : 1.0; } - static double calculateItemHeight(int itemIndex, int size) { - final value = (maxListItemHeight / size) * (itemIndex + 1); - return value.h; + static double calculateMaxListItemHeight(BuildContext context) { + final screenHeight = MediaQuery.of(context).size.height * 0.65; + + return screenHeight > 0 ? screenHeight : 1.0; + } + + static double calculateItemHeight( + BuildContext context, + int itemIndex, + int size, + int selectedAlgorithmsLength, + ) { + final value = (calculateMaxListItemHeight(context) / size) * (itemIndex + 1); + final perc = selectedAlgorithmsLength == 1 + ? 0.95 + : selectedAlgorithmsLength <= 2 + ? 0.9 + : selectedAlgorithmsLength <= 4 + ? 0.8 + : selectedAlgorithmsLength <= 6 + ? 0.7 + : 0.6; + return value.h / selectedAlgorithmsLength * perc; } Duration get speedDuration => state.swipeDuration; int get _size => state.size; + SortingEnum get _getOperation => state.operationStatus; + + set _setOperation(SortingEnum value) { + state = state.copyWith(operationStatus: value); + } + void _initializePositions() { final positions = {}; final itemWidth = calculateItemWidth(ScreenSize.context!, _size); @@ -74,39 +92,41 @@ abstract class SortingNotifier extends StateNotifier { } void changeSize(double size) { - if (operation == SortingEnum.played) return; + if (_getOperation == SortingEnum.played) return; final newSize = _minSize + (_maxSize - _minSize) * size; state = state.copyWith(size: newSize.toInt()); generateAgain(); } - void stopSorting() { - cancelableSort?.cancel(); - operation = SortingEnum.stopped; + Future cancelSorting() async { + await _cancelableSort?.cancel(); } - Future playSorting() async { - if (operation == SortingEnum.played) return; - operation = SortingEnum.played; + Future stopSorting() async { + await _cancelableSort?.cancel(); + if (_getOperation == SortingEnum.played) _setOperation = SortingEnum.stopped; + } - await startSelectedSorting(); + Future playSorting(BuildContext context) async { + if (_getOperation == SortingEnum.played) return; + _setOperation = SortingEnum.played; - operation = SortingEnum.none; + await _startSelectedSorting(); + +// to avoid error of mounted when popup while the sorting algorithm still running + if (context.mounted) _setOperation = SortingEnum.none; } Future generateAgain() async { - await cancelableSort?.cancel(); - operation = SortingEnum.none; - - i = 0; - j = 0; + await _cancelableSort?.cancel(); + _setOperation = SortingEnum.none; - state = state.copyWith(list: generateList(_size)); + state = state.copyWith(list: _generateList(_size)); _initializePositions(); } - Future greenSortedItemsAsDone() async { + Future _greenSortedItemsAsDone() async { final list = List.from(state.list); for (int i = 0; i < list.length; i++) { @@ -116,24 +136,24 @@ abstract class SortingNotifier extends StateNotifier { } } - Future startSelectedSorting() async { - cancelableSort = CancelableOperation.fromFuture(buildSort()); + Future _startSelectedSorting() async { + _cancelableSort = CancelableOperation.fromFuture(_buildSort()); try { - await cancelableSort?.value; + await _cancelableSort?.value; } catch (e) { debugPrint("something wrong with bubbleSort: $e"); } } - Future buildSort() async { + Future _buildSort() async { final list = List.from(state.list); final values = list.map((e) => e.value).toList(); final steps = buildSorting(values).steps; for (final step in steps) { - if (operation != SortingEnum.played) return; + if (_getOperation != SortingEnum.played) return; switch (step.action) { case SortingStatus.compared: @@ -169,7 +189,7 @@ abstract class SortingNotifier extends StateNotifier { state = state.copyWith(list: list); break; - // i don't want to make it green while sorting and mark all of them at once as green at the end + /// i don't want to make it green while sorting and mark all of them at once as green at the end case SortingStatus.sorted: case SortingStatus.none: list[step.index1] = list[step.index1].copyWith(sortedStatus: SortingStatus.none); @@ -180,7 +200,7 @@ abstract class SortingNotifier extends StateNotifier { await Future.delayed(speedDuration); } - await greenSortedItemsAsDone(); + await _greenSortedItemsAsDone(); } SortingResult buildSorting(List values); diff --git a/lib/features/sorting/base/view_model/sorting_state.dart b/lib/features/sorting/base/view_model/sorting_state.dart index ec1917b..5311605 100644 --- a/lib/features/sorting/base/view_model/sorting_state.dart +++ b/lib/features/sorting/base/view_model/sorting_state.dart @@ -5,7 +5,9 @@ class SortingNotifierState { final Map positions; final Duration swipeDuration; final int size; + final SortingEnum operationStatus; SortingNotifierState({ + this.operationStatus = SortingEnum.none, this.size = SortingNotifier._defaultSize, this.swipeDuration = SortingNotifier._defaultSpeedDuration, required this.list, @@ -17,9 +19,10 @@ class SortingNotifierState { Duration? swipeDuration, List? list, Map? positions, - List? selectedAlgorithms, + SortingEnum? operationStatus, }) { return SortingNotifierState( + operationStatus: operationStatus ?? this.operationStatus, size: size ?? this.size, swipeDuration: swipeDuration ?? this.swipeDuration, list: list ?? this.list, diff --git a/lib/features/sorting/base/widgets/control_buttons.dart b/lib/features/sorting/base/widgets/control_buttons.dart index 221a801..c9eb1a5 100644 --- a/lib/features/sorting/base/widgets/control_buttons.dart +++ b/lib/features/sorting/base/widgets/control_buttons.dart @@ -1,9 +1,29 @@ part of '../view/sorting_page.dart'; -class _ControlButtons extends ConsumerWidget { - const _ControlButtons(this.instance); +class _SortingControlButtons extends ConsumerWidget { + const _SortingControlButtons(this.instance); final StateNotifierProvider instance; + @override + Widget build(BuildContext context, ref) { + return SortingControlButtons( + playSorting: () => ref.read(instance.notifier).playSorting(context), + stopSorting: () => ref.read(instance.notifier).stopSorting(), + generateAgain: () => ref.read(instance.notifier).generateAgain(), + ); + } +} + +class SortingControlButtons extends ConsumerWidget { + const SortingControlButtons({ + required this.playSorting, + required this.stopSorting, + required this.generateAgain, + super.key, + }); + final VoidCallback playSorting; + final VoidCallback stopSorting; + final VoidCallback generateAgain; @override Widget build(BuildContext context, ref) { return Row( @@ -12,36 +32,30 @@ class _ControlButtons extends ConsumerWidget { CustomRoundedElevatedButton( roundedRadius: 3, backgroundColor: ThemeEnum.blackOp10, + onPressed: playSorting, child: const RegularText( StringsManager.play, fontSize: 14, ), - onPressed: () { - ref.read(instance.notifier).playSorting(); - }, ), CustomRoundedElevatedButton( roundedRadius: 3, backgroundColor: ThemeEnum.blackOp10, + onPressed: stopSorting, child: const RegularText( StringsManager.stop, fontSize: 14, ), - onPressed: () { - ref.read(instance.notifier).stopSorting(); - }, ), CustomRoundedElevatedButton( roundedRadius: 3, backgroundColor: ThemeEnum.redColor, + onPressed: generateAgain, child: const RegularText( StringsManager.reset, color: ThemeEnum.whiteColor, fontSize: 14, ), - onPressed: () { - ref.read(instance.notifier).generateAgain(); - }, ), ], ); diff --git a/lib/features/sorting/base/widgets/size_draggable.dart b/lib/features/sorting/base/widgets/size_draggable.dart new file mode 100644 index 0000000..49cbc3f --- /dev/null +++ b/lib/features/sorting/base/widgets/size_draggable.dart @@ -0,0 +1,59 @@ +part of '../view/sorting_page.dart'; + +class _SizeDraggable extends ConsumerWidget { + const _SizeDraggable({ required this.instance}); + + final StateNotifierProvider instance; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final operationStatus = ref.watch(instance.select((state) => state.operationStatus)); + final isRunning = operationStatus == SortingEnum.played || operationStatus == SortingEnum.stopped; + return SizeDraggable( + isRunning: isRunning, + onChanged: (persent) { + ref.read(instance.notifier).changeSize(persent); + }, + ); + } +} + +class SizeDraggable extends ConsumerWidget { + const SizeDraggable({super.key, required this.onChanged, required this.isRunning}); + + final ValueChanged onChanged; + final bool isRunning; + @override + Widget build(BuildContext context, WidgetRef ref) { + return Flexible( + child: Row( + children: [ + MediumText( + StringsManager.size, + fontSize: 12, + color: isRunning ? ThemeEnum.whiteD7Color : null, + ), + Flexible( + child: Stack( + alignment: AlignmentDirectional.center, + children: [ + DraggableProgressBar( + isActive: !isRunning, + runOnChangedInitially: true, + sliderValue: 0.15, + onChanged: onChanged, + ), + if (isRunning) + Container( + color: ColorManager.transparent, + height: 20.r, + width: double.infinity, + ) + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/features/sorting/base/widgets/speed_draggable.dart b/lib/features/sorting/base/widgets/speed_draggable.dart new file mode 100644 index 0000000..6159dba --- /dev/null +++ b/lib/features/sorting/base/widgets/speed_draggable.dart @@ -0,0 +1,38 @@ +part of '../view/sorting_page.dart'; + +class _SpeedDraggable extends ConsumerWidget { + const _SpeedDraggable({required this.instance}); + + final StateNotifierProvider instance; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return SpeedDraggable( + onChanged: (persent) { + ref.read(instance.notifier).changeSpeed(persent); + }, + ); + } +} + +class SpeedDraggable extends ConsumerWidget { + const SpeedDraggable({super.key, required this.onChanged}); + + final ValueChanged onChanged; + @override + Widget build(BuildContext context, WidgetRef ref) { + return Flexible( + child: Row( + children: [ + const MediumText(StringsManager.speed, fontSize: 12), + Flexible( + child: DraggableProgressBar( + runOnChangedInitially: true, + onChanged: onChanged, + ), + ), + ], + ), + ); + } +} diff --git a/lib/features/sorting/bubble/view/bubble_sort_page.dart b/lib/features/sorting/bubble/view/bubble_sort_page.dart index c88f7fa..89f36c6 100644 --- a/lib/features/sorting/bubble/view/bubble_sort_page.dart +++ b/lib/features/sorting/bubble/view/bubble_sort_page.dart @@ -9,20 +9,9 @@ final _notifierProvider = StateNotifierProvider BubbleSortNotifier(), ); -class BubbleSortPage extends ConsumerStatefulWidget { +class BubbleSortPage extends StatelessWidget { const BubbleSortPage({super.key}); - @override - ConsumerState createState() => _BubbleSortPageState(); -} - -class _BubbleSortPageState extends ConsumerState { - @override - void deactivate() { - ref.invalidate(_notifierProvider); // deletes current instance and resets - super.deactivate(); - } - @override Widget build(BuildContext context) { return SortingPage(instance: _notifierProvider, title: StringsManager.bubbleSort); diff --git a/lib/features/sorting/bucket/view/bucket_sort_page.dart b/lib/features/sorting/bucket/view/bucket_sort_page.dart new file mode 100644 index 0000000..4d283e4 --- /dev/null +++ b/lib/features/sorting/bucket/view/bucket_sort_page.dart @@ -0,0 +1,19 @@ +import 'package:algorithm_visualizer/core/resources/strings_manager.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view/sorting_page.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/bucket/view_model/bucket_sort_notifier.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +final _notifierProvider = StateNotifierProvider( + (ref) => BucketSortNotifier(), +); + +class BucketSortPage extends StatelessWidget { + const BucketSortPage({super.key}); + + @override + Widget build(BuildContext context) { + return SortingPage(instance: _notifierProvider, title: StringsManager.bucketSort); + } +} diff --git a/lib/features/sorting/bucket/view_model/bucket_sort_notifier.dart b/lib/features/sorting/bucket/view_model/bucket_sort_notifier.dart new file mode 100644 index 0000000..b184e72 --- /dev/null +++ b/lib/features/sorting/bucket/view_model/bucket_sort_notifier.dart @@ -0,0 +1,61 @@ +import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:collection/collection.dart'; + +class BucketSortNotifier extends SortingNotifier { + @override + SortingResult buildSorting(List values) { + final steps = []; + final arr = List.from(values); + + if (arr.isEmpty) { + return SortingResult(sortedValues: arr, steps: steps); + } + + int n = arr.length; + int maxVal = arr.reduce((a, b) => a > b ? a : b); + int minVal = arr.reduce((a, b) => a < b ? a : b); + + int bucketCount = n; + double bucketRange = (maxVal - minVal + 1) / bucketCount; + + final buckets = List.generate(bucketCount, (_) => []); + + for (int value in arr) { + int bucketIndex = ((value - minVal) / bucketRange).floor(); + if (bucketIndex >= bucketCount) bucketIndex = bucketCount - 1; + buckets[bucketIndex].add(value); + } + + for (var bucket in buckets) { + for (int i = 1; i < bucket.length; i++) { + int key = bucket[i]; + int j = i - 1; + while (j >= 0 && bucket[j] > key) { + bucket[j + 1] = bucket[j]; + j--; + } + bucket[j + 1] = key; + } + } + + int index = 0; + for (var bucket in buckets) { + for (int value in bucket) { + if (arr[index] != value) { + // Find where the value currently is + int targetIndex = arr.indexOf(value, index); + + // Swap for visualization + steps.add(SortingStep(index1: index, index2: targetIndex, action: SortingStatus.swapping)); + arr.swap(index, targetIndex); + steps.add(SortingStep(index1: index, index2: targetIndex, action: SortingStatus.swapped)); + } + index++; + } + } + + steps.add(SortingStep(index1: arr.length - 1, index2: arr.length - 1, action: SortingStatus.sorted)); + + return SortingResult(sortedValues: arr, steps: steps); + } +} diff --git a/lib/features/sorting/comparison/view/comparison_sort_page.dart b/lib/features/sorting/comparison/view/comparison_sort_page.dart new file mode 100644 index 0000000..ea16486 --- /dev/null +++ b/lib/features/sorting/comparison/view/comparison_sort_page.dart @@ -0,0 +1,186 @@ +import 'package:algorithm_visualizer/core/resources/strings_manager.dart'; +import 'package:algorithm_visualizer/core/resources/theme_manager.dart'; +import 'package:algorithm_visualizer/core/widgets/adaptive/padding/adaptive_padding.dart'; +import 'package:algorithm_visualizer/core/widgets/adaptive/text/adaptive_text.dart'; +import 'package:algorithm_visualizer/core/widgets/custom_widgets/custom_icon.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view/sorting_page.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/comparison/view_model/comparison_sort_notifier.dart'; +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +final _notifierProvider = StateNotifierProvider( + (ref) => ComparisonSortNotifier(), +); + +class ComparisonSortPage extends ConsumerStatefulWidget { + const ComparisonSortPage({super.key}); + + @override + ConsumerState createState() => _ComparisonSortPageState(); +} + +class _ComparisonSortPageState extends ConsumerState { + @override + Widget build(BuildContext context) { + return PopScope( + onPopInvokedWithResult: (didPop, result) async { + if (didPop) { + await ref.read(_notifierProvider.notifier).cancelSorting(ref); + + ComparisonSortNotifier.sortingAlgorithms.values.toList().forEach( + (element) { + try { + ref.invalidate(element.provider); + } catch (e) { + // + } + }, + ); + ref.invalidate(_notifierProvider); // deletes current instance and resets + } + }, + child: Scaffold( + appBar: appBar(), + drawer: const _DrawerMenu(), + body: SafeArea( + child: Column( + children: [ + const Flexible(child: _BuildComparisonLists()), + const RSizedBox(height: 15), + Padding( + padding: REdgeInsets.symmetric(horizontal: 0), + child: Align( + alignment: AlignmentDirectional.bottomCenter, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + spacing: 10, + children: [ + SortingControlButtons( + playSorting: () => ref.read(_notifierProvider.notifier).playSorting(context, ref), + stopSorting: () => ref.read(_notifierProvider.notifier).stopSorting(ref), + generateAgain: () => ref.read(_notifierProvider.notifier).generateAgain(ref), + ), + SymmetricPadding( + horizontal: 15, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SpeedDraggable( + onChanged: (persent) { + ref.read(_notifierProvider.notifier).changeSpeed(persent, ref); + }, + ), + _SizeDraggable(ref: ref), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ); + } + + AppBar appBar() { + return AppBar( + elevation: 1, + title: const SortingAppBar(title: StringsManager.comparisonSort), + actions: const [ + CloseButton(), + ], + ); + } +} + +class _SizeDraggable extends StatelessWidget { + const _SizeDraggable({required this.ref}); + + final WidgetRef ref; + + @override + Widget build(BuildContext context) { + final operationStatus = ref.watch(_notifierProvider.select((state) => state.operationStatus)); + final isRunning = operationStatus == SortingEnum.played || operationStatus == SortingEnum.stopped; + + return SizeDraggable( + isRunning: isRunning, + onChanged: (persent) { + ref.read(_notifierProvider.notifier).changeSize(persent, ref); + }, + ); + } +} + +class _DrawerMenu extends ConsumerWidget { + const _DrawerMenu(); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final selectedAlgorithms = ref.watch(_notifierProvider.select((state) => state.selectedAlgorithms)); + final algorithms = ComparisonSortNotifier.sortingAlgorithms.keys.toList(); + return Drawer( + child: SafeArea( + child: ListView( + padding: EdgeInsets.zero, + children: [ + const ListTile( + title: SemiBoldText(StringsManager.comparisonAlgorithms, color: ThemeEnum.focusColor), + ), + ...List.generate( + algorithms.length, + (index) => ListTile( + trailing: + selectedAlgorithms.firstWhereOrNull((element) => element.name == algorithms[index]) != + null + ? const CustomIcon(Icons.check) + : null, + title: RegularText(algorithms[index]), + onTap: () { + ref.read(_notifierProvider.notifier).selectAlgorithm(algorithms[index]); + }, + ), + ), + ], + ), + ), + ); + } +} + +class _BuildComparisonLists extends ConsumerWidget { + const _BuildComparisonLists(); + + @override + Widget build(BuildContext context, WidgetRef ref) { + final selectedAlgorithms = ref.watch(_notifierProvider.select((state) => state.selectedAlgorithms)); + + return Align( + alignment: AlignmentDirectional.topCenter, + child: Column( + children: List.generate( + selectedAlgorithms.length, + (index) => Flexible( + child: Column( + children: [ + Flexible( + child: ShowUpSortingList( + selectedAlgorithms[index].provider, + selectedAlgorithmLength: selectedAlgorithms.length, + ), + ), + RegularText(selectedAlgorithms[index].name, fontSize: 12), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/features/sorting/comparison/view_model/comparison_sort_notifier.dart b/lib/features/sorting/comparison/view_model/comparison_sort_notifier.dart new file mode 100644 index 0000000..fef9d0d --- /dev/null +++ b/lib/features/sorting/comparison/view_model/comparison_sort_notifier.dart @@ -0,0 +1,165 @@ +import 'package:algorithm_visualizer/core/resources/strings_manager.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/bubble/view_model/bubble_sort_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/bucket/view_model/bucket_sort_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/counting/view_model/counting_sort_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/heap/view_model/heap_sort_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/insertion/view_model/insertion_sort_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/merge/view_model/merge_sort_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/quick/view_model/quick_sort_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/radix/view_model/radix_sort_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/selection/view_model/selection_sort_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/shell/view_model/shell_sort_notifier.dart'; +import 'package:collection/collection.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +part 'comparison_sort_state.dart'; + +class SortingAlgorithm { + final String name; + final StateNotifierProvider provider; + SortingAlgorithm({required this.name, required this.provider}); +} + +class ComparisonSortNotifier extends StateNotifier { + ComparisonSortNotifier() + : super( + ComparisonSortingNotifierState( + selectedAlgorithms: [sortingAlgorithms[StringsManager.bubbleSort]!], + ), + ); + + static final Map sortingAlgorithms = { + StringsManager.bubbleSort: SortingAlgorithm( + name: StringsManager.bubbleSort, + provider: StateNotifierProvider( + (ref) => BubbleSortNotifier(), + ), + ), + StringsManager.insertionSort: SortingAlgorithm( + name: StringsManager.insertionSort, + provider: StateNotifierProvider( + (ref) => InsertionSortNotifier(), + ), + ), + StringsManager.selectionSort: SortingAlgorithm( + name: StringsManager.selectionSort, + provider: StateNotifierProvider( + (ref) => SelectionSortNotifier(), + ), + ), + StringsManager.mergeSort: SortingAlgorithm( + name: StringsManager.mergeSort, + provider: StateNotifierProvider( + (ref) => MergeSortNotifier(), + ), + ), + StringsManager.heapSort: SortingAlgorithm( + name: StringsManager.heapSort, + provider: StateNotifierProvider( + (ref) => HeapSortNotifier(), + ), + ), + StringsManager.quickSort: SortingAlgorithm( + name: StringsManager.quickSort, + provider: StateNotifierProvider( + (ref) => QuickSortNotifier(), + ), + ), + StringsManager.radixSort: SortingAlgorithm( + name: StringsManager.radixSort, + provider: StateNotifierProvider( + (ref) => RadixSortNotifier(), + ), + ), + StringsManager.shellSort: SortingAlgorithm( + name: StringsManager.shellSort, + provider: StateNotifierProvider( + (ref) => ShellSortNotifier(), + ), + ), + StringsManager.countingSort: SortingAlgorithm( + name: StringsManager.countingSort, + provider: StateNotifierProvider( + (ref) => CountingSortNotifier(), + ), + ), + StringsManager.bucketSort: SortingAlgorithm( + name: StringsManager.bucketSort, + provider: StateNotifierProvider( + (ref) => BucketSortNotifier(), + ), + ), + }; + + SortingEnum get _getOperation => state.operationStatus; + + set _setOperation(SortingEnum value) { + state = state.copyWith(operationStatus: value); + } + + void selectAlgorithm(String algo) { + final isExist = state.selectedAlgorithms.firstWhereOrNull((element) => element.name == algo) != null; + if (isExist && state.selectedAlgorithms.length == 1) return; + + if (isExist) { + state = state.copyWith( + selectedAlgorithms: state.selectedAlgorithms.where((element) => element.name != algo).toList()); + return; + } + + final value = sortingAlgorithms[algo]; + if (value != null) { + state = state.copyWith( + selectedAlgorithms: [ + ...state.selectedAlgorithms, + value, + ], + ); + } + } + + void changeSize(double size, WidgetRef ref) { + if (_getOperation == SortingEnum.played) return; + + for (var element in state.selectedAlgorithms) { + ref.read(element.provider.notifier).changeSize(size); + } + } + + void changeSpeed(double percent, WidgetRef ref) { + for (var element in state.selectedAlgorithms) { + ref.read(element.provider.notifier).changeSpeed(percent); + } + } + + Future generateAgain(WidgetRef ref) async { + final generateAgain = state.selectedAlgorithms.map((e) => ref.read(e.provider.notifier).generateAgain()); + await Future.wait(generateAgain.toList()); + _setOperation = SortingEnum.none; + } + + Future playSorting(BuildContext context, WidgetRef ref) async { + if (_getOperation == SortingEnum.played) return; + + final playSorting = + state.selectedAlgorithms.map((e) => ref.read(e.provider.notifier).playSorting(context)); + _setOperation = SortingEnum.played; + + await Future.wait(playSorting.toList()); + if (context.mounted) _setOperation = SortingEnum.none; + } + + Future stopSorting(WidgetRef ref) async { + final stopSorting = state.selectedAlgorithms.map((e) => ref.read(e.provider.notifier).stopSorting()); + _setOperation = SortingEnum.played; + + await Future.wait(stopSorting.toList()); + + if (_getOperation == SortingEnum.played) _setOperation = SortingEnum.stopped; + } + Future cancelSorting(WidgetRef ref) async { + final cancelSorting = state.selectedAlgorithms.map((e) => ref.read(e.provider.notifier).cancelSorting()); + await Future.wait(cancelSorting.toList()); + } +} diff --git a/lib/features/sorting/comparison/view_model/comparison_sort_state.dart b/lib/features/sorting/comparison/view_model/comparison_sort_state.dart new file mode 100644 index 0000000..de54e24 --- /dev/null +++ b/lib/features/sorting/comparison/view_model/comparison_sort_state.dart @@ -0,0 +1,21 @@ +part of 'comparison_sort_notifier.dart'; + +class ComparisonSortingNotifierState { + final List selectedAlgorithms; + final SortingEnum operationStatus; + + ComparisonSortingNotifierState({ + required this.selectedAlgorithms, + this.operationStatus = SortingEnum.none, + }); + + ComparisonSortingNotifierState copyWith({ + SortingEnum? operationStatus, + List? selectedAlgorithms, + }) { + return ComparisonSortingNotifierState( + operationStatus: operationStatus ?? this.operationStatus, + selectedAlgorithms: selectedAlgorithms ?? this.selectedAlgorithms, + ); + } +} diff --git a/lib/features/sorting/counting/view/counting_sort_page.dart b/lib/features/sorting/counting/view/counting_sort_page.dart new file mode 100644 index 0000000..14879fd --- /dev/null +++ b/lib/features/sorting/counting/view/counting_sort_page.dart @@ -0,0 +1,19 @@ +import 'package:algorithm_visualizer/core/resources/strings_manager.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view/sorting_page.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/counting/view_model/counting_sort_notifier.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +final _notifierProvider = StateNotifierProvider( + (ref) => CountingSortNotifier(), +); + +class CountingSortPage extends StatelessWidget { + const CountingSortPage({super.key}); + + @override + Widget build(BuildContext context) { + return SortingPage(instance: _notifierProvider, title: StringsManager.countingSort); + } +} diff --git a/lib/features/sorting/counting/view_model/counting_sort_notifier.dart b/lib/features/sorting/counting/view_model/counting_sort_notifier.dart new file mode 100644 index 0000000..267a0b1 --- /dev/null +++ b/lib/features/sorting/counting/view_model/counting_sort_notifier.dart @@ -0,0 +1,43 @@ +import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:collection/collection.dart'; + +class CountingSortNotifier extends SortingNotifier { + @override + SortingResult buildSorting(List values) { + final steps = []; + final arr = List.from(values); + + if (arr.isEmpty) return SortingResult(sortedValues: arr, steps: steps); + + int maxVal = arr.reduce((a, b) => a > b ? a : b); + int minVal = arr.reduce((a, b) => a < b ? a : b); + int range = maxVal - minVal + 1; + + final count = List.filled(range, 0); + for (int i = 0; i < arr.length; i++) { + count[arr[i] - minVal]++; + } + + int index = 0; + for (int i = 0; i < range; i++) { + while (count[i] > 0) { + int correctValue = i + minVal; + + if (arr[index] != correctValue) { + int targetIndex = arr.indexOf(correctValue, index); + + steps.add(SortingStep(index1: index, index2: targetIndex, action: SortingStatus.swapping)); + arr.swap(index, targetIndex); + steps.add(SortingStep(index1: index, index2: targetIndex, action: SortingStatus.swapped)); + } + + index++; + count[i]--; + } + } + + steps.add(SortingStep(index1: arr.length - 1, index2: arr.length - 1, action: SortingStatus.sorted)); + + return SortingResult(sortedValues: arr, steps: steps); + } +} diff --git a/lib/features/sorting/heap/view/heap_sort_page.dart b/lib/features/sorting/heap/view/heap_sort_page.dart new file mode 100644 index 0000000..cc7de2d --- /dev/null +++ b/lib/features/sorting/heap/view/heap_sort_page.dart @@ -0,0 +1,19 @@ +import 'package:algorithm_visualizer/core/resources/strings_manager.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view/sorting_page.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/heap/view_model/heap_sort_notifier.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +final _notifierProvider = StateNotifierProvider( + (ref) => HeapSortNotifier(), +); + +class HeapSortPage extends StatelessWidget { + const HeapSortPage({super.key}); + + @override + Widget build(BuildContext context) { + return SortingPage(instance: _notifierProvider, title: StringsManager.heapSort); + } +} diff --git a/lib/features/sorting/heap/view_model/heap_sort_notifier.dart b/lib/features/sorting/heap/view_model/heap_sort_notifier.dart new file mode 100644 index 0000000..b533775 --- /dev/null +++ b/lib/features/sorting/heap/view_model/heap_sort_notifier.dart @@ -0,0 +1,61 @@ +import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:collection/collection.dart'; + +class HeapSortNotifier extends SortingNotifier { + @override + SortingResult buildSorting(List values) { + final steps = []; + final arr = List.from(values); + + void heapify(int n, int i) { + int largest = i; + int left = 2 * i + 1; + int right = 2 * i + 2; + + if (left < n) { + steps.add(SortingStep(index1: i, index2: left, action: SortingStatus.compared)); + steps.add(SortingStep(index1: i, index2: left, action: SortingStatus.unSorted)); + if (arr[left] > arr[largest]) { + largest = left; + } + } + + if (right < n) { + steps.add(SortingStep(index1: i, index2: right, action: SortingStatus.compared)); + steps.add(SortingStep(index1: i, index2: right, action: SortingStatus.unSorted)); + if (arr[right] > arr[largest]) { + largest = right; + } + } + + if (largest != i) { + steps.add(SortingStep(index1: i, index2: largest, action: SortingStatus.swapping)); + arr.swap(i, largest); + steps.add(SortingStep(index1: i, index2: largest, action: SortingStatus.swapped)); + + heapify(n, largest); + } + } + + void heapSort() { + int n = arr.length; + + for (int i = (n ~/ 2) - 1; i >= 0; i--) { + heapify(n, i); + } + + for (int i = n - 1; i > 0; i--) { + steps.add(SortingStep(index1: 0, index2: i, action: SortingStatus.swapping)); + arr.swap(0, i); + steps.add(SortingStep(index1: 0, index2: i, action: SortingStatus.swapped)); + + heapify(i, 0); + } + } + + if (arr.isNotEmpty) heapSort(); + steps.add(SortingStep(index1: 0, index2: 0, action: SortingStatus.sorted)); + + return SortingResult(sortedValues: arr, steps: steps); + } +} diff --git a/lib/features/sorting/insertion/view/insertion_sort_page.dart b/lib/features/sorting/insertion/view/insertion_sort_page.dart index 992213c..b0fd495 100644 --- a/lib/features/sorting/insertion/view/insertion_sort_page.dart +++ b/lib/features/sorting/insertion/view/insertion_sort_page.dart @@ -9,20 +9,9 @@ final _notifierProvider = StateNotifierProvider InsertionSortNotifier(), ); -class InsertionSortPage extends ConsumerStatefulWidget { +class InsertionSortPage extends StatelessWidget { const InsertionSortPage({super.key}); - @override - ConsumerState createState() => _InsertionSortPageState(); -} - -class _InsertionSortPageState extends ConsumerState { - @override - void deactivate() { - ref.invalidate(_notifierProvider); // deletes current instance and resets - super.deactivate(); - } - @override Widget build(BuildContext context) { return SortingPage(instance: _notifierProvider, title: StringsManager.insertionSort); diff --git a/lib/features/sorting/merge/view/merge_sort_page.dart b/lib/features/sorting/merge/view/merge_sort_page.dart index 79ed2a7..bb11e68 100644 --- a/lib/features/sorting/merge/view/merge_sort_page.dart +++ b/lib/features/sorting/merge/view/merge_sort_page.dart @@ -9,20 +9,9 @@ final _notifierProvider = StateNotifierProvider MergeSortNotifier(), ); -class MergeSortPage extends ConsumerStatefulWidget { +class MergeSortPage extends StatelessWidget { const MergeSortPage({super.key}); - @override - ConsumerState createState() => _MergeSortPageState(); -} - -class _MergeSortPageState extends ConsumerState { - @override - void deactivate() { - ref.invalidate(_notifierProvider); // deletes current instance and resets - super.deactivate(); - } - @override Widget build(BuildContext context) { return SortingPage(instance: _notifierProvider, title: StringsManager.mergeSort); diff --git a/lib/features/sorting/merge/view_model/merge_sort_notifier.dart b/lib/features/sorting/merge/view_model/merge_sort_notifier.dart index 1787a71..7fc2e0d 100644 --- a/lib/features/sorting/merge/view_model/merge_sort_notifier.dart +++ b/lib/features/sorting/merge/view_model/merge_sort_notifier.dart @@ -1,9 +1,48 @@ import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:collection/collection.dart'; class MergeSortNotifier extends SortingNotifier { @override SortingResult buildSorting(List values) { - // TODO: implement buildSorting - throw UnimplementedError(); + final steps = []; + final arr = List.from(values); + + void mergeInPlace(int left, int mid, int right) { + int i = left; + int j = mid + 1; + + while (i <= mid && j <= right) { + steps.add(SortingStep(index1: i, index2: j, action: SortingStatus.compared)); + steps.add(SortingStep(index1: i, index2: j, action: SortingStatus.unSorted)); + + if (arr[i] <= arr[j]) { + i++; + } else { + int k = j; + while (k > i) { + steps.add(SortingStep(index1: k, index2: k - 1, action: SortingStatus.swapping)); + arr.swap(k, k - 1); + steps.add(SortingStep(index1: k, index2: k - 1, action: SortingStatus.swapped)); + k--; + } + i++; + mid++; + j++; + } + } + } + + void mergeSort(int left, int right) { + if (left < right) { + final mid = (left + right) >> 1; + mergeSort(left, mid); + mergeSort(mid + 1, right); + mergeInPlace(left, mid, right); + } + } + + if (arr.isNotEmpty) mergeSort(0, arr.length - 1); + + return SortingResult(sortedValues: arr, steps: steps); } } diff --git a/lib/features/sorting/quick/view/quick_sort_page.dart b/lib/features/sorting/quick/view/quick_sort_page.dart new file mode 100644 index 0000000..511876e --- /dev/null +++ b/lib/features/sorting/quick/view/quick_sort_page.dart @@ -0,0 +1,19 @@ +import 'package:algorithm_visualizer/core/resources/strings_manager.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view/sorting_page.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/quick/view_model/quick_sort_notifier.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +final _notifierProvider = StateNotifierProvider( + (ref) => QuickSortNotifier(), +); + +class QuickSortPage extends StatelessWidget { + const QuickSortPage({super.key}); + + @override + Widget build(BuildContext context) { + return SortingPage(instance: _notifierProvider, title: StringsManager.quickSort); + } +} diff --git a/lib/features/sorting/quick/view_model/quick_sort_notifier.dart b/lib/features/sorting/quick/view_model/quick_sort_notifier.dart new file mode 100644 index 0000000..761fdde --- /dev/null +++ b/lib/features/sorting/quick/view_model/quick_sort_notifier.dart @@ -0,0 +1,49 @@ +import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:collection/collection.dart'; + +class QuickSortNotifier extends SortingNotifier { + @override + SortingResult buildSorting(List values) { + final steps = []; + final arr = List.from(values); + + int partition(int low, int high) { + final pivot = arr[high]; + int i = low - 1; + + for (int j = low; j < high; j++) { + steps.add(SortingStep(index1: j, index2: high, action: SortingStatus.compared)); + steps.add(SortingStep(index1: j, index2: high, action: SortingStatus.unSorted)); + + if (arr[j] <= pivot) { + i++; + if (i != j) { + steps.add(SortingStep(index1: i, index2: j, action: SortingStatus.swapping)); + arr.swap(i, j); + steps.add(SortingStep(index1: i, index2: j, action: SortingStatus.swapped)); + } + } + } + + if (i + 1 != high) { + steps.add(SortingStep(index1: i + 1, index2: high, action: SortingStatus.swapping)); + arr.swap(i + 1, high); + steps.add(SortingStep(index1: i + 1, index2: high, action: SortingStatus.swapped)); + } + + return i + 1; + } + + void quickSort(int low, int high) { + if (low < high) { + final pi = partition(low, high); + quickSort(low, pi - 1); + quickSort(pi + 1, high); + } + } + + if (arr.isNotEmpty) quickSort(0, arr.length - 1); + + return SortingResult(sortedValues: arr, steps: steps); + } +} diff --git a/lib/features/sorting/radix/view/radix_sort_page.dart b/lib/features/sorting/radix/view/radix_sort_page.dart new file mode 100644 index 0000000..39fa6db --- /dev/null +++ b/lib/features/sorting/radix/view/radix_sort_page.dart @@ -0,0 +1,19 @@ +import 'package:algorithm_visualizer/core/resources/strings_manager.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view/sorting_page.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/radix/view_model/radix_sort_notifier.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +final _notifierProvider = StateNotifierProvider( + (ref) => RadixSortNotifier(), +); + +class RadixSortPage extends StatelessWidget { + const RadixSortPage({super.key}); + + @override + Widget build(BuildContext context) { + return SortingPage(instance: _notifierProvider, title: StringsManager.radixSort); + } +} diff --git a/lib/features/sorting/radix/view_model/radix_sort_notifier.dart b/lib/features/sorting/radix/view_model/radix_sort_notifier.dart new file mode 100644 index 0000000..c038c53 --- /dev/null +++ b/lib/features/sorting/radix/view_model/radix_sort_notifier.dart @@ -0,0 +1,54 @@ +import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:collection/collection.dart'; + +class RadixSortNotifier extends SortingNotifier { + @override + SortingResult buildSorting(List values) { + final steps = []; + final arr = List.from(values); + + if (arr.isEmpty) { + return SortingResult(sortedValues: arr, steps: steps); + } + + int maxVal = arr.reduce((a, b) => a > b ? a : b); + + for (int exp = 1; maxVal ~/ exp > 0; exp *= 10) { + _countingSortByDigit(arr, exp, steps); + } + + steps.add(SortingStep(index1: arr.length - 1, index2: arr.length - 1, action: SortingStatus.sorted)); + + return SortingResult(sortedValues: arr, steps: steps); + } + + void _countingSortByDigit(List arr, int exp, List steps) { + int n = arr.length; + List output = List.filled(n, 0); + List count = List.filled(10, 0); + + for (int i = 0; i < n; i++) { + int digit = (arr[i] ~/ exp) % 10; + count[digit]++; + } + + for (int i = 1; i < 10; i++) { + count[i] += count[i - 1]; + } + + for (int i = n - 1; i >= 0; i--) { + int digit = (arr[i] ~/ exp) % 10; + output[count[digit] - 1] = arr[i]; + count[digit]--; + } + + for (int i = 0; i < n; i++) { + if (arr[i] != output[i]) { + int oldIndex = arr.indexOf(output[i], i); + steps.add(SortingStep(index1: i, index2: oldIndex, action: SortingStatus.swapping)); + arr.swap(i, oldIndex); + steps.add(SortingStep(index1: i, index2: oldIndex, action: SortingStatus.swapped)); + } + } + } +} diff --git a/lib/features/sorting/selection/view/selection_sort_page.dart b/lib/features/sorting/selection/view/selection_sort_page.dart index dd2f321..d4b27af 100644 --- a/lib/features/sorting/selection/view/selection_sort_page.dart +++ b/lib/features/sorting/selection/view/selection_sort_page.dart @@ -9,20 +9,9 @@ final _notifierProvider = StateNotifierProvider SelectionSortNotifier(), ); -class SelectionSortPage extends ConsumerStatefulWidget { +class SelectionSortPage extends StatelessWidget { const SelectionSortPage({super.key}); - @override - ConsumerState createState() => _SelectionSortPageState(); -} - -class _SelectionSortPageState extends ConsumerState { - @override - void deactivate() { - ref.invalidate(_notifierProvider); // deletes current instance and resets - super.deactivate(); - } - @override Widget build(BuildContext context) { return SortingPage(instance: _notifierProvider,title: StringsManager.selectionSort); diff --git a/lib/features/sorting/selection/view_model/selection_sort_notifier.dart b/lib/features/sorting/selection/view_model/selection_sort_notifier.dart index a0d99db..c2ceb98 100644 --- a/lib/features/sorting/selection/view_model/selection_sort_notifier.dart +++ b/lib/features/sorting/selection/view_model/selection_sort_notifier.dart @@ -15,7 +15,6 @@ class SelectionSortNotifier extends SortingNotifier { if (arr[j] < arr[minIndex]) { final previousIndex = minIndex; - // to reset action if (minIndex != i) { steps.add(SortingStep(index1: previousIndex, index2: previousIndex, action: SortingStatus.none)); } @@ -29,7 +28,8 @@ class SelectionSortNotifier extends SortingNotifier { steps.add(SortingStep(index1: i, index2: minIndex, action: SortingStatus.swapping)); arr.swap(minIndex, i); - steps.add(SortingStep(index1: minIndex, index2: j, action: SortingStatus.swapped)); + + steps.add(SortingStep(index1: minIndex, index2: i, action: SortingStatus.swapped)); } steps.add(SortingStep(index1: i, index2: i, action: SortingStatus.sorted)); diff --git a/lib/features/sorting/shell/view/shell_sort_page.dart b/lib/features/sorting/shell/view/shell_sort_page.dart new file mode 100644 index 0000000..298e394 --- /dev/null +++ b/lib/features/sorting/shell/view/shell_sort_page.dart @@ -0,0 +1,19 @@ +import 'package:algorithm_visualizer/core/resources/strings_manager.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view/sorting_page.dart'; +import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:algorithm_visualizer/features/sorting/shell/view_model/shell_sort_notifier.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +final _notifierProvider = StateNotifierProvider( + (ref) => ShellSortNotifier(), +); + +class ShellSortPage extends StatelessWidget { + const ShellSortPage({super.key}); + + @override + Widget build(BuildContext context) { + return SortingPage(instance: _notifierProvider, title: StringsManager.shellSort); + } +} diff --git a/lib/features/sorting/shell/view_model/shell_sort_notifier.dart b/lib/features/sorting/shell/view_model/shell_sort_notifier.dart new file mode 100644 index 0000000..44ed082 --- /dev/null +++ b/lib/features/sorting/shell/view_model/shell_sort_notifier.dart @@ -0,0 +1,34 @@ +import 'package:algorithm_visualizer/features/sorting/base/view_model/sorting_notifier.dart'; +import 'package:collection/collection.dart'; + +class ShellSortNotifier extends SortingNotifier { + @override + SortingResult buildSorting(List values) { + final steps = []; + final arr = List.from(values); + int n = arr.length; + + for (int gap = n ~/ 2; gap > 0; gap ~/= 2) { + for (int i = gap; i < n; i++) { + int j = i; + while (j >= gap) { + steps.add(SortingStep(index1: j, index2: j - gap, action: SortingStatus.compared)); + steps.add(SortingStep(index1: j, index2: j - gap, action: SortingStatus.unSorted)); + + if (arr[j] < arr[j - gap]) { + steps.add(SortingStep(index1: j, index2: j - gap, action: SortingStatus.swapping)); + arr.swap(j, j - gap); + steps.add(SortingStep(index1: j, index2: j - gap, action: SortingStatus.swapped)); + } else { + break; + } + j -= gap; + } + } + } + + steps.add(SortingStep(index1: arr.length - 1, index2: arr.length - 1, action: SortingStatus.sorted)); + + return SortingResult(sortedValues: arr, steps: steps); + } +} diff --git a/macos/Podfile.lock b/macos/Podfile.lock new file mode 100644 index 0000000..8590126 --- /dev/null +++ b/macos/Podfile.lock @@ -0,0 +1,23 @@ +PODS: + - FlutterMacOS (1.0.0) + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + +DEPENDENCIES: + - FlutterMacOS (from `Flutter/ephemeral`) + - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) + +EXTERNAL SOURCES: + FlutterMacOS: + :path: Flutter/ephemeral + path_provider_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin + +SPEC CHECKSUMS: + FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 + path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 + +PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367 + +COCOAPODS: 1.16.2 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index a6f9901..05ed00a 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -27,6 +27,8 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + BC0695BE8BA6DC7C18097C19 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EFF8E0EB3563FC8B93AB509 /* Pods_RunnerTests.framework */; }; + FD5A63B08DF895FB684A09FE /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0FBA750DA18DC593C98ECBE /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -60,11 +62,13 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 0EFF8E0EB3563FC8B93AB509 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 23A4DBC67A1A6A65723262E9 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* algorithm_visualizer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "algorithm_visualizer.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* algorithm_visualizer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = algorithm_visualizer.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -76,8 +80,14 @@ 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 560AC72BC0C18017F5A9626B /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 8411ABA32E67EC1D74FB3B96 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + B8EB7DF779F1EFC007352DCF /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + C22B857E797CFF10C241D852 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + D0FBA750DA18DC593C98ECBE /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + DC777C9E959E5C0BFB9580AF /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -85,6 +95,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + BC0695BE8BA6DC7C18097C19 /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -92,6 +103,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + FD5A63B08DF895FB684A09FE /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -125,6 +137,7 @@ 331C80D6294CF71000263BE5 /* RunnerTests */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, + D5E1AE4133BFDC95E9F8843F /* Pods */, ); sourceTree = ""; }; @@ -172,9 +185,25 @@ path = Runner; sourceTree = ""; }; + D5E1AE4133BFDC95E9F8843F /* Pods */ = { + isa = PBXGroup; + children = ( + 560AC72BC0C18017F5A9626B /* Pods-Runner.debug.xcconfig */, + 23A4DBC67A1A6A65723262E9 /* Pods-Runner.release.xcconfig */, + 8411ABA32E67EC1D74FB3B96 /* Pods-Runner.profile.xcconfig */, + C22B857E797CFF10C241D852 /* Pods-RunnerTests.debug.xcconfig */, + DC777C9E959E5C0BFB9580AF /* Pods-RunnerTests.release.xcconfig */, + B8EB7DF779F1EFC007352DCF /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; D73912EC22F37F3D000D13A0 /* Frameworks */ = { isa = PBXGroup; children = ( + D0FBA750DA18DC593C98ECBE /* Pods_Runner.framework */, + 0EFF8E0EB3563FC8B93AB509 /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -186,6 +215,7 @@ isa = PBXNativeTarget; buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + 0D13C9B613943B381077B388 /* [CP] Check Pods Manifest.lock */, 331C80D1294CF70F00263BE5 /* Sources */, 331C80D2294CF70F00263BE5 /* Frameworks */, 331C80D3294CF70F00263BE5 /* Resources */, @@ -204,11 +234,13 @@ isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + CE18D4BD866962CCF82166CC /* [CP] Check Pods Manifest.lock */, 33CC10E92044A3C60003C045 /* Sources */, 33CC10EA2044A3C60003C045 /* Frameworks */, 33CC10EB2044A3C60003C045 /* Resources */, 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, + 7A625F1AF1C52229A9606F09 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -291,6 +323,28 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 0D13C9B613943B381077B388 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -329,6 +383,45 @@ shellPath = /bin/sh; shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; + 7A625F1AF1C52229A9606F09 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + CE18D4BD866962CCF82166CC /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -380,6 +473,7 @@ /* Begin XCBuildConfiguration section */ 331C80DB294CF71000263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = C22B857E797CFF10C241D852 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -394,6 +488,7 @@ }; 331C80DC294CF71000263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = DC777C9E959E5C0BFB9580AF /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -408,6 +503,7 @@ }; 331C80DD294CF71000263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = B8EB7DF779F1EFC007352DCF /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 7e4fd8b..06f7eef 100644 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -59,6 +59,7 @@ ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" + enableGPUValidationMode = "1" allowLocationSimulation = "YES"> diff --git a/macos/Runner.xcworkspace/contents.xcworkspacedata b/macos/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/macos/Runner.xcworkspace/contents.xcworkspacedata +++ b/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift index d53ef64..b3c1761 100644 --- a/macos/Runner/AppDelegate.swift +++ b/macos/Runner/AppDelegate.swift @@ -1,9 +1,13 @@ import Cocoa import FlutterMacOS -@NSApplicationMain +@main class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } } diff --git a/pubspec.lock b/pubspec.lock index 2bfec98..e4330a2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -180,26 +180,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" + sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" url: "https://pub.dev" source: hosted - version: "10.0.9" + version: "11.0.1" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.9" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" lints: dependency: transitive description: @@ -393,10 +393,10 @@ packages: dependency: transitive description: name: test_api - sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.4" + version: "0.7.6" typed_data: dependency: transitive description: @@ -433,10 +433,10 @@ packages: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" vm_service: dependency: transitive description: @@ -470,5 +470,5 @@ packages: source: hosted version: "6.5.0" sdks: - dart: ">=3.7.0-0 <4.0.0" + dart: ">=3.8.0-0 <4.0.0" flutter: ">=3.22.0"