├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── flutter_analysis.yml │ ├── gh_pages.yml │ ├── publish.yml │ └── stale.yml ├── .gitignore ├── .metadata ├── .pubignore ├── .vscode ├── launch.json └── settings.json ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── NOTICES ├── README.md ├── SECURITY.md ├── TODO.md ├── analysis_options.yaml ├── android ├── .gitignore ├── .gradle │ └── 5.1 │ │ ├── fileChanges │ │ └── last-build.bin │ │ ├── fileHashes │ │ └── fileHashes.lock │ │ └── gc.properties ├── app │ └── src │ │ └── main │ │ └── java │ │ └── io │ │ └── flutter │ │ └── plugins │ │ └── GeneratedPluginRegistrant.java ├── build.gradle ├── local.properties ├── settings.gradle └── src │ ├── main │ ├── AndroidManifest.xml │ └── kotlin │ │ └── ch │ │ └── waio │ │ └── pro_image_editor │ │ └── ProImageEditorPlugin.kt │ └── test │ └── kotlin │ └── ch │ └── waio │ └── pro_image_editor │ └── ProImageEditorPluginTest.kt ├── assets ├── fonts │ └── ProImageEditorIcons.ttf ├── logo.jpg ├── preview │ ├── blur-editor.gif │ ├── crop-rotate-editor.gif │ ├── emoji-editor.gif │ ├── filter-editor.gif │ ├── frosted-glass-design.gif │ ├── grounded-design.gif │ ├── paint-editor.gif │ ├── sticker-editor.gif │ ├── text-editor.gif │ └── whatsapp-design.gif ├── schema_capture_image.jpeg ├── showcase-frosted-glass.jpg ├── showcase-whatsapp.jpg └── showcase.jpg ├── example ├── .gitignore ├── .metadata ├── README.md ├── analysis_options.yaml ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ ├── ch │ │ │ │ │ └── waio │ │ │ │ │ │ └── pro_image_editor_example │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── example │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── drawable-v21 │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values-night │ │ │ │ └── styles.xml │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── build.gradle.kts │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── settings.gradle │ └── settings.gradle.kts ├── assets │ ├── demo.mp4 │ ├── demo.png │ ├── frame.png │ ├── frame1.png │ └── google_fonts │ │ └── NotoColorEmoji-Regular.ttf ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ ├── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ │ └── LaunchImage.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ └── README.md │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h │ └── RunnerTests │ │ └── RunnerTests.swift ├── lib │ ├── core │ │ ├── constants │ │ │ ├── example_constants.dart │ │ │ ├── example_list_constant.dart │ │ │ └── history_demo │ │ │ │ ├── import_history_4_0_0.dart │ │ │ │ ├── import_history_5_0_0.dart │ │ │ │ ├── import_history_5_0_0_minified.dart │ │ │ │ ├── import_history_6_0_0.dart │ │ │ │ ├── import_history_6_0_0_crop_rotate.dart │ │ │ │ └── import_history_6_0_0_minified.dart │ │ ├── mixin │ │ │ └── example_helper.dart │ │ └── models │ │ │ └── example_model.dart │ ├── features │ │ ├── background_remover │ │ │ ├── background_remover_example.dart │ │ │ └── background_remover_stub_example.dart │ │ ├── crop_to_main_editor.dart │ │ ├── custom_widgets_example.dart │ │ ├── default_example.dart │ │ ├── design_examples │ │ │ ├── design_example.dart │ │ │ ├── frosted_glass_example.dart │ │ │ ├── grounded_example.dart │ │ │ ├── highly_configurable_example.dart │ │ │ └── whatsapp_example.dart │ │ ├── emoji_translate_example.dart │ │ ├── firebase_supabase_example.dart │ │ ├── frame_example.dart │ │ ├── generation_configs_example.dart │ │ ├── google_font_example.dart │ │ ├── image_format_convert_example.dart │ │ ├── import_export_example.dart │ │ ├── movable_background_image.dart │ │ ├── pick_image_example.dart │ │ ├── preview │ │ │ ├── preview_img.dart │ │ │ └── preview_video.dart │ │ ├── reorder_layer_example.dart │ │ ├── round_cropper_example.dart │ │ ├── selectable_layer_example.dart │ │ ├── signature_drawing_example.dart │ │ ├── standalone_example.dart │ │ ├── stickers_example.dart │ │ ├── video_examples │ │ │ ├── mixins │ │ │ │ └── video_editor_mixin.dart │ │ │ ├── pages │ │ │ │ ├── chewie_player_example.dart │ │ │ │ ├── flick_video_player_example.dart │ │ │ │ ├── video_media_kit_example.dart │ │ │ │ └── video_player_example.dart │ │ │ ├── video_example.dart │ │ │ └── widgets │ │ │ │ └── video_initializing_widget.dart │ │ └── zoom_example.dart │ ├── main.dart │ └── shared │ │ └── widgets │ │ ├── demo_build_stickers.dart │ │ ├── material_icon_button.dart │ │ ├── not_found_example.dart │ │ ├── paragraph_info_widget.dart │ │ ├── pixel_transparent_painter.dart │ │ ├── prepare_image_widget.dart │ │ └── video_progress_alert.dart ├── linux │ ├── .gitignore │ ├── CMakeLists.txt │ ├── flutter │ │ ├── CMakeLists.txt │ │ ├── generated_plugin_registrant.cc │ │ ├── generated_plugin_registrant.h │ │ └── generated_plugins.cmake │ ├── main.cc │ ├── my_application.cc │ └── my_application.h ├── macos │ ├── .gitignore │ ├── Flutter │ │ ├── Flutter-Debug.xcconfig │ │ ├── Flutter-Release.xcconfig │ │ └── GeneratedPluginRegistrant.swift │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ ├── app_icon_1024.png │ │ │ │ ├── app_icon_128.png │ │ │ │ ├── app_icon_16.png │ │ │ │ ├── app_icon_256.png │ │ │ │ ├── app_icon_32.png │ │ │ │ ├── app_icon_512.png │ │ │ │ └── app_icon_64.png │ │ ├── Base.lproj │ │ │ └── MainMenu.xib │ │ ├── Configs │ │ │ ├── AppInfo.xcconfig │ │ │ ├── Debug.xcconfig │ │ │ ├── Release.xcconfig │ │ │ └── Warnings.xcconfig │ │ ├── DebugProfile.entitlements │ │ ├── Info.plist │ │ ├── MainFlutterWindow.swift │ │ └── Release.entitlements │ ├── RunnerTests │ │ └── RunnerTests.swift │ └── package-lock.json ├── pubspec.yaml ├── test │ └── widget_test.dart ├── web │ ├── favicon.png │ ├── flutter_bootstrap.js │ ├── icons │ │ ├── Icon-192.png │ │ ├── Icon-512.png │ │ ├── Icon-maskable-192.png │ │ └── Icon-maskable-512.png │ ├── index.html │ └── manifest.json └── windows │ ├── .gitignore │ ├── CMakeLists.txt │ ├── flutter │ ├── CMakeLists.txt │ ├── generated_plugin_registrant.cc │ ├── generated_plugin_registrant.h │ └── generated_plugins.cmake │ └── runner │ ├── CMakeLists.txt │ ├── Runner.rc │ ├── flutter_window.cpp │ ├── flutter_window.h │ ├── main.cpp │ ├── resource.h │ ├── resources │ └── app_icon.ico │ ├── runner.exe.manifest │ ├── utils.cpp │ ├── utils.h │ ├── win32_window.cpp │ └── win32_window.h ├── lib ├── core │ ├── constants │ │ ├── editor_shader_constants.dart │ │ ├── editor_style_constants.dart │ │ ├── editor_various_constants.dart │ │ ├── editor_web_constants.dart │ │ └── image_constants.dart │ ├── enums │ │ ├── design_mode.dart │ │ ├── editor_mode.dart │ │ ├── sub_editors_name.dart │ │ └── swipe_mode.dart │ ├── mixins │ │ ├── converted_callbacks.dart │ │ ├── converted_configs.dart │ │ ├── editor_callbacks_mixin.dart │ │ ├── editor_configs_mixin.dart │ │ └── standalone_editor.dart │ ├── models │ │ ├── complete_parameters.dart │ │ ├── custom_widgets │ │ │ ├── blur_editor_widgets.dart │ │ │ ├── crop_rotate_editor_widgets.dart │ │ │ ├── dialog_widgets.dart │ │ │ ├── filter_editor_widgets.dart │ │ │ ├── layer_interaction_widgets.dart │ │ │ ├── main_editor_widgets.dart │ │ │ ├── paint_editor_widgets.dart │ │ │ ├── progress_indicator_widgets.dart │ │ │ ├── text_editor_widgets.dart │ │ │ ├── tune_editor_widgets.dart │ │ │ ├── utils │ │ │ │ ├── custom_widgets_standalone_editor.dart │ │ │ │ └── custom_widgets_typedef.dart │ │ │ └── video_editor_widgets.dart │ │ ├── editor_callbacks │ │ │ ├── blur_editor_callbacks.dart │ │ │ ├── crop_rotate_editor_callbacks.dart │ │ │ ├── editor_callbacks_typedef.dart │ │ │ ├── emoji_editor_callbacks.dart │ │ │ ├── filter_editor_callbacks.dart │ │ │ ├── main_editor │ │ │ │ ├── helper_lines │ │ │ │ │ └── helper_lines_callbacks.dart │ │ │ │ └── main_editor_callbacks.dart │ │ │ ├── paint_editor_callbacks.dart │ │ │ ├── pro_image_editor_callbacks.dart │ │ │ ├── standalone_editor_callbacks.dart │ │ │ ├── sticker_editor_callbacks.dart │ │ │ ├── text_editor_callbacks.dart │ │ │ ├── tune_editor_callbacks.dart │ │ │ └── video_editor_callbacks.dart │ │ ├── editor_configs │ │ │ ├── blur_editor_configs.dart │ │ │ ├── crop_rotate_editor_configs.dart │ │ │ ├── dialog_configs.dart │ │ │ ├── emoji_editor_configs.dart │ │ │ ├── filter_editor_configs.dart │ │ │ ├── helper_lines_configs.dart │ │ │ ├── image_generation_configs │ │ │ │ ├── image_generation_configs.dart │ │ │ │ ├── output_formats.dart │ │ │ │ └── processor_configs.dart │ │ │ ├── layer_interaction_configs.dart │ │ │ ├── main_editor_configs.dart │ │ │ ├── paint_editor │ │ │ │ ├── censor_configs.dart │ │ │ │ └── paint_editor_configs.dart │ │ │ ├── pro_image_editor_configs.dart │ │ │ ├── progress_indicator_configs.dart │ │ │ ├── state_history_configs.dart │ │ │ ├── sticker_editor_configs.dart │ │ │ ├── text_editor_configs.dart │ │ │ ├── tune_editor_configs.dart │ │ │ ├── utils │ │ │ │ ├── editor_safe_area.dart │ │ │ │ └── zoom_configs.dart │ │ │ └── video_editor_configs.dart │ │ ├── editor_image.dart │ │ ├── history │ │ │ ├── last_layer_interaction_position.dart │ │ │ └── state_history.dart │ │ ├── i18n │ │ │ ├── i18n.dart │ │ │ ├── i18n_blur_editor.dart │ │ │ ├── i18n_crop_rotate_editor.dart │ │ │ ├── i18n_emoji_editor.dart │ │ │ ├── i18n_filter_editor.dart │ │ │ ├── i18n_layer_interaction.dart │ │ │ ├── i18n_paint_editor.dart │ │ │ ├── i18n_sticker_editor.dart │ │ │ ├── i18n_text_editor.dart │ │ │ ├── i18n_tune_editor.dart │ │ │ └── i18n_various.dart │ │ ├── icons │ │ │ ├── blur_editor_icons.dart │ │ │ ├── crop_rotate_editor_icons.dart │ │ │ ├── emoji_editor_icons.dart │ │ │ ├── filter_editor_icons.dart │ │ │ ├── layer_interaction_icons.dart │ │ │ ├── main_editor_icons.dart │ │ │ ├── paint_editor_icons.dart │ │ │ ├── sticker_editor_icons.dart │ │ │ ├── text_editor_icons.dart │ │ │ ├── tune_editor_icons.dart │ │ │ └── video_editor_icons.dart │ │ ├── init_configs │ │ │ ├── blur_editor_init_configs.dart │ │ │ ├── crop_rotate_editor_init_configs.dart │ │ │ ├── editor_init_configs.dart │ │ │ ├── filter_editor_init_configs.dart │ │ │ ├── paint_editor_init_configs.dart │ │ │ └── tune_editor_init_configs.dart │ │ ├── layers │ │ │ ├── emoji_layer.dart │ │ │ ├── enums │ │ │ │ └── layer_background_mode.dart │ │ │ ├── layer.dart │ │ │ ├── layer_interaction.dart │ │ │ ├── paint_layer.dart │ │ │ ├── text_layer.dart │ │ │ └── widget_layer.dart │ │ ├── multi_threading │ │ │ ├── thread_capture_model.dart │ │ │ ├── thread_request_model.dart │ │ │ ├── thread_response_model.dart │ │ │ ├── thread_task_model.dart │ │ │ └── thread_web_request_model.dart │ │ ├── styles │ │ │ ├── adaptive_dialog_style.dart │ │ │ ├── blur_editor_style.dart │ │ │ ├── crop_rotate_editor_style.dart │ │ │ ├── dialog_style.dart │ │ │ ├── draggable_sheet_style.dart │ │ │ ├── emoji_editor_style.dart │ │ │ ├── filter_editor_style.dart │ │ │ ├── helper_line_style.dart │ │ │ ├── layer_interaction_style.dart │ │ │ ├── loading_dialog_style.dart │ │ │ ├── main_editor_style.dart │ │ │ ├── paint_editor_style.dart │ │ │ ├── sticker_editor_style.dart │ │ │ ├── sub_editor_page_style.dart │ │ │ ├── text_editor_style.dart │ │ │ ├── tune_editor_style.dart │ │ │ ├── types │ │ │ │ └── style_types.dart │ │ │ └── video_editor_style.dart │ │ ├── transform_helper.dart │ │ └── video │ │ │ └── trim_duration_span_model.dart │ ├── platform │ │ └── io │ │ │ ├── io_helper.dart │ │ │ └── io_web.dart │ ├── ui │ │ └── pro_image_editor_icons.dart │ └── utils │ │ ├── image_converter.dart │ │ └── size_utils.dart ├── designs │ ├── frosted_glass │ │ ├── frosted_glass.dart │ │ └── widgets │ │ │ ├── appbar │ │ │ ├── frosted_glass_appbar.dart │ │ │ ├── frosted_glass_blur_appbar.dart │ │ │ ├── frosted_glass_filter_appbar.dart │ │ │ ├── frosted_glass_paint_appbar.dart │ │ │ ├── frosted_glass_text_appbar.dart │ │ │ └── frosted_glass_tune_appbar.dart │ │ │ ├── bottombar │ │ │ ├── frosted_glass_paint_bottombar.dart │ │ │ ├── frosted_glass_text_bottombar.dart │ │ │ └── frosted_glass_tune_bottombar.dart │ │ │ ├── frosted_glass_close_dialog.dart │ │ │ ├── frosted_glass_crop_rotate_toolbar.dart │ │ │ ├── frosted_glass_effect.dart │ │ │ ├── frosted_glass_loading_dialog.dart │ │ │ ├── frosted_glass_sticker_editor.dart │ │ │ └── frosted_glass_text_size_slider.dart │ ├── grounded │ │ ├── constants │ │ │ └── grounded_constants.dart │ │ ├── grounded_design.dart │ │ └── widgets │ │ │ ├── bottombar │ │ │ ├── grounded_blur_bar.dart │ │ │ ├── grounded_bottom_bar.dart │ │ │ ├── grounded_crop_rotate_bar.dart │ │ │ ├── grounded_filter_bar.dart │ │ │ ├── grounded_main_bar.dart │ │ │ ├── grounded_paint_bar.dart │ │ │ ├── grounded_text_bar.dart │ │ │ └── grounded_tune_bar.dart │ │ │ ├── grounded_bottom_wrapper.dart │ │ │ ├── grounded_emoji_editor.dart │ │ │ ├── grounded_loading_dialog.dart │ │ │ ├── grounded_sticker_editor.dart │ │ │ └── grounded_text_size_slider.dart │ └── whatsapp │ │ ├── styles │ │ └── whatsapp_appbar_button_style.dart │ │ ├── whatsapp.dart │ │ ├── whatsapp_color_picker.dart │ │ ├── whatsapp_crop_rotate_toolbar.dart │ │ ├── whatsapp_done_btn.dart │ │ ├── whatsapp_paint_colorpicker.dart │ │ ├── whatsapp_sticker_editor.dart │ │ ├── whatsapp_text_colorpicker.dart │ │ ├── whatsapp_text_size_slider.dart │ │ └── widgets │ │ ├── appbar │ │ ├── whatsapp_appbar.dart │ │ ├── whatsapp_paint_appbar.dart │ │ └── whatsapp_text_appbar.dart │ │ ├── bottombar │ │ ├── whatsapp_paint_bottombar.dart │ │ └── whatsapp_text_bottombar.dart │ │ └── filter │ │ ├── whatsapp_filter_button.dart │ │ ├── whatsapp_filters.dart │ │ └── whatsapp_open_filter_button.dart ├── features │ ├── blur_editor │ │ ├── blur_editor.dart │ │ └── widgets │ │ │ ├── blur_editor_appbar.dart │ │ │ └── blur_editor_bottombar.dart │ ├── crop_rotate_editor │ │ ├── crop_rotate_editor.dart │ │ ├── enums │ │ │ ├── crop_area_part.dart │ │ │ └── crop_rotate_angle_side.dart │ │ ├── mixins │ │ │ └── crop_area_history.dart │ │ ├── models │ │ │ ├── aspect_ratio_item.dart │ │ │ ├── rotate_direction.dart │ │ │ └── transform_factors.dart │ │ ├── services │ │ │ └── crop_desktop_interaction_manager.dart │ │ ├── utils │ │ │ ├── crop_aspect_ratios.dart │ │ │ └── rotate_angle.dart │ │ └── widgets │ │ │ ├── crop_aspect_ratio_button.dart │ │ │ ├── crop_aspect_ratio_options.dart │ │ │ ├── crop_corner_painter.dart │ │ │ ├── crop_editor_appbar.dart │ │ │ ├── crop_editor_bottombar.dart │ │ │ ├── crop_layer_painter.dart │ │ │ └── outside_gestures │ │ │ ├── crop_rotate_gesture_detector.dart │ │ │ ├── outside_gesture_behavior.dart │ │ │ ├── outside_gesture_detector.dart │ │ │ ├── outside_gesture_listener.dart │ │ │ ├── outside_raw_gesture_detector.dart │ │ │ ├── outside_render_proxy_box.dart │ │ │ └── outside_render_semantics_gesture_handler.dart │ ├── emoji_editor │ │ ├── emoji_editor.dart │ │ ├── services │ │ │ └── emoji_state_manager.dart │ │ └── widgets │ │ │ ├── emoji_cell_extended.dart │ │ │ ├── emoji_editor_bottom_bar.dart │ │ │ ├── emoji_editor_category_view.dart │ │ │ ├── emoji_editor_full_screen_search.dart │ │ │ ├── emoji_editor_header_search.dart │ │ │ └── emoji_picker_view.dart │ ├── filter_editor │ │ ├── filter_editor.dart │ │ ├── types │ │ │ └── filter_matrix.dart │ │ ├── utils │ │ │ └── filter_generator │ │ │ │ ├── NOTICES │ │ │ │ ├── filter_addons.dart │ │ │ │ ├── filter_model.dart │ │ │ │ └── filter_presets.dart │ │ └── widgets │ │ │ ├── filter_editor_appbar.dart │ │ │ ├── filter_editor_item_list.dart │ │ │ ├── filter_generator.dart │ │ │ └── filtered_widget.dart │ ├── main_editor │ │ ├── controllers │ │ │ └── main_editor_controllers.dart │ │ ├── helpers │ │ │ └── whats_app_helper.dart │ │ ├── main_editor.dart │ │ ├── mixins │ │ │ └── main_editor_global_keys.dart │ │ ├── providers │ │ │ └── image_infos_provider.dart │ │ ├── services │ │ │ ├── desktop_interaction_manager.dart │ │ │ ├── layer_copy_manager.dart │ │ │ ├── layer_interaction_manager.dart │ │ │ ├── main_editor_state_history_service.dart │ │ │ ├── sizes_manager.dart │ │ │ └── state_manager.dart │ │ └── widgets │ │ │ ├── main_editor_appbar.dart │ │ │ ├── main_editor_background_image.dart │ │ │ ├── main_editor_background_video.dart │ │ │ ├── main_editor_bottombar.dart │ │ │ ├── main_editor_font_preloader.dart │ │ │ ├── main_editor_helper_lines.dart │ │ │ ├── main_editor_interactive_content.dart │ │ │ ├── main_editor_layers.dart │ │ │ └── main_editor_remove_layer_area.dart │ ├── paint_editor │ │ ├── controllers │ │ │ └── paint_controller.dart │ │ ├── enums │ │ │ └── paint_editor_enum.dart │ │ ├── models │ │ │ ├── paint_bottom_bar_item.dart │ │ │ └── painted_model.dart │ │ ├── paint_editor.dart │ │ ├── services │ │ │ └── paint_desktop_interaction_manager.dart │ │ ├── utils │ │ │ └── paint_element.dart │ │ └── widgets │ │ │ ├── draw_paint_item.dart │ │ │ ├── paint_canvas.dart │ │ │ ├── paint_editor_appbar.dart │ │ │ ├── paint_editor_bottombar.dart │ │ │ └── paint_editor_color_picker.dart │ ├── sticker_editor │ │ └── sticker_editor.dart │ ├── text_editor │ │ ├── text_editor.dart │ │ └── widgets │ │ │ ├── text_editor_appbar.dart │ │ │ ├── text_editor_bottom_bar.dart │ │ │ ├── text_editor_color_picker.dart │ │ │ └── text_editor_input.dart │ └── tune_editor │ │ ├── models │ │ ├── tune_adjustment_item.dart │ │ └── tune_adjustment_matrix.dart │ │ ├── tune_editor.dart │ │ ├── utils │ │ └── tune_presets.dart │ │ └── widgets │ │ ├── tune_editor_appbar.dart │ │ └── tune_editor_bottombar.dart ├── plugins │ ├── archive │ │ ├── NOTICES │ │ └── src │ │ │ ├── codecs │ │ │ ├── zlib │ │ │ │ ├── _zlib_encoder.dart │ │ │ │ ├── _zlib_encoder_base.dart │ │ │ │ ├── _zlib_encoder_io.dart │ │ │ │ ├── _zlib_encoder_web.dart │ │ │ │ └── deflate.dart │ │ │ └── zlib_encoder.dart │ │ │ └── utils │ │ │ ├── adler32.dart │ │ │ ├── byte_order.dart │ │ │ ├── crc32.dart │ │ │ ├── input_memory_stream.dart │ │ │ ├── input_stream.dart │ │ │ ├── output_memory_stream.dart │ │ │ └── output_stream.dart │ ├── defer_pointer │ │ ├── NOTICES │ │ ├── defer_pointer.dart │ │ ├── deferred_pointer_handler.dart │ │ └── deferred_pointer_handler_link.dart │ ├── emoji_picker_flutter │ │ ├── NOTICES │ │ ├── emoji_picker_flutter.dart │ │ ├── locales │ │ │ ├── default_emoji_set_locale.dart │ │ │ ├── emoji_set.dart │ │ │ ├── emoji_set_de.dart │ │ │ ├── emoji_set_en.dart │ │ │ ├── emoji_set_es.dart │ │ │ ├── emoji_set_fr.dart │ │ │ ├── emoji_set_hi.dart │ │ │ ├── emoji_set_it.dart │ │ │ ├── emoji_set_ja.dart │ │ │ ├── emoji_set_pt.dart │ │ │ ├── emoji_set_ru.dart │ │ │ └── emoji_set_zh.dart │ │ └── src │ │ │ ├── bottom_action_bar │ │ │ ├── bottom_action_bar.dart │ │ │ ├── bottom_action_bar_config.dart │ │ │ └── default_bottom_action_bar.dart │ │ │ ├── category_view │ │ │ ├── category_emoji.dart │ │ │ ├── category_extra_tab.dart │ │ │ ├── category_icon.dart │ │ │ ├── category_icons.dart │ │ │ ├── category_view.dart │ │ │ ├── category_view_config.dart │ │ │ ├── default_category_tab_bar.dart │ │ │ ├── default_category_view.dart │ │ │ └── recent_tab_behavior.dart │ │ │ ├── config.dart │ │ │ ├── default_emoji_set.dart │ │ │ ├── emoji.dart │ │ │ ├── emoji_picker.dart │ │ │ ├── emoji_picker_internal_utils.dart │ │ │ ├── emoji_picker_utils.dart │ │ │ ├── emoji_text_editing_controller.dart │ │ │ ├── emoji_text_style.dart │ │ │ ├── emoji_view │ │ │ ├── default_emoji_picker_view.dart │ │ │ ├── emoji_container.dart │ │ │ ├── emoji_picker_view.dart │ │ │ └── emoji_view_config.dart │ │ │ ├── emoji_view_state.dart │ │ │ ├── recent_emoji.dart │ │ │ ├── search_view │ │ │ ├── default_search_view.dart │ │ │ ├── search_view.dart │ │ │ └── search_view_config.dart │ │ │ ├── skin_tones │ │ │ ├── emoji_skin_tones.dart │ │ │ ├── skin_tone_config.dart │ │ │ ├── skin_tone_overlay.dart │ │ │ └── triangle_decoration.dart │ │ │ ├── view_order_config.dart │ │ │ └── widgets │ │ │ ├── backspace_button.dart │ │ │ ├── emoji_cell.dart │ │ │ └── search_button.dart │ ├── image │ │ ├── NOTICES │ │ └── src │ │ │ ├── color │ │ │ ├── channel.dart │ │ │ ├── channel_iterator.dart │ │ │ ├── channel_order.dart │ │ │ ├── color.dart │ │ │ ├── color_float16.dart │ │ │ ├── color_float32.dart │ │ │ ├── color_float64.dart │ │ │ ├── color_int16.dart │ │ │ ├── color_int32.dart │ │ │ ├── color_int8.dart │ │ │ ├── color_uint1.dart │ │ │ ├── color_uint16.dart │ │ │ ├── color_uint2.dart │ │ │ ├── color_uint32.dart │ │ │ ├── color_uint4.dart │ │ │ ├── color_uint8.dart │ │ │ └── format.dart │ │ │ ├── exif │ │ │ ├── exif_data.dart │ │ │ ├── exif_tag.dart │ │ │ ├── ifd_container.dart │ │ │ ├── ifd_directory.dart │ │ │ └── ifd_value.dart │ │ │ ├── formats │ │ │ ├── bmp │ │ │ │ └── bmp_info.dart │ │ │ ├── bmp_encoder.dart │ │ │ ├── cur_encoder.dart │ │ │ ├── decode_info.dart │ │ │ ├── encoder.dart │ │ │ ├── formats.dart │ │ │ ├── ico_encoder.dart │ │ │ ├── jpeg │ │ │ │ ├── jpeg_chroma.dart │ │ │ │ └── jpeg_marker.dart │ │ │ ├── jpeg_encoder.dart │ │ │ ├── png │ │ │ │ ├── png_filter.dart │ │ │ │ ├── png_frame.dart │ │ │ │ └── png_info.dart │ │ │ ├── png_encoder.dart │ │ │ ├── pvr │ │ │ │ ├── pvr_bit_utility.dart │ │ │ │ ├── pvr_color.dart │ │ │ │ ├── pvr_color_bounding_box.dart │ │ │ │ └── pvr_packet.dart │ │ │ ├── pvr_encoder.dart │ │ │ ├── tga_encoder.dart │ │ │ ├── tiff │ │ │ │ ├── tiff_bit_reader.dart │ │ │ │ ├── tiff_entry.dart │ │ │ │ ├── tiff_fax_decoder.dart │ │ │ │ ├── tiff_image.dart │ │ │ │ ├── tiff_info.dart │ │ │ │ └── tiff_lzw_decoder.dart │ │ │ └── tiff_encoder.dart │ │ │ ├── image │ │ │ ├── icc_profile.dart │ │ │ ├── image.dart │ │ │ ├── image_data.dart │ │ │ ├── image_data_uint8.dart │ │ │ ├── interpolation.dart │ │ │ ├── palette.dart │ │ │ ├── palette_uint32.dart │ │ │ ├── palette_uint8.dart │ │ │ ├── palette_undefined.dart │ │ │ ├── pixel.dart │ │ │ ├── pixel_range_iterator.dart │ │ │ ├── pixel_uint8.dart │ │ │ └── pixel_undefined.dart │ │ │ └── util │ │ │ ├── _cast.dart │ │ │ ├── _internal.dart │ │ │ ├── bit_utils.dart │ │ │ ├── color_util.dart │ │ │ ├── float16.dart │ │ │ ├── image_exception.dart │ │ │ ├── input_buffer.dart │ │ │ ├── neural_quantizer.dart │ │ │ ├── output_buffer.dart │ │ │ ├── point.dart │ │ │ ├── quantizer.dart │ │ │ └── rational.dart │ ├── mime │ │ ├── NOTICES │ │ └── mime.dart │ └── rounded_background_text │ │ ├── NOTICES │ │ └── src │ │ ├── rounded_background_text.dart │ │ └── rounded_background_text_field.dart ├── pro_image_editor.dart ├── pro_image_editor_method_channel.dart ├── pro_image_editor_platform_interface.dart ├── shared │ ├── controllers │ │ └── video_controller.dart │ ├── extensions │ │ ├── box_constraints_extension.dart │ │ ├── color_extension.dart │ │ ├── double_extension.dart │ │ ├── duration_extension.dart │ │ └── int_extension.dart │ ├── factories │ │ ├── editor_factory.dart │ │ └── editor_mapper.dart │ ├── mixins │ │ ├── editor_zoom.mixin.dart │ │ └── extended_loop.dart │ ├── services │ │ ├── content_recorder │ │ │ ├── controllers │ │ │ │ └── content_recorder_controller.dart │ │ │ ├── models │ │ │ │ ├── isolate_thread.dart │ │ │ │ ├── thread.dart │ │ │ │ └── web_worker_thread.dart │ │ │ ├── services │ │ │ │ ├── image_converter_service.dart │ │ │ │ ├── image_render_service.dart │ │ │ │ ├── isolate_manager.dart │ │ │ │ ├── thread_fallback_manager.dart │ │ │ │ ├── thread_manager.dart │ │ │ │ └── web_worker │ │ │ │ │ ├── web_worker_manager.dart │ │ │ │ │ └── web_worker_manager_dummy.dart │ │ │ ├── utils │ │ │ │ ├── converters │ │ │ │ │ ├── convert_flutter_ui_to_image.dart │ │ │ │ │ └── convert_raw_image.dart │ │ │ │ ├── dart_ui_remove_transparent_image_areas.dart │ │ │ │ ├── encoder │ │ │ │ │ └── encode_image.dart │ │ │ │ ├── generate_high_quality_image.dart │ │ │ │ ├── isolate_thread_utils.dart │ │ │ │ ├── processor_helper.dart │ │ │ │ └── web_worker_utils.dart │ │ │ └── widgets │ │ │ │ ├── content_recorder.dart │ │ │ │ └── record_invisible_widget.dart │ │ ├── import_export │ │ │ ├── constants │ │ │ │ ├── export_import_version.dart │ │ │ │ └── minified_keys.dart │ │ │ ├── enums │ │ │ │ └── export_import_enum.dart │ │ │ ├── export_state_history.dart │ │ │ ├── import_state_history.dart │ │ │ ├── models │ │ │ │ ├── export_state_history_configs.dart │ │ │ │ ├── import_state_history_configs.dart │ │ │ │ └── widget_layer_export_configs.dart │ │ │ ├── types │ │ │ │ └── widget_loader.dart │ │ │ └── utils │ │ │ │ ├── history_compatibility │ │ │ │ └── history_compatibility_layer_interaction.dart │ │ │ │ └── key_minifier.dart │ │ ├── layer_transform_generator.dart │ │ └── shader_manager.dart │ ├── shaders │ │ └── pixelate.frag │ ├── styles │ │ └── platform_text_styles.dart │ ├── utils │ │ ├── converters.dart │ │ ├── debounce.dart │ │ ├── decode_image.dart │ │ ├── file_constructor_utils.dart │ │ ├── interpolation_utils.dart │ │ ├── map_utils.dart │ │ ├── parser │ │ │ ├── double_parser.dart │ │ │ ├── int_parser.dart │ │ │ └── size_parser.dart │ │ ├── platform_info.dart │ │ └── unique_id_generator.dart │ └── widgets │ │ ├── adaptive_dialog.dart │ │ ├── animated │ │ ├── fade_in_base.dart │ │ ├── fade_in_left.dart │ │ └── fade_in_up.dart │ │ ├── auto_image.dart │ │ ├── bottom_sheets_header_row.dart │ │ ├── censor │ │ ├── abstract │ │ │ └── censor_area_item.dart │ │ ├── blur_area_item.dart │ │ └── pixelate_area_item.dart │ │ ├── color_picker │ │ ├── bar_color_picker.dart │ │ └── color_picker_configs.dart │ │ ├── extended │ │ ├── extended_custom_paint.dart │ │ ├── extended_interactive_viewer.dart │ │ ├── extended_pop_scope.dart │ │ ├── extended_transform_scale.dart │ │ ├── extended_transform_translate.dart │ │ ├── mouse_region │ │ │ └── extended_rebuild_mouse_region.dart │ │ └── repaint │ │ │ ├── extended_render_repaint_boundary.dart │ │ │ └── extended_repaint_boundary.dart │ │ ├── flat_icon_text_button.dart │ │ ├── layer │ │ ├── enums │ │ │ └── layer_widget_type_enum.dart │ │ ├── interaction_helper │ │ │ ├── layer_interaction_border_painter.dart │ │ │ ├── layer_interaction_button.dart │ │ │ └── layer_interaction_helper_widget.dart │ │ ├── layer_stack.dart │ │ ├── layer_widget.dart │ │ ├── models │ │ │ └── layer_item_interaction.dart │ │ ├── services │ │ │ └── layer_widget_context_menu.dart │ │ └── widgets │ │ │ ├── layer_widget_censor_item.dart │ │ │ ├── layer_widget_custom_item.dart │ │ │ ├── layer_widget_emoji_item.dart │ │ │ ├── layer_widget_paint_item.dart │ │ │ └── layer_widget_text_item.dart │ │ ├── overlays │ │ └── loading_dialog │ │ │ ├── animations │ │ │ ├── loading_dialog_base_animation.dart │ │ │ └── loading_dialog_opacity_animation.dart │ │ │ ├── loading_dialog.dart │ │ │ └── models │ │ │ └── loading_dialog_overlay_details.dart │ │ ├── platform │ │ ├── platform_circular_progress_indicator.dart │ │ └── platform_popup_menu.dart │ │ ├── reactive_widgets │ │ ├── reactive_custom_appbar.dart │ │ └── reactive_custom_widget.dart │ │ ├── screen_resize_detector.dart │ │ ├── slider_bottom_sheet.dart │ │ ├── transform │ │ └── transformed_content_generator.dart │ │ └── video │ │ ├── export_prebuild │ │ ├── video_editor_prebuild_remove_area.dart │ │ └── video_editor_prebuild_widgets.dart │ │ ├── toolbar │ │ ├── video_editor_info_banner.dart │ │ ├── video_editor_mute_button.dart │ │ ├── video_editor_play_button.dart │ │ └── video_editor_trim_info_widget.dart │ │ ├── trimmer │ │ ├── video_editor_play_time_indicator.dart │ │ ├── video_editor_trim_bar.dart │ │ ├── video_editor_trim_handle.dart │ │ ├── video_editor_trim_skeleton.dart │ │ └── video_editor_trim_thumbnail_bar.dart │ │ ├── video_editor_configurable.dart │ │ ├── video_editor_controls_widget.dart │ │ └── video_editor_state_widget.dart └── web │ ├── web_worker.dart │ ├── web_worker.dart.js │ └── web_worker.dart.js.map ├── pubspec.yaml └── test ├── fake └── fake_image.dart ├── features ├── blur_editor_test.dart ├── crop_rotate_editor │ ├── crop_rotate_editor_test.dart │ └── widgets │ │ ├── crop_aspect_ratio_options_test.dart │ │ └── crop_corner_painter_test.dart ├── emoji_editor_test.dart ├── filter_editor_test.dart ├── paint_editor │ ├── paint_editor_test.dart │ ├── painting_canvas_test.dart │ └── utils │ │ ├── draw │ │ └── draw_canvas_test.dart │ │ └── paint_controller_test.dart ├── sticker_editor_test.dart ├── text_editor_test.dart └── tune_editor_test.dart ├── models └── editor_image_test.dart ├── pro_image_editor_method_channel_test.dart ├── pro_image_editor_test.dart ├── shared ├── services │ └── import_export │ │ └── constants │ │ └── minified_keys_test.dart └── widgets │ ├── auto_image_test.dart │ ├── auto_image_test.mocks.dart │ ├── color_picker │ ├── bar_color_picker_test.dart │ └── bar_color_picker_test.mocks.dart │ └── layer_widget_test.dart └── utils ├── converters.dart └── parser ├── double_parser_test.dart └── int_parser.dart /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [hm21] -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: Question 4 | url: https://github.com/hm21/pro_image_editor/discussions/new?category=q-a 5 | about: The Issues tab is for reporting bugs or suggesting features. For general questions, support, or guidance, the Discussions tab is the right place to go. -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: "Feature request" 2 | description: "Suggest an idea or enhancement for this project" 3 | title: "[Feature request] " 4 | labels: ["enhancement"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to fill out this feature request! 10 | - type: dropdown 11 | id: platforms 12 | attributes: 13 | label: Platforms 14 | description: Check all that apply 15 | multiple: true 16 | options: 17 | - Android 18 | - iOS 19 | - Web 20 | - Windows 21 | - macOS 22 | - Linux 23 | validations: 24 | required: true 25 | - type: textarea 26 | id: description 27 | attributes: 28 | label: Description 29 | description: "Describe the feature you want to be added" 30 | placeholder: "ex. I want to add a new method to get the thumbnail of the asset." 31 | validations: 32 | required: true 33 | - type: textarea 34 | id: why 35 | attributes: 36 | label: Why 37 | description: "Why do you want this feature to be added? What's the use case?" 38 | placeholder: "Thumbnails are very important for picture display and must be available. [some design images]" 39 | validations: 40 | required: false 41 | - type: markdown 42 | attributes: 43 | value: | 44 | Add as many reasons as possible to prioritize the request. -------------------------------------------------------------------------------- /.github/workflows/flutter_analysis.yml: -------------------------------------------------------------------------------- 1 | name: Flutter Analysis 2 | on: 3 | push: 4 | branches: 5 | - stable 6 | pull_request: 7 | workflow_dispatch: 8 | 9 | jobs: 10 | package-analysis: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Clone repository 15 | uses: actions/checkout@v4 16 | 17 | - name: Set up Flutter 18 | uses: subosito/flutter-action@v2 19 | with: 20 | channel: stable 21 | flutter-version: 3.32.0 22 | 23 | - name: Install dependencies 24 | run: flutter pub get 25 | 26 | - name: Check formatting 27 | run: dart format --output=none --set-exit-if-changed . 28 | 29 | - name: Analyze code 30 | run: flutter analyze . 31 | 32 | - name: Run tests 33 | run: flutter test -------------------------------------------------------------------------------- /.github/workflows/gh_pages.yml: -------------------------------------------------------------------------------- 1 | name: GH-Pages 2 | on: 3 | push: 4 | branches: 5 | - stable 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | env: 11 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 12 | steps: 13 | - name: Clone repository 14 | uses: actions/checkout@v4 15 | 16 | - name: Set up Flutter 17 | uses: subosito/flutter-action@v2 18 | with: 19 | channel: stable 20 | flutter-version: 3.32.0 21 | 22 | - name: Install Package Dependencies 23 | run: flutter pub get 24 | 25 | - name: Install Example Dependencies 26 | run: flutter pub get 27 | working-directory: ./example 28 | 29 | - name: Build Web 30 | run: flutter build web --release 31 | working-directory: ./example 32 | 33 | - name: Deploy 34 | run: | 35 | cd example/build/web 36 | git init 37 | git config user.name "hm21" 38 | git config user.email "alex.frei@hotmail.ch" 39 | git remote add secure-origin https://username:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git 40 | git checkout -b gh-pages 41 | git add . 42 | git commit -m "Deployed Github Pages" 43 | git push --force secure-origin gh-pages 44 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to pub.dev 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v[0-9]+.[0-9]+.[0-9]+*' 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Clone repository 14 | uses: actions/checkout@v4 15 | 16 | - name: Set up Flutter 17 | uses: subosito/flutter-action@v2 18 | with: 19 | channel: stable 20 | flutter-version: 3.32.0 21 | 22 | - name: Install dependencies 23 | run: flutter pub get 24 | 25 | - name: Check formatting 26 | run: dart format --output=none --set-exit-if-changed . 27 | 28 | - name: Analyze code 29 | run: flutter analyze . 30 | 31 | - name: Run tests 32 | run: flutter test 33 | 34 | - name: Setup Pub Credentials 35 | run: | 36 | echo "PUB_DEV_PUBLISH_ACCESS_TOKEN=${{ secrets.PUB_DEV_PUBLISH_ACCESS_TOKEN }}" >> $GITHUB_ENV 37 | echo "PUB_DEV_PUBLISH_REFRESH_TOKEN=${{ secrets.PUB_DEV_PUBLISH_REFRESH_TOKEN }}" >> $GITHUB_ENV 38 | 39 | - name: Check Publish Warnings 40 | run: dart pub publish --dry-run 41 | 42 | - name: Publish Package 43 | run: dart pub publish -f -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Close inactive issues 2 | on: 3 | schedule: 4 | - cron: "0 0 * * *" 5 | 6 | jobs: 7 | close-issues: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | issues: write 11 | pull-requests: write 12 | steps: 13 | - uses: actions/stale@v5 14 | with: 15 | days-before-issue-stale: 3 16 | days-before-issue-close: 5 17 | stale-issue-label: "stale" 18 | exempt-issue-labels: "in-progress" 19 | stale-issue-message: "This issue is stale because it has been open for 3 days with no activity." 20 | close-issue-message: "This issue was closed because it has been inactive for 5 days since being marked as stale." 21 | days-before-pr-stale: -1 22 | days-before-pr-close: -1 23 | repo-token: ${{ secrets.GITHUB_TOKEN }} 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | .flutter-plugins-dependencies 30 | .flutter-plugins 31 | /example/.flutter-plugins 32 | /example/.flutter-plugins-dependencies 33 | /example/pubspec.lock 34 | /example/android/app/.cxx 35 | /lib/web/web_worker.dart.js.deps 36 | /lib/web/web_worker.dart.unopt.wasm.map 37 | /lib/web/web_worker.dart.wasm.map 38 | build/ 39 | /devtools_options.yaml 40 | /example/devtools_options.yaml 41 | 42 | # Ignoring all of the Cocoapods files in the example app. 43 | Podfile 44 | Podfile.* 45 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: "c23637390482d4cf9598c3ce3f2be31aa7332daf" 8 | channel: "stable" 9 | 10 | project_type: plugin 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf 17 | base_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf 18 | - platform: android 19 | create_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf 20 | base_revision: c23637390482d4cf9598c3ce3f2be31aa7332daf 21 | 22 | # User provided section 23 | 24 | # List of Local paths (relative to this file) that should be 25 | # ignored by the migrate tool. 26 | # 27 | # Files that are not part of the templates will be ignored by default. 28 | unmanaged_files: 29 | - 'lib/main.dart' 30 | - 'ios/Runner.xcodeproj/project.pbxproj' 31 | -------------------------------------------------------------------------------- /.pubignore: -------------------------------------------------------------------------------- 1 | .dart_tool/ 2 | .github/ 3 | .idea/ 4 | .vscode/ 5 | assets/preview/ 6 | build/ 7 | .packages 8 | .pub/ 9 | .git/ 10 | .gitignore 11 | pub_login.sh 12 | /example/android/app/.cxx 13 | /lib/web/web_worker.dart.js.deps 14 | /lib/web/web_worker.dart.unopt.wasm.map 15 | /lib/web/web_worker.dart.wasm.map 16 | /devtools_options.yaml 17 | /example/devtools_options.yaml -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Verwendet IntelliSense zum Ermitteln möglicher Attribute. 3 | // Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen. 4 | // Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "pro_image_editor", 9 | "request": "launch", 10 | "type": "dart" 11 | }, 12 | { 13 | "name": "pro_image_editor (profile mode)", 14 | "request": "launch", 15 | "type": "dart", 16 | "flutterMode": "profile" 17 | }, 18 | { 19 | "name": "pro_image_editor (release mode)", 20 | "request": "launch", 21 | "type": "dart", 22 | "flutterMode": "release" 23 | }, 24 | { 25 | "name": "example", 26 | "cwd": "example", 27 | "request": "launch", 28 | "type": "dart" 29 | }, 30 | { 31 | "name": "example (profile mode)", 32 | "cwd": "example", 33 | "request": "launch", 34 | "type": "dart", 35 | "flutterMode": "profile" 36 | }, 37 | { 38 | "name": "example (release mode)", 39 | "cwd": "example", 40 | "request": "launch", 41 | "type": "dart", 42 | "flutterMode": "release" 43 | } 44 | ] 45 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "bbox", 4 | "Bezier", 5 | "Cooldown", 6 | "diegotori", 7 | "dismissibility", 8 | "ellipsize", 9 | "endtemplate", 10 | "fdtbl", 11 | "LTRBR", 12 | "overriden", 13 | "Rgba", 14 | "selectability", 15 | "trackpad", 16 | "unawaited", 17 | "uvac", 18 | "uvdc" 19 | ], 20 | "diffEditor.experimental.showEmptyDecorations": true, 21 | "diffEditor.hideUnchangedRegions.enabled": false, 22 | "editor.minimap.showMarkSectionHeaders": true, 23 | "github.copilot.enable": { 24 | "*": false, 25 | "plaintext": false, 26 | "markdown": false, 27 | "scminput": false 28 | } 29 | } -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | We actively support and release security updates for the following versions of `pro_image_editor`: 6 | 7 | | Version | Supported | 8 | |-----------------|--------------------| 9 | | Latest release | ✅ | 10 | | Older versions | ❌ | 11 | 12 | Please update to the latest version to ensure you receive the latest security patches and updates. 13 | 14 | ## Reporting a Vulnerability 15 | 16 | If you discover a security vulnerability in `pro_image_editor`, please report it responsibly to help us maintain a safe and secure project. 17 | 18 | ### Steps to Report: 19 | 1. **Do not open a public issue.** 20 | Instead, email us privately at **[alex.frei@hotmail.ch]** to report the issue. 21 | 22 | 2. **Include the following details in your report:** 23 | - A detailed description of the vulnerability. 24 | - Steps to reproduce the issue. 25 | - The potential impact of the vulnerability. 26 | - Any suggested fixes or mitigations. 27 | 28 | 3. **Response Time:** 29 | We aim to acknowledge security reports within **48 hours** and provide a resolution or mitigation plan within **7 days**, depending on the severity and complexity of the issue. 30 | 31 | 4. **Confidentiality:** 32 | We request you keep the vulnerability confidential until we have released a fix and informed our users. 33 | 34 | ## Thank You 35 | 36 | We appreciate your efforts to responsibly disclose security issues. Your contribution helps make `pro_image_editor` safer for everyone. 37 | 38 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | - Video-Editor 2 | - Generate Native Output File 3 | - Web 4 | - Android 5 | - iOS 6 | - macOS 7 | - Linux 8 | - Windows 9 | - Fix Web Video Player (May require a new native solution) 10 | - Remove deprecated warnings on the video constructors -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .cxx 10 | -------------------------------------------------------------------------------- /android/.gradle/5.1/fileChanges/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /android/.gradle/5.1/fileHashes/fileHashes.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/android/.gradle/5.1/fileHashes/fileHashes.lock -------------------------------------------------------------------------------- /android/.gradle/5.1/gc.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/android/.gradle/5.1/gc.properties -------------------------------------------------------------------------------- /android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java: -------------------------------------------------------------------------------- 1 | package io.flutter.plugins; 2 | 3 | import androidx.annotation.Keep; 4 | import androidx.annotation.NonNull; 5 | import io.flutter.Log; 6 | 7 | import io.flutter.embedding.engine.FlutterEngine; 8 | 9 | /** 10 | * Generated file. Do not edit. 11 | * This file is generated by the Flutter tool based on the 12 | * plugins that support the Android platform. 13 | */ 14 | @Keep 15 | public final class GeneratedPluginRegistrant { 16 | private static final String TAG = "GeneratedPluginRegistrant"; 17 | public static void registerWith(@NonNull FlutterEngine flutterEngine) { 18 | try { 19 | flutterEngine.getPlugins().add(new com.fintasys.emoji_picker_flutter.EmojiPickerFlutterPlugin()); 20 | } catch (Exception e) { 21 | Log.e(TAG, "Error registering plugin emoji_picker_flutter, com.fintasys.emoji_picker_flutter.EmojiPickerFlutterPlugin", e); 22 | } 23 | try { 24 | flutterEngine.getPlugins().add(new io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin()); 25 | } catch (Exception e) { 26 | Log.e(TAG, "Error registering plugin shared_preferences_android, io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin", e); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /android/local.properties: -------------------------------------------------------------------------------- 1 | sdk.dir=C:\\Users\\AlexF\\AppData\\Local\\Android\\Sdk 2 | flutter.sdk=C:\\flutter -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'pro_image_editor' 2 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /android/src/test/kotlin/ch/waio/pro_image_editor/ProImageEditorPluginTest.kt: -------------------------------------------------------------------------------- 1 | package ch.waio.pro_image_editor 2 | 3 | import io.flutter.plugin.common.MethodCall 4 | import io.flutter.plugin.common.MethodChannel 5 | import kotlin.test.Test 6 | import org.mockito.Mockito 7 | 8 | /* 9 | * This demonstrates a simple unit test of the Kotlin portion of this plugin's implementation. 10 | * 11 | * Once you have built the plugin's example app, you can run these tests from the command 12 | * line by running `./gradlew testDebugUnitTest` in the `example/android/` directory, or 13 | * you can run them directly from IDEs that support JUnit such as Android Studio. 14 | */ 15 | 16 | internal class ProImageEditorPluginTest { 17 | @Test 18 | fun onMethodCall_getPlatformVersion_returnsExpectedValue() { 19 | val plugin = ProImageEditorPlugin() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /assets/fonts/ProImageEditorIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/fonts/ProImageEditorIcons.ttf -------------------------------------------------------------------------------- /assets/logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/logo.jpg -------------------------------------------------------------------------------- /assets/preview/blur-editor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/preview/blur-editor.gif -------------------------------------------------------------------------------- /assets/preview/crop-rotate-editor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/preview/crop-rotate-editor.gif -------------------------------------------------------------------------------- /assets/preview/emoji-editor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/preview/emoji-editor.gif -------------------------------------------------------------------------------- /assets/preview/filter-editor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/preview/filter-editor.gif -------------------------------------------------------------------------------- /assets/preview/frosted-glass-design.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/preview/frosted-glass-design.gif -------------------------------------------------------------------------------- /assets/preview/grounded-design.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/preview/grounded-design.gif -------------------------------------------------------------------------------- /assets/preview/paint-editor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/preview/paint-editor.gif -------------------------------------------------------------------------------- /assets/preview/sticker-editor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/preview/sticker-editor.gif -------------------------------------------------------------------------------- /assets/preview/text-editor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/preview/text-editor.gif -------------------------------------------------------------------------------- /assets/preview/whatsapp-design.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/preview/whatsapp-design.gif -------------------------------------------------------------------------------- /assets/schema_capture_image.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/schema_capture_image.jpeg -------------------------------------------------------------------------------- /assets/showcase-frosted-glass.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/showcase-frosted-glass.jpg -------------------------------------------------------------------------------- /assets/showcase-whatsapp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/showcase-whatsapp.jpg -------------------------------------------------------------------------------- /assets/showcase.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/assets/showcase.jpg -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Symbolication related 35 | app.*.symbols 36 | 37 | # Obfuscation related 38 | app.*.map.json 39 | 40 | # Android Studio will place build artifacts here 41 | /android/app/debug 42 | /android/app/profile 43 | /android/app/release 44 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # example 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) 13 | 14 | For help getting started with Flutter development, view the 15 | [online documentation](https://docs.flutter.dev/), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/ch/waio/pro_image_editor_example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package ch.waio.pro_image_editor_example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity : FlutterActivity() 6 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/example/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.8.22' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 10 | } 11 | } 12 | 13 | allprojects { 14 | repositories { 15 | google() 16 | mavenCentral() 17 | } 18 | } 19 | 20 | rootProject.buildDir = '../build' 21 | subprojects { 22 | project.buildDir = "${rootProject.buildDir}/${project.name}" 23 | } 24 | subprojects { 25 | project.evaluationDependsOn(':app') 26 | } 27 | 28 | tasks.register("clean", Delete) { 29 | delete rootProject.buildDir 30 | } 31 | -------------------------------------------------------------------------------- /example/android/build.gradle.kts: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get() 9 | rootProject.layout.buildDirectory.value(newBuildDir) 10 | 11 | subprojects { 12 | val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) 13 | project.layout.buildDirectory.value(newSubprojectBuildDir) 14 | } 15 | subprojects { 16 | project.evaluationDependsOn(":app") 17 | } 18 | 19 | tasks.register("clean") { 20 | delete(rootProject.layout.buildDirectory) 21 | } 22 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4G 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip 6 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | } 9 | settings.ext.flutterSdkPath = flutterSdkPath() 10 | 11 | includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") 12 | 13 | repositories { 14 | google() 15 | mavenCentral() 16 | gradlePluginPortal() 17 | } 18 | 19 | plugins { 20 | id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false 21 | } 22 | } 23 | 24 | plugins { 25 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 26 | id "com.android.application" version "8.3.0" apply false 27 | } 28 | 29 | include ":app" 30 | -------------------------------------------------------------------------------- /example/android/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | val flutterSdkPath = run { 3 | val properties = java.util.Properties() 4 | file("local.properties").inputStream().use { properties.load(it) } 5 | val flutterSdkPath = properties.getProperty("flutter.sdk") 6 | require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } 7 | flutterSdkPath 8 | } 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id("dev.flutter.flutter-plugin-loader") version "1.0.0" 21 | id("com.android.application") version "8.7.0" apply false 22 | id("org.jetbrains.kotlin.android") version "1.8.22" apply false 23 | } 24 | 25 | include(":app") 26 | -------------------------------------------------------------------------------- /example/assets/demo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/assets/demo.mp4 -------------------------------------------------------------------------------- /example/assets/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/assets/demo.png -------------------------------------------------------------------------------- /example/assets/frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/assets/frame.png -------------------------------------------------------------------------------- /example/assets/frame1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/assets/frame1.png -------------------------------------------------------------------------------- /example/assets/google_fonts/NotoColorEmoji-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/assets/google_fonts/NotoColorEmoji-Regular.ttf -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @main 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/ios/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /example/lib/core/constants/example_constants.dart: -------------------------------------------------------------------------------- 1 | /// A path to a demo image asset in the project. 2 | final String kImageEditorExampleAssetPath = 'assets/demo.png'; 3 | 4 | /// A URL to a demo image hosted on a remote server. 5 | final String kImageEditorExampleNetworkUrl = 6 | 'https://picsum.photos/id/230/2000'; 7 | 8 | /// A URL to a demo image hosted on a remote server. 9 | final String kVideoEditorExampleAssetPath = 'assets/demo.mp4'; 10 | 11 | /// Breakpoint for desktop layout in the image editor example. 12 | final kImageEditorExampleIsDesktopBreakPoint = 900; 13 | -------------------------------------------------------------------------------- /example/lib/core/models/example_model.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | /// Represents an example item with a name, path, icon, and associated page. 4 | /// 5 | /// This class is typically used to define examples in an application, where 6 | /// each example has: 7 | /// - A [path]: The navigation route or identifier for the example. 8 | /// - A [name]: A user-friendly name for the example. 9 | /// - An [icon]: An icon representing the example. 10 | /// - A [page]: The widget representing the content of the example. 11 | class Example { 12 | /// Creates an instance of [Example]. 13 | /// 14 | /// All fields are required. 15 | const Example({ 16 | required this.path, 17 | required this.name, 18 | required this.icon, 19 | required this.page, 20 | this.disabled = false, 21 | this.disabledMessage = '', 22 | }); 23 | 24 | /// The navigation route or identifier for the example. 25 | final String path; 26 | 27 | /// The user-friendly name of the example. 28 | final String name; 29 | 30 | /// The icon representing the example. 31 | final IconData icon; 32 | 33 | /// The widget representing the content of the example. 34 | final Widget page; 35 | 36 | /// Indicates whether the example is disabled. 37 | final bool disabled; 38 | 39 | /// Message to display when the example is disabled. 40 | final String disabledMessage; 41 | } 42 | -------------------------------------------------------------------------------- /example/lib/features/background_remover/background_remover_stub_example.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | // Project imports: 6 | import '/core/mixin/example_helper.dart'; 7 | 8 | /// IMPORTANT: 9 | /// This is just a stub class for the web implementation. The actual source code 10 | /// is in the same folder, using the same name without 'stub' in the class name. 11 | class BackgroundRemoverExample extends StatefulWidget { 12 | /// Stub-Constructor 13 | const BackgroundRemoverExample({super.key}); 14 | 15 | @override 16 | State createState() => 17 | _BackgroundRemoverExampleState(); 18 | } 19 | 20 | class _BackgroundRemoverExampleState extends State 21 | with ExampleHelperState { 22 | @override 23 | Widget build(BuildContext context) { 24 | return Container(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /example/lib/shared/widgets/not_found_example.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// A widget that displays a centered "Example not found" message. 4 | /// 5 | /// This widget is useful as a placeholder for screens or routes 6 | /// that have not been implemented yet or when content is unavailable. 7 | class NotFoundExample extends StatefulWidget { 8 | /// Creates a `NotFoundExample` widget. 9 | const NotFoundExample({super.key}); 10 | 11 | @override 12 | State createState() => _NotFoundExampleState(); 13 | } 14 | 15 | class _NotFoundExampleState extends State { 16 | @override 17 | Widget build(BuildContext context) { 18 | return const Scaffold( 19 | body: Center( 20 | child: Text( 21 | 'Example not found', 22 | style: TextStyle( 23 | fontSize: 20, 24 | color: Colors.red, 25 | ), 26 | ), 27 | ), 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /example/lib/shared/widgets/paragraph_info_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | /// A widget that visually highlights a paragraph with a colored left border. 4 | /// 5 | /// Useful for drawing attention to a block of content, such as a tip, 6 | /// warning, or important note. 7 | /// 8 | /// You can customize the [color] of the border and apply optional [margin] 9 | /// around the widget. The [child] is the content displayed inside. 10 | class ParagraphInfoWidget extends StatelessWidget { 11 | /// Creates a [ParagraphInfoWidget]. 12 | /// 13 | /// The [child] is required and will be displayed inside the bordered area. 14 | /// You can optionally customize the [margin] and [color]. 15 | const ParagraphInfoWidget({ 16 | super.key, 17 | required this.child, 18 | this.margin, 19 | this.color = const Color(0xFF0f7dff), 20 | }); 21 | 22 | /// The widget displayed inside the bordered container. 23 | final Widget child; 24 | 25 | /// Optional margin around the container. 26 | final EdgeInsets? margin; 27 | 28 | /// The color of the left border. 29 | final Color color; 30 | 31 | @override 32 | Widget build(BuildContext context) { 33 | return Container( 34 | margin: margin, 35 | padding: const EdgeInsets.only(left: 16), 36 | decoration: BoxDecoration( 37 | border: Border( 38 | left: BorderSide( 39 | color: color, 40 | width: 2, 41 | ), 42 | ), 43 | ), 44 | child: child, 45 | ); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /example/linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | -------------------------------------------------------------------------------- /example/linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void fl_register_plugins(FlPluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /example/linux/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | file_saver 7 | file_selector_linux 8 | gtk 9 | media_kit_libs_linux 10 | media_kit_video 11 | pro_video_editor 12 | url_launcher_linux 13 | volume_controller 14 | ) 15 | 16 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 17 | onnxruntime 18 | ) 19 | 20 | set(PLUGIN_BUNDLED_LIBRARIES) 21 | 22 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 23 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) 24 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 25 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 26 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 27 | endforeach(plugin) 28 | 29 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 30 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) 31 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 32 | endforeach(ffi_plugin) 33 | -------------------------------------------------------------------------------- /example/linux/main.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | int main(int argc, char** argv) { 4 | g_autoptr(MyApplication) app = my_application_new(); 5 | return g_application_run(G_APPLICATION(app), argc, argv); 6 | } 7 | -------------------------------------------------------------------------------- /example/linux/my_application.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_MY_APPLICATION_H_ 2 | #define FLUTTER_MY_APPLICATION_H_ 3 | 4 | #include 5 | 6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, 7 | GtkApplication) 8 | 9 | /** 10 | * my_application_new: 11 | * 12 | * Creates a new Flutter-based application. 13 | * 14 | * Returns: a new #MyApplication. 15 | */ 16 | MyApplication* my_application_new(); 17 | 18 | #endif // FLUTTER_MY_APPLICATION_H_ 19 | -------------------------------------------------------------------------------- /example/macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @main 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /example/macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = example 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2024 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /example/macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | com.apple.security.network.client 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example/macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /example/macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /example/macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.network.client 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/macos/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import FlutterMacOS 2 | import Cocoa 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /example/macos/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "macos", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": {} 6 | } 7 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: example 2 | description: "A new Flutter project." 3 | publish_to: "none" # Remove this line if you wish to publish to pub.dev 4 | 5 | version: 1.0.0+1 6 | 7 | environment: 8 | sdk: '>=3.4.0 <4.0.0' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | pro_image_editor: 15 | path: ../ 16 | 17 | intl: ^0.20.1 18 | 19 | bot_toast: ^4.1.0 20 | cupertino_icons: ^1.0.8 21 | file_picker: 8.1.4 22 | gal: ^2.3.1 23 | google_fonts: ^6.2.1 24 | file_saver: ^0.2.14 25 | firebase_core: ^3.12.1 26 | firebase_storage: ^12.4.4 27 | supabase_flutter: ^2.8.1 28 | image_background_remover: ^1.0.0 29 | image_picker: ^1.1.2 30 | mime: ^2.0.0 31 | url_launcher: ^6.3.1 32 | flutter_colorpicker: ^1.1.0 33 | vibration: ^3.1.1 34 | 35 | # Video-Editing 36 | pro_video_editor: ^0.1.0 37 | ### Choose one player below 38 | video_player: ^2.9.3 39 | chewie: ^1.11.0 40 | flick_video_player: ^0.9.0 41 | media_kit: ^1.1.11 # Primary package. 42 | media_kit_video: ^1.2.5 # For video rendering. 43 | media_kit_libs_video: ^1.0.5 # Native video dependencies. 44 | 45 | dev_dependencies: 46 | flutter_test: 47 | sdk: flutter 48 | 49 | flutter_lints: ^5.0.0 50 | import_sorter: ^4.6.0 51 | 52 | dependency_overrides: 53 | # Fix conflict with supabase 54 | mime: ^2.0.0 55 | 56 | flutter: 57 | uses-material-design: true 58 | assets: 59 | - assets/demo.png 60 | - assets/demo.mp4 61 | - assets/frame.png 62 | - assets/frame1.png 63 | - assets/google_fonts/ -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility in the flutter_test package. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | void main() {} 9 | -------------------------------------------------------------------------------- /example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/web/favicon.png -------------------------------------------------------------------------------- /example/web/flutter_bootstrap.js: -------------------------------------------------------------------------------- 1 | /* https://docs.flutter.dev/platform-integration/web/bootstrapping */ 2 | 3 | {{flutter_js}} 4 | {{flutter_build_config}} 5 | 6 | _flutter.loader.load({ 7 | serviceWorkerSettings: { 8 | serviceWorkerVersion: {{flutter_service_worker_version}}, 9 | }, 10 | onEntrypointLoaded: function (engineInitializer) { 11 | engineInitializer.initializeEngine({ 12 | useColorEmoji: true, 13 | renderer: 'canvaskit' 14 | }).then(function (appRunner) { 15 | appRunner.runApp(); 16 | }); 17 | } 18 | }); 19 | 20 | 21 | window.addEventListener('flutter-first-frame', function () { 22 | var loadingScreen = document.getElementById('loading-screen'); 23 | if (loadingScreen) { 24 | loadingScreen.style.display = 'none'; 25 | loadingScreen.remove(); 26 | } 27 | }); -------------------------------------------------------------------------------- /example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /example/web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "short_name": "example", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /example/windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /example/windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /example/windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | app_links 7 | file_saver 8 | file_selector_windows 9 | firebase_core 10 | firebase_storage 11 | gal 12 | media_kit_libs_windows_video 13 | media_kit_video 14 | pro_video_editor 15 | url_launcher_windows 16 | volume_controller 17 | ) 18 | 19 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 20 | onnxruntime 21 | ) 22 | 23 | set(PLUGIN_BUNDLED_LIBRARIES) 24 | 25 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 26 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 27 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 28 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 29 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 30 | endforeach(plugin) 31 | 32 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 33 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) 34 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 35 | endforeach(ffi_plugin) 36 | -------------------------------------------------------------------------------- /example/windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_FLUTTER_WINDOW_H_ 2 | #define RUNNER_FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "win32_window.h" 10 | 11 | // A window that does nothing but host a Flutter view. 12 | class FlutterWindow : public Win32Window { 13 | public: 14 | // Creates a new FlutterWindow hosting a Flutter view running |project|. 15 | explicit FlutterWindow(const flutter::DartProject& project); 16 | virtual ~FlutterWindow(); 17 | 18 | protected: 19 | // Win32Window: 20 | bool OnCreate() override; 21 | void OnDestroy() override; 22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 23 | LPARAM const lparam) noexcept override; 24 | 25 | private: 26 | // The project to run. 27 | flutter::DartProject project_; 28 | 29 | // The Flutter instance hosted by this window. 30 | std::unique_ptr flutter_controller_; 31 | }; 32 | 33 | #endif // RUNNER_FLUTTER_WINDOW_H_ 34 | -------------------------------------------------------------------------------- /example/windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "utils.h" 7 | 8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 9 | _In_ wchar_t *command_line, _In_ int show_command) { 10 | // Attach to console when present (e.g., 'flutter run') or create a 11 | // new console when running with a debugger. 12 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 13 | CreateAndAttachConsole(); 14 | } 15 | 16 | // Initialize COM, so that it is available for use in the library and/or 17 | // plugins. 18 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 19 | 20 | flutter::DartProject project(L"data"); 21 | 22 | std::vector command_line_arguments = 23 | GetCommandLineArguments(); 24 | 25 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); 26 | 27 | FlutterWindow window(project); 28 | Win32Window::Point origin(10, 10); 29 | Win32Window::Size size(1280, 720); 30 | if (!window.Create(L"example", origin, size)) { 31 | return EXIT_FAILURE; 32 | } 33 | window.SetQuitOnClose(true); 34 | 35 | ::MSG msg; 36 | while (::GetMessage(&msg, nullptr, 0, 0)) { 37 | ::TranslateMessage(&msg); 38 | ::DispatchMessage(&msg); 39 | } 40 | 41 | ::CoUninitialize(); 42 | return EXIT_SUCCESS; 43 | } 44 | -------------------------------------------------------------------------------- /example/windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /example/windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hm21/pro_image_editor/da1998d543d160f36b55589aeb7fa56b3237fc65/example/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /example/windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /example/windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | -------------------------------------------------------------------------------- /lib/core/constants/editor_shader_constants.dart: -------------------------------------------------------------------------------- 1 | /// The file path to the pixelate shader used in the image editor. 2 | /// 3 | /// This constant defines the location of the fragment shader file 4 | /// that is used to apply a pixelation effect to images within the 5 | /// image editor package. 6 | const kImageEditorPixelateShaderPath = 7 | 'packages/pro_image_editor/lib/shared/shaders/pixelate.frag'; 8 | -------------------------------------------------------------------------------- /lib/core/constants/editor_style_constants.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/services.dart'; 2 | 3 | /// Primary color used in the image editor interface. 4 | const kImageEditorPrimaryColor = Color(0xFF004C9E); 5 | 6 | /// Color of the bottom bar in the image editor. 7 | const kImageEditorBottomBarColor = Color(0xFFFFFFFF); 8 | 9 | /// Background color of the bottom bar in the image editor. 10 | const kImageEditorBottomBarBackground = Color(0xFF000000); 11 | 12 | /// Color of the app bar in the image editor. 13 | const kImageEditorAppBarColor = Color(0xFFFFFFFF); 14 | 15 | /// Background color of the app bar in the image editor. 16 | const kImageEditorAppBarBackground = Color(0xFF000000); 17 | 18 | /// Background color for the image editor. 19 | const kImageEditorBackground = Color(0xFF161616); 20 | 21 | /// Text color used in the image editor interface. 22 | const kImageEditorTextColor = Color(0xFFE1E1E1); 23 | 24 | /// UI overlay style for the image editor. 25 | const kImageEditorUiOverlayStyle = SystemUiOverlayStyle( 26 | statusBarColor: Color(0x42000000), 27 | statusBarIconBrightness: Brightness.light, 28 | systemNavigationBarIconBrightness: Brightness.light, 29 | statusBarBrightness: Brightness.dark, 30 | systemNavigationBarColor: Color(0xFF000000), 31 | ); 32 | -------------------------------------------------------------------------------- /lib/core/constants/editor_various_constants.dart: -------------------------------------------------------------------------------- 1 | /// Hero tag used for transitions in the Pro Image Editor. 2 | const kImageEditorHeroTag = 'Pro-Image-Editor-Hero'; 3 | -------------------------------------------------------------------------------- /lib/core/constants/editor_web_constants.dart: -------------------------------------------------------------------------------- 1 | /// The URL of the web worker script. 2 | /// 3 | /// This URL points to the JavaScript file that will be loaded by the 4 | /// [web.Worker] instance to run the web worker's code. 5 | const kImageEditorWebWorkerPath = 6 | 'assets/packages/pro_image_editor/lib/web/web_worker.dart.js'; 7 | -------------------------------------------------------------------------------- /lib/core/constants/image_constants.dart: -------------------------------------------------------------------------------- 1 | // Dart imports: 2 | import 'dart:typed_data'; 3 | 4 | /// Transparent image 5 | final kImageEditorTransparentBytes = Uint8List.fromList([ 6 | 0x89, 7 | 0x50, 8 | 0x4E, 9 | 0x47, 10 | 0x0D, 11 | 0x0A, 12 | 0x1A, 13 | 0x0A, 14 | 0x00, 15 | 0x00, 16 | 0x00, 17 | 0x0D, 18 | 0x49, 19 | 0x48, 20 | 0x44, 21 | 0x52, 22 | 0x00, 23 | 0x00, 24 | 0x00, 25 | 0x01, 26 | 0x00, 27 | 0x00, 28 | 0x00, 29 | 0x01, 30 | 0x08, 31 | 0x06, 32 | 0x00, 33 | 0x00, 34 | 0x00, 35 | 0x1F, 36 | 0x15, 37 | 0xC4, 38 | 0x89, 39 | 0x00, 40 | 0x00, 41 | 0x00, 42 | 0x0A, 43 | 0x49, 44 | 0x44, 45 | 0x41, 46 | 0x54, 47 | 0x78, 48 | 0x9C, 49 | 0x63, 50 | 0x00, 51 | 0x01, 52 | 0x00, 53 | 0x00, 54 | 0x05, 55 | 0x00, 56 | 0x01, 57 | 0x0D, 58 | 0x0A, 59 | 0x2D, 60 | 0xB4, 61 | 0x00, 62 | 0x00, 63 | 0x00, 64 | 0x00, 65 | 0x49, 66 | 0x45, 67 | 0x4E, 68 | 0x44, 69 | 0xAE, 70 | 0x42, 71 | 0x60, 72 | 0x82 73 | ]); 74 | -------------------------------------------------------------------------------- /lib/core/enums/design_mode.dart: -------------------------------------------------------------------------------- 1 | /// Enum representing design modes for an image editor. 2 | /// 3 | /// The `ImageEditorDesignMode` enum defines two design modes: Material and 4 | /// Cupertino. These design modes determine the visual style and user interface 5 | /// elements used in an image editor. 6 | /// 7 | /// - `material`: Represents the Material Design style, which is a modern 8 | /// design language developed by Google. It typically includes bold colors and 9 | /// shadows. 10 | /// - `cupertino`: Represents the Cupertino Design style, which is Apple's 11 | /// design language known for its clean and minimalistic appearance with rounded 12 | /// elements. 13 | /// 14 | /// Example Usage: 15 | /// ```dart 16 | /// // Use the Material design mode for the image editor. 17 | /// ImageEditorDesignMode designMode = ImageEditorDesignMode.material; 18 | /// 19 | /// // Use the Cupertino design mode for the image editor. 20 | /// ImageEditorDesignMode designMode = ImageEditorDesignMode.cupertino; 21 | /// ``` 22 | enum ImageEditorDesignMode { 23 | /// Represents the Material Design style. 24 | material, 25 | 26 | /// Represents the Cupertino Design style. 27 | cupertino, 28 | } 29 | -------------------------------------------------------------------------------- /lib/core/enums/editor_mode.dart: -------------------------------------------------------------------------------- 1 | /// Defines the available editor modes. 2 | enum EditorMode { 3 | /// The main editor. 4 | main, 5 | 6 | /// The paint editor. 7 | paint, 8 | 9 | /// The text editor. 10 | text, 11 | 12 | /// The crop & rotate editor. 13 | cropRotate, 14 | 15 | /// The tune editor. 16 | tune, 17 | 18 | /// The filter editor. 19 | filter, 20 | 21 | /// The blur editor. 22 | blur, 23 | 24 | /// The emoji editor. 25 | emoji, 26 | 27 | /// The sticker editor. 28 | sticker, 29 | } 30 | -------------------------------------------------------------------------------- /lib/core/enums/sub_editors_name.dart: -------------------------------------------------------------------------------- 1 | /// An enumeration representing different types of sub-editors available in the 2 | /// image editor. 3 | enum SubEditor { 4 | /// Represents the paint sub-editor. 5 | paint, 6 | 7 | /// Represents the text sub-editor. 8 | text, 9 | 10 | /// Represents the crop and rotate sub-editor. 11 | cropRotate, 12 | 13 | /// Represents the filter sub-editor. 14 | filter, 15 | 16 | /// Represents the blur sub-editor. 17 | blur, 18 | 19 | /// Represents the emoji sub-editor. 20 | emoji, 21 | 22 | /// Represents the sticker sub-editor. 23 | sticker, 24 | 25 | /// Represents the Tune sub-editor. 26 | tune, 27 | 28 | /// Represents an unknown sub-editor. 29 | unknown, 30 | } 31 | -------------------------------------------------------------------------------- /lib/core/enums/swipe_mode.dart: -------------------------------------------------------------------------------- 1 | /// An enumeration representing the modes of swipe interaction. 2 | /// 3 | /// The [SwipeMode] enum defines the possible directions for swipe gestures 4 | /// and a default state representing no swipe action. It can be used in 5 | /// applications to determine how user swipe inputs should be handled. 6 | enum SwipeMode { 7 | /// Represents an upward swipe gesture. 8 | /// 9 | /// This mode indicates that a user has swiped up on the interface, and it 10 | /// can be used to trigger actions or transitions that correspond to upward 11 | /// motion. 12 | up, 13 | 14 | /// Represents a downward swipe gesture. 15 | /// 16 | /// This mode indicates that a user has swiped down on the interface, and it 17 | /// can be used to trigger actions or transitions that correspond to downward 18 | /// motion. 19 | down, 20 | 21 | /// Represents the absence of any swipe gesture. 22 | /// 23 | /// This mode is used to indicate that no swipe action has occurred, and it 24 | /// can serve as a default state for handling swipe interactions. 25 | none, 26 | } 27 | -------------------------------------------------------------------------------- /lib/core/mixins/editor_configs_mixin.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/material.dart'; 3 | 4 | import '../models/editor_callbacks/pro_image_editor_callbacks.dart'; 5 | import '../models/editor_configs/pro_image_editor_configs.dart'; 6 | import 'converted_configs.dart'; 7 | 8 | /// A mixin providing access to simple editor configurations. 9 | mixin SimpleConfigsAccess on StatefulWidget { 10 | /// Returns the configuration options for the editor. 11 | ProImageEditorConfigs get configs; 12 | 13 | /// Returns the callbacks for the editor. 14 | ProImageEditorCallbacks get callbacks; 15 | } 16 | 17 | /// A mixin providing access to simple editor configurations within a state. 18 | mixin SimpleConfigsAccessState 19 | on State, ImageEditorConvertedConfigs { 20 | SimpleConfigsAccess get _widget => (widget as SimpleConfigsAccess); 21 | 22 | @override 23 | ProImageEditorConfigs get configs => _widget.configs; 24 | 25 | /// Returns the callbacks for the editor. 26 | ProImageEditorCallbacks get callbacks => _widget.callbacks; 27 | } 28 | -------------------------------------------------------------------------------- /lib/core/models/custom_widgets/progress_indicator_widgets.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | /// Configuration class for customizing progress indicators. 4 | class ProgressIndicatorWidgets { 5 | /// Creates a new instance of [ProgressIndicatorWidgets]. 6 | const ProgressIndicatorWidgets({ 7 | this.circularProgressIndicator, 8 | }); 9 | 10 | /// Custom widget to replace the default [CircularProgressIndicator]. 11 | final Widget? circularProgressIndicator; 12 | 13 | /// Creates a copy of this configuration with the specified overrides. 14 | ProgressIndicatorWidgets copyWith({ 15 | Widget? circularProgressIndicator, 16 | }) { 17 | return ProgressIndicatorWidgets( 18 | circularProgressIndicator: 19 | circularProgressIndicator ?? this.circularProgressIndicator, 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/core/models/editor_callbacks/emoji_editor_callbacks.dart: -------------------------------------------------------------------------------- 1 | // Project imports: 2 | import '/core/models/editor_callbacks/standalone_editor_callbacks.dart'; 3 | 4 | /// A class representing callbacks for the emoji editor. 5 | class EmojiEditorCallbacks extends StandaloneEditorCallbacks { 6 | /// Creates a new instance of [EmojiEditorCallbacks]. 7 | const EmojiEditorCallbacks({ 8 | super.onInit, 9 | super.onAfterViewInit, 10 | }); 11 | 12 | /// Creates a copy with modified editor callbacks. 13 | EmojiEditorCallbacks copyWith({ 14 | Function()? onInit, 15 | Function()? onAfterViewInit, 16 | }) { 17 | return EmojiEditorCallbacks( 18 | onInit: onInit ?? this.onInit, 19 | onAfterViewInit: onAfterViewInit ?? this.onAfterViewInit, 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/core/models/editor_configs/dialog_configs.dart: -------------------------------------------------------------------------------- 1 | import '../custom_widgets/dialog_widgets.dart'; 2 | import '../styles/dialog_style.dart'; 3 | 4 | export '../custom_widgets/dialog_widgets.dart'; 5 | export '../styles/dialog_style.dart'; 6 | 7 | /// Configuration class for customizing the dialog in the editor. 8 | class DialogConfigs { 9 | /// Creates a new instance of [DialogConfigs]. 10 | const DialogConfigs({ 11 | this.widgets = const DialogWidgets(), 12 | this.style = const DialogStyle(), 13 | }); 14 | 15 | /// Widgets used for customizing the dialogs. 16 | final DialogWidgets widgets; 17 | 18 | /// Style configuration for dialogs in the editor. 19 | final DialogStyle style; 20 | 21 | /// Creates a copy of this configuration with the specified overrides. 22 | DialogConfigs copyWith({ 23 | DialogWidgets? widgets, 24 | DialogStyle? style, 25 | }) { 26 | return DialogConfigs( 27 | widgets: widgets ?? this.widgets, 28 | style: style ?? this.style, 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/core/models/editor_configs/progress_indicator_configs.dart: -------------------------------------------------------------------------------- 1 | import '../custom_widgets/progress_indicator_widgets.dart'; 2 | 3 | export '../custom_widgets/progress_indicator_widgets.dart'; 4 | 5 | /// Configuration class for customizing progress indicators. 6 | class ProgressIndicatorConfigs { 7 | /// Creates a new instance of [ProgressIndicatorConfigs]. 8 | const ProgressIndicatorConfigs({ 9 | this.widgets = const ProgressIndicatorWidgets(), 10 | }); 11 | 12 | /// Widgets used for customizing progress indicators. 13 | final ProgressIndicatorWidgets widgets; 14 | 15 | /// Creates a copy of this configuration with the specified overrides. 16 | ProgressIndicatorConfigs copyWith({ 17 | ProgressIndicatorWidgets? widgets, 18 | }) { 19 | return ProgressIndicatorConfigs( 20 | widgets: widgets ?? this.widgets, 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/core/models/i18n/i18n_blur_editor.dart: -------------------------------------------------------------------------------- 1 | /// Internationalization (i18n) settings for the Blur Editor component. 2 | class I18nBlurEditor { 3 | /// Creates an instance of [I18nBlurEditor] with customizable 4 | /// internationalization settings. 5 | /// 6 | /// You can provide translations and messages specifically for the Blur Editor 7 | /// component of your application. Customize the text for the bottom 8 | /// navigation bar, messages such as "Blur is being applied," 9 | /// 10 | /// Example: 11 | /// 12 | /// ```dart 13 | /// I18nBlurEditor( 14 | /// applyBlurDialogMsg: 'Blur is being applied.', 15 | /// bottomNavigationBarText: 'Blur', 16 | /// done: 'Apply', 17 | /// back: 'Cancel', 18 | /// ) 19 | /// ``` 20 | const I18nBlurEditor({ 21 | this.bottomNavigationBarText = 'Blur', 22 | this.back = 'Back', 23 | this.done = 'Done', 24 | }); 25 | 26 | /// Text for the bottom navigation bar item that opens the Blur Editor. 27 | final String bottomNavigationBarText; 28 | 29 | /// Text for the "Back" button in the Blur Editor. 30 | final String back; 31 | 32 | /// Text for the "Done" button in the Blur Editor. 33 | final String done; 34 | } 35 | -------------------------------------------------------------------------------- /lib/core/models/i18n/i18n_sticker_editor.dart: -------------------------------------------------------------------------------- 1 | /// Internationalization (i18n) settings for the I18nStickerEditor Editor 2 | /// component. 3 | class I18nStickerEditor { 4 | /// Creates an instance of [I18nStickerEditor] with customizable 5 | /// internationalization settings. 6 | /// 7 | /// You can provide translations and messages specifically for the 8 | /// I18nStickerEditor Editor 9 | /// component of your application. 10 | /// 11 | /// Example: 12 | /// 13 | /// ```dart 14 | /// I18nStickerEditor( 15 | /// bottomNavigationBarText: 'I18nStickerEditor', 16 | /// ) 17 | /// ``` 18 | const I18nStickerEditor({ 19 | this.bottomNavigationBarText = 'Stickers', 20 | }); 21 | 22 | /// Text for the bottom navigation bar item that opens the I18nStickerEditor 23 | /// Editor. 24 | final String bottomNavigationBarText; 25 | } 26 | -------------------------------------------------------------------------------- /lib/core/models/icons/emoji_editor_icons.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/material.dart'; 3 | 4 | /// Customizable icons for the Emoji Editor component. 5 | class EmojiEditorIcons { 6 | /// Creates an instance of [EmojiEditorIcons] with customizable icon settings. 7 | /// 8 | /// You can provide a custom [bottomNavBar] icon to be displayed in the 9 | /// bottom navigation bar of the Emoji Editor component. If no custom icon 10 | /// is provided, the default icon is used. 11 | /// 12 | /// Example: 13 | /// 14 | /// ```dart 15 | /// EmojiEditorIcons( 16 | /// bottomNavBar: Icons.sentiment_satisfied_alt_rounded, 17 | /// ) 18 | /// ``` 19 | const EmojiEditorIcons({ 20 | this.bottomNavBar = Icons.sentiment_satisfied_alt_rounded, 21 | }); 22 | 23 | /// The icon to be displayed in the bottom navigation bar. 24 | final IconData bottomNavBar; 25 | 26 | /// Creates a copy of this `IconsEmojiEditor` object with the given fields 27 | /// replaced with new values. 28 | /// 29 | /// The [copyWith] method allows you to create a new instance of 30 | /// [EmojiEditorIcons] with some properties updated while keeping the 31 | /// others unchanged. 32 | EmojiEditorIcons copyWith({ 33 | IconData? bottomNavBar, 34 | }) { 35 | return EmojiEditorIcons( 36 | bottomNavBar: bottomNavBar ?? this.bottomNavBar, 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/core/models/icons/sticker_editor_icons.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/material.dart'; 3 | 4 | // Project imports: 5 | import '/core/ui/pro_image_editor_icons.dart'; 6 | 7 | /// Customizable icons for the Sticker Editor component. 8 | class StickerEditorIcons { 9 | /// Creates an instance of [StickerEditorIcons] with customizable icon 10 | /// settings. 11 | /// 12 | /// You can provide a custom [bottomNavBar] icon to be displayed in the 13 | /// bottom navigation bar of the Sticker Editor component. If no custom icon 14 | /// is provided, the default icon is used. 15 | /// 16 | /// Example: 17 | /// 18 | /// ```dart 19 | /// IconsStickerEditor( 20 | /// bottomNavBar: Icons.layers_outlined, 21 | /// ) 22 | /// ``` 23 | const StickerEditorIcons({ 24 | this.bottomNavBar = ProImageEditorIcons.stickers, 25 | }); 26 | 27 | /// The icon to be displayed in the bottom navigation bar. 28 | final IconData bottomNavBar; 29 | 30 | /// Creates a copy of this `IconsStickerEditor` object with the given fields 31 | /// replaced with new values. 32 | /// 33 | /// The [copyWith] method allows you to create a new instance of 34 | /// [StickerEditorIcons] with some properties updated while keeping the 35 | /// others unchanged. 36 | StickerEditorIcons copyWith({ 37 | IconData? bottomNavBar, 38 | }) { 39 | return StickerEditorIcons( 40 | bottomNavBar: bottomNavBar ?? this.bottomNavBar, 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/core/models/icons/video_editor_icons.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// Defines icon configurations for the video editor. 4 | class VideoEditorIcons { 5 | /// Creates an instance of [VideoEditorIcons]. 6 | /// 7 | /// Provides customizable icons for play, mute, and trim controls. 8 | const VideoEditorIcons({ 9 | this.playIndicator = Icons.play_arrow_rounded, 10 | this.pauseIndicator = Icons.pause_rounded, 11 | this.muteActive = Icons.volume_off_rounded, 12 | this.muteInactive = Icons.volume_up_rounded, 13 | }); 14 | 15 | /// Icon displayed when the video is playing. 16 | final IconData playIndicator; 17 | 18 | /// Icon displayed when the video is paused . 19 | final IconData pauseIndicator; 20 | 21 | /// Icon displayed when the video is muted. 22 | final IconData muteActive; 23 | 24 | /// Icon displayed when the video is not muted. 25 | final IconData muteInactive; 26 | 27 | /// Creates a copy of this instance with the given parameters overridden. 28 | VideoEditorIcons copyWith({ 29 | IconData? playIndicator, 30 | IconData? pauseIndicator, 31 | IconData? muteActive, 32 | IconData? muteInactive, 33 | }) { 34 | return VideoEditorIcons( 35 | playIndicator: playIndicator ?? this.playIndicator, 36 | muteActive: muteActive ?? this.muteActive, 37 | muteInactive: muteInactive ?? this.muteInactive, 38 | pauseIndicator: pauseIndicator ?? this.pauseIndicator, 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/core/models/init_configs/blur_editor_init_configs.dart: -------------------------------------------------------------------------------- 1 | // Project imports: 2 | import 'editor_init_configs.dart'; 3 | 4 | /// TODO: Remove deprecated callbacks 5 | 6 | /// Configuration class for initializing the blur editor. 7 | /// 8 | /// This class extends [EditorInitConfigs] and adds parameters for the image 9 | /// size and whether to return the image as a Uint8List when closing the editor. 10 | class BlurEditorInitConfigs extends EditorInitConfigs { 11 | /// Creates a new instance of [BlurEditorInitConfigs]. 12 | /// 13 | /// The [theme] parameter specifies the theme data for the editor. 14 | /// The [imageSize] parameter specifies the size of the image. 15 | /// The [convertToUint8List] parameter determines whether to return the image 16 | /// as a Uint8List when closing the editor. 17 | /// The other parameters are inherited from [EditorInitConfigs]. 18 | const BlurEditorInitConfigs({ 19 | super.configs, 20 | super.transformConfigs, 21 | super.layers, 22 | super.callbacks, 23 | super.mainImageSize, 24 | super.mainBodySize, 25 | super.appliedFilters, 26 | super.appliedTuneAdjustments, 27 | super.appliedBlurFactor, 28 | @Deprecated('Use [callbacks.onCloseEditor] instead') super.onCloseEditor, 29 | @Deprecated('Use [callbacks.onImageEditingComplete] instead') 30 | super.onImageEditingComplete, 31 | @Deprecated('Use [callbacks.onImageEditingStarted] instead') 32 | super.onImageEditingStarted, 33 | super.convertToUint8List, 34 | required super.theme, 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /lib/core/models/init_configs/filter_editor_init_configs.dart: -------------------------------------------------------------------------------- 1 | // Project imports: 2 | import 'editor_init_configs.dart'; 3 | 4 | /// TODO: Remove deprecated callbacks 5 | 6 | /// Configuration class for initializing the filter editor. 7 | /// 8 | /// This class extends [EditorInitConfigs] and adds a parameter to determine 9 | /// whether to return the image as a Uint8List when closing the editor. 10 | class FilterEditorInitConfigs extends EditorInitConfigs { 11 | /// Creates a new instance of [FilterEditorInitConfigs]. 12 | /// 13 | /// The [theme] parameter specifies the theme data for the editor. 14 | /// The [convertToUint8List] parameter determines whether to return the image 15 | /// as a Uint8List when closing the editor. 16 | /// The other parameters are inherited from [EditorInitConfigs]. 17 | const FilterEditorInitConfigs({ 18 | super.transformConfigs, 19 | super.configs, 20 | super.callbacks, 21 | super.mainImageSize, 22 | super.mainBodySize, 23 | super.layers, 24 | super.appliedFilters, 25 | super.appliedTuneAdjustments, 26 | super.appliedBlurFactor, 27 | @Deprecated('Use [callbacks.onCloseEditor] instead') super.onCloseEditor, 28 | @Deprecated('Use [callbacks.onImageEditingComplete] instead') 29 | super.onImageEditingComplete, 30 | @Deprecated('Use [callbacks.onImageEditingStarted] instead') 31 | super.onImageEditingStarted, 32 | super.convertToUint8List, 33 | required super.theme, 34 | }); 35 | } 36 | -------------------------------------------------------------------------------- /lib/core/models/init_configs/tune_editor_init_configs.dart: -------------------------------------------------------------------------------- 1 | // Project imports: 2 | import 'editor_init_configs.dart'; 3 | 4 | /// TODO: Remove deprecated callbacks 5 | 6 | /// Configuration class for initializing the tune editor. 7 | /// 8 | /// This class extends [EditorInitConfigs] and adds a parameter to determine 9 | /// whether to return the image as a Uint8List when closing the editor. 10 | class TuneEditorInitConfigs extends EditorInitConfigs { 11 | /// Creates a new instance of [TuneEditorInitConfigs]. 12 | /// 13 | /// The [theme] parameter specifies the theme data for the editor. 14 | /// The [convertToUint8List] parameter determines whether to return the image 15 | /// as a Uint8List when closing the editor. 16 | /// The other parameters are inherited from [EditorInitConfigs]. 17 | const TuneEditorInitConfigs({ 18 | super.transformConfigs, 19 | super.configs, 20 | super.callbacks, 21 | super.mainImageSize, 22 | super.mainBodySize, 23 | super.layers, 24 | super.appliedFilters, 25 | super.appliedTuneAdjustments, 26 | super.appliedBlurFactor, 27 | @Deprecated('Use [callbacks.onCloseEditor] instead') super.onCloseEditor, 28 | @Deprecated('Use [callbacks.onImageEditingComplete] instead') 29 | super.onImageEditingComplete, 30 | @Deprecated('Use [callbacks.onImageEditingStarted] instead') 31 | super.onImageEditingStarted, 32 | super.convertToUint8List, 33 | required super.theme, 34 | }); 35 | } 36 | -------------------------------------------------------------------------------- /lib/core/models/layers/enums/layer_background_mode.dart: -------------------------------------------------------------------------------- 1 | /// Enumeration for controlling the background color mode of the text layer. 2 | enum LayerBackgroundMode { 3 | /// Display only the background without affecting the text color. 4 | background, 5 | 6 | /// Display the background and change the text color. 7 | backgroundAndColor, 8 | 9 | /// Display the background and change the text color with added opacity. 10 | backgroundAndColorWithOpacity, 11 | 12 | /// Change only the text color without displaying the background. 13 | onlyColor, 14 | } 15 | -------------------------------------------------------------------------------- /lib/core/models/multi_threading/thread_response_model.dart: -------------------------------------------------------------------------------- 1 | // Dart imports: 2 | import 'dart:typed_data'; 3 | 4 | /// Represents a response containing image data from the image processing 5 | /// thread. 6 | class ThreadResponse { 7 | /// Constructs a [ThreadResponse] instance. 8 | /// 9 | /// All parameters are required. 10 | const ThreadResponse({ 11 | required this.id, 12 | required this.bytes, 13 | }); 14 | 15 | /// The unique identifier. 16 | final String id; 17 | 18 | /// The byte data of the image, can be null. 19 | final Uint8List? bytes; 20 | } 21 | -------------------------------------------------------------------------------- /lib/core/models/multi_threading/thread_task_model.dart: -------------------------------------------------------------------------------- 1 | // Dart imports: 2 | import 'dart:async'; 3 | import 'dart:typed_data'; 4 | 5 | /// Model representing a task to be processed in a separate thread. 6 | class ThreadTaskModel { 7 | /// Constructor for creating a ThreadTaskModel instance. 8 | ThreadTaskModel({ 9 | /// Unique identifier for the task. 10 | required this.taskId, 11 | 12 | /// Completer to handle asynchronous data processing. 13 | required this.bytes$, 14 | 15 | /// Identifier for the thread handling this task. 16 | required this.threadId, 17 | }); 18 | 19 | /// Unique identifier for the task. 20 | final String taskId; 21 | 22 | /// Completer for handling asynchronous byte data. 23 | final Completer bytes$; 24 | 25 | /// Identifier for the thread handling this task. 26 | final String threadId; 27 | } 28 | -------------------------------------------------------------------------------- /lib/core/models/styles/adaptive_dialog_style.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/widgets.dart'; 3 | 4 | /// A style configuration for adaptive dialogs. 5 | class AdaptiveDialogStyle { 6 | /// Constructs an [AdaptiveDialogStyle] object with the given parameters. 7 | const AdaptiveDialogStyle({ 8 | this.cupertinoPrimaryColorLight = const Color(0xFF000000), 9 | this.cupertinoPrimaryColorDark = const Color(0xFFFFFFFF), 10 | }); 11 | 12 | /// Primary color in the Cupertino design with brightness `light`. 13 | final Color cupertinoPrimaryColorLight; 14 | 15 | /// Primary color in the Cupertino design with brightness `dark`. 16 | final Color cupertinoPrimaryColorDark; 17 | 18 | /// Creates a copy of this `AdaptiveDialogStyle` object with the given fields 19 | /// replaced with new values. 20 | /// 21 | /// The [copyWith] method allows you to create a new instance of 22 | /// [AdaptiveDialogStyle] with some properties updated while keeping the 23 | /// others unchanged. 24 | AdaptiveDialogStyle copyWith({ 25 | Color? cupertinoPrimaryColorLight, 26 | Color? cupertinoPrimaryColorDark, 27 | }) { 28 | return AdaptiveDialogStyle( 29 | cupertinoPrimaryColorLight: 30 | cupertinoPrimaryColorLight ?? this.cupertinoPrimaryColorLight, 31 | cupertinoPrimaryColorDark: 32 | cupertinoPrimaryColorDark ?? this.cupertinoPrimaryColorDark, 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/core/models/styles/dialog_style.dart: -------------------------------------------------------------------------------- 1 | import 'adaptive_dialog_style.dart'; 2 | import 'loading_dialog_style.dart'; 3 | 4 | export 'adaptive_dialog_style.dart'; 5 | export 'loading_dialog_style.dart'; 6 | 7 | /// Style configuration class for dialogs used in the editor. 8 | class DialogStyle { 9 | /// Creates a new instance of [DialogStyle]. 10 | const DialogStyle({ 11 | this.loadingDialog = const LoadingDialogStyle(), 12 | this.adaptiveDialog = const AdaptiveDialogStyle(), 13 | }); 14 | 15 | /// Style configuration for the loading dialog. 16 | final LoadingDialogStyle loadingDialog; 17 | 18 | /// Style configuration for adaptive dialogs. 19 | final AdaptiveDialogStyle adaptiveDialog; 20 | 21 | /// Creates a copy of this style configuration with the specified overrides. 22 | DialogStyle copyWith({ 23 | LoadingDialogStyle? loadingDialog, 24 | AdaptiveDialogStyle? adaptiveDialog, 25 | }) { 26 | return DialogStyle( 27 | loadingDialog: loadingDialog ?? this.loadingDialog, 28 | adaptiveDialog: adaptiveDialog ?? this.adaptiveDialog, 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/core/models/styles/types/style_types.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/widgets.dart'; 3 | 4 | // Project imports: 5 | import '/core/models/editor_configs/pro_image_editor_configs.dart'; 6 | 7 | /// Creates custom [BoxConstraints] to use when displaying 8 | /// editors in modal bottom sheets. 9 | typedef EditorBoxConstraintsBuilder = BoxConstraints? Function( 10 | BuildContext context, 11 | ProImageEditorConfigs configs, 12 | ); 13 | -------------------------------------------------------------------------------- /lib/core/models/video/trim_duration_span_model.dart: -------------------------------------------------------------------------------- 1 | /// Represents a span of time within a video for trimming purposes. 2 | class TrimDurationSpan { 3 | /// Creates a [TrimDurationSpan] with a required start and end duration. 4 | const TrimDurationSpan({ 5 | required this.start, 6 | required this.end, 7 | }); 8 | 9 | /// The start time of the trim span. 10 | final Duration start; 11 | 12 | /// The end time of the trim span. 13 | final Duration end; 14 | 15 | /// Returns the total duration of the trim span. 16 | Duration get duration => end - start; 17 | } 18 | -------------------------------------------------------------------------------- /lib/core/platform/io/io_helper.dart: -------------------------------------------------------------------------------- 1 | export 'io_web.dart' if (dart.library.io) 'dart:io'; 2 | -------------------------------------------------------------------------------- /lib/core/ui/pro_image_editor_icons.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/widgets.dart'; 3 | 4 | /// A collection of custom icons used in the Pro Image Editor. 5 | class ProImageEditorIcons { 6 | ProImageEditorIcons._(); 7 | 8 | static const _kFontFam = 'ProImageEditorIcons'; 9 | static const String _kFontPkg = 'pro_image_editor'; 10 | 11 | /// Icon representing a pen with size 3. 12 | static const IconData penSize3 = 13 | IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg); 14 | 15 | /// Icon representing a pen with size 2. 16 | static const IconData penSize2 = 17 | IconData(0xe802, fontFamily: _kFontFam, fontPackage: _kFontPkg); 18 | 19 | /// Icon representing a pen with size 1. 20 | static const IconData penSize1 = 21 | IconData(0xe803, fontFamily: _kFontFam, fontPackage: _kFontPkg); 22 | 23 | /// Icon representing stickers. 24 | static const IconData stickers = 25 | IconData(0xe804, fontFamily: _kFontFam, fontPackage: _kFontPkg); 26 | } 27 | -------------------------------------------------------------------------------- /lib/core/utils/size_utils.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | /// Gets the minimum size between two sizes. 4 | /// 5 | /// This method returns the smaller of two sizes, ensuring that the resulting 6 | /// size is neither null nor empty. If the first size (`a`) 7 | /// is valid (non-null and non-empty), it is returned. 8 | /// Otherwise, the second size (`b`) is checked. If `b` is also empty, 9 | /// a default size of (1, 1) is returned. 10 | /// If `b` is valid, it is returned. 11 | Size getValidSizeOrDefault(Size? a, Size b) { 12 | return a == null || a.isEmpty 13 | ? b.isEmpty 14 | ? const Size(1, 1) 15 | : b 16 | : a; 17 | } 18 | -------------------------------------------------------------------------------- /lib/designs/frosted_glass/frosted_glass.dart: -------------------------------------------------------------------------------- 1 | export 'widgets/appbar/frosted_glass_appbar.dart'; 2 | export 'widgets/appbar/frosted_glass_blur_appbar.dart'; 3 | export 'widgets/appbar/frosted_glass_filter_appbar.dart'; 4 | export 'widgets/appbar/frosted_glass_paint_appbar.dart'; 5 | export 'widgets/appbar/frosted_glass_text_appbar.dart'; 6 | export 'widgets/appbar/frosted_glass_tune_appbar.dart'; 7 | export 'widgets/bottombar/frosted_glass_paint_bottombar.dart'; 8 | export 'widgets/bottombar/frosted_glass_text_bottombar.dart'; 9 | export 'widgets/bottombar/frosted_glass_tune_bottombar.dart'; 10 | export 'widgets/frosted_glass_close_dialog.dart'; 11 | export 'widgets/frosted_glass_crop_rotate_toolbar.dart'; 12 | export 'widgets/frosted_glass_effect.dart'; 13 | export 'widgets/frosted_glass_loading_dialog.dart'; 14 | export 'widgets/frosted_glass_sticker_editor.dart'; 15 | export 'widgets/frosted_glass_text_size_slider.dart'; 16 | -------------------------------------------------------------------------------- /lib/designs/grounded/constants/grounded_constants.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: constant_identifier_names 2 | 3 | /// The duration used for fade-in animations in the Grounded design. 4 | const kGroundedFadeInDuration = Duration(milliseconds: 220); 5 | 6 | /// The stagger delay between multiple fade-in animations in the Grounded 7 | /// design. 8 | const kGroundedFadeInStaggerDelay = Duration(milliseconds: 25); 9 | 10 | /// The height of the sub-bar used in the Grounded design. 11 | const kGroundedSubBarHeight = 65.0; 12 | -------------------------------------------------------------------------------- /lib/designs/grounded/grounded_design.dart: -------------------------------------------------------------------------------- 1 | export 'constants/grounded_constants.dart'; 2 | export 'widgets/bottombar/grounded_blur_bar.dart'; 3 | export 'widgets/bottombar/grounded_bottom_bar.dart'; 4 | export 'widgets/bottombar/grounded_crop_rotate_bar.dart'; 5 | export 'widgets/bottombar/grounded_filter_bar.dart'; 6 | export 'widgets/bottombar/grounded_main_bar.dart'; 7 | export 'widgets/bottombar/grounded_paint_bar.dart'; 8 | export 'widgets/bottombar/grounded_text_bar.dart'; 9 | export 'widgets/bottombar/grounded_tune_bar.dart'; 10 | export 'widgets/grounded_bottom_wrapper.dart'; 11 | export 'widgets/grounded_emoji_editor.dart'; 12 | export 'widgets/grounded_loading_dialog.dart'; 13 | export 'widgets/grounded_sticker_editor.dart'; 14 | export 'widgets/grounded_text_size_slider.dart'; 15 | -------------------------------------------------------------------------------- /lib/designs/whatsapp/styles/whatsapp_appbar_button_style.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/material.dart'; 3 | 4 | /// Represents the button style for WhatsApp-themed buttons. 5 | /// 6 | /// This [ButtonStyle] defines the visual appearance of buttons in a 7 | /// WhatsApp-themed style. It includes properties such as background color, 8 | /// padding, icon size, minimum size, and tap target size. 9 | final ButtonStyle whatsAppButtonStyle = IconButton.styleFrom( 10 | backgroundColor: Colors.black38, 11 | padding: const EdgeInsets.all(8), 12 | iconSize: 22, 13 | minimumSize: const Size.fromRadius(10), 14 | tapTargetSize: MaterialTapTargetSize.shrinkWrap, 15 | ); 16 | -------------------------------------------------------------------------------- /lib/designs/whatsapp/whatsapp.dart: -------------------------------------------------------------------------------- 1 | export '/features/main_editor/helpers/whats_app_helper.dart'; 2 | export 'whatsapp_crop_rotate_toolbar.dart'; 3 | export 'whatsapp_paint_colorpicker.dart'; 4 | export 'whatsapp_sticker_editor.dart'; 5 | export 'whatsapp_text_colorpicker.dart'; 6 | export 'whatsapp_text_size_slider.dart'; 7 | export 'widgets/appbar/whatsapp_appbar.dart'; 8 | export 'widgets/appbar/whatsapp_paint_appbar.dart'; 9 | export 'widgets/appbar/whatsapp_text_appbar.dart'; 10 | export 'widgets/bottombar/whatsapp_paint_bottombar.dart'; 11 | export 'widgets/bottombar/whatsapp_text_bottombar.dart'; 12 | export 'widgets/filter/whatsapp_filter_button.dart'; 13 | export 'widgets/filter/whatsapp_filters.dart'; 14 | export 'widgets/filter/whatsapp_open_filter_button.dart'; 15 | -------------------------------------------------------------------------------- /lib/features/crop_rotate_editor/enums/crop_area_part.dart: -------------------------------------------------------------------------------- 1 | /// Enumeration representing different parts of a crop area. 2 | enum CropAreaPart { 3 | /// Represents no specific part of the crop area. 4 | none, 5 | 6 | /// Represents the top-left corner of the crop area. 7 | topLeft, 8 | 9 | /// Represents the top-right corner of the crop area. 10 | topRight, 11 | 12 | /// Represents the bottom-left corner of the crop area. 13 | bottomLeft, 14 | 15 | /// Represents the bottom-right corner of the crop area. 16 | bottomRight, 17 | 18 | /// Represents the left side of the crop area. 19 | left, 20 | 21 | /// Represents the right side of the crop area. 22 | right, 23 | 24 | /// Represents the top side of the crop area. 25 | top, 26 | 27 | /// Represents the bottom side of the crop area. 28 | bottom, 29 | 30 | /// Represents the inside area of the crop. 31 | inside, 32 | } 33 | -------------------------------------------------------------------------------- /lib/features/crop_rotate_editor/enums/crop_rotate_angle_side.dart: -------------------------------------------------------------------------------- 1 | /// Enum representing different rotation angle sides. 2 | enum RotateAngleSide { 3 | /// Represents the left rotation angle side. 4 | left, 5 | 6 | /// Represents the bottom rotation angle side. 7 | bottom, 8 | 9 | /// Represents the right rotation angle side. 10 | right, 11 | 12 | /// Represents the top rotation angle side. 13 | top, 14 | } 15 | -------------------------------------------------------------------------------- /lib/features/crop_rotate_editor/models/rotate_direction.dart: -------------------------------------------------------------------------------- 1 | /// An enumeration representing the direction of rotation for an image editor. 2 | /// 3 | /// This enum defines the available directions for rotating an image, allowing 4 | /// users to specify whether to rotate left or right. 5 | enum RotateDirection { 6 | /// Rotate the image to the left. 7 | /// 8 | /// This direction specifies a counter-clockwise rotation, typically used 9 | /// when users want to rotate the image 90 degrees to the left. 10 | left, 11 | 12 | /// Rotate the image to the right. 13 | /// 14 | /// This direction specifies a clockwise rotation, typically used when users 15 | /// want to rotate the image 90 degrees to the right. 16 | right, 17 | } 18 | -------------------------------------------------------------------------------- /lib/features/crop_rotate_editor/utils/crop_aspect_ratios.dart: -------------------------------------------------------------------------------- 1 | /// A utility class containing commonly used crop aspect ratios. 2 | class CropAspectRatios { 3 | /// Represents a custom aspect ratio. 4 | /// 5 | /// Use this value when a custom aspect ratio is desired. 6 | static const double custom = -1; 7 | 8 | /// Represents the original aspect ratio. 9 | /// 10 | /// Use this value to maintain the original aspect ratio of an image or 11 | /// content. 12 | static const double original = 0; 13 | 14 | /// Represents a 1:1 aspect ratio. 15 | static const double ratio1_1 = 1; 16 | 17 | /// Represents a 4:3 aspect ratio. 18 | static const double ratio4_3 = 4 / 3; 19 | 20 | /// Represents a 3:4 aspect ratio. 21 | static const double ratio3_4 = 3 / 4; 22 | 23 | /// Represents a 16:9 aspect ratio. 24 | static const double ratio16_9 = 16 / 9; 25 | 26 | /// Represents a 9:16 aspect ratio. 27 | static const double ratio9_16 = 9 / 16; 28 | } 29 | -------------------------------------------------------------------------------- /lib/features/crop_rotate_editor/utils/rotate_angle.dart: -------------------------------------------------------------------------------- 1 | // Dart imports: 2 | import 'dart:math'; 3 | 4 | import '../enums/crop_rotate_angle_side.dart'; 5 | 6 | /// Calculates the rotation angle side based on the given angle factor. 7 | /// 8 | /// The [angleFactor] is the factor used to calculate the rotation angle side. 9 | /// It should be a value in radians. 10 | /// 11 | /// Returns a [RotateAngleSide] enum value representing the rotation angle side. 12 | RotateAngleSide getRotateAngleSide(double angleFactor) { 13 | double pi2 = pi * 2; 14 | String factor = (angleFactor % pi2).toStringAsFixed(3); 15 | 16 | if (factor == (pi * 1.5).toStringAsFixed(3)) { 17 | return RotateAngleSide.left; 18 | } else if (factor == pi.toStringAsFixed(3)) { 19 | return RotateAngleSide.bottom; 20 | } else if (factor == (pi / 2).toStringAsFixed(3)) { 21 | return RotateAngleSide.right; 22 | } else { 23 | return RotateAngleSide.top; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/features/crop_rotate_editor/widgets/outside_gestures/outside_gesture_behavior.dart: -------------------------------------------------------------------------------- 1 | /// How to behave during hit tests. 2 | enum OutsideHitTestBehavior { 3 | /// Targets that defer to their children receive events within their bounds 4 | /// only if one of their children is hit by the hit test. 5 | deferToChild, 6 | 7 | /// Opaque targets can be hit by hit tests, causing them to both receive 8 | /// events within their bounds and prevent targets visually behind them from 9 | /// also receiving events. 10 | opaque, 11 | 12 | /// Translucent targets both receive events within their bounds and permit 13 | /// targets visually behind them to also receive events. 14 | translucent, 15 | 16 | /// Targets all events even if they are outside the widget. 17 | all, 18 | } 19 | -------------------------------------------------------------------------------- /lib/features/emoji_editor/services/emoji_state_manager.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '/plugins/emoji_picker_flutter/emoji_picker_flutter.dart'; 4 | 5 | /// Manages the state of the emoji picker, including the active category. 6 | class EmojiStateManager extends InheritedWidget { 7 | /// Constructor for EmojiStateManager, accepting a key, child widget, 8 | /// active category, and a function to update the active category. 9 | const EmojiStateManager({ 10 | super.key, 11 | required super.child, 12 | required this.activeCategory, 13 | required this.setActiveCategory, 14 | }); 15 | 16 | /// The currently active emoji category. 17 | final Category activeCategory; 18 | 19 | /// Function to update the active emoji category. 20 | final Function(Category) setActiveCategory; 21 | 22 | /// Retrieves the closest [EmojiStateManager] instance in the widget tree. 23 | static EmojiStateManager? of(BuildContext context) { 24 | return context.dependOnInheritedWidgetOfExactType(); 25 | } 26 | 27 | /// Determines if the widget should notify listeners about changes. 28 | @override 29 | bool updateShouldNotify(EmojiStateManager oldWidget) { 30 | return oldWidget.activeCategory != activeCategory; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/features/filter_editor/types/filter_matrix.dart: -------------------------------------------------------------------------------- 1 | /// A typedef representing a matrix for image filtering operations. 2 | /// 3 | /// This typedef defines a two-dimensional list of doubles, used as a matrix 4 | /// for applying various image filtering transformations. Each sub-list 5 | /// represents a row in the matrix, and each element in the sub-list represents 6 | /// a coefficient used in the filtering calculation. 7 | /// 8 | /// The [FilterMatrix] is typically used in image processing to define how 9 | /// different color channels should be adjusted to achieve effects like 10 | /// brightness, contrast, saturation, and other visual modifications. 11 | /// 12 | /// Example: 13 | /// ``` 14 | /// FilterMatrix exampleMatrix = [ 15 | /// [1.0, 0.0, 0.0, 0.0, 0.0], 16 | /// [0.0, 1.0, 0.0, 0.0, 0.0], 17 | /// [0.0, 0.0, 1.0, 0.0, 0.0], 18 | /// [0.0, 0.0, 0.0, 1.0, 0.0], 19 | /// [0.0, 0.0, 0.0, 0.0, 1.0], 20 | /// ]; 21 | /// ``` 22 | /// 23 | /// In this example, the [exampleMatrix] is an identity matrix that does not 24 | /// alter the image when applied, as it keeps the color channels unchanged. 25 | typedef FilterMatrix = List>; 26 | -------------------------------------------------------------------------------- /lib/features/filter_editor/utils/filter_generator/filter_model.dart: -------------------------------------------------------------------------------- 1 | // Project imports: 2 | import '/features/filter_editor/types/filter_matrix.dart'; 3 | 4 | /// A model class that represents a filter with a name and associated filter 5 | /// matrix. 6 | class FilterModel { 7 | /// Constructs a [FilterModel] instance with the specified [name] and 8 | /// [filters]. 9 | /// 10 | /// The [name] parameter is required and represents the name of the filter. 11 | /// The [filters] parameter is required and represents the filter matrix to 12 | /// be applied. 13 | const FilterModel({ 14 | required this.name, 15 | required this.filters, 16 | }); 17 | 18 | /// The name of the filter. 19 | final String name; 20 | 21 | /// The filter matrix associated with this filter. 22 | final FilterMatrix filters; 23 | } 24 | -------------------------------------------------------------------------------- /lib/features/main_editor/widgets/main_editor_font_preloader.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/material.dart'; 3 | 4 | import '/core/models/editor_configs/emoji_editor_configs.dart'; 5 | 6 | /// A widget responsible for preloading fonts for the main editor, 7 | /// ensuring smooth rendering of text and emoji elements. 8 | class MainEditorFontPreloader extends StatelessWidget { 9 | /// Creates a `MainEditorFontPreloader` with the provided emoji editor 10 | /// configurations. 11 | /// 12 | /// - [emojiEditorConfigs]: Configuration settings related to the emoji 13 | /// editor, 14 | /// which include font settings and other necessary configurations. 15 | const MainEditorFontPreloader({ 16 | super.key, 17 | required this.emojiEditorConfigs, 18 | }); 19 | 20 | /// Configuration settings related to the emoji editor, including font 21 | /// details. 22 | final EmojiEditorConfigs emojiEditorConfigs; 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | if (kIsWeb && emojiEditorConfigs.enablePreloadWebFont) { 27 | return Offstage( 28 | child: Text('😀', style: emojiEditorConfigs.style.textStyle), 29 | ); 30 | } else { 31 | return const SizedBox.shrink(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/features/paint_editor/enums/paint_editor_enum.dart: -------------------------------------------------------------------------------- 1 | /// The `PaintMode` enum represents different paint-item modes for a drawing 2 | /// application in Flutter. 3 | enum PaintMode { 4 | /// Allows to move and zoom the editor 5 | moveAndZoom, 6 | 7 | /// Allows freehand drawing. 8 | freeStyle, 9 | 10 | /// Draws a straight line between two points. 11 | line, 12 | 13 | /// Creates a rectangle shape. 14 | rect, 15 | 16 | /// Draws a line with an arrowhead at the end point. 17 | arrow, 18 | 19 | /// Creates a circle shape starting from a point. 20 | circle, 21 | 22 | /// Draws a dashed line between two points. 23 | dashLine, 24 | 25 | /// Draws a Polygon with multiple connected lines. 26 | polygon, 27 | 28 | /// Remove paint-items when hit. 29 | eraser, 30 | 31 | /// Creates an area that blurs the background. 32 | blur, 33 | 34 | /// Creates an area that will pixelate the background. 35 | pixelate, 36 | } 37 | -------------------------------------------------------------------------------- /lib/features/paint_editor/models/paint_bottom_bar_item.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/widgets.dart'; 3 | 4 | // Project imports: 5 | import '../enums/paint_editor_enum.dart'; 6 | 7 | /// Represents a model for a paint-mode item, including an icon, a mode 8 | /// identifier, and a label. 9 | class PaintModeBottomBarItem { 10 | /// Creates a [PaintModeBottomBarItem] instance to define a paint mode. 11 | /// 12 | /// - [icon]: An optional icon to visually represent the paint mode. 13 | /// - [mode]: The identifier for the paint mode (enum value). 14 | /// - [label]: A descriptive label for the paint mode. 15 | const PaintModeBottomBarItem({ 16 | required this.icon, 17 | required this.mode, 18 | required this.label, 19 | }); 20 | 21 | /// The icon representing the paint mode. 22 | final IconData icon; 23 | 24 | /// The identifier for the paint mode. 25 | final PaintMode mode; 26 | 27 | /// A descriptive label for the paint mode. 28 | final String label; 29 | } 30 | -------------------------------------------------------------------------------- /lib/plugins/archive/NOTICES: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2013-2021 Brendan Duncan. 4 | All rights reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. -------------------------------------------------------------------------------- /lib/plugins/archive/src/codecs/zlib/_zlib_encoder.dart: -------------------------------------------------------------------------------- 1 | export '_zlib_encoder_web.dart' if (dart.library.io) '_zlib_encoder_io.dart'; 2 | -------------------------------------------------------------------------------- /lib/plugins/archive/src/codecs/zlib/_zlib_encoder_base.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import 'dart:typed_data'; 4 | import '../../utils/input_stream.dart'; 5 | import '../../utils/output_stream.dart'; 6 | 7 | abstract class ZLibEncoderBase { 8 | const ZLibEncoderBase(); 9 | 10 | Uint8List encodeBytes(List bytes, 11 | {int? level, int? windowBits, bool raw = false}); 12 | 13 | void encodeStream(InputStream input, OutputStream output, 14 | {int? level, int? windowBits, bool raw = false}); 15 | } 16 | -------------------------------------------------------------------------------- /lib/plugins/archive/src/codecs/zlib/_zlib_encoder_io.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: annotate_overrides, public_member_api_docs 2 | 3 | import 'dart:io'; 4 | import 'dart:typed_data'; 5 | 6 | import '/plugins/archive/src/utils/input_stream.dart'; 7 | import '/plugins/archive/src/utils/output_stream.dart'; 8 | 9 | import '_zlib_encoder_base.dart'; 10 | 11 | const platformZLibEncoder = _ZLibEncoder(); 12 | 13 | class _ZLibEncoder extends ZLibEncoderBase { 14 | const _ZLibEncoder(); 15 | 16 | Uint8List encodeBytes(List bytes, 17 | {int? level, int? windowBits, bool raw = false}) => 18 | ZLibCodec(level: level ?? 6, windowBits: windowBits ?? 15, raw: raw) 19 | .encode(bytes) as Uint8List; 20 | 21 | @override 22 | void encodeStream(InputStream input, OutputStream output, 23 | {int? level, int? windowBits, bool raw = false}) { 24 | throw ArgumentError('Not implemented'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/plugins/archive/src/codecs/zlib_encoder.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import 'dart:typed_data'; 4 | 5 | import 'zlib/_zlib_encoder.dart'; 6 | 7 | /// Compress data with the zlib format encoder. 8 | /// The actual encoder used will depend on the platform the code is run on. 9 | /// In a 'dart:io' based platform, like Flutter, the native ZLibCodec will 10 | /// be used to improve performance. On web platforms, a Dart implementation 11 | /// of ZLib will be used, via the [Deflate] class. 12 | /// If you want to force the use of the Dart implementation, you can use the 13 | /// [ZLibEncoderWeb] class. 14 | class ZLibEncoder { 15 | const ZLibEncoder(); 16 | 17 | static const maxWindowBits = 15; 18 | 19 | /// Compress the given [bytes] with the ZLib format. 20 | /// [level] will set the compression level to use, between 0 and 9, 6 is the 21 | /// default. 22 | Uint8List encodeBytes(List bytes, 23 | {int? level, int windowBits = maxWindowBits}) => 24 | platformZLibEncoder.encodeBytes(bytes, level: level); 25 | 26 | /// Alias for [encodeBytes], kept for backwards compatibility. 27 | List encode(List bytes, 28 | {int? level, int windowBits = maxWindowBits}) => 29 | encodeBytes(bytes, level: level, windowBits: windowBits); 30 | } 31 | -------------------------------------------------------------------------------- /lib/plugins/archive/src/utils/adler32.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import 'input_stream.dart'; 4 | 5 | int getAdler32Stream(InputStream stream, [int adler = 1]) { 6 | // largest prime smaller than 65536 7 | const base = 65521; 8 | 9 | var s1 = adler & 0xffff; 10 | var s2 = adler >> 16; 11 | var len = stream.length; 12 | while (len > 0) { 13 | var n = 3800; 14 | if (n > len) { 15 | n = len; 16 | } 17 | len -= n; 18 | while (--n >= 0) { 19 | s1 = s1 + stream.readByte(); 20 | s2 = s2 + s1; 21 | } 22 | s1 %= base; 23 | s2 %= base; 24 | } 25 | 26 | return (s2 << 16) | s1; 27 | } 28 | -------------------------------------------------------------------------------- /lib/plugins/archive/src/utils/byte_order.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | enum ByteOrder { littleEndian, bigEndian } 4 | -------------------------------------------------------------------------------- /lib/plugins/defer_pointer/NOTICES: -------------------------------------------------------------------------------- 1 | 2 | The files in the defer_pointer folder are from the 3 | [defer_pointer](https://pub.dev/packages/defer_pointer) package, 4 | created by gskinner. I have optimized some code which fit better to 5 | pro_image_editor, but these changes are not suitable for a pull request. 6 | Nonetheless, special thanks for this great package. 7 | 8 | ----------------------------------------------------------------------------- 9 | 10 | defer_pointer (0.0.2): 11 | 12 | MIT License 13 | 14 | Copyright (c) 2019 gskinner.com 15 | 16 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /lib/plugins/defer_pointer/deferred_pointer_handler_link.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | part of 'defer_pointer.dart'; 4 | 5 | /// Holds a list of [DeferPointerRenderObject]s which the 6 | /// [DeferredPointerHandler] widget uses to perform hit tests. 7 | class DeferredPointerHandlerLink extends ChangeNotifier { 8 | DeferredPointerHandlerLink(); 9 | final List _painters = []; 10 | 11 | void descendantNeedsPaint() => notifyListeners(); 12 | 13 | /// All painters currently attached to this link 14 | List get painters => 15 | UnmodifiableListView(_painters); 16 | 17 | /// Add a render object to the link. Does nothing if item already exists. 18 | void add(DeferPointerRenderObject value) { 19 | if (!_painters.contains(value)) { 20 | _painters.add(value); 21 | notifyListeners(); 22 | } 23 | } 24 | 25 | /// Remove a render object from the link. Does nothing if item is not in list. 26 | void remove(DeferPointerRenderObject value) { 27 | if (_painters.contains(value)) { 28 | _painters.remove(value); 29 | notifyListeners(); 30 | } 31 | } 32 | 33 | /// Clears all currently attached links 34 | void removeAll() { 35 | _painters.clear(); 36 | notifyListeners(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/NOTICES: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Stefan Humm 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/locales/default_emoji_set_locale.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '/plugins/emoji_picker_flutter/emoji_picker_flutter.dart'; 4 | 5 | /// Default method for locale selection 6 | List getDefaultEmojiLocale(Locale locale) { 7 | switch (locale.languageCode) { 8 | case 'de': 9 | return emojiSetGerman; 10 | case 'en': 11 | return emojiSetEnglish; 12 | case 'es': 13 | return emojiSetSpanish; 14 | case 'fr': 15 | return emojiSetFrance; 16 | case 'hi': 17 | return emojiSetHindi; 18 | case 'it': 19 | return emojiSetItalian; 20 | case 'ja': 21 | return emojiSetJapanese; 22 | case 'pt': 23 | return emojiSetPortuguese; 24 | case 'ru': 25 | return emojiSetRussian; 26 | case 'zh': 27 | return emojiSetChinese; 28 | default: 29 | return emojiSetEnglish; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/locales/emoji_set.dart: -------------------------------------------------------------------------------- 1 | export 'emoji_set_de.dart'; 2 | export 'emoji_set_en.dart'; 3 | export 'emoji_set_es.dart'; 4 | export 'emoji_set_fr.dart'; 5 | export 'emoji_set_hi.dart'; 6 | export 'emoji_set_it.dart'; 7 | export 'emoji_set_ja.dart'; 8 | export 'emoji_set_pt.dart'; 9 | export 'emoji_set_ru.dart'; 10 | export 'emoji_set_zh.dart'; 11 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/bottom_action_bar/bottom_action_bar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '/plugins/emoji_picker_flutter/emoji_picker_flutter.dart'; 4 | 5 | /// Template class for custom implementation 6 | abstract class BottomActionBar extends StatefulWidget { 7 | /// Constructor 8 | const BottomActionBar( 9 | this.config, 10 | this.state, 11 | this.showSearchView, { 12 | super.key, 13 | }); 14 | 15 | /// Config for customizations 16 | final Config config; 17 | 18 | /// State that holds current emoji data 19 | final EmojiViewState state; 20 | 21 | /// Show Search Bar 22 | final VoidCallback showSearchView; 23 | } 24 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/category_view/category_emoji.dart: -------------------------------------------------------------------------------- 1 | import '/plugins/emoji_picker_flutter/emoji_picker_flutter.dart'; 2 | 3 | /// Container for Category and their emoji 4 | class CategoryEmoji { 5 | /// Constructor 6 | const CategoryEmoji(this.category, this.emoji); 7 | 8 | /// Category instance 9 | final Category category; 10 | 11 | /// List of emoji of this category 12 | final List emoji; 13 | 14 | /// Copy method 15 | CategoryEmoji copyWith({Category? category, List? emoji}) { 16 | return CategoryEmoji( 17 | category ?? this.category, 18 | emoji ?? this.emoji, 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/category_view/category_extra_tab.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: constant_identifier_names 2 | 3 | /// Behavior of extra tab 4 | enum CategoryExtraTab { 5 | /// Don't show extra tab 6 | NONE, 7 | 8 | /// Display backspace button in tab bar 9 | BACKSPACE, 10 | 11 | /// Display search button in tab bar 12 | SEARCH, 13 | } 14 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/category_view/category_icon.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// Class that defines the icon representing a [Category] 4 | class CategoryIcon { 5 | /// Icon of Category 6 | const CategoryIcon({ 7 | required this.icon, 8 | this.color = const Color.fromRGBO(211, 211, 211, 1), 9 | this.selectedColor = const Color.fromRGBO(178, 178, 178, 1), 10 | }); 11 | 12 | /// The icon to represent the category 13 | final IconData icon; 14 | 15 | /// The default color of the icon 16 | final Color color; 17 | 18 | /// The color of the icon once the category is selected 19 | final Color selectedColor; 20 | } 21 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/category_view/category_icons.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// Class used to define all the [CategoryIcon] shown for each [Category] 4 | /// 5 | /// This allows the keyboard to be personalized by changing icons shown. 6 | /// If a [CategoryIcon] is set as null or not defined during initialization, 7 | /// the default icons will be used instead 8 | class CategoryIcons { 9 | /// Constructor 10 | const CategoryIcons({ 11 | this.recentIcon = Icons.access_time, 12 | this.smileyIcon = Icons.tag_faces, 13 | this.animalIcon = Icons.pets, 14 | this.foodIcon = Icons.fastfood, 15 | this.activityIcon = Icons.directions_run, 16 | this.travelIcon = Icons.location_city, 17 | this.objectIcon = Icons.lightbulb_outline, 18 | this.symbolIcon = Icons.emoji_symbols, 19 | this.flagIcon = Icons.flag, 20 | }); 21 | 22 | /// Icon for [Category.RECENT] 23 | final IconData recentIcon; 24 | 25 | /// Icon for [Category.SMILEYS] 26 | final IconData smileyIcon; 27 | 28 | /// Icon for [Category.ANIMALS] 29 | final IconData animalIcon; 30 | 31 | /// Icon for [Category.FOODS] 32 | final IconData foodIcon; 33 | 34 | /// Icon for [Category.ACTIVITIES] 35 | final IconData activityIcon; 36 | 37 | /// Icon for [Category.TRAVEL] 38 | final IconData travelIcon; 39 | 40 | /// Icon for [Category.OBJECTS] 41 | final IconData objectIcon; 42 | 43 | /// Icon for [Category.SYMBOLS] 44 | final IconData symbolIcon; 45 | 46 | /// Icon for [Category.FLAGS] 47 | final IconData flagIcon; 48 | } 49 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/category_view/recent_tab_behavior.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: constant_identifier_names 2 | 3 | /// Behavior of Recent Tab 4 | enum RecentTabBehavior { 5 | /// Don't show Recent Tab 6 | NONE, 7 | 8 | /// Display the last used emoji at the top of the list 9 | RECENT, 10 | 11 | /// Display the most often used emoji at the top of the list 12 | POPULAR, 13 | } 14 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/emoji_text_style.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// Emoji text style providing commonly available fallback fonts 4 | // ignore: constant_identifier_names 5 | const DefaultEmojiTextStyle = TextStyle( 6 | inherit: true, 7 | // Commonly available fallback fonts. 8 | fontFamilyFallback: [ 9 | // iOS and MacOs. 10 | 'Apple Color Emoji', 11 | // Android, ChromeOS, Ubuntu and some other Linux distros. 12 | 'Noto Color Emoji', 13 | // Windows. 14 | 'Segoe UI Emoji', 15 | ], 16 | ); 17 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/emoji_view/emoji_container.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '/plugins/emoji_picker_flutter/src/emoji_picker.dart'; 4 | 5 | /// A wrapper around a grid or list of emojis. 6 | /// If the button style is Cupertino or None, this is just wrapping the 7 | /// `child` with a container of a provided color. 8 | /// For Material style it is a `Material` widget that allows to render 9 | /// touch response for individual InkWell cells. 10 | class EmojiContainer extends StatelessWidget { 11 | /// Constructor 12 | const EmojiContainer({ 13 | super.key, 14 | required this.color, 15 | required this.buttonMode, 16 | this.padding, 17 | required this.child, 18 | }); 19 | 20 | /// Background color for container 21 | final Color color; 22 | 23 | /// Button mode that affects the type of container 24 | final ButtonMode buttonMode; 25 | 26 | /// Optional padding 27 | final EdgeInsets? padding; 28 | 29 | /// Child widget 30 | final Widget child; 31 | 32 | @override 33 | Widget build(BuildContext context) { 34 | if (buttonMode == ButtonMode.MATERIAL) { 35 | return Material( 36 | color: color, 37 | child: padding == null 38 | ? child 39 | : Padding( 40 | padding: padding!, 41 | child: child, 42 | ), 43 | ); 44 | } else { 45 | return Container( 46 | color: color, 47 | padding: padding, 48 | child: child, 49 | ); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/emoji_view/emoji_picker_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '/plugins/emoji_picker_flutter/src/config.dart'; 4 | import '/plugins/emoji_picker_flutter/src/emoji_view_state.dart'; 5 | 6 | /// Template class for custom implementation 7 | /// Inhert this class to create your own EmojiPicker 8 | abstract class EmojiPickerView extends StatefulWidget { 9 | /// Constructor 10 | const EmojiPickerView( 11 | this.config, 12 | this.state, 13 | this.showSearchBar, { 14 | super.key, 15 | }); 16 | 17 | /// Config for customizations 18 | final Config config; 19 | 20 | /// State that holds current emoji data 21 | final EmojiViewState state; 22 | 23 | /// Show Search Bar 24 | final VoidCallback showSearchBar; 25 | } 26 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/emoji_view_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '/plugins/emoji_picker_flutter/emoji_picker_flutter.dart'; 4 | 5 | /// State that holds current emoji data 6 | class EmojiViewState { 7 | /// Constructor 8 | EmojiViewState( 9 | this.categoryEmoji, 10 | this.onEmojiSelected, 11 | this.onBackspacePressed, 12 | this.onBackspaceLongPressed, 13 | this.onShowSearchView, 14 | ); 15 | 16 | /// List of all category including their emoji 17 | final List categoryEmoji; 18 | 19 | /// Callback when pressed on emoji 20 | final OnEmojiSelected onEmojiSelected; 21 | 22 | /// Callback when pressed on backspace 23 | final OnBackspacePressed? onBackspacePressed; 24 | 25 | /// Callback when long pressed on backspace 26 | final OnBackspaceLongPressed onBackspaceLongPressed; 27 | 28 | /// Callback when pressed on search 29 | final VoidCallback onShowSearchView; 30 | } 31 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/recent_emoji.dart: -------------------------------------------------------------------------------- 1 | import '/plugins/emoji_picker_flutter/src/emoji.dart'; 2 | 3 | /// Class that holds an recent emoji 4 | /// Recent Emoji has an instance of the emoji 5 | /// And a counter, which counts how often this emoji 6 | /// has been used before 7 | class RecentEmoji { 8 | /// Constructor 9 | RecentEmoji(this.emoji, this.counter); 10 | 11 | /// Emoji instance 12 | final Emoji emoji; 13 | 14 | /// Counter how often emoji has been used before 15 | int counter = 0; 16 | 17 | /// Parse RecentEmoji from json 18 | static RecentEmoji fromJson(dynamic json) { 19 | return RecentEmoji( 20 | Emoji.fromJson(json['emoji'] as Map), 21 | json['counter'] as int, 22 | ); 23 | } 24 | 25 | /// Encode RecentEmoji to json 26 | Map toJson() => { 27 | 'emoji': emoji, 28 | 'counter': counter, 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/skin_tones/emoji_skin_tones.dart: -------------------------------------------------------------------------------- 1 | /// Alternative skin tones of Emoji 2 | class SkinTone { 3 | SkinTone._(); 4 | 5 | /// Light Skin Tone 6 | static const String light = '🏻'; 7 | 8 | /// Medium-Light Skin Tone 9 | static const String mediumLight = '🏼'; 10 | 11 | /// Medium Skin Tone 12 | static const String medium = '🏽'; 13 | 14 | /// Medium-Dark Skin Tone 15 | static const String mediumDark = '🏾'; 16 | 17 | /// Dark Skin Tone 18 | static const String dark = '🏿'; 19 | 20 | /// Return all values as Array 21 | static const values = [light, mediumLight, medium, mediumDark, dark]; 22 | } 23 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/skin_tones/skin_tone_config.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// Skin tone config Config 4 | class SkinToneConfig { 5 | /// Constructor 6 | const SkinToneConfig({ 7 | this.enabled = true, 8 | this.dialogBackgroundColor = Colors.white, 9 | this.indicatorColor = Colors.grey, 10 | }); 11 | 12 | /// Enable feature to select a skin tone of certain emoji's 13 | final bool enabled; 14 | 15 | /// The background color of the skin tone dialog 16 | final Color dialogBackgroundColor; 17 | 18 | /// Color of the small triangle next to multiple skin tone emoji 19 | final Color indicatorColor; 20 | 21 | @override 22 | bool operator ==(other) { 23 | return (other is SkinToneConfig) && 24 | other.enabled == enabled && 25 | other.dialogBackgroundColor == dialogBackgroundColor && 26 | other.indicatorColor == indicatorColor; 27 | } 28 | 29 | @override 30 | int get hashCode => 31 | enabled.hashCode ^ 32 | dialogBackgroundColor.hashCode ^ 33 | indicatorColor.hashCode; 34 | } 35 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/view_order_config.dart: -------------------------------------------------------------------------------- 1 | /// View order config 2 | class ViewOrderConfig { 3 | /// Constructor 4 | const ViewOrderConfig({ 5 | this.top = EmojiPickerItem.categoryBar, 6 | this.middle = EmojiPickerItem.emojiView, 7 | this.bottom = EmojiPickerItem.searchBar, 8 | }) : assert(!identical(top, middle) && 9 | !identical(top, bottom) && 10 | !identical(middle, bottom)); 11 | 12 | /// First item 13 | final EmojiPickerItem top; 14 | 15 | /// Middle item 16 | final EmojiPickerItem middle; 17 | 18 | /// Last item 19 | final EmojiPickerItem bottom; 20 | 21 | @override 22 | bool operator ==(other) { 23 | return (other is ViewOrderConfig) && 24 | other.top == top && 25 | other.middle == middle && 26 | other.bottom == bottom; 27 | } 28 | 29 | @override 30 | int get hashCode => top.hashCode ^ middle.hashCode ^ bottom.hashCode; 31 | } 32 | 33 | /// Widgets shown in `EmojiPicker` view 34 | enum EmojiPickerItem { 35 | /// The tab bar to choose between different emoji categories 36 | categoryBar, 37 | 38 | /// The area that shows emojis 39 | emojiView, 40 | 41 | /// The search bar to search emojis 42 | searchBar, 43 | } 44 | -------------------------------------------------------------------------------- /lib/plugins/emoji_picker_flutter/src/widgets/search_button.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '/plugins/emoji_picker_flutter/emoji_picker_flutter.dart'; 4 | 5 | /// Search Button Widget 6 | class SearchButton extends StatelessWidget { 7 | /// Constructor 8 | const SearchButton(this.config, this.showSearchView, this.buttonIconColor, 9 | {super.key}); 10 | 11 | /// Config 12 | final Config config; 13 | 14 | /// Show search view callback 15 | final VoidCallback showSearchView; 16 | 17 | /// Button icon color 18 | final Color buttonIconColor; 19 | 20 | @override 21 | Widget build(BuildContext context) { 22 | return IconButton( 23 | onPressed: showSearchView, 24 | icon: config.customSearchIcon ?? 25 | Icon( 26 | Icons.search, 27 | color: buttonIconColor, 28 | ), 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/plugins/image/NOTICES: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2013-2022 Brendan Duncan. 4 | All rights reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. -------------------------------------------------------------------------------- /lib/plugins/image/src/color/channel.dart: -------------------------------------------------------------------------------- 1 | /// A channel of a color 2 | enum Channel { 3 | /// Red channel 4 | red, 5 | 6 | /// Green channel 7 | green, 8 | 9 | /// Blue channel 10 | blue, 11 | 12 | /// Alpha channel 13 | alpha, 14 | 15 | /// Luminance is not an actual channel, it is the brightness value of the 16 | /// color. 17 | luminance 18 | } 19 | -------------------------------------------------------------------------------- /lib/plugins/image/src/color/channel_iterator.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import 'color.dart'; 4 | 5 | /// An iterator over the channels of a [Color]. 6 | class ChannelIterator implements Iterator { 7 | ChannelIterator(this.color); 8 | int index = -1; 9 | Color color; 10 | 11 | @override 12 | bool moveNext() { 13 | index++; 14 | return index < color.length; 15 | } 16 | 17 | @override 18 | num get current => color[index]; 19 | } 20 | -------------------------------------------------------------------------------- /lib/plugins/image/src/color/channel_order.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | /// Ordering of the channels in a pixel, used with Image.fromBytes and 4 | /// Image.getBytes to support alternative channel ordering. 5 | enum ChannelOrder { 6 | rgba, 7 | bgra, 8 | abgr, 9 | argb, 10 | rgb, 11 | bgr, 12 | grayAlpha, 13 | red, 14 | } 15 | 16 | /// The number of channels for each ChannelOrder. 17 | const channelOrderLength = { 18 | ChannelOrder.rgba: 4, 19 | ChannelOrder.bgra: 4, 20 | ChannelOrder.abgr: 4, 21 | ChannelOrder.argb: 4, 22 | ChannelOrder.rgb: 3, 23 | ChannelOrder.bgr: 3, 24 | ChannelOrder.grayAlpha: 2, 25 | ChannelOrder.red: 1 26 | }; 27 | -------------------------------------------------------------------------------- /lib/plugins/image/src/formats/cur_encoder.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import '../util/point.dart'; 4 | import 'ico_encoder.dart'; 5 | 6 | class CurEncoder extends WinEncoder { 7 | CurEncoder({this.hotSpots}); 8 | 9 | /// Number of image mapped with x and y hotspot coordinates 10 | Map? hotSpots; 11 | 12 | @override 13 | int colorPlanesOrXHotSpot(int index) { 14 | if (hotSpots != null) { 15 | if (hotSpots!.containsKey(index)) { 16 | return hotSpots![index]!.xi; 17 | } 18 | } 19 | return 0; 20 | } 21 | 22 | @override 23 | int bitsPerPixelOrYHotSpot(int index) { 24 | if (hotSpots != null) { 25 | if (hotSpots!.containsKey(index)) { 26 | return hotSpots![index]!.yi; 27 | } 28 | } 29 | return 0; 30 | } 31 | 32 | @override 33 | int get type => 2; 34 | } 35 | -------------------------------------------------------------------------------- /lib/plugins/image/src/formats/decode_info.dart: -------------------------------------------------------------------------------- 1 | import '../color/color.dart'; 2 | 3 | /// Provides information about the image being decoded. 4 | abstract class DecodeInfo { 5 | /// The width of the image canvas. 6 | int get width; 7 | 8 | /// The height of the image canvas. 9 | int get height; 10 | 11 | /// The suggested background color of the canvas. 12 | Color? get backgroundColor; 13 | 14 | /// The number of frames that can be decoded. 15 | int get numFrames; 16 | } 17 | -------------------------------------------------------------------------------- /lib/plugins/image/src/formats/encoder.dart: -------------------------------------------------------------------------------- 1 | import 'dart:typed_data'; 2 | 3 | import '../image/image.dart'; 4 | 5 | /// Base class for image format encoders. 6 | abstract class Encoder { 7 | /// Encode an [image] to an image format. 8 | /// If [singleFrame] is true, only the one Image will be encoded; 9 | /// otherwise if image has animation, all frames of the [image] will be 10 | /// encoded if the encoder supports animation. 11 | Uint8List encode(Image image, {bool singleFrame = false}); 12 | 13 | /// True if the encoder supports animated Images; otherwise false. 14 | bool get supportsAnimation => false; 15 | } 16 | -------------------------------------------------------------------------------- /lib/plugins/image/src/formats/jpeg/jpeg_chroma.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | /// JPEG Chroma (sub)sampling format. 4 | enum JpegChroma { 5 | yuv444, 6 | yuv420, 7 | } 8 | -------------------------------------------------------------------------------- /lib/plugins/image/src/formats/png/png_filter.dart: -------------------------------------------------------------------------------- 1 | // ignore: public_member_api_docs 2 | enum PngFilter { none, sub, up, average, paeth } 3 | -------------------------------------------------------------------------------- /lib/plugins/image/src/formats/png/png_frame.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import '../../util/_internal.dart'; 4 | 5 | enum PngDisposeMode { none, background, previous } 6 | 7 | enum PngBlendMode { source, over } 8 | 9 | // Decodes a frame from a PNG animation. 10 | class PngFrame { 11 | PngFrame( 12 | {this.sequenceNumber = 0, 13 | this.width = 0, 14 | this.height = 0, 15 | this.xOffset = 0, 16 | this.yOffset = 0, 17 | this.delayNum = 0, 18 | this.delayDen = 0, 19 | this.dispose = PngDisposeMode.none, 20 | this.blend = PngBlendMode.source}); 21 | int sequenceNumber; 22 | int width; 23 | int height; 24 | int xOffset; 25 | int yOffset; 26 | int delayNum; 27 | int delayDen; 28 | PngDisposeMode dispose; 29 | PngBlendMode blend; 30 | 31 | double get delay => delayNum == 0 || delayDen == 0 ? 0 : delayNum / delayDen; 32 | } 33 | 34 | @internal 35 | class InternalPngFrame extends PngFrame { 36 | InternalPngFrame( 37 | {super.sequenceNumber, 38 | super.width, 39 | super.height, 40 | super.xOffset, 41 | super.yOffset, 42 | super.delayNum, 43 | super.delayDen, 44 | super.dispose, 45 | super.blend}); 46 | 47 | final fdat = []; 48 | } 49 | -------------------------------------------------------------------------------- /lib/plugins/image/src/formats/pvr/pvr_color_bounding_box.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import 'pvr_color.dart'; 4 | 5 | class PvrColorBoundingBox> { 6 | PvrColorBoundingBox(PvrColor min, PvrColor max) 7 | : min = min.copy(), 8 | max = max.copy(); 9 | PvrColor min; 10 | PvrColor max; 11 | 12 | void add(PvrColor c) { 13 | min.setMin(c); 14 | max.setMax(c); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/plugins/image/src/formats/tiff/tiff_bit_reader.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import '../../util/input_buffer.dart'; 4 | 5 | class TiffBitReader { 6 | TiffBitReader(this.input); 7 | InputBuffer input; 8 | 9 | int readByte() => readBits(8); 10 | 11 | // Read a number of bits from the input stream. 12 | int readBits(int numBits) { 13 | if (numBits == 0) { 14 | return 0; 15 | } 16 | 17 | if (_bitPos == 0) { 18 | _bitPos = 8; 19 | _bitBuffer = input.readByte(); 20 | } 21 | 22 | var value = 0; 23 | 24 | while (numBits > _bitPos) { 25 | value = (value << _bitPos) + (_bitBuffer & _bitMask[_bitPos]); 26 | numBits -= _bitPos; 27 | _bitPos = 8; 28 | _bitBuffer = input.readByte(); 29 | } 30 | 31 | if (numBits > 0) { 32 | if (_bitPos == 0) { 33 | _bitPos = 8; 34 | _bitBuffer = input.readByte(); 35 | } 36 | 37 | value = (value << numBits) + 38 | (_bitBuffer >> (_bitPos - numBits) & _bitMask[numBits]); 39 | 40 | _bitPos -= numBits; 41 | } 42 | 43 | return value; 44 | } 45 | 46 | // Flush the rest of the bits in the buffer so the next read starts at the 47 | // next byte. 48 | void flushByte() { 49 | _bitPos = 0; 50 | } 51 | 52 | int _bitBuffer = 0; 53 | int _bitPos = 0; 54 | 55 | static const List _bitMask = [0, 1, 3, 7, 15, 31, 63, 127, 255]; 56 | } 57 | -------------------------------------------------------------------------------- /lib/plugins/image/src/formats/tiff/tiff_info.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import '../../color/color.dart'; 4 | import '../../formats/decode_info.dart'; 5 | import 'tiff_image.dart'; 6 | 7 | class TiffInfo implements DecodeInfo { 8 | @override 9 | int width = 0; 10 | @override 11 | int height = 0; 12 | bool? bigEndian; 13 | int? signature; 14 | 15 | int? ifdOffset; 16 | List images = []; 17 | 18 | @override 19 | int get numFrames => images.length; 20 | 21 | @override 22 | Color? get backgroundColor => null; 23 | } 24 | -------------------------------------------------------------------------------- /lib/plugins/image/src/image/icc_profile.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import 'dart:typed_data'; 4 | 5 | import '/plugins/archive/src/codecs/zlib_encoder.dart'; 6 | 7 | enum IccProfileCompression { none, deflate } 8 | 9 | /// ICC Profile data stored with an image. 10 | class IccProfile { 11 | IccProfile(this.name, this.compression, this.data); 12 | 13 | IccProfile.from(IccProfile other) 14 | : name = other.name, 15 | compression = other.compression, 16 | data = other.data.sublist(0); 17 | String name = ''; 18 | IccProfileCompression compression; 19 | Uint8List data; 20 | 21 | IccProfile clone() => IccProfile.from(this); 22 | 23 | /// Returns the compressed data of the ICC Profile, compressing the stored 24 | /// data as necessary. 25 | Uint8List compressed() { 26 | if (compression == IccProfileCompression.deflate) { 27 | return data; 28 | } 29 | data = const ZLibEncoder().encode(data) as Uint8List; 30 | compression = IccProfileCompression.deflate; 31 | return data; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/plugins/image/src/image/interpolation.dart: -------------------------------------------------------------------------------- 1 | /// Interpolation method to use when resizing images. 2 | enum Interpolation { 3 | /// Select the closest pixel. Fastest, lowest quality. 4 | nearest, 5 | 6 | /// Linearly blend between the neighboring pixels. 7 | linear, 8 | 9 | /// Cubic blend between the neighboring pixels. Slowest, highest Quality. 10 | cubic, 11 | 12 | /// Average the colors of the neighboring pixels. 13 | average 14 | } 15 | -------------------------------------------------------------------------------- /lib/plugins/image/src/image/palette_undefined.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import 'dart:typed_data'; 4 | 5 | import '../color/format.dart'; 6 | import 'palette.dart'; 7 | 8 | class PaletteUndefined extends Palette { 9 | PaletteUndefined() : super(0, 0); 10 | @override 11 | PaletteUndefined clone() => PaletteUndefined(); 12 | @override 13 | int get lengthInBytes => 0; 14 | @override 15 | Format get format => Format.uint8; 16 | @override 17 | int get maxChannelValue => 0; 18 | @override 19 | ByteBuffer get buffer => Uint8List(0).buffer; 20 | @override 21 | void set(int index, int channel, num value) {} 22 | @override 23 | void setRgb(int index, num r, num g, num b) {} 24 | @override 25 | void setRgba(int index, num r, num g, num b, num a) {} 26 | @override 27 | num get(int index, int channel) => 0; 28 | @override 29 | num getRed(int index) => 0; 30 | @override 31 | num getGreen(int index) => 0; 32 | @override 33 | num getBlue(int index) => 0; 34 | @override 35 | num getAlpha(int index) => 0; 36 | @override 37 | void setRed(int index, num value) {} 38 | @override 39 | void setGreen(int index, num value) {} 40 | @override 41 | void setBlue(int index, num value) {} 42 | @override 43 | void setAlpha(int index, num value) {} 44 | } 45 | -------------------------------------------------------------------------------- /lib/plugins/image/src/image/pixel_range_iterator.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import 'pixel.dart'; 4 | 5 | class PixelRangeIterator implements Iterator { 6 | PixelRangeIterator(this.pixel, int x, int y, int width, int height) 7 | : x1 = x, 8 | y1 = y, 9 | x2 = x + width - 1, 10 | y2 = y + height - 1 { 11 | pixel.setPosition(x - 1, y); 12 | } 13 | Pixel pixel; 14 | int x1; 15 | int y1; 16 | int x2; 17 | int y2; 18 | 19 | @override 20 | bool moveNext() { 21 | if ((pixel.x + 1) > x2) { 22 | pixel.setPosition(x1, pixel.y + 1); 23 | return pixel.y <= y2; 24 | } 25 | return pixel.moveNext(); 26 | } 27 | 28 | @override 29 | Pixel get current => pixel; 30 | } 31 | -------------------------------------------------------------------------------- /lib/plugins/image/src/util/_cast.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import 'dart:typed_data'; 4 | 5 | Uint8List castToUint8List(T data) => 6 | data is Uint8List ? data : data as Uint8List; 7 | -------------------------------------------------------------------------------- /lib/plugins/image/src/util/_internal.dart: -------------------------------------------------------------------------------- 1 | /// Annotates a function or class that's for internal use within the image 2 | /// library and is not to be exported as part of the main API. 3 | const internal = _Internal(); 4 | 5 | class _Internal { 6 | const _Internal(); 7 | } 8 | -------------------------------------------------------------------------------- /lib/plugins/image/src/util/image_exception.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | /// An exception thrown when there was a problem in the image library. 4 | class ImageException implements Exception { 5 | ImageException(this.message); 6 | 7 | /// A message describing the error. 8 | final String message; 9 | 10 | @override 11 | String toString() => 'ImageException: $message'; 12 | } 13 | -------------------------------------------------------------------------------- /lib/plugins/image/src/util/point.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | /// 2-dimensional point 4 | class Point { 5 | Point([this.x = 0, this.y = 0]); 6 | 7 | Point.from(Point other) 8 | : x = other.x, 9 | y = other.y; 10 | num x; 11 | num y; 12 | 13 | int get xi => x.toInt(); 14 | int get yi => y.toInt(); 15 | 16 | Point operator *(double s) => Point(x * s, y * s); 17 | 18 | Point operator +(Point rhs) => Point(x + rhs.x, y + rhs.y); 19 | 20 | @override 21 | bool operator ==(Object other) => 22 | other is Point && x == other.x && y == other.y; 23 | 24 | @override 25 | int get hashCode => x.hashCode ^ y.hashCode; 26 | } 27 | -------------------------------------------------------------------------------- /lib/plugins/image/src/util/quantizer.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | import '../color/color.dart'; 4 | import '../image/image.dart'; 5 | import '../image/palette.dart'; 6 | 7 | enum QuantizerType { octree, neural, binary } 8 | 9 | /// Abstract class for color quantizers, which reduce the total number of colors 10 | /// used by an image to a given maximum, used to convert images to palette 11 | /// images. 12 | abstract class Quantizer { 13 | Palette get palette; 14 | 15 | /// Find the index of the closest color to [c] in the colorMap. 16 | Color getQuantizedColor(Color c); 17 | 18 | int getColorIndex(Color c); 19 | 20 | int getColorIndexRgb(int r, int g, int b); 21 | 22 | /// Convert the [image] to a palette image. 23 | Image getIndexImage(Image image) { 24 | final target = Image( 25 | width: image.width, 26 | height: image.height, 27 | numChannels: 1, 28 | palette: palette); 29 | 30 | final ti = target.iterator..moveNext(); 31 | target 32 | ..frameIndex = image.frameIndex 33 | ..frameType = image.frameType 34 | ..frameDuration = image.frameDuration; 35 | 36 | for (final p in image) { 37 | final t = ti.current; 38 | t[0] = getColorIndex(p); 39 | ti.moveNext(); 40 | } 41 | 42 | return target; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/plugins/image/src/util/rational.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: public_member_api_docs 2 | 3 | /// Represents a floating-point number in rational form of [numerator] 4 | /// and [denominator]. 5 | class Rational { 6 | Rational(this.numerator, this.denominator); 7 | int numerator; 8 | int denominator; 9 | 10 | void simplify() { 11 | final d = numerator.gcd(denominator); 12 | if (d != 0) { 13 | numerator ~/= d; 14 | denominator ~/= d; 15 | } 16 | } 17 | 18 | int toInt() => denominator == 0 ? 0 : numerator ~/ denominator; 19 | 20 | double toDouble() => denominator == 0 ? 0.0 : numerator / denominator; 21 | 22 | @override 23 | bool operator ==(Object other) => 24 | other is Rational && 25 | numerator == other.numerator && 26 | denominator == other.denominator; 27 | 28 | @override 29 | int get hashCode => Object.hash(numerator, denominator); 30 | 31 | @override 32 | String toString() => '$numerator/$denominator'; 33 | } 34 | -------------------------------------------------------------------------------- /lib/plugins/rounded_background_text/NOTICES: -------------------------------------------------------------------------------- 1 | Copyright 2021 Bruno D'Luka 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 4 | 5 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 6 | 7 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /lib/pro_image_editor_method_channel.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/services.dart'; 3 | 4 | import 'pro_image_editor_platform_interface.dart'; 5 | 6 | /// An implementation of [ProImageEditorPlatform] that uses method channels. 7 | class MethodChannelProImageEditor extends ProImageEditorPlatform { 8 | /// The method channel used to interact with the native platform. 9 | @visibleForTesting 10 | final methodChannel = const MethodChannel('pro_image_editor'); 11 | 12 | @override 13 | Future?> getSupportedEmojis(List emojis) async { 14 | var result = await methodChannel.invokeMethod>( 15 | 'getSupportedEmojis', 16 | {'source': emojis}, 17 | ); 18 | 19 | return List.castFrom(result ?? []); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/shared/extensions/box_constraints_extension.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// An extension on [BoxConstraints] that provides additional functionality 4 | /// for converting constraint values into a [Map]. 5 | /// ``` 6 | extension BoxConstraintsExtension on BoxConstraints { 7 | /// Converts the [BoxConstraints] properties into a [Map]. 8 | /// 9 | /// The returned map contains the following keys: 10 | /// - `'minWidth'`: The minimum width constraint. 11 | /// - `'maxWidth'`: The maximum width constraint. 12 | /// - `'minHeight'`: The minimum height constraint. 13 | /// - `'maxHeight'`: The maximum height constraint. 14 | Map toMap() { 15 | return { 16 | 'minWidth': minWidth, 17 | 'maxWidth': maxWidth, 18 | 'minHeight': minHeight, 19 | 'maxHeight': maxHeight, 20 | }; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/shared/extensions/color_extension.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | /// Extension on the [Color] class to provide a method for converting a color 4 | /// to its hexadecimal representation. 5 | extension ColorToHex on Color { 6 | /// Converts a [Color] to its hexadecimal representation. 7 | int toHex({bool leadingHashSign = true}) { 8 | int floatToInt8(double x) { 9 | return (x * 255.0).round() & 0xff; 10 | } 11 | 12 | return floatToInt8(a) << 24 | 13 | floatToInt8(r) << 16 | 14 | floatToInt8(g) << 8 | 15 | floatToInt8(b) << 0; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/shared/extensions/double_extension.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | /// Extension for [double] values that provides safe clamping methods. 4 | extension DoubleExtension on double { 5 | /// Clamps the double value between [lowerLimit] and [upperLimit], 6 | /// ensuring [lowerLimit] is not greater than [upperLimit]. 7 | /// 8 | /// Returns the clamped value as a double. 9 | /// 10 | /// Example: 11 | /// ```dart 12 | /// 3.5.safeMinClamp(8, 5); // returns 5 13 | /// 5.5.safeMinClamp(2, 10); // returns 5.5 14 | /// 12.0.safeMinClamp(2, 10); // returns 10.0 15 | /// ``` 16 | double safeMinClamp(num lowerLimit, num upperLimit) { 17 | return clamp( 18 | min(lowerLimit, upperLimit), 19 | upperLimit, 20 | ).toDouble(); 21 | } 22 | 23 | /// Clamps the double value between [lowerLimit] and [upperLimit], 24 | /// ensuring [upperLimit] is not less than [lowerLimit]. 25 | /// 26 | /// Returns the clamped value as a double. 27 | /// 28 | /// Example: 29 | /// ```dart 30 | /// 12.safeMinClamp(8, 5); // returns 8 31 | /// 1.5.safeMaxClamp(2, 10); // returns 2.0 32 | /// 5.5.safeMaxClamp(2, 10); // returns 5.5 33 | /// ``` 34 | double safeMaxClamp(num lowerLimit, num upperLimit) { 35 | return clamp( 36 | lowerLimit, 37 | max(lowerLimit, upperLimit), 38 | ).toDouble(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/shared/extensions/duration_extension.dart: -------------------------------------------------------------------------------- 1 | /// Extension for formatting [Duration] as a time string. 2 | extension DurationFormatter on Duration { 3 | /// Converts the duration to a formatted time string (MM:SS). 4 | /// 5 | /// Example: 6 | /// ```dart 7 | /// Duration(seconds: 75).toTimeString(); // "01:15" 8 | /// ``` 9 | String toTimeString() { 10 | int totalSeconds = inSeconds; 11 | int minutes = totalSeconds ~/ 60; 12 | int seconds = totalSeconds % 60; 13 | return '${minutes.toString().padLeft(2, '0')}:' 14 | '${seconds.toString().padLeft(2, '0')}'; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lib/shared/extensions/int_extension.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | /// Extension for formatting an [int] value representing bytes. 4 | extension IntFormatter on int { 5 | /// Converts a byte value into a human-readable string with units. 6 | /// 7 | /// Example: 8 | /// ```dart 9 | /// 1024.toBytesString(); // "1.00 KB" 10 | /// 1048576.toBytesString(1); // "1.0 MB" 11 | /// ``` 12 | /// 13 | /// [decimals] specifies the number of decimal places (default is 2). 14 | String toBytesString([int decimals = 2]) { 15 | if (this <= 0) return '0 B'; 16 | const suffixes = ['B', 'KB', 'MB', 'GB', 'TB']; 17 | var i = (log(this) / log(1024)).floor(); 18 | var size = this / pow(1024, i); 19 | return '${size.toStringAsFixed(decimals)} ${suffixes[i]}'; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/shared/services/content_recorder/services/thread_fallback_manager.dart: -------------------------------------------------------------------------------- 1 | import '/shared/services/content_recorder/services/thread_manager.dart'; 2 | 3 | /// Fallback manager for ThreadManager if multithreading isn't required. 4 | class ThreadFallbackManager extends ThreadManager { 5 | /// Constructs a `ThreadFallbackManager` instance with the specified 6 | /// configuration and initializes the threading environment. 7 | ThreadFallbackManager(super.configs); 8 | 9 | @override 10 | void initialize() { 11 | // No initialization required for fallback manager. 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/shared/services/content_recorder/services/web_worker/web_worker_manager_dummy.dart: -------------------------------------------------------------------------------- 1 | // Project imports: 2 | import '../thread_manager.dart'; 3 | 4 | /// Manages web workers for background operations. 5 | /// 6 | /// Extends [ThreadManager] to handle the initialization and management of 7 | /// web workers, which can perform background tasks in a web environment. 8 | class WebWorkerManager extends ThreadManager { 9 | /// Constructs an instance of `WebWorkerManager` with the provided 10 | /// configuration. 11 | WebWorkerManager(super.configs); 12 | 13 | /// Indicates whether web workers are supported. 14 | @override 15 | bool get isSupported => false; 16 | 17 | @override 18 | void initialize() { 19 | // Initialization logic for web workers. 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/shared/services/content_recorder/utils/converters/convert_flutter_ui_to_image.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui' as ui; 2 | 3 | import '/plugins/image/src/image/image.dart' as img; 4 | 5 | /// Converts a Flutter ui.Image to img.Image suitable for processing. 6 | /// 7 | /// [uiImage] - The image to be converted. 8 | Future convertFlutterUiToImage(ui.Image uiImage) async { 9 | final uiBytes = await uiImage.toByteData(format: ui.ImageByteFormat.rawRgba); 10 | 11 | final image = img.Image.fromBytes( 12 | width: uiImage.width, 13 | height: uiImage.height, 14 | bytes: uiBytes!.buffer, 15 | numChannels: 4, 16 | ); 17 | 18 | return image; 19 | } 20 | -------------------------------------------------------------------------------- /lib/shared/services/import_export/constants/export_import_version.dart: -------------------------------------------------------------------------------- 1 | /// Class containing version constants for export and import functionality. 2 | class ExportImportVersion { 3 | /// The version string representing version `1.0.0` which is used in the 4 | /// editor version < `3.0.0`. 5 | static const version_1_0_0 = '1.0.0'; 6 | 7 | /// The version string representing version `2.0.0` which is used in the 8 | /// editor version >= `3.0.0` && < `6.0.0`. 9 | static const version_2_0_0 = '2.0.0'; 10 | 11 | /// The version string representing version `3.0.0` which is used in the 12 | /// editor version >= `6.0.0` && < `6.1.5`. 13 | static const version_3_0_0 = '3.0.0'; 14 | 15 | /// The version string representing version `3.0.1` which is used in the 16 | /// editor version >= `6.1.5` && < `7.5.0`. 17 | static const version_3_0_1 = '3.0.1'; 18 | 19 | /// The version string representing version `4.0.0` which is used in the 20 | /// editor version >= `7.5.0` && < `7.6.0`. 21 | static const version_4_0_0 = '4.0.0'; 22 | 23 | /// The version string representing version `5.0.0` which is used in the 24 | /// editor version >= `7.6.0` && < `8.0.0`. 25 | static const version_5_0_0 = '5.0.0'; 26 | 27 | /// The version string representing version `6.0.0` which is used in the 28 | /// editor version >= `8.0.0`. 29 | static const version_6_0_0 = '6.0.0'; 30 | } 31 | -------------------------------------------------------------------------------- /lib/shared/services/import_export/enums/export_import_enum.dart: -------------------------------------------------------------------------------- 1 | /// Enum representing different spans of export history. 2 | enum ExportHistorySpan { 3 | /// Export the entire export history. 4 | all, 5 | 6 | /// Export only the current state without any history. 7 | current, 8 | 9 | /// Export the current state and all future changes. 10 | currentAndForward, 11 | 12 | /// Export the current state and all past changes. 13 | currentAndBackward, 14 | } 15 | 16 | /// Enum representing different merge modes for importing editor data. 17 | enum ImportEditorMergeMode { 18 | /// Merge imported data with existing editor data. 19 | merge, 20 | 21 | /// Replace existing editor data with imported data. 22 | replace, 23 | } 24 | -------------------------------------------------------------------------------- /lib/shared/services/import_export/models/import_state_history_configs.dart: -------------------------------------------------------------------------------- 1 | // Project imports: 2 | import '../enums/export_import_enum.dart'; 3 | import '../types/widget_loader.dart'; 4 | 5 | /// This class represents configurations for importing editor data. 6 | class ImportEditorConfigs { 7 | /// Constructs an [ImportEditorConfigs] instance. 8 | /// 9 | /// - [recalculateSizeAndPosition] is set to `true` 10 | /// - [mergeMode] is set to [ImportEditorMergeMode.replace] 11 | const ImportEditorConfigs({ 12 | this.recalculateSizeAndPosition = true, 13 | this.mergeMode = ImportEditorMergeMode.replace, 14 | this.widgetLoader, 15 | }); 16 | 17 | /// The merge mode for importing editor data. 18 | final ImportEditorMergeMode mergeMode; 19 | 20 | /// A flag indicating whether to recalculate size and position during import 21 | /// based on the new image size and device size. 22 | final bool recalculateSizeAndPosition; 23 | 24 | /// {@macro widgetLoader} 25 | final WidgetLoader? widgetLoader; 26 | } 27 | -------------------------------------------------------------------------------- /lib/shared/shaders/pixelate.frag: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | uniform vec2 u_size; // Layer size 4 | uniform float u_pixel_block_size; // The pixelation block size 5 | uniform vec2 u_device_size; // The pixelation block size 6 | uniform float u_fit_to_width; // If the image fits the device, it is 1, if not, it is 0. 7 | uniform sampler2D u_texture_input; 8 | 9 | out vec4 frag_color; 10 | 11 | void main() { 12 | /// Flutter rerender the shader when we read the raw rgb data. 13 | /// To ensure the pixelation will not be reduced we need to calculate 14 | /// that difference to the rendered image in the screen. 15 | float generationHelper = u_fit_to_width == 1 16 | ? u_size.x / u_device_size.x 17 | : u_size.y / u_device_size.y; 18 | 19 | /// Normalize coordinates 20 | vec2 uv = FlutterFragCoord().xy / u_size; 21 | 22 | /// Calculate the real pixel block size 23 | float pixelBlockSize = u_pixel_block_size * generationHelper; 24 | 25 | /// Calculate the pixelated UV by snapping to the grid 26 | vec2 pixelated_uv = floor(uv * u_size / pixelBlockSize) * pixelBlockSize / u_size; 27 | 28 | /// Sample the texture using the pixelated coordinates 29 | frag_color = texture(u_texture_input, pixelated_uv); 30 | } 31 | -------------------------------------------------------------------------------- /lib/shared/styles/platform_text_styles.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/cupertino.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | // Project imports: 6 | import '/core/enums/design_mode.dart'; 7 | 8 | /// Determines the appropriate text style based on the platform and design mode. 9 | /// 10 | /// The `platformTextStyle` function returns a text style that is suitable for 11 | /// the given platform (iOS or Android) and design mode (Material or Cupertino). 12 | /// 13 | /// Parameters: 14 | /// - `context`: A BuildContext object representing the current build context. 15 | /// - `mode`: An `ImageEditorDesignMode` enum representing the design mode 16 | /// (Material or Cupertino). 17 | /// 18 | /// Returns: 19 | /// A `TextStyle` object that matches the text style of the specified platform 20 | /// and design mode. 21 | /// 22 | /// Example Usage: 23 | /// ```dart 24 | /// // Get the appropriate text style for Material Design on Android. 25 | /// TextStyle textStyle = 26 | /// platformTextStyle(context, ImageEditorDesignMode.material); 27 | /// 28 | /// // Get the appropriate text style for Cupertino Design on iOS. 29 | /// TextStyle textStyle = 30 | /// platformTextStyle(context, ImageEditorDesignMode.cupertino); 31 | /// ``` 32 | TextStyle platformTextStyle(BuildContext context, ImageEditorDesignMode mode) { 33 | if (mode == ImageEditorDesignMode.cupertino) { 34 | return CupertinoTheme.of(context).textTheme.textStyle; 35 | } else { 36 | return Theme.of(context).textTheme.bodyLarge ?? const TextStyle(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/shared/utils/file_constructor_utils.dart: -------------------------------------------------------------------------------- 1 | import '/core/platform/io/io_helper.dart'; 2 | 3 | /// Converts a given dynamic input into a `File` instance. 4 | /// 5 | /// This function ensures that the provided input is either: 6 | /// - A `String` representing a file path, which is then converted into a 7 | /// `File`. 8 | /// - An existing `File` instance, which is returned as is. 9 | /// 10 | /// Throws an [ArgumentError] if the input is neither a `String` nor a `File`. 11 | /// 12 | /// Example usage: 13 | /// ```dart 14 | /// // Converts String to File 15 | /// File file1 = ensureFileInstance('path/to/file.txt'); 16 | /// // Returns existing File 17 | /// File file2 = ensureFileInstance(existingFile); 18 | /// ``` 19 | /// 20 | /// @param [file] A `String` (file path) or a `File` instance. 21 | /// 22 | /// @returns A `File` instance corresponding to the given input. 23 | /// 24 | /// @throws [ArgumentError] If the input is neither a `String` nor a `File`. 25 | File ensureFileInstance(dynamic file) { 26 | if (file is String) { 27 | return File(file); 28 | } else if (file is File) { 29 | return file; 30 | } 31 | 32 | throw ArgumentError( 33 | 'Only type `File` or `String` which is the path from the file is ' 34 | 'allowed!', 35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /lib/shared/utils/interpolation_utils.dart: -------------------------------------------------------------------------------- 1 | // Dart imports: 2 | import 'dart:math'; 3 | 4 | /// Applies an ease-in-out interpolation function to the input value [t]. 5 | /// Returns a value between 0 and 1 based on the input. 6 | double easeInOut(double t) { 7 | return t < 0.5 ? 0.5 * pow(2 * t, 2) : 0.5 * (2 - pow(2 * (1 - t), 2)); 8 | } 9 | 10 | /// Applies a decelerating interpolation function to the input value [t]. 11 | /// Returns a value between 0 and 1 based on the input. 12 | double decelerate(double t) { 13 | t = 1.0 - t; 14 | return 1.0 - t * t; 15 | } 16 | 17 | /// Applies a linear interpolation function to the input value [t]. 18 | /// Returns the input value unchanged. 19 | double linear(double t) { 20 | return t; 21 | } 22 | -------------------------------------------------------------------------------- /lib/shared/utils/map_utils.dart: -------------------------------------------------------------------------------- 1 | /// Compares two dynamic objects to check if they are equal. 2 | /// 3 | /// This function supports comparison of nested Maps and Lists. It recursively 4 | /// checks the equality of each element in the Maps or Lists. If the objects are 5 | /// neither Maps nor Lists, it performs a simple equality check. 6 | /// 7 | /// - Parameters: 8 | /// - a: The first dynamic object to compare. 9 | /// - b: The second dynamic object to compare. 10 | /// 11 | /// - Returns: A boolean value indicating whether the two objects are equal. 12 | bool mapIsEqual(dynamic a, dynamic b) { 13 | if (a is Map && b is Map) { 14 | if (a.length != b.length) return false; 15 | for (var key in a.keys) { 16 | if (!b.containsKey(key) || !mapIsEqual(a[key], b[key])) { 17 | return false; 18 | } 19 | } 20 | return true; 21 | } else if (a is List && b is List) { 22 | if (a.length != b.length) return false; 23 | for (int i = 0; i < a.length; i++) { 24 | if (!mapIsEqual(a[i], b[i])) { 25 | return false; 26 | } 27 | } 28 | return true; 29 | } else { 30 | return a == b; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/shared/utils/platform_info.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/foundation.dart'; 3 | import '/core/enums/design_mode.dart'; 4 | import '/core/platform/io/io_helper.dart'; 5 | 6 | /// Checks if the app is running on a desktop platform. 7 | final isDesktop = !isWebMobile && 8 | (kIsWeb || Platform.isMacOS || Platform.isWindows || Platform.isLinux); 9 | 10 | /// Checks if the current platform is a web mobile device. 11 | final isWebMobile = kIsWeb && 12 | (defaultTargetPlatform == TargetPlatform.iOS || 13 | defaultTargetPlatform == TargetPlatform.android); 14 | 15 | /// Determines if the platform uses Material Design. 16 | final platformIsMaterialDesign = kIsWeb || 17 | (defaultTargetPlatform != TargetPlatform.iOS && 18 | defaultTargetPlatform != TargetPlatform.macOS); 19 | 20 | /// Sets the design mode for the image editor based on the platform. 21 | /// Uses Material Design for non-iOS/macOS platforms and Cupertino for iOS/macOS. 22 | final ImageEditorDesignMode platformDesignMode = platformIsMaterialDesign 23 | ? ImageEditorDesignMode.material 24 | : ImageEditorDesignMode.cupertino; 25 | -------------------------------------------------------------------------------- /lib/shared/utils/unique_id_generator.dart: -------------------------------------------------------------------------------- 1 | // Dart imports: 2 | import 'dart:math'; 3 | 4 | /// Generates a unique ID based on the current time. 5 | String generateUniqueId() { 6 | const String characters = 7 | 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; 8 | 9 | final Random random = Random(); 10 | final String timestamp = (DateTime.now().millisecondsSinceEpoch ~/ 1000) 11 | .toRadixString(36) 12 | .padLeft(8, '0'); 13 | 14 | String randomPart = ''; 15 | for (int i = 0; i < 20; i++) { 16 | randomPart += characters[random.nextInt(characters.length)]; 17 | } 18 | 19 | return '$timestamp$randomPart'; 20 | } 21 | -------------------------------------------------------------------------------- /lib/shared/widgets/animated/fade_in_left.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'fade_in_base.dart'; 4 | 5 | /// A widget that applies a fade-in animation combined with a slide-from-left 6 | /// effect to its child. 7 | class FadeInLeft extends FadeInBase { 8 | /// Creates a [FadeInLeft] animation widget. 9 | /// 10 | /// The [child] parameter is required, while [duration], [delay], and [offset] 11 | /// are optional with default values. 12 | const FadeInLeft({ 13 | super.key, 14 | required super.child, 15 | super.duration, 16 | super.delay, 17 | super.offset, 18 | }); 19 | 20 | @override 21 | State createState() => _FadeInLeftState(); 22 | } 23 | 24 | class _FadeInLeftState extends FadeInBaseState { 25 | @override 26 | Offset buildInitialOffsetPosition() { 27 | return Offset(widget.offset / 100, 0); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/shared/widgets/animated/fade_in_up.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'fade_in_base.dart'; 4 | 5 | /// A widget that applies a fade-in animation combined with a slide-from-bottom 6 | /// effect to its child. 7 | class FadeInUp extends FadeInBase { 8 | /// Creates a [FadeInUp] animation widget. 9 | /// 10 | /// The [child] parameter is required, while [duration], [delay], and [offset] 11 | /// are optional with default values. 12 | const FadeInUp({ 13 | super.key, 14 | required super.child, 15 | super.duration, 16 | super.delay, 17 | super.offset, 18 | }); 19 | 20 | @override 21 | State createState() => _FadeInUpState(); 22 | } 23 | 24 | class _FadeInUpState extends FadeInBaseState { 25 | @override 26 | Offset buildInitialOffsetPosition() { 27 | return Offset(0, widget.offset / 100); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /lib/shared/widgets/censor/blur_area_item.dart: -------------------------------------------------------------------------------- 1 | import 'dart:ui'; 2 | 3 | import 'package:flutter/widgets.dart'; 4 | 5 | import 'abstract/censor_area_item.dart'; 6 | 7 | /// A widget that applies a blur effect to a defined area. 8 | /// 9 | /// This class extends [CensorAreaItem] and implements the blur effect 10 | /// using a [BackdropFilter] with a blur filter. The intensity of the blur 11 | /// is controlled by the [CensorConfigs] properties [blurSigmaX] and 12 | /// [blurSigmaY]. 13 | class BlurAreaItem extends CensorAreaItem { 14 | /// Creates a [BlurAreaItem] with the specified [censorConfigs] and 15 | /// optional [size]. 16 | const BlurAreaItem({ 17 | super.key, 18 | required super.censorConfigs, 19 | super.size, 20 | }); 21 | 22 | /// Builds a [BackdropFilter] that applies a blur effect based on the provided 23 | /// [censorConfigs]. 24 | /// 25 | /// The blur intensity is controlled by [censorConfigs.blurSigmaX] and 26 | /// [censorConfigs.blurSigmaY]. 27 | @override 28 | Widget buildBackdropFilter({ 29 | required Widget child, 30 | required BuildContext context, 31 | }) { 32 | return BackdropFilter( 33 | filter: ImageFilter.blur( 34 | sigmaX: censorConfigs.blurSigmaX, 35 | sigmaY: censorConfigs.blurSigmaY, 36 | ), 37 | blendMode: censorConfigs.blurBlendMode, 38 | child: child, 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/shared/widgets/color_picker/color_picker_configs.dart: -------------------------------------------------------------------------------- 1 | /// An enumeration representing different modes for color picking. 2 | enum PickMode { 3 | /// Color mode: Allows picking from a range of colors. 4 | color, 5 | 6 | /// Grey mode: Allows picking from shades of grey. 7 | grey, 8 | } 9 | -------------------------------------------------------------------------------- /lib/shared/widgets/flat_icon_text_button.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/material.dart'; 3 | 4 | /// A custom TextButton widget with an icon placed above the label. 5 | class FlatIconTextButton extends TextButton { 6 | /// Creates a [FlatIconTextButton] widget with the specified properties. 7 | /// 8 | /// The [icon] and [label] parameters are required, while the others are 9 | /// optional. 10 | FlatIconTextButton({ 11 | super.key, 12 | super.onPressed, 13 | super.clipBehavior, 14 | super.focusNode, 15 | double spacing = 5.0, 16 | required Widget icon, 17 | required Widget label, 18 | }) : super( 19 | style: TextButton.styleFrom( 20 | padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 2), 21 | maximumSize: 22 | const Size(double.infinity, kBottomNavigationBarHeight), 23 | ), 24 | child: Column( 25 | mainAxisSize: MainAxisSize.min, 26 | children: [ 27 | icon, 28 | SizedBox(height: spacing), 29 | label, 30 | ], 31 | ), 32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /lib/shared/widgets/layer/enums/layer_widget_type_enum.dart: -------------------------------------------------------------------------------- 1 | /// Represents the different types of layer widgets that can be used in the 2 | /// application. 3 | enum LayerWidgetType { 4 | /// A layer that contains an emoji. 5 | emoji, 6 | 7 | /// A layer that contains text. 8 | text, 9 | 10 | /// A layer that contains a generic widget. 11 | widget, 12 | 13 | /// A layer that represents a drawable canvas. 14 | canvas, 15 | 16 | /// A layer that applies a censoring effect, such as blurring or pixelation. 17 | censor, 18 | 19 | /// An unknown or undefined layer type. 20 | unknown, 21 | } 22 | -------------------------------------------------------------------------------- /lib/shared/widgets/layer/models/layer_item_interaction.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/gestures.dart'; 2 | 3 | /// Class that holds interactions for a layer item. 4 | class LayerItemInteractions { 5 | /// Constructor for LayerItemInteractions. 6 | /// 7 | /// Requires all callbacks to be provided. 8 | LayerItemInteractions({ 9 | required this.edit, 10 | required this.remove, 11 | required this.scaleRotateDown, 12 | required this.scaleRotateUp, 13 | }); 14 | 15 | /// Callback function for editing the layer. 16 | final Function() edit; 17 | 18 | /// Callback function for removing the layer. 19 | final Function() remove; 20 | 21 | /// Callback function triggered when a scale/rotate gesture starts. 22 | /// 23 | /// This function is required to initiate the scaling and rotation 24 | /// operations on the layer. 25 | final Function(PointerDownEvent event) scaleRotateDown; 26 | 27 | /// Callback function triggered when a scale/rotate gesture ends. 28 | /// 29 | /// This function is required to finalize the scaling and rotation 30 | /// operations on the layer, applying the changes. 31 | final Function(PointerUpEvent event) scaleRotateUp; 32 | } 33 | -------------------------------------------------------------------------------- /lib/shared/widgets/layer/widgets/layer_widget_censor_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '/core/models/editor_configs/paint_editor/censor_configs.dart'; 4 | import '/core/models/layers/paint_layer.dart'; 5 | import '/features/paint_editor/enums/paint_editor_enum.dart'; 6 | import '/shared/widgets/censor/blur_area_item.dart'; 7 | import '/shared/widgets/censor/pixelate_area_item.dart'; 8 | 9 | /// A widget representing a censor layer in the sticker editor. 10 | /// 11 | /// This widget applies a pixelation or blur effect based on the paint mode. 12 | class LayerWidgetCensorItem extends StatelessWidget { 13 | /// Creates a [LayerWidgetCensorItem] with the given censor configurations 14 | /// and paint layer. 15 | const LayerWidgetCensorItem({ 16 | super.key, 17 | required this.censorConfigs, 18 | required this.layer, 19 | }); 20 | 21 | /// The configuration settings for the censor effect. 22 | final CensorConfigs censorConfigs; 23 | 24 | /// The paint layer that determines the censor effect. 25 | final PaintLayer layer; 26 | 27 | @override 28 | Widget build(BuildContext context) { 29 | switch (layer.item.mode) { 30 | case PaintMode.pixelate: 31 | return PixelateAreaItem( 32 | censorConfigs: censorConfigs, 33 | size: layer.size, 34 | ); 35 | case PaintMode.blur: 36 | return BlurAreaItem( 37 | censorConfigs: censorConfigs, 38 | size: layer.size, 39 | ); 40 | default: 41 | throw UnimplementedError(); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/shared/widgets/layer/widgets/layer_widget_custom_item.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import '/core/models/editor_configs/sticker_editor_configs.dart'; 4 | import '/core/models/layers/widget_layer.dart'; 5 | 6 | /// A custom widget item representing a layer in the sticker editor. 7 | class LayerWidgetCustomItem extends StatelessWidget { 8 | /// Creates a [LayerWidgetCustomItem] with the given layer and editor 9 | /// configurations. 10 | const LayerWidgetCustomItem({ 11 | super.key, 12 | required this.layer, 13 | required this.stickerEditorConfigs, 14 | }); 15 | 16 | /// The widget layer that this item represents. 17 | final WidgetLayer layer; 18 | 19 | /// Configuration settings for the sticker editor. 20 | final StickerEditorConfigs stickerEditorConfigs; 21 | 22 | @override 23 | Widget build(BuildContext context) { 24 | return SizedBox( 25 | width: stickerEditorConfigs.initWidth * layer.scale, 26 | child: FittedBox( 27 | fit: BoxFit.contain, 28 | child: layer.widget, 29 | ), 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/shared/widgets/platform/platform_circular_progress_indicator.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/cupertino.dart'; 3 | import 'package:flutter/material.dart'; 4 | import '/core/models/editor_configs/pro_image_editor_configs.dart'; 5 | 6 | /// A circular progress indicator that adapts to the platform. 7 | /// 8 | /// On web and non-iOS/macOS platforms, it displays a [CircularProgressIndicator]. 9 | /// On iOS and macOS, it displays a [CupertinoActivityIndicator]. 10 | class PlatformCircularProgressIndicator extends StatefulWidget { 11 | /// Creates a platform-aware circular progress indicator. 12 | const PlatformCircularProgressIndicator({ 13 | super.key, 14 | required this.configs, 15 | }); 16 | 17 | /// A class representing configuration options for the Image Editor. 18 | final ProImageEditorConfigs configs; 19 | 20 | @override 21 | State createState() => 22 | _PlatformCircularProgressIndicatorState(); 23 | } 24 | 25 | class _PlatformCircularProgressIndicatorState 26 | extends State { 27 | @override 28 | Widget build(BuildContext context) { 29 | // Conditionally choose the progress indicator based on the platform. 30 | return widget.configs.progressIndicatorConfigs.widgets 31 | .circularProgressIndicator ?? 32 | (widget.configs.designMode == ImageEditorDesignMode.material 33 | ? const CircularProgressIndicator() 34 | : const CupertinoActivityIndicator()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/shared/widgets/video/export_prebuild/video_editor_prebuild_widgets.dart: -------------------------------------------------------------------------------- 1 | export './video_editor_prebuild_remove_area.dart'; 2 | -------------------------------------------------------------------------------- /test/fake/fake_image.dart: -------------------------------------------------------------------------------- 1 | // Dart imports: 2 | import 'dart:typed_data'; 3 | 4 | import 'package:pro_image_editor/core/platform/io/io_helper.dart'; 5 | 6 | Uint8List get fakeMemoryImage => Uint8List.fromList([ 7 | 0x89, 8 | 0x50, 9 | 0x4E, 10 | 0x47, 11 | 0x0D, 12 | 0x0A, 13 | 0x1A, 14 | 0x0A, 15 | 0x00, 16 | 0x00, 17 | 0x00, 18 | 0x0D, 19 | 0x49, 20 | 0x48, 21 | 0x44, 22 | 0x52, 23 | 0x00, 24 | 0x00, 25 | 0x00, 26 | 0x01, 27 | 0x00, 28 | 0x00, 29 | 0x00, 30 | 0x01, 31 | 0x08, 32 | 0x06, 33 | 0x00, 34 | 0x00, 35 | 0x00, 36 | 0x1F, 37 | 0x15, 38 | 0xC4, 39 | 0x89, 40 | 0x00, 41 | 0x00, 42 | 0x00, 43 | 0x0A, 44 | 0x49, 45 | 0x44, 46 | 0x41, 47 | 0x54, 48 | 0x78, 49 | 0x9C, 50 | 0x63, 51 | 0x00, 52 | 0x01, 53 | 0x00, 54 | 0x00, 55 | 0x05, 56 | 0x00, 57 | 0x01, 58 | 0x0D, 59 | 0x0A, 60 | 0x2D, 61 | 0xB4, 62 | 0x00, 63 | 0x00, 64 | 0x00, 65 | 0x00, 66 | 0x49, 67 | 0x45, 68 | 0x4E, 69 | 0x44, 70 | 0xAE, 71 | 0x42, 72 | 0x60, 73 | 0x82 74 | ]); 75 | 76 | final fakeFileImage = File(''); 77 | 78 | const fakeNetworkImage = 'https://picsum.photos/200'; 79 | -------------------------------------------------------------------------------- /test/features/crop_rotate_editor/widgets/crop_aspect_ratio_options_test.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/material.dart'; 3 | 4 | // Package imports: 5 | import 'package:flutter_test/flutter_test.dart'; 6 | import 'package:mockito/mockito.dart'; 7 | import 'package:pro_image_editor/features/crop_rotate_editor/widgets/crop_aspect_ratio_button.dart'; 8 | import 'package:pro_image_editor/pro_image_editor.dart'; 9 | 10 | class MockProImageEditorConfigs extends Mock implements ProImageEditorConfigs {} 11 | 12 | void main() { 13 | group('CropAspectRatioOptions Tests', () { 14 | testWidgets('Initializes with correct aspect ratio', 15 | (WidgetTester tester) async { 16 | const String ratioText = 'Ratio-Text'; 17 | await tester.pumpWidget( 18 | const MaterialApp( 19 | home: Scaffold( 20 | body: CropAspectRatioOptions( 21 | aspectRatio: 1.0, 22 | originalAspectRatio: 1.0, 23 | configs: ProImageEditorConfigs( 24 | cropRotateEditor: CropRotateEditorConfigs(aspectRatios: [ 25 | AspectRatioItem(text: ratioText, value: 1), 26 | ])), 27 | ), 28 | ), 29 | ), 30 | ); 31 | 32 | expect(find.byType(AspectRatioButton), findsWidgets); 33 | expect(find.text(ratioText), findsOneWidget); 34 | }); 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /test/features/emoji_editor_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:pro_image_editor/features/emoji_editor/emoji_editor.dart'; 4 | import 'package:pro_image_editor/plugins/emoji_picker_flutter/emoji_picker_flutter.dart'; 5 | 6 | void main() { 7 | group('EmojiEditor Tests', () { 8 | testWidgets('EmojiEditor should build without error', 9 | (WidgetTester tester) async { 10 | await tester.pumpWidget( 11 | const MaterialApp( 12 | home: Scaffold( 13 | body: EmojiEditor(), 14 | ), 15 | ), 16 | ); 17 | 18 | expect(find.byType(EmojiEditor), findsOneWidget); 19 | }); 20 | 21 | testWidgets('EmojiEditor should have EmojiPicker', 22 | (WidgetTester tester) async { 23 | await tester.pumpWidget( 24 | const MaterialApp( 25 | home: Scaffold( 26 | body: EmojiEditor(), 27 | ), 28 | ), 29 | ); 30 | expect(find.byType(EmojiPicker), findsOneWidget); 31 | }); 32 | }); 33 | } 34 | -------------------------------------------------------------------------------- /test/features/sticker_editor_test.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/material.dart'; 3 | 4 | // Package imports: 5 | import 'package:flutter_test/flutter_test.dart'; 6 | 7 | // Project imports: 8 | import 'package:pro_image_editor/pro_image_editor.dart'; 9 | 10 | void main() { 11 | group('StickerEditor Tests', () { 12 | testWidgets('widget should be created', (WidgetTester tester) async { 13 | await tester.pumpWidget(MaterialApp( 14 | home: StickerEditor( 15 | scrollController: ScrollController(), 16 | configs: ProImageEditorConfigs( 17 | stickerEditor: StickerEditorConfigs( 18 | enabled: true, 19 | builder: (setLayer, scrollController) { 20 | return Container(); 21 | }, 22 | ), 23 | ), 24 | ), 25 | )); 26 | 27 | expect(find.byType(StickerEditor), findsOneWidget); 28 | }); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /test/features/text_editor_test.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/material.dart'; 3 | 4 | // Package imports: 5 | import 'package:flutter_test/flutter_test.dart'; 6 | import 'package:pro_image_editor/features/text_editor/text_editor.dart'; 7 | 8 | void main() { 9 | group('TextEditor Tests', () { 10 | testWidgets('should build without error', (WidgetTester tester) async { 11 | await tester.pumpWidget( 12 | MaterialApp( 13 | home: Scaffold( 14 | body: TextEditor( 15 | theme: ThemeData.dark(), 16 | ), 17 | ), 18 | ), 19 | ); 20 | 21 | expect(find.byType(TextEditor), findsOneWidget); 22 | }); 23 | testWidgets('set text correctly', (WidgetTester tester) async { 24 | await tester.pumpWidget( 25 | MaterialApp( 26 | home: Scaffold( 27 | body: TextEditor( 28 | theme: ThemeData.dark(), 29 | ), 30 | ), 31 | ), 32 | ); 33 | 34 | expect(find.byType(TextEditor), findsOneWidget); 35 | 36 | await tester.enterText(find.byType(EditableText), 'Hello, World!'); 37 | 38 | expect(find.text('Hello, World!'), findsOneWidget); 39 | }); 40 | }); 41 | } 42 | -------------------------------------------------------------------------------- /test/pro_image_editor_method_channel_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/foundation.dart'; 2 | import 'package:flutter/services.dart'; 3 | import 'package:flutter_test/flutter_test.dart'; 4 | import 'package:pro_image_editor/core/platform/io/io_helper.dart'; 5 | import 'package:pro_image_editor/pro_image_editor_method_channel.dart'; 6 | 7 | void main() { 8 | TestWidgetsFlutterBinding.ensureInitialized(); 9 | 10 | MethodChannelProImageEditor platform = MethodChannelProImageEditor(); 11 | const MethodChannel channel = MethodChannel('pro_image_editor'); 12 | 13 | setUp(() { 14 | TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger 15 | .setMockMethodCallHandler( 16 | channel, 17 | (MethodCall methodCall) async { 18 | return []; 19 | }, 20 | ); 21 | }); 22 | 23 | tearDown(() { 24 | TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger 25 | .setMockMethodCallHandler(channel, null); 26 | }); 27 | 28 | test('getSupportedEmojis', () async { 29 | if (!kIsWeb && Platform.isAndroid) { 30 | expect(await platform.getSupportedEmojis([]), []); 31 | } 32 | }); 33 | } 34 | -------------------------------------------------------------------------------- /test/shared/widgets/color_picker/bar_color_picker_test.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/material.dart'; 3 | 4 | // Package imports: 5 | import 'package:flutter_test/flutter_test.dart'; 6 | import 'package:mockito/annotations.dart'; 7 | 8 | // Project imports: 9 | import 'package:pro_image_editor/core/models/editor_configs/pro_image_editor_configs.dart'; 10 | import 'package:pro_image_editor/shared/widgets/color_picker/bar_color_picker.dart'; 11 | 12 | @GenerateNiceMocks([MockSpec()]) 13 | void main() { 14 | group('BarColorPicker Tests', () { 15 | testWidgets('Picks color on tap', (WidgetTester tester) async { 16 | int colorValue = 0; 17 | await tester.pumpWidget(MaterialApp( 18 | home: BarColorPicker( 19 | configs: const ProImageEditorConfigs(), 20 | initialColor: const Color(0xffff0000), 21 | colorListener: (value) => colorValue = value, 22 | ), 23 | )); 24 | 25 | /// Wait that init animation is done 26 | await tester.pump(const Duration(milliseconds: 500)); 27 | await tester.tap(find.byType(BarColorPicker)); 28 | await tester.pumpAndSettle(); 29 | 30 | expect(colorValue, isNot(equals(0))); 31 | }); 32 | }); 33 | } 34 | -------------------------------------------------------------------------------- /test/shared/widgets/layer_widget_test.dart: -------------------------------------------------------------------------------- 1 | // Flutter imports: 2 | import 'package:flutter/material.dart'; 3 | 4 | // Package imports: 5 | import 'package:flutter_test/flutter_test.dart'; 6 | 7 | // Project imports: 8 | import 'package:pro_image_editor/pro_image_editor.dart'; 9 | import 'package:pro_image_editor/shared/widgets/layer/layer_widget.dart'; 10 | 11 | void main() { 12 | testWidgets('LayerWidget test', (WidgetTester tester) async { 13 | // Create a mock layer for testing. 14 | final layer = TextLayer( 15 | text: 'Test Text', 16 | color: Colors.white, 17 | background: Colors.blue, 18 | offset: const Offset(10, 10), 19 | align: TextAlign.center, 20 | flipX: false, 21 | flipY: false, 22 | rotation: 0.0, 23 | scale: 1.0, 24 | ); 25 | 26 | await tester.pumpWidget( 27 | MaterialApp( 28 | home: Scaffold( 29 | body: Stack( 30 | children: [ 31 | LayerWidget( 32 | editorCenterX: 250, 33 | editorCenterY: 250, 34 | layerData: layer, 35 | configs: const ProImageEditorConfigs(), 36 | onTap: (Layer tapLayer) { 37 | expect(layer, equals(tapLayer)); 38 | }, 39 | ), 40 | ], 41 | ), 42 | ), 43 | ), 44 | ); 45 | 46 | expect(find.byType(LayerWidget), findsOneWidget); 47 | 48 | await tester.tapAt(const Offset(11, 11)); 49 | }); 50 | } 51 | -------------------------------------------------------------------------------- /test/utils/converters.dart: -------------------------------------------------------------------------------- 1 | // Dart imports: 2 | import 'dart:typed_data'; 3 | 4 | // Flutter imports: 5 | import 'package:flutter/services.dart'; 6 | 7 | // Package imports: 8 | import 'package:flutter_test/flutter_test.dart'; 9 | import 'package:network_image_mock/network_image_mock.dart'; 10 | 11 | // Project imports: 12 | import 'package:pro_image_editor/shared/utils/converters.dart'; 13 | import '../fake/fake_image.dart'; 14 | 15 | void main() { 16 | group('converters tests', () { 17 | test('fetchImageAsUint8List', () async { 18 | await mockNetworkImagesFor(() async { 19 | final Uint8List imageBytes = 20 | await fetchImageAsUint8List(fakeNetworkImage); 21 | 22 | expect(imageBytes, isNotNull); 23 | }); 24 | }); 25 | 26 | test('readFileAsUint8List', () async { 27 | final Uint8List fileBytes = await readFileAsUint8List(fakeFileImage); 28 | 29 | expect(fileBytes, isNotNull); 30 | }); 31 | }); 32 | } 33 | --------------------------------------------------------------------------------