├── .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 |
--------------------------------------------------------------------------------