├── flutter-package ├── example │ ├── lib │ │ ├── test.dart │ │ ├── widgets │ │ │ ├── no_preview.txt │ │ │ ├── resizable.dart │ │ │ └── chip.dart │ │ ├── preview.dart │ │ ├── main.preview.dart │ │ ├── external │ │ │ ├── theme.dart │ │ │ └── preview.dart │ │ └── widget.dart │ ├── windows │ │ ├── flutter │ │ │ ├── .template_version │ │ │ ├── generated_plugin_registrant.cc │ │ │ ├── generated_plugin_registrant.h │ │ │ ├── generated_plugins.cmake │ │ │ └── CMakeLists.txt │ │ ├── runner │ │ │ ├── resources │ │ │ │ └── app_icon.ico │ │ │ ├── utils.h │ │ │ ├── window_configuration.cpp │ │ │ ├── resource.h │ │ │ ├── utils.cpp │ │ │ ├── CMakeLists.txt │ │ │ ├── window_configuration.h │ │ │ ├── runner.exe.manifest │ │ │ ├── flutter_window.cpp │ │ │ ├── flutter_window.h │ │ │ ├── run_loop.h │ │ │ ├── main.cpp │ │ │ ├── Runner.rc │ │ │ ├── run_loop.cpp │ │ │ └── win32_window.h │ │ ├── .gitignore │ │ └── CMakeLists.txt │ ├── ios │ │ ├── Runner │ │ │ ├── Runner-Bridging-Header.h │ │ │ ├── Assets.xcassets │ │ │ │ ├── LaunchImage.imageset │ │ │ │ │ ├── LaunchImage.png │ │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ │ ├── README.md │ │ │ │ │ └── Contents.json │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ ├── 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-1024x1024@1x.png │ │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ │ └── Contents.json │ │ │ ├── AppDelegate.swift │ │ │ ├── Base.lproj │ │ │ │ ├── Main.storyboard │ │ │ │ └── LaunchScreen.storyboard │ │ │ └── Info.plist │ │ ├── Flutter │ │ │ ├── Debug.xcconfig │ │ │ ├── Release.xcconfig │ │ │ └── AppFrameworkInfo.plist │ │ ├── Runner.xcodeproj │ │ │ ├── project.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcshareddata │ │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ ├── Runner.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── .gitignore │ │ ├── Podfile.lock │ │ └── Podfile │ ├── .vs │ │ ├── ProjectSettings.json │ │ ├── VSWorkspaceState.json │ │ ├── slnx.sqlite │ │ └── example │ │ │ └── v16 │ │ │ ├── .suo │ │ │ └── Browse.VC.db │ ├── web │ │ ├── favicon.png │ │ ├── icons │ │ │ ├── Icon-192.png │ │ │ └── Icon-512.png │ │ ├── manifest.json │ │ └── index.html │ ├── macos │ │ ├── .gitignore │ │ ├── Runner │ │ │ ├── Configs │ │ │ │ ├── Debug.xcconfig │ │ │ │ ├── Release.xcconfig │ │ │ │ ├── Warnings.xcconfig │ │ │ │ └── AppInfo.xcconfig │ │ │ ├── Assets.xcassets │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ ├── app_icon_16.png │ │ │ │ │ ├── app_icon_32.png │ │ │ │ │ ├── app_icon_64.png │ │ │ │ │ ├── app_icon_1024.png │ │ │ │ │ ├── app_icon_128.png │ │ │ │ │ ├── app_icon_256.png │ │ │ │ │ ├── app_icon_512.png │ │ │ │ │ └── Contents.json │ │ │ ├── AppDelegate.swift │ │ │ ├── Release.entitlements │ │ │ ├── DebugProfile.entitlements │ │ │ ├── MainFlutterWindow.swift │ │ │ ├── exampleDebug.entitlements │ │ │ └── Info.plist │ │ ├── Flutter │ │ │ ├── Flutter-Debug.xcconfig │ │ │ ├── Flutter-Release.xcconfig │ │ │ └── GeneratedPluginRegistrant.swift │ │ ├── Runner.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── Runner.xcodeproj │ │ │ ├── project.xcworkspace │ │ │ │ └── xcshareddata │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ ├── Podfile.lock │ │ └── Podfile │ ├── preview │ │ ├── assets │ │ │ ├── cover1.jpg │ │ │ ├── cover2.jpg │ │ │ └── cover3.jpg │ │ └── screenshots │ │ │ ├── Chip.png │ │ │ ├── test.png │ │ │ └── MusicCard.png │ ├── android │ │ ├── gradle.properties │ │ ├── app │ │ │ ├── src │ │ │ │ ├── main │ │ │ │ │ ├── res │ │ │ │ │ │ ├── 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 │ │ │ │ │ │ ├── drawable │ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ │ └── values │ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── kotlin │ │ │ │ │ │ └── com │ │ │ │ │ │ │ └── example │ │ │ │ │ │ │ ├── example │ │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ │ │ │ └── preview_example │ │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── debug │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ └── profile │ │ │ │ │ └── AndroidManifest.xml │ │ │ └── build.gradle │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ └── gradle-wrapper.properties │ │ ├── .gitignore │ │ ├── settings.gradle │ │ └── build.gradle │ ├── .metadata │ ├── .vscode │ │ └── launch.json │ ├── README.md │ ├── .gitignore │ ├── test │ │ └── widget_test.dart │ └── pubspec.yaml ├── bin │ ├── old │ │ ├── hot_restart_server.dart │ │ ├── serve.dart │ │ ├── asset_server.dart │ │ ├── vm_hot_reload.dart │ │ ├── run.dart │ │ └── daemon_service.dart │ ├── utils.dart │ ├── templates.dart │ ├── daemon_service.dart │ └── preview.dart ├── test │ └── preview_test.dart ├── CHANGELOG.md ├── .gitignore ├── assets │ ├── PreviewIcons.ttf │ └── config.json ├── .idea │ ├── runConfigurations │ │ └── example_lib_main_dart.xml │ ├── modules.xml │ ├── libraries │ │ └── Dart_SDK.xml │ └── workspace.xml ├── .metadata ├── lib │ └── src │ │ ├── assets │ │ └── image.dart │ │ ├── preview_icons.dart │ │ ├── utils.dart │ │ ├── persist.dart │ │ ├── screenshot.dart │ │ ├── vm │ │ └── preview_service.dart │ │ └── controls.dart ├── .vscode │ └── launch.json ├── preview.iml ├── LICENSE ├── pubspec.yaml └── README.md ├── vscode-extension ├── src │ ├── test │ │ ├── suite │ │ │ ├── index.ts │ │ │ └── extension.test.ts │ │ └── runTest.ts │ ├── extension.ts │ ├── rcp.ts │ └── preview.ts ├── .gitignore ├── images │ ├── icon.png │ ├── icon_dark.svg │ └── icon_light.svg ├── .vscodeignore ├── .vscode │ ├── extensions.json │ ├── tasks.json │ ├── settings.json │ └── launch.json ├── CHANGELOG.md ├── .eslintrc.json ├── tsconfig.json ├── LICENSE ├── snippets.json ├── vsc-extension-quickstart.md ├── package.json └── README.md ├── screenshots ├── custom_preview.png ├── macos_helper.png ├── preview_button.jpg ├── flutter_preview.jpg └── flutter_preview_header.png └── LICENSE /flutter-package/example/lib/test.dart: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /vscode-extension/src/test/suite/index.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flutter-package/bin/old/hot_restart_server.dart: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /flutter-package/example/lib/widgets/no_preview.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /flutter-package/test/preview_test.dart: -------------------------------------------------------------------------------- 1 | void main() {} 2 | -------------------------------------------------------------------------------- /flutter-package/example/windows/flutter/.template_version: -------------------------------------------------------------------------------- 1 | 4 2 | -------------------------------------------------------------------------------- /vscode-extension/.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | .vscode-test/ 4 | *.vsix 5 | -------------------------------------------------------------------------------- /flutter-package/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.0.1 2 | 3 | * TODO: Describe initial release. 4 | -------------------------------------------------------------------------------- /flutter-package/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | 4 | .packages 5 | .pub/ 6 | 7 | build/ 8 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /flutter-package/example/.vs/ProjectSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "CurrentProjectSetting": "No hay configuraciones" 3 | } -------------------------------------------------------------------------------- /screenshots/custom_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/screenshots/custom_preview.png -------------------------------------------------------------------------------- /screenshots/macos_helper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/screenshots/macos_helper.png -------------------------------------------------------------------------------- /screenshots/preview_button.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/screenshots/preview_button.jpg -------------------------------------------------------------------------------- /screenshots/flutter_preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/screenshots/flutter_preview.jpg -------------------------------------------------------------------------------- /vscode-extension/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/vscode-extension/images/icon.png -------------------------------------------------------------------------------- /flutter-package/assets/PreviewIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/assets/PreviewIcons.ttf -------------------------------------------------------------------------------- /flutter-package/example/.vs/VSWorkspaceState.json: -------------------------------------------------------------------------------- 1 | { 2 | "ExpandedNodes": [ 3 | "" 4 | ], 5 | "PreviewInSolutionExplorer": false 6 | } -------------------------------------------------------------------------------- /flutter-package/example/.vs/slnx.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/.vs/slnx.sqlite -------------------------------------------------------------------------------- /flutter-package/example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/web/favicon.png -------------------------------------------------------------------------------- /screenshots/flutter_preview_header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/screenshots/flutter_preview_header.png -------------------------------------------------------------------------------- /flutter-package/example/macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/xcuserdata/ 7 | -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /flutter-package/example/.vs/example/v16/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/.vs/example/v16/.suo -------------------------------------------------------------------------------- /flutter-package/example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /flutter-package/example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /flutter-package/example/preview/assets/cover1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/preview/assets/cover1.jpg -------------------------------------------------------------------------------- /flutter-package/example/preview/assets/cover2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/preview/assets/cover2.jpg -------------------------------------------------------------------------------- /flutter-package/example/preview/assets/cover3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/preview/assets/cover3.jpg -------------------------------------------------------------------------------- /flutter-package/example/.vs/example/v16/Browse.VC.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/.vs/example/v16/Browse.VC.db -------------------------------------------------------------------------------- /flutter-package/example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /flutter-package/example/preview/screenshots/Chip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/preview/screenshots/Chip.png -------------------------------------------------------------------------------- /flutter-package/example/preview/screenshots/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/preview/screenshots/test.png -------------------------------------------------------------------------------- /flutter-package/example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /flutter-package/example/preview/screenshots/MusicCard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/preview/screenshots/MusicCard.png -------------------------------------------------------------------------------- /flutter-package/example/windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /flutter-package/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 | -------------------------------------------------------------------------------- /flutter-package/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 | -------------------------------------------------------------------------------- /flutter-package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /flutter-package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /flutter-package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /vscode-extension/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | src/** 5 | .gitignore 6 | vsc-extension-quickstart.md 7 | **/tsconfig.json 8 | **/.eslintrc.json 9 | **/*.map 10 | **/*.ts 11 | -------------------------------------------------------------------------------- /flutter-package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /flutter-package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /flutter-package/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 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /vscode-extension/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /flutter-package/example/lib/preview.dart: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | /* class ScreenShotPreview extends StatelessWidget with Previewer { 5 | @override 6 | Widget build(BuildContext context) { 7 | return 8 | } 9 | 10 | } 11 | */ 12 | -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /flutter-package/example/android/app/src/main/kotlin/com/example/preview_example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.preview_example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesblasco/flutter_preview/HEAD/flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /flutter-package/example/windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #include "generated_plugin_registrant.h" 6 | 7 | 8 | void RegisterPlugins(flutter::PluginRegistry* registry) { 9 | } 10 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /vscode-extension/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to the "flutter-preview" extension will be documented in this file. 4 | 5 | Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. 6 | 7 | ## [Unreleased] 8 | 9 | - Initial release -------------------------------------------------------------------------------- /flutter-package/example/windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSOLE_UTILS_H_ 2 | #define CONSOLE_UTILS_H_ 3 | 4 | // Creates a console for the process, and redirects stdout and stderr to 5 | // it for both the runner and the Flutter library. 6 | void CreateAndAttachConsole(); 7 | 8 | #endif // CONSOLE_UTILS_H_ 9 | -------------------------------------------------------------------------------- /flutter-package/bin/utils.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | Future getUnusedPort(InternetAddress address) { 4 | return ServerSocket.bind(address ?? InternetAddress.anyIPv4, 0) 5 | .then((socket) { 6 | var port = socket.port; 7 | socket.close(); 8 | return port; 9 | }); 10 | } 11 | -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /flutter-package/example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /flutter-package/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 | -------------------------------------------------------------------------------- /flutter-package/example/windows/runner/window_configuration.cpp: -------------------------------------------------------------------------------- 1 | #include "window_configuration.h" 2 | 3 | const wchar_t* kFlutterWindowTitle = L"example"; 4 | const unsigned int kFlutterWindowOriginX = 10; 5 | const unsigned int kFlutterWindowOriginY = 10; 6 | const unsigned int kFlutterWindowWidth = 1280; 7 | const unsigned int kFlutterWindowHeight = 720; 8 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /flutter-package/.idea/runConfigurations/example_lib_main_dart.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /flutter-package/.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: f73f498da1fe4224e29cf9692161575a3d994f8f 8 | channel: dev 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /flutter-package/example/.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: f73f498da1fe4224e29cf9692161575a3d994f8f 8 | channel: dev 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /flutter-package/example/macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import shared_preferences_macos 9 | 10 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 11 | SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) 12 | } 13 | -------------------------------------------------------------------------------- /flutter-package/example/windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 6 | #define GENERATED_PLUGIN_REGISTRANT_ 7 | 8 | #include 9 | 10 | // Registers Flutter plugins. 11 | void RegisterPlugins(flutter::PluginRegistry* registry); 12 | 13 | #endif // GENERATED_PLUGIN_REGISTRANT_ 14 | -------------------------------------------------------------------------------- /flutter-package/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 | -------------------------------------------------------------------------------- /flutter-package/example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /flutter-package/example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /flutter-package/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. -------------------------------------------------------------------------------- /flutter-package/example/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Flutter", 9 | "request": "launch", 10 | "type": "dart" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /flutter-package/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 | 12 | 13 | -------------------------------------------------------------------------------- /vscode-extension/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 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 | -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 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 | -------------------------------------------------------------------------------- /flutter-package/lib/src/assets/image.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/rendering.dart'; 2 | import 'package:preview/src/utils.dart'; 3 | import 'package:preview/src/vm/preview_service.dart'; 4 | 5 | extension PreviewImage on NetworkImage { 6 | static NetworkImage asset(String asset, {double scale}) { 7 | assert(debugAssertPreviewModeRequired('PreviewImage')); 8 | assert(debugPreviewPortRequired('PreviewImage')); 9 | return NetworkImage('http://$previewAddress:$kPreviewPort/asset/$asset'); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /vscode-extension/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 10 | "typescript.tsc.autoDetect": "off" 11 | } -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner/exampleDebug.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.client 10 | 11 | com.apple.security.network.server 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /flutter-package/example/lib/main.preview.dart: -------------------------------------------------------------------------------- 1 | 2 | import 'package:flutter/widgets.dart'; 3 | import 'package:preview/preview.dart'; 4 | import 'widgets/resizable.dart'; 5 | void main() { 6 | runApp(_PreviewApp()); 7 | } 8 | 9 | class _PreviewApp extends StatelessWidget { 10 | @override 11 | Widget build(BuildContext context) { 12 | return PreviewPage( 13 | path: 'widgets/resizable.dart', 14 | providers: () => [ 15 | WidgetPreview(), 16 | 17 | ], 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /flutter-package/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 | -------------------------------------------------------------------------------- /vscode-extension/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": [ 9 | "@typescript-eslint" 10 | ], 11 | "rules": { 12 | "@typescript-eslint/class-name-casing": "warn", 13 | "@typescript-eslint/semi": "warn", 14 | "curly": "warn", 15 | "eqeqeq": "warn", 16 | "no-throw-literal": "warn", 17 | "semi": "off" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /flutter-package/example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /vscode-extension/src/test/suite/extension.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | 3 | // You can import and use all API from the 'vscode' module 4 | // as well as import your extension to test it 5 | import * as vscode from 'vscode'; 6 | // import * as myExtension from '../../extension'; 7 | 8 | suite('Extension Test Suite', () => { 9 | vscode.window.showInformationMessage('Start all tests.'); 10 | 11 | test('Sample test', () => { 12 | assert.equal(-1, [1, 2, 3].indexOf(5)); 13 | assert.equal(-1, [1, 2, 3].indexOf(0)); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /flutter-package/example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /flutter-package/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 | -------------------------------------------------------------------------------- /flutter-package/example/windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | ) 7 | 8 | set(PLUGIN_BUNDLED_LIBRARIES) 9 | 10 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 11 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 12 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 13 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 14 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 15 | endforeach(plugin) 16 | -------------------------------------------------------------------------------- /flutter-package/example/windows/runner/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | void CreateAndAttachConsole() { 11 | if (::AllocConsole()) { 12 | FILE *unused; 13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) { 14 | _dup2(_fileno(stdout), 1); 15 | } 16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) { 17 | _dup2(_fileno(stdout), 2); 18 | } 19 | std::ios::sync_with_stdio(); 20 | FlutterDesktopResyncOutputStreams(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /flutter-package/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /flutter-package/assets/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PreviewIcons", 3 | "css_prefix_text": "", 4 | "css_use_suffix": false, 5 | "hinting": true, 6 | "units_per_em": 1000, 7 | "ascent": 850, 8 | "glyphs": [ 9 | { 10 | "uid": "e760c2177bd9d125a1770f7d955ceccc", 11 | "css": "lightning-bolt", 12 | "code": 59392, 13 | "src": "custom_icons", 14 | "selected": true, 15 | "svg": { 16 | "path": "M458.3 625H250L541.7 41.7V375H750L458.3 958.3V625Z", 17 | "width": 1000 18 | }, 19 | "search": [ 20 | "lightning-bolt" 21 | ] 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /flutter-package/example/README.md: -------------------------------------------------------------------------------- 1 | # preview_example 2 | 3 | Demonstrates how to use the preview plugin. 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://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /flutter-package/bin/old/serve.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'run.dart'; 3 | 4 | Future main() async { 5 | final server = await HttpServer.bind('127.0.0.1', 8081); 6 | await for (HttpRequest request in server) { 7 | final file = request.uri.queryParameters['file']; 8 | if (file != null) { 9 | try { 10 | generatePreview(file); 11 | // request.response.write('Hello, world'); 12 | await request.response.close(); 13 | } catch (e) { 14 | print(e); 15 | request.response.statusCode = HttpStatus.internalServerError; 16 | await request.response.close(); 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /flutter-package/example/windows/runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(runner LANGUAGES CXX) 3 | 4 | add_executable(${BINARY_NAME} WIN32 5 | "flutter_window.cpp" 6 | "main.cpp" 7 | "run_loop.cpp" 8 | "utils.cpp" 9 | "win32_window.cpp" 10 | "window_configuration.cpp" 11 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 12 | "Runner.rc" 13 | "runner.exe.manifest" 14 | ) 15 | apply_standard_settings(${BINARY_NAME}) 16 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) 17 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") 18 | add_dependencies(${BINARY_NAME} flutter_assemble) 19 | -------------------------------------------------------------------------------- /flutter-package/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 | -------------------------------------------------------------------------------- /flutter-package/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 © 2020 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /flutter-package/example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /flutter-package/example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "preview_example", 3 | "short_name": "preview_example", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "Demonstrates how to use the preview plugin.", 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 | } 24 | -------------------------------------------------------------------------------- /flutter-package/example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /vscode-extension/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "esModuleInterop": true, 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "target": "es6", 6 | "outDir": "out", 7 | "lib": [ 8 | "es6" 9 | ], 10 | "sourceMap": true, 11 | "rootDir": "src", 12 | "esModuleInterop": true, 13 | "strict": true /* enable all strict type-checking options */ 14 | /* Additional Checks */ 15 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 16 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 17 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 18 | }, 19 | "exclude": [ 20 | "node_modules", 21 | ".vscode-test" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /vscode-extension/src/test/runTest.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | 3 | import { runTests } from 'vscode-test'; 4 | 5 | async function main() { 6 | try { 7 | // The folder containing the Extension Manifest package.json 8 | // Passed to `--extensionDevelopmentPath` 9 | const extensionDevelopmentPath = path.resolve(__dirname, '../../'); 10 | 11 | // The path to test runner 12 | // Passed to --extensionTestsPath 13 | const extensionTestsPath = path.resolve(__dirname, './suite/index'); 14 | 15 | // Download VS Code, unzip it and run the integration test 16 | await runTests({ extensionDevelopmentPath, extensionTestsPath }); 17 | } catch (err) { 18 | console.error('Failed to run tests'); 19 | process.exit(1); 20 | } 21 | } 22 | 23 | main(); 24 | -------------------------------------------------------------------------------- /flutter-package/example/lib/external/theme.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:preview/preview.dart'; 3 | import 'package:flutter_material_showcase/flutter_material_showcase.dart'; 4 | 5 | class ThemePreview extends StatelessWidget with Previewer { 6 | @override 7 | Widget build(BuildContext context) { 8 | return Theme( 9 | data: 10 | ThemeData(primarySwatch: Colors.green, primaryColor: Colors.green[900] 11 | // accentColor: Colors.greenAccent 12 | ), 13 | child: Scaffold( 14 | appBar: AppBar( 15 | title: Text('Material Design Showcase'), 16 | ), 17 | body: SingleChildScrollView( 18 | child: MaterialShowcase(), 19 | ), 20 | ), 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /flutter-package/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "program": "example/lib/main.dart", 9 | "name": "Flutter", 10 | "request": "launch", 11 | "type": "dart" 12 | }, 13 | { 14 | "cwd": "example/", 15 | "name": "Flutter Preview", 16 | "request": "launch", 17 | "type": "dart", 18 | "args": [ 19 | "--target=.dart_tool/preview/main.preview.dart", 20 | "--verbose", 21 | ], 22 | } 23 | ] 24 | } -------------------------------------------------------------------------------- /flutter-package/example/windows/runner/window_configuration.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_CONFIGURATION_ 2 | #define WINDOW_CONFIGURATION_ 3 | 4 | // This is a temporary approach to isolate changes that people are likely to 5 | // make to main.cpp, where the APIs are still in flux. This will reduce the 6 | // need to resolve conflicts or re-create changes slightly differently every 7 | // time the Windows Flutter API surface changes. 8 | // 9 | // Longer term there should be simpler configuration options for common 10 | // customizations like this, without requiring native code changes. 11 | 12 | extern const wchar_t* kFlutterWindowTitle; 13 | extern const unsigned int kFlutterWindowOriginX; 14 | extern const unsigned int kFlutterWindowOriginY; 15 | extern const unsigned int kFlutterWindowWidth; 16 | extern const unsigned int kFlutterWindowHeight; 17 | 18 | #endif // WINDOW_CONFIGURATION_ 19 | -------------------------------------------------------------------------------- /flutter-package/example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Exceptions to above rules. 44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 45 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /flutter-package/lib/src/preview_icons.dart: -------------------------------------------------------------------------------- 1 | /// Flutter icons PreviewIcons 2 | /// Copyright (C) 2020 by original authors @ fluttericon.com, fontello.com 3 | /// This font was generated by FlutterIcon.com, which is derived from Fontello. 4 | /// 5 | /// To use this font, place it in your fonts/ directory and include the 6 | /// following in your pubspec.yaml 7 | /// 8 | /// flutter: 9 | /// fonts: 10 | /// - family: PreviewIcons 11 | /// fonts: 12 | /// - asset: fonts/PreviewIcons.ttf 13 | /// 14 | /// 15 | /// 16 | import 'package:flutter/widgets.dart'; 17 | import 'package:preview/src/utils.dart'; 18 | 19 | class PreviewIcons { 20 | PreviewIcons._() : assert(debugAssertPreviewModeRequired(runtimeType)); 21 | 22 | static const _kFontFam = 'PreviewIcons'; 23 | static const _kFontPkg = 'preview'; 24 | 25 | static const IconData lightning_bolt = 26 | IconData(0xe800, fontFamily: _kFontFam, fontPackage: _kFontPkg); 27 | } 28 | -------------------------------------------------------------------------------- /flutter-package/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 | -------------------------------------------------------------------------------- /flutter-package/preview.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /flutter-package/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 that Flutter provides. 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 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:preview_example/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Verify Platform version', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that platform version is retrieved. 19 | expect( 20 | find.byWidgetPredicate( 21 | (Widget widget) => 22 | widget is Text && widget.data.startsWith('Running on:'), 23 | ), 24 | findsOneWidget, 25 | ); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /flutter-package/example/windows/runner/flutter_window.cpp: -------------------------------------------------------------------------------- 1 | #include "flutter_window.h" 2 | 3 | #include "flutter/generated_plugin_registrant.h" 4 | 5 | FlutterWindow::FlutterWindow(RunLoop* run_loop, 6 | const flutter::DartProject& project) 7 | : run_loop_(run_loop), project_(project) {} 8 | 9 | FlutterWindow::~FlutterWindow() {} 10 | 11 | void FlutterWindow::OnCreate() { 12 | Win32Window::OnCreate(); 13 | 14 | // The size here is arbitrary since SetChildContent will resize it. 15 | flutter_controller_ = 16 | std::make_unique(100, 100, project_); 17 | RegisterPlugins(flutter_controller_.get()); 18 | run_loop_->RegisterFlutterInstance(flutter_controller_.get()); 19 | SetChildContent(flutter_controller_->view()->GetNativeWindow()); 20 | } 21 | 22 | void FlutterWindow::OnDestroy() { 23 | if (flutter_controller_) { 24 | run_loop_->UnregisterFlutterInstance(flutter_controller_.get()); 25 | flutter_controller_ = nullptr; 26 | } 27 | 28 | Win32Window::OnDestroy(); 29 | } 30 | -------------------------------------------------------------------------------- /flutter-package/example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /flutter-package/example/macos/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FlutterMacOS (1.0.0) 3 | - shared_preferences (0.0.1) 4 | - shared_preferences_macos (0.0.1): 5 | - FlutterMacOS 6 | 7 | DEPENDENCIES: 8 | - FlutterMacOS (from `Flutter/ephemeral/.symlinks/flutter/darwin-x64`) 9 | - shared_preferences (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences/macos`) 10 | - shared_preferences_macos (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos`) 11 | 12 | EXTERNAL SOURCES: 13 | FlutterMacOS: 14 | :path: Flutter/ephemeral/.symlinks/flutter/darwin-x64 15 | shared_preferences: 16 | :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences/macos 17 | shared_preferences_macos: 18 | :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_macos/macos 19 | 20 | SPEC CHECKSUMS: 21 | FlutterMacOS: 15bea8a44d2fa024068daa0140371c020b4b6ff9 22 | shared_preferences: 9fec34d1bd906196a4da48fcf6c3ad521cc00b8d 23 | shared_preferences_macos: 480ce071d0666e37cef23fe6c702293a3d21799e 24 | 25 | PODFILE CHECKSUM: d8ba9b3e9e93c62c74a660b46c6fcb09f03991a7 26 | 27 | COCOAPODS: 1.8.4 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Jaime Blasco 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. -------------------------------------------------------------------------------- /flutter-package/example/windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_WINDOW_H_ 2 | #define FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include "run_loop.h" 8 | #include "win32_window.h" 9 | 10 | #include 11 | 12 | // A window that does nothing but host a Flutter view. 13 | class FlutterWindow : public Win32Window { 14 | public: 15 | // Creates a new FlutterWindow driven by the |run_loop|, hosting a 16 | // Flutter view running |project|. 17 | explicit FlutterWindow(RunLoop* run_loop, 18 | const flutter::DartProject& project); 19 | virtual ~FlutterWindow(); 20 | 21 | protected: 22 | // Win32Window: 23 | void OnCreate() override; 24 | void OnDestroy() override; 25 | 26 | private: 27 | // The run loop driving events for this window. 28 | RunLoop* run_loop_; 29 | 30 | // The project to run. 31 | flutter::DartProject project_; 32 | 33 | // The Flutter instance hosted by this window. 34 | std::unique_ptr flutter_controller_; 35 | }; 36 | 37 | #endif // FLUTTER_WINDOW_H_ 38 | -------------------------------------------------------------------------------- /flutter-package/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Jaime Blasco 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. -------------------------------------------------------------------------------- /flutter-package/example/lib/widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:preview/preview.dart'; 4 | 5 | class Example extends StatefulWidget { 6 | @override 7 | _ExampleState createState() => _ExampleState(); 8 | } 9 | 10 | class _ExampleState extends State { 11 | @override 12 | Widget build(BuildContext context) { 13 | return Container( 14 | color: Theme.of(context).accentColor, 15 | ); 16 | } 17 | } 18 | 19 | class ExamplePreview extends PreviewProvider { 20 | @override 21 | List get previews => [ 22 | Preview( 23 | theme: ThemeData(), 24 | width: 40, 25 | height: 40, 26 | child: Example(), 27 | ), 28 | Preview( 29 | width: 40, 30 | height: 40, 31 | child: Example(), 32 | ), 33 | Preview( 34 | width: 40, 35 | height: 40, 36 | child: Example(), 37 | ), 38 | Preview( 39 | width: 40, 40 | height: 40, 41 | child: Example(), 42 | ) 43 | ]; 44 | } 45 | -------------------------------------------------------------------------------- /vscode-extension/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Jaime Blasco 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. -------------------------------------------------------------------------------- /vscode-extension/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "runtimeExecutable": "${execPath}", 13 | "args": [ 14 | "--extensionDevelopmentPath=${workspaceFolder}" 15 | ], 16 | "outFiles": [ 17 | "${workspaceFolder}/out/**/*.js" 18 | ], 19 | "preLaunchTask": "${defaultBuildTask}" 20 | }, 21 | { 22 | "name": "Extension Tests", 23 | "type": "extensionHost", 24 | "request": "launch", 25 | "runtimeExecutable": "${execPath}", 26 | "args": [ 27 | "--extensionDevelopmentPath=${workspaceFolder}", 28 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 29 | ], 30 | "outFiles": [ 31 | "${workspaceFolder}/out/test/**/*.js" 32 | ], 33 | "preLaunchTask": "${defaultBuildTask}" 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /flutter-package/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 | -------------------------------------------------------------------------------- /flutter-package/example/windows/runner/run_loop.h: -------------------------------------------------------------------------------- 1 | #ifndef RUN_LOOP_H_ 2 | #define RUN_LOOP_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | // A runloop that will service events for Flutter instances as well 10 | // as native messages. 11 | class RunLoop { 12 | public: 13 | RunLoop(); 14 | ~RunLoop(); 15 | 16 | // Prevent copying 17 | RunLoop(RunLoop const&) = delete; 18 | RunLoop& operator=(RunLoop const&) = delete; 19 | 20 | // Runs the run loop until the application quits. 21 | void Run(); 22 | 23 | // Registers the given Flutter instance for event servicing. 24 | void RegisterFlutterInstance( 25 | flutter::FlutterViewController* flutter_instance); 26 | 27 | // Unregisters the given Flutter instance from event servicing. 28 | void UnregisterFlutterInstance( 29 | flutter::FlutterViewController* flutter_instance); 30 | 31 | private: 32 | using TimePoint = std::chrono::steady_clock::time_point; 33 | 34 | // Processes all currently pending messages for registered Flutter instances. 35 | TimePoint ProcessFlutterMessages(); 36 | 37 | std::set flutter_instances_; 38 | }; 39 | 40 | #endif // RUN_LOOP_H_ 41 | -------------------------------------------------------------------------------- /flutter-package/example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | preview_example 18 | 19 | 20 | 21 | 24 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /flutter-package/example/windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "run_loop.h" 7 | #include "utils.h" 8 | #include "window_configuration.h" 9 | 10 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 11 | _In_ wchar_t *command_line, _In_ int show_command) { 12 | // Attach to console when present (e.g., 'flutter run') or create a 13 | // new console when running with a debugger. 14 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 15 | CreateAndAttachConsole(); 16 | } 17 | 18 | // Initialize COM, so that it is available for use in the library and/or 19 | // plugins. 20 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 21 | 22 | RunLoop run_loop; 23 | 24 | flutter::DartProject project(L"data"); 25 | FlutterWindow window(&run_loop, project); 26 | Win32Window::Point origin(kFlutterWindowOriginX, kFlutterWindowOriginY); 27 | Win32Window::Size size(kFlutterWindowWidth, kFlutterWindowHeight); 28 | if (!window.CreateAndShow(kFlutterWindowTitle, origin, size)) { 29 | return EXIT_FAILURE; 30 | } 31 | window.SetQuitOnClose(true); 32 | 33 | run_loop.Run(); 34 | 35 | ::CoUninitialize(); 36 | return EXIT_SUCCESS; 37 | } 38 | -------------------------------------------------------------------------------- /flutter-package/.idea/libraries/Dart_SDK.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /flutter-package/lib/src/utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:preview/src/vm/preview_service.dart'; 2 | 3 | bool debugAssertPreviewModeRequired([dynamic t]) { 4 | assert(() { 5 | if (!kPreviewMode) throw PreviewModeRequiredException(t); 6 | return true; 7 | }()); 8 | return true; 9 | } 10 | 11 | bool debugPreviewPortRequired([dynamic t]) { 12 | assert(() { 13 | if (kPreviewPort == null) throw PreviewPortRequiredException(t); 14 | return true; 15 | }()); 16 | return true; 17 | } 18 | 19 | class PreviewPortRequiredException implements Exception { 20 | final dynamic t; 21 | const PreviewPortRequiredException([this.t]); 22 | @override 23 | String toString() => 24 | 'Preview port is required for using this widget ${t ?? ''}. \n' 25 | 'You should not used it inside your app'; 26 | } 27 | 28 | class PreviewModeRequiredException implements Exception { 29 | final dynamic t; 30 | const PreviewModeRequiredException([this.t]); 31 | @override 32 | String toString() => 33 | 'Preview mode is required for using this widget ${t ?? ''}. \n' 34 | 'You should not used it inside your app'; 35 | } 36 | 37 | extension IterableExtension on Iterable { 38 | Iterable addInBetween(T item) sync* { 39 | if (length <= 1) { 40 | yield* this; 41 | return; 42 | } 43 | for (final widget in take(length - 1)) { 44 | yield widget; 45 | yield item; 46 | } 47 | yield last; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /flutter-package/lib/src/persist.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class PersistController extends ChangeNotifier { 4 | Key __key = UniqueKey(); 5 | Key get _key => isHotRestart ? __key = UniqueKey() : __key; 6 | 7 | bool _isHotRestart = true; 8 | bool get isHotRestart => _isHotRestart; 9 | 10 | set isHotRestart(bool value) { 11 | if (_isHotRestart != value) { 12 | _isHotRestart = value; 13 | notifyListeners(); 14 | } 15 | } 16 | 17 | restart() { 18 | __key = UniqueKey(); 19 | notifyListeners(); 20 | } 21 | } 22 | 23 | class Persist extends StatefulWidget { 24 | final Widget child; 25 | final PersistController controller; 26 | 27 | const Persist({Key key, this.child, this.controller}) : super(key: key); 28 | @override 29 | _PersistState createState() => _PersistState(); 30 | } 31 | 32 | class _PersistState extends State { 33 | PersistController get controller => widget.controller; 34 | 35 | update() => setState(() {}); 36 | 37 | @override 38 | void initState() { 39 | super.initState(); 40 | controller.addListener(update); 41 | } 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | return KeyedSubtree( 46 | child: Builder( 47 | builder: (context) => widget.child, 48 | key: controller._key, 49 | ), 50 | ); 51 | } 52 | 53 | @override 54 | void dispose() { 55 | controller.removeListener(update); 56 | super.dispose(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /flutter-package/example/lib/widgets/resizable.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:preview/preview.dart'; 3 | 4 | void main() => runApp(MyApp()); 5 | 6 | class MyApp extends StatelessWidget { 7 | @override 8 | Widget build(BuildContext context) { 9 | return MaterialApp( 10 | title: 'Text Overflow Demo', 11 | theme: ThemeData.dark(), 12 | home: Scaffold( 13 | body: Demo(), 14 | ), 15 | ); 16 | } 17 | } 18 | 19 | class Demo extends StatefulWidget { 20 | @override 21 | _DemoState createState() => _DemoState(); 22 | } 23 | 24 | class _DemoState extends State { 25 | @override 26 | Widget build(BuildContext context) { 27 | return ResizableWidget( 28 | child: Container( 29 | padding: EdgeInsets.all(20), 30 | color: Colors.white10, 31 | child: Text( 32 | '''I've just did simple prototype to show main idea. 33 | 1. Draw size handlers with container; 34 | 2. Use GestureDetector to get new variables of sizes 35 | 3. Refresh the main container size.''', 36 | overflow: TextOverflow.fade, 37 | softWrap: true, 38 | style: TextStyle(fontSize: 24), 39 | ), 40 | ), 41 | ); 42 | } 43 | } 44 | 45 | class WidgetPreview extends PreviewProvider { 46 | @override 47 | List get previews => [ 48 | Preview( 49 | height: 600, 50 | width: 700, 51 | frame: Frames.iphoneXR, 52 | child: MyApp(), 53 | ) 54 | ]; 55 | } 56 | -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /vscode-extension/src/extension.ts: -------------------------------------------------------------------------------- 1 | // The module 'vscode' contains the VS Code extensibility API 2 | // Import the module and reference it with the alias vscode in your code below 3 | import * as vscode from 'vscode'; 4 | import fs = require("fs"); 5 | import path = require("path"); 6 | import { ChildProcess } from 'child_process'; 7 | import { PreviewService } from './preview'; 8 | 9 | 10 | const spawn = require('child_process').spawn; 11 | 12 | 13 | const isActiveContext = 'flutter_preview.isActive'; 14 | 15 | 16 | var service: PreviewService | undefined; 17 | 18 | 19 | export function activate(context: vscode.ExtensionContext) { 20 | 21 | console.log('Congratulations, your extension "flutter-preview" is now active!'); 22 | 23 | vscode.commands.executeCommand("setContext", isActiveContext, false); 24 | vscode.commands.executeCommand("flutter-preview.activate"); 25 | 26 | 27 | let disposable2 = vscode.commands.registerCommand('flutter-preview.activate', () => { 28 | 29 | 30 | // The code you place here will be executed every time your command is executed 31 | 32 | if (vscode.workspace.workspaceFolders) { 33 | const folderPath = vscode.workspace.workspaceFolders[0].uri; 34 | 35 | service?.dispose(); 36 | service = new PreviewService(folderPath); 37 | 38 | 39 | } else { 40 | vscode.window.showInformationMessage('No Workspace Found'); 41 | } 42 | 43 | 44 | }); 45 | 46 | 47 | 48 | 49 | let disposable = vscode.commands.registerCommand('flutter-preview.run', () => { 50 | service?.start(); 51 | }); 52 | 53 | 54 | // envStatusBarItem.command = disposable; 55 | context.subscriptions.push(disposable); 56 | } 57 | 58 | 59 | // this method is called when your extension is deactivated 60 | export function deactivate() { 61 | service?.dispose(); 62 | service = undefined; 63 | } 64 | -------------------------------------------------------------------------------- /flutter-package/lib/src/screenshot.dart: -------------------------------------------------------------------------------- 1 | import 'dart:typed_data'; 2 | import 'dart:ui'; 3 | 4 | import 'package:flutter/rendering.dart'; 5 | import 'package:flutter/widgets.dart'; 6 | 7 | class Screenshottable extends StatefulWidget { 8 | final Widget child; 9 | final ScreenshotController controller; 10 | 11 | const Screenshottable({Key key, this.child, this.controller}) 12 | : super(key: key); 13 | @override 14 | _ScreenshottableState createState() => _ScreenshottableState(); 15 | } 16 | 17 | class _ScreenshottableState extends State { 18 | @override 19 | Widget build(BuildContext context) { 20 | return RepaintBoundary(key: widget.controller._key, child: widget.child); 21 | } 22 | } 23 | 24 | class ScreenshotController { 25 | final _key = GlobalKey(); 26 | 27 | ScreenshotSettings settings = ScreenshotSettings(); 28 | 29 | Future takeScreenshot() async { 30 | RenderRepaintBoundary boundary = _key.currentContext.findRenderObject(); 31 | final image = await boundary.toImage(pixelRatio: settings.pixelRatio); 32 | final byteData = await image.toByteData(format: ImageByteFormat.png); 33 | final pngBytes = byteData.buffer.asUint8List(); 34 | return pngBytes; 35 | } 36 | } 37 | 38 | class ScreenshotSettings { 39 | final double pixelRatio; 40 | final String filename; 41 | 42 | ScreenshotSettings({this.filename, double pixelRatio}) 43 | : assert(filename == null || filename.endsWith('.png'), 44 | 'Screenshot filename must have the extension .png'), 45 | this.pixelRatio = pixelRatio ?? window.devicePixelRatio; 46 | 47 | ScreenshotSettings copyWith({String filename, double pixelRatio}) { 48 | return ScreenshotSettings( 49 | filename: filename ?? this.filename, 50 | pixelRatio: pixelRatio ?? this.pixelRatio); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - path_provider_linux (0.0.1): 4 | - Flutter 5 | - shared_preferences (0.0.1): 6 | - Flutter 7 | - shared_preferences_linux (0.0.1): 8 | - Flutter 9 | - shared_preferences_macos (0.0.1): 10 | - Flutter 11 | - shared_preferences_web (0.0.1): 12 | - Flutter 13 | 14 | DEPENDENCIES: 15 | - Flutter (from `Flutter`) 16 | - path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`) 17 | - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) 18 | - shared_preferences_linux (from `.symlinks/plugins/shared_preferences_linux/ios`) 19 | - shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`) 20 | - shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`) 21 | 22 | EXTERNAL SOURCES: 23 | Flutter: 24 | :path: Flutter 25 | path_provider_linux: 26 | :path: ".symlinks/plugins/path_provider_linux/ios" 27 | shared_preferences: 28 | :path: ".symlinks/plugins/shared_preferences/ios" 29 | shared_preferences_linux: 30 | :path: ".symlinks/plugins/shared_preferences_linux/ios" 31 | shared_preferences_macos: 32 | :path: ".symlinks/plugins/shared_preferences_macos/ios" 33 | shared_preferences_web: 34 | :path: ".symlinks/plugins/shared_preferences_web/ios" 35 | 36 | SPEC CHECKSUMS: 37 | Flutter: 0e3d915762c693b495b44d77113d4970485de6ec 38 | path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4 39 | shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d 40 | shared_preferences_linux: afefbfe8d921e207f01ede8b60373d9e3b566b78 41 | shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087 42 | shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9 43 | 44 | PODFILE CHECKSUM: c34e2287a9ccaa606aeceab922830efb9a6ff69a 45 | 46 | COCOAPODS: 1.8.4 47 | -------------------------------------------------------------------------------- /flutter-package/bin/old/asset_server.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:path/path.dart' as path; 3 | 4 | final localAddress = InternetAddress('127.0.0.1'); 5 | 6 | class AssetServer { 7 | HttpServer _server; 8 | 9 | Future runServer(int port) async { 10 | try { 11 | _server = await HttpServer.bind(localAddress, port); 12 | return true; 13 | } catch (e, s) { 14 | stderr.addError(e, s); 15 | return false; 16 | } 17 | } 18 | 19 | Future listen() async { 20 | await for (final request in _server) { 21 | try { 22 | if (request.uri.path.startsWith('/asset/')) { 23 | final File file = 24 | new File(request.uri.path.replaceFirst('/asset/', '')); 25 | 26 | if (file.existsSync()) { 27 | final raw = await file.readAsBytes(); 28 | 29 | request.response.headers 30 | .set('Content-Type', 'image/${path.extension(file.path)}'); 31 | request.response.headers.set('Content-Length', raw.length); 32 | request.response.add(raw); 33 | await request.response.close(); 34 | } else { 35 | request.response.statusCode = HttpStatus.notFound; 36 | request.response.write('Not found'); 37 | await request.response.close(); 38 | } 39 | } else { 40 | request.response.statusCode = HttpStatus.notFound; 41 | request.response.write('Not found'); 42 | await request.response.close(); 43 | } 44 | } catch (e, s) { 45 | stderr.addError(e, s); 46 | request.response.statusCode = HttpStatus.internalServerError; 47 | request.response.write('Internal Error'); 48 | await request.response.close(); 49 | } 50 | } 51 | } 52 | 53 | Future close() async { 54 | await _server.close(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /flutter-package/example/windows/runner/Runner.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #pragma code_page(65001) 4 | #include "resource.h" 5 | 6 | #define APSTUDIO_READONLY_SYMBOLS 7 | ///////////////////////////////////////////////////////////////////////////// 8 | // 9 | // Generated from the TEXTINCLUDE 2 resource. 10 | // 11 | #include "winres.h" 12 | 13 | ///////////////////////////////////////////////////////////////////////////// 14 | #undef APSTUDIO_READONLY_SYMBOLS 15 | 16 | ///////////////////////////////////////////////////////////////////////////// 17 | // English (United States) resources 18 | 19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Icon 51 | // 52 | 53 | // Icon with lowest ID value placed first to ensure application icon 54 | // remains consistent on all systems. 55 | IDI_APP_ICON ICON "resources\\app_icon.ico" 56 | 57 | #endif // English (United States) resources 58 | ///////////////////////////////////////////////////////////////////////////// 59 | 60 | 61 | 62 | #ifndef APSTUDIO_INVOKED 63 | ///////////////////////////////////////////////////////////////////////////// 64 | // 65 | // Generated from the TEXTINCLUDE 3 resource. 66 | // 67 | 68 | 69 | ///////////////////////////////////////////////////////////////////////////// 70 | #endif // not APSTUDIO_INVOKED 71 | -------------------------------------------------------------------------------- /flutter-package/example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 28 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.preview_example" 42 | minSdkVersion 16 43 | targetSdkVersion 28 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | // TODO: Add your own signing config for the release build. 51 | // Signing with the debug keys for now, so `flutter run --release` works. 52 | signingConfig signingConfigs.debug 53 | } 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | 61 | dependencies { 62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 63 | } 64 | -------------------------------------------------------------------------------- /vscode-extension/snippets.json: -------------------------------------------------------------------------------- 1 | { 2 | "Flutter Preview": { 3 | "prefix": [ 4 | "preview" 5 | ], 6 | "body": [ 7 | "", 8 | "class WidgetPreview extends PreviewProvider {", 9 | " @override", 10 | " List get previews { ", 11 | " return [", 12 | " Preview( ", 13 | " child: ", 14 | " ),", 15 | " ", 16 | " ];", 17 | " }", 18 | "}" 19 | ], 20 | "description": "Add a preview provider." 21 | }, 22 | "Flutter stateless widget with Preview": { 23 | "prefix": [ 24 | "preview stless" 25 | ], 26 | "description": "Insert a StatelessWidget with a preview", 27 | "body": [ 28 | "class $1 extends StatelessWidget {", 29 | " @override", 30 | " Widget build(BuildContext context) {", 31 | " return Container(", 32 | " $2", 33 | " );", 34 | " }", 35 | "}", 36 | "", 37 | "", 38 | "", 39 | "class $1Preview extends PreviewProvider {", 40 | " @override", 41 | " List get previews { ", 42 | " return [", 43 | " Preview(", 44 | " child: $1(),", 45 | " )", 46 | " ];", 47 | " }", 48 | "}" 49 | ] 50 | }, 51 | "Flutter stateful widget": { 52 | "prefix": [ 53 | "preview stful" 54 | ], 55 | "description": "Insert a StatefulWidget with a preview", 56 | "body": [ 57 | "class $1 extends StatefulWidget {", 58 | " @override", 59 | " _$1State createState() => _$1State();", 60 | "}", 61 | "", 62 | "class _$1State extends State<$1> {", 63 | " @override", 64 | " Widget build(BuildContext context) {", 65 | " return Container(", 66 | " $2", 67 | " );", 68 | " }", 69 | "}", 70 | "", 71 | "class $1Preview extends PreviewProvider {", 72 | " @override", 73 | " List get previews { ", 74 | " return [", 75 | " Preview(", 76 | " child: $1(),", 77 | " )", 78 | " ];", 79 | " }", 80 | "}" 81 | ] 82 | } 83 | } -------------------------------------------------------------------------------- /flutter-package/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /flutter-package/bin/old/vm_hot_reload.dart: -------------------------------------------------------------------------------- 1 | // import 'dart:developer' as dev; 2 | 3 | // import 'package:vm_service/utils.dart' as vms_utils; 4 | // import 'package:vm_service/vm_service.dart' as vms; 5 | // import 'package:vm_service/vm_service_io.dart' as vms_io; 6 | // import 'dart:io' as io; 7 | // import 'dart:isolate' as isolate; 8 | // import 'package:path/path.dart' as p; 9 | 10 | // vms.VmService _vmService; 11 | 12 | // Future _getVmService() async { 13 | // if (_vmService == null) { 14 | // final devServiceURL = (await dev.Service.getInfo()).serverUri; 15 | // if (devServiceURL == null) { 16 | // throw new StateError( 17 | // 'VM service not available! You need to run dart with --enable-vm-service.'); 18 | // } 19 | // final wsURL = 20 | // vms_utils.convertToWebSocketUrl(serviceProtocolUrl: devServiceURL); 21 | 22 | // _vmService = await vms_io.vmServiceConnectUri(wsURL.toString()); 23 | // } 24 | // return _vmService; 25 | // } 26 | 27 | // Future restart() async { 28 | // if (_vmService == null) await _getVmService(); 29 | // final vm = await _vmService.getVM(); 30 | 31 | // final isolates = vm.isolates; 32 | 33 | // for (final isolate in isolates) { 34 | // final reloadReport = await _vmService.reloadSources(isolate.id, 35 | // force: true, packagesUri: null); 36 | // print(reloadReport); 37 | // } 38 | // } 39 | 40 | // io.File _packagesFile; 41 | // Future get packagesFile async { 42 | // if (_packagesFile == null) { 43 | // final path = 44 | // (await isolate.Isolate.packageConfig)?.toFilePath() ?? '.packages'; 45 | // _packagesFile = new io.File(path).absolute; 46 | // } 47 | // return _packagesFile; 48 | // } 49 | 50 | // io.Directory _pubCacheDir; 51 | // io.Directory get pubCacheDir { 52 | // if (_pubCacheDir == null) { 53 | // final env = io.Platform.environment; 54 | // final path = // 55 | // env.containsKey('PUB_CACHE') 56 | // ? env['PUB_CACHE'] 57 | // : io.Platform.isWindows 58 | // ? p.join(env['APPDATA'], 'Pub', 'Cache') 59 | // : '${env['HOME']}/.pub-cache'; 60 | // _pubCacheDir = new io.Directory(p.normalize(path)).absolute; 61 | // } 62 | // return _pubCacheDir; 63 | // } 64 | -------------------------------------------------------------------------------- /flutter-package/example/lib/widgets/chip.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'package:preview/preview.dart'; 4 | 5 | class Chip extends StatelessWidget { 6 | final String title; 7 | final Color color; 8 | final bool outline; 9 | 10 | const Chip({Key key, this.title, this.color, this.outline = false}) 11 | : super(key: key); 12 | 13 | const Chip.outlined({Key key, this.title, this.color}) 14 | : this.outline = true, 15 | super(key: key); 16 | @override 17 | Widget build(BuildContext context) { 18 | final _color = color ?? Theme.of(context).accentColor; 19 | final padding = EdgeInsets.symmetric(horizontal: 20, vertical: 4); 20 | final radius = BorderRadius.circular(4); 21 | if (outline) { 22 | return Container( 23 | decoration: BoxDecoration( 24 | border: Border.all(color: _color), borderRadius: radius), 25 | padding: padding, 26 | child: Text( 27 | title, 28 | style: TextStyle(color: _color), 29 | ), 30 | ); 31 | } else { 32 | final textColor = 33 | _color.computeLuminance() > 0.5 ? Colors.black : Colors.white; 34 | return Container( 35 | decoration: BoxDecoration(color: _color, borderRadius: radius), 36 | padding: padding, 37 | child: Text( 38 | title, 39 | style: TextStyle(color: textColor), 40 | ), 41 | ); 42 | } 43 | } 44 | } 45 | 46 | class WidgetPreview extends PreviewProvider { 47 | @override 48 | List get previews { 49 | return [ 50 | Preview( 51 | child: Chip(title: 'TAG'), 52 | ), 53 | Preview( 54 | child: Chip(title: 'TAG'), 55 | ), 56 | Preview( 57 | child: Chip( 58 | color: Colors.red, 59 | title: 'TAG', 60 | ), 61 | ), 62 | Preview( 63 | child: Chip( 64 | color: Colors.black, 65 | title: 'TAG', 66 | ), 67 | ), 68 | Preview( 69 | child: Chip.outlined( 70 | color: Colors.white, 71 | title: 'TAG', 72 | ), 73 | ), 74 | Preview( 75 | child: Chip.outlined( 76 | color: Colors.red, 77 | title: 'TAG', 78 | ), 79 | ), 80 | Preview( 81 | child: Chip.outlined( 82 | title: 'TAG', 83 | ), 84 | ), 85 | ]; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /flutter-package/example/windows/runner/run_loop.cpp: -------------------------------------------------------------------------------- 1 | #include "run_loop.h" 2 | 3 | #include 4 | // Don't stomp std::min/std::max 5 | #undef max 6 | #undef min 7 | 8 | #include 9 | 10 | RunLoop::RunLoop() {} 11 | 12 | RunLoop::~RunLoop() {} 13 | 14 | void RunLoop::Run() { 15 | bool keep_running = true; 16 | TimePoint next_flutter_event_time = TimePoint::clock::now(); 17 | while (keep_running) { 18 | std::chrono::nanoseconds wait_duration = 19 | std::max(std::chrono::nanoseconds(0), 20 | next_flutter_event_time - TimePoint::clock::now()); 21 | ::MsgWaitForMultipleObjects( 22 | 0, nullptr, FALSE, static_cast(wait_duration.count() / 1000), 23 | QS_ALLINPUT); 24 | bool processed_events = false; 25 | MSG message; 26 | // All pending Windows messages must be processed; MsgWaitForMultipleObjects 27 | // won't return again for items left in the queue after PeekMessage. 28 | while (::PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) { 29 | processed_events = true; 30 | if (message.message == WM_QUIT) { 31 | keep_running = false; 32 | break; 33 | } 34 | ::TranslateMessage(&message); 35 | ::DispatchMessage(&message); 36 | // Allow Flutter to process messages each time a Windows message is 37 | // processed, to prevent starvation. 38 | next_flutter_event_time = 39 | std::min(next_flutter_event_time, ProcessFlutterMessages()); 40 | } 41 | // If the PeekMessage loop didn't run, process Flutter messages. 42 | if (!processed_events) { 43 | next_flutter_event_time = 44 | std::min(next_flutter_event_time, ProcessFlutterMessages()); 45 | } 46 | } 47 | } 48 | 49 | void RunLoop::RegisterFlutterInstance( 50 | flutter::FlutterViewController* flutter_instance) { 51 | flutter_instances_.insert(flutter_instance); 52 | } 53 | 54 | void RunLoop::UnregisterFlutterInstance( 55 | flutter::FlutterViewController* flutter_instance) { 56 | flutter_instances_.erase(flutter_instance); 57 | } 58 | 59 | RunLoop::TimePoint RunLoop::ProcessFlutterMessages() { 60 | TimePoint next_event_time = TimePoint::max(); 61 | for (auto flutter_controller : flutter_instances_) { 62 | std::chrono::nanoseconds wait_duration = 63 | flutter_controller->ProcessMessages(); 64 | if (wait_duration != std::chrono::nanoseconds::max()) { 65 | next_event_time = 66 | std::min(next_event_time, TimePoint::clock::now() + wait_duration); 67 | } 68 | } 69 | return next_event_time; 70 | } 71 | -------------------------------------------------------------------------------- /vscode-extension/src/rcp.ts: -------------------------------------------------------------------------------- 1 | 2 | import * as rpc from "@open-rpc/client-js"; 3 | import * as ev from "events"; 4 | 5 | const reqUri = 'request'; 6 | const resUri = 'response'; 7 | 8 | 9 | 10 | export class RcpService { 11 | private redeable: NodeJS.ReadableStream; 12 | private writable: NodeJS.WritableStream; 13 | private emitter = new ev.EventEmitter(); 14 | private transport = new rpc.EventEmitterTransport(this.emitter, reqUri, resUri); 15 | private requestManager = new rpc.RequestManager([this.transport]); 16 | private client = new rpc.Client(this.requestManager); 17 | 18 | private notificationListeners: Array<(data: any) => void> = []; 19 | 20 | constructor(redeable: NodeJS.ReadableStream, writable: NodeJS.WritableStream) { 21 | 22 | this.redeable = redeable; 23 | this.writable = writable; 24 | 25 | 26 | try { 27 | let self = this; 28 | 29 | // Stdout daemon callback 30 | this.redeable.on('data', (data) => { 31 | self.emitRedeable(data); 32 | }); 33 | 34 | // Stdin daemon callback 35 | this.emitter.on(reqUri, (data) => { 36 | let request = JSON.stringify(data); 37 | console.log(`Request sent: ${request}`); 38 | self.writable.write(request + '\n'); // Send the output correctly from server 39 | }); 40 | 41 | this.client.onNotification((data) => { 42 | self.notificationListeners.forEach((callback) => callback(data)); 43 | }); 44 | this.client.onError((error: rpc.JSONRPCError) => { 45 | console.log(`Error ${error.message}`); 46 | }); 47 | 48 | 49 | 50 | } catch (e) { 51 | console.log(e); // never called 52 | } 53 | 54 | } 55 | 56 | 57 | request(method: string, params?: any, timeout?: number): Promise { 58 | return this.client.request(method, params, timeout); 59 | 60 | } 61 | 62 | 63 | onNotification(callback: (data: any) => void) { 64 | this.notificationListeners.push(callback); 65 | } 66 | 67 | private emitRedeable(data: any) { 68 | let list = `${data}`.split('\n').filter((e) => e.trim().length !== 0); 69 | if (list.length === 0) { return; } 70 | let responses = `[ ${list.join(', ')} ]`; 71 | console.log(`Response received: ${responses}`); 72 | this.emitter.emit(resUri, responses); 73 | } 74 | 75 | dispose() { 76 | this.emitter.removeAllListeners(); 77 | } 78 | 79 | } 80 | 81 | -------------------------------------------------------------------------------- /vscode-extension/images/icon_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 2 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /flutter-package/example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: preview_example 2 | description: Demonstrates how to use the preview plugin. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | environment: 9 | sdk: ">=2.7.0 <3.0.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | 15 | palette_generator: ^0.2.3 16 | random_color: ^1.0.5 17 | flutter_staggered_grid_view: ^0.3.0 18 | 19 | # The following adds the Cupertino Icons font to your application. 20 | # Use with the CupertinoIcons class for iOS style icons. 21 | cupertino_icons: ^0.1.3 22 | 23 | dev_dependencies: 24 | flutter_test: 25 | sdk: flutter 26 | preview: 27 | path: ../ 28 | device_preview: ^0.4.5 29 | flutter_storyboard: ^0.1.6 30 | flutter_material_showcase: ^1.0.1 31 | 32 | 33 | 34 | 35 | # For information on the generic Dart part of this file, see the 36 | # following page: https://dart.dev/tools/pub/pubspec 37 | 38 | # The following section is specific to Flutter. 39 | flutter: 40 | 41 | # The following line ensures that the Material Icons font is 42 | # included with your application, so that you can use the icons in 43 | # the material Icons class. 44 | uses-material-design: true 45 | 46 | # To add assets to your application, add an assets section, like this: 47 | # assets: 48 | # - images/a_dot_burr.jpeg 49 | # - images/a_dot_ham.jpeg 50 | 51 | # An image asset can refer to one or more resolution-specific "variants", see 52 | # https://flutter.dev/assets-and-images/#resolution-aware. 53 | 54 | # For details regarding adding assets from package dependencies, see 55 | # https://flutter.dev/assets-and-images/#from-packages 56 | 57 | # To add custom fonts to your application, add a fonts section here, 58 | # in this "flutter" section. Each entry in this list should have a 59 | # "family" key with the font family name, and a "fonts" key with a 60 | # list giving the asset and other descriptors for the font. For 61 | # example: 62 | # fonts: 63 | # - family: Schyler 64 | # fonts: 65 | # - asset: fonts/Schyler-Regular.ttf 66 | # - asset: fonts/Schyler-Italic.ttf 67 | # style: italic 68 | # - family: Trajan Pro 69 | # fonts: 70 | # - asset: fonts/TrajanPro.ttf 71 | # - asset: fonts/TrajanPro_Bold.ttf 72 | # weight: 700 73 | # 74 | # For details regarding fonts from package dependencies, 75 | # see https://flutter.dev/custom-fonts/#from-packages 76 | -------------------------------------------------------------------------------- /vscode-extension/images/icon_light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 2 Copy 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /vscode-extension/vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your VS Code Extension 2 | 3 | ## What's in the folder 4 | 5 | * This folder contains all of the files necessary for your extension. 6 | * `package.json` - this is the manifest file in which you declare your extension and command. 7 | * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `src/extension.ts` - this is the main file where you will provide the implementation of your command. 9 | * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 10 | * We pass the function containing the implementation of the command as the second parameter to `registerCommand`. 11 | 12 | ## Get up and running straight away 13 | 14 | * Press `F5` to open a new window with your extension loaded. 15 | * Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. 16 | * Set breakpoints in your code inside `src/extension.ts` to debug your extension. 17 | * Find output from your extension in the debug console. 18 | 19 | ## Make changes 20 | 21 | * You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`. 22 | * You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. 23 | 24 | 25 | ## Explore the API 26 | 27 | * You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`. 28 | 29 | ## Run tests 30 | 31 | * Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`. 32 | * Press `F5` to run the tests in a new window with your extension loaded. 33 | * See the output of the test result in the debug console. 34 | * Make changes to `src/test/suite/extension.test.ts` or create new test files inside the `test/suite` folder. 35 | * The provided test runner will only consider files matching the name pattern `**.test.ts`. 36 | * You can create folders inside the `test` folder to structure your tests any way you want. 37 | 38 | ## Go further 39 | 40 | * Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension). 41 | * [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VSCode extension marketplace. 42 | * Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration). 43 | -------------------------------------------------------------------------------- /flutter-package/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: preview 2 | description: Create samples of your Flutter widgets and preview them in real time 3 | version: 0.0.8 4 | repository: https://github.com/jamesblasco/flutter_preview/ 5 | 6 | environment: 7 | sdk: ">=2.7.0 <3.0.0" 8 | flutter: ">=1.10.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | path: ">=0.9.0 <2.0.0" 14 | analyzer: '>=0.35.0 <0.40.0' 15 | args: ">=1.4.0 <2.0.0" 16 | vm_service: '>=3.0.0 <5.0.0' 17 | async: ^2.3.0 18 | http: '>=0.12.0+2 <0.13.0' 19 | dart_style: ^1.3.4 20 | device_frame: ^0.1.0 21 | json_rpc_2: ^2.2.1 22 | web_socket_channel: ^1.1.0 23 | stream_channel: ^2.0.0 24 | shelf: ^0.7.7 25 | shelf_router: ^0.7.2 26 | shelf_web_socket: ^0.2.3 27 | shelf_static: ^0.2.8 28 | http_server: ^0.9.8+3 29 | mime: ^0.9.6+3 30 | http_parser: ^3.1.4 31 | 32 | # window_size: 33 | # path: ./plugins/window_size/ 34 | 35 | dev_dependencies: 36 | flutter_test: 37 | sdk: flutter 38 | 39 | 40 | 41 | 42 | 43 | 44 | # For information on the generic Dart part of this file, see the 45 | # following page: https://dart.dev/tools/pub/pubspec 46 | 47 | # The following section is specific to Flutter. 48 | flutter: 49 | 50 | fonts: 51 | - family: PreviewIcons 52 | fonts: 53 | - asset: assets/PreviewIcons.ttf 54 | # This section identifies this Flutter project as a plugin project. 55 | # The 'pluginClass' and Android 'package' identifiers should not ordinarily 56 | # be modified. They are used by the tooling to maintain consistency when 57 | # adding or updating assets for this project. 58 | 59 | 60 | # To add assets to your plugin package, add an assets section, like this: 61 | # assets: 62 | # - images/a_dot_burr.jpeg 63 | # - images/a_dot_ham.jpeg 64 | # 65 | # For details regarding assets in packages, see 66 | # https://flutter.dev/assets-and-images/#from-packages 67 | # 68 | # An image asset can refer to one or more resolution-specific "variants", see 69 | # https://flutter.dev/assets-and-images/#resolution-aware. 70 | 71 | # To add custom fonts to your plugin package, add a fonts section here, 72 | # in this "flutter" section. Each entry in this list should have a 73 | # "family" key with the font family name, and a "fonts" key with a 74 | # list giving the asset and other descriptors for the font. For 75 | # example: 76 | # fonts: 77 | # - family: Schyler 78 | # fonts: 79 | # - asset: fonts/Schyler-Regular.ttf 80 | # - asset: fonts/Schyler-Italic.ttf 81 | # style: italic 82 | # - family: Trajan Pro 83 | # fonts: 84 | # - asset: fonts/TrajanPro.ttf 85 | # - asset: fonts/TrajanPro_Bold.ttf 86 | # weight: 700 87 | # 88 | # For details regarding fonts in packages, see 89 | # https://flutter.dev/custom-fonts/#from-packages 90 | -------------------------------------------------------------------------------- /flutter-package/example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 10 | 14 | 21 | 25 | 29 | 34 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /vscode-extension/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flutter-preview", 3 | "displayName": "Flutter Preview", 4 | "description": "Display a real-time preview of a Flutter widget while building it", 5 | "publisher": "jamesblasco", 6 | "version": "0.0.8", 7 | "icon": "images/icon.png", 8 | "engines": { 9 | "vscode": "^1.46.0" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/jamesblasco/flutter_preview.git" 14 | }, 15 | "homepage": "https://github.com/jamesblasco/flutter_preview/blob/master/README.md", 16 | "preview": true, 17 | "categories": [ 18 | "Other", 19 | "Snippets" 20 | ], 21 | "activationEvents": [ 22 | "onLanguage:dart", 23 | "workspaceContains:**/pubspec.yaml", 24 | "workspaceContains:**/*.dart", 25 | "workspaceContains:dart.sh.create", 26 | "workspaceContains:flutter.sh.create", 27 | "workspaceContains:flutter.create", 28 | "onCommand:flutter.createProject", 29 | "onCommand:dart.createProject", 30 | "onCommand:_dart.flutter.createSampleProject", 31 | "onCommand:flutter.doctor", 32 | "onCommand:flutter.upgrade", 33 | "onUri" 34 | ], 35 | "main": "./out/extension.js", 36 | "contributes": { 37 | "commands": [ 38 | { 39 | "command": "flutter-preview.run", 40 | "title": "Flutter Preview : Run", 41 | "category": "preview", 42 | "icon": { 43 | "light": "./images/icon_light.svg", 44 | "dark": "./images/icon_dark.svg" 45 | } 46 | }, 47 | { 48 | "command": "flutter-preview.activate", 49 | "title": "Flutter Preview : Activate" 50 | } 51 | ], 52 | "menus": { 53 | "editor/title": [ 54 | { 55 | "when": "resourceLangId == dart && !flutter_preview.isActive", 56 | "command": "flutter-preview.run", 57 | "group": "navigation@1" 58 | } 59 | ] 60 | }, 61 | "snippets": [ 62 | { 63 | "language": "dart", 64 | "path": "./snippets.json" 65 | } 66 | ] 67 | }, 68 | "scripts": { 69 | "vscode:prepublish": "npm run compile", 70 | "compile": "tsc -p ./", 71 | "lint": "eslint src --ext ts", 72 | "watch": "tsc -watch -p ./", 73 | "pretest": "npm run compile && npm run lint", 74 | "test": "node ./out/test/runTest.js" 75 | }, 76 | "devDependencies": { 77 | "@types/glob": "^7.1.3", 78 | "@types/mocha": "^7.0.2", 79 | "@types/node": "^13.13.14", 80 | "@types/vscode": "^1.46.0", 81 | "@typescript-eslint/eslint-plugin": "^2.30.0", 82 | "@typescript-eslint/parser": "^2.30.0", 83 | "eslint": "^6.8.0", 84 | "glob": "^7.1.6", 85 | "mocha": "^7.1.2", 86 | "typescript": "^3.9.7", 87 | "vscode-test": "^1.3.0" 88 | }, 89 | "extensionPack": [ 90 | "dart-code.flutter" 91 | ], 92 | "dependencies": { 93 | "@open-rpc/client-js": "^1.3.3", 94 | "@types/ws": "^7.2.6", 95 | "bufferutil": "^4.0.1", 96 | "tree-kill": "^1.2.2", 97 | "utf-8-validate": "^5.0.2" 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /flutter-package/lib/src/vm/preview_service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:typed_data'; 3 | 4 | import 'package:flutter/foundation.dart'; 5 | import 'package:json_rpc_2/json_rpc_2.dart'; 6 | import 'package:preview/src/utils.dart'; 7 | import 'package:stream_channel/stream_channel.dart'; 8 | import 'package:web_socket_channel/web_socket_channel.dart'; 9 | import 'package:http/http.dart' as http; 10 | import 'package:http_parser/http_parser.dart' as http; 11 | 12 | const kPreviewMode = 13 | bool.fromEnvironment('flutter.preview', defaultValue: false); 14 | 15 | const kPreviewPort = int.fromEnvironment('preview.port'); 16 | 17 | String get previewAddress { 18 | if (defaultTargetPlatform == TargetPlatform.android) { 19 | // AVD uses '10.0.2.2' as an alias of '127.0.0.1' 20 | return '10.0.2.2'; 21 | } else { 22 | return '127.0.0.1'; 23 | } 24 | } 25 | 26 | class PreviewService { 27 | static final PreviewService _singleton = PreviewService._internal(); 28 | 29 | factory PreviewService() { 30 | assert(debugAssertPreviewModeRequired()); 31 | assert(debugPreviewPortRequired()); 32 | return _singleton; 33 | } 34 | 35 | PreviewService._internal(); 36 | 37 | StreamChannel _socket; 38 | Peer _server; 39 | 40 | start() async { 41 | try { 42 | _socket = WebSocketChannel.connect( 43 | Uri.parse('ws://$previewAddress:$kPreviewPort/ws')) 44 | .cast(); 45 | 46 | _server = Peer(_socket.cast(), strictProtocolChecks: false, 47 | onUnhandledError: (e, s) { 48 | print(e); 49 | }); 50 | 51 | _server.listen(); 52 | 53 | _server.sendNotification('preview.appAttached'); 54 | 55 | final response = await _server.sendRequest('preview.getPort'); 56 | 57 | print('port$response'); 58 | print('Preview attached to deamon'); 59 | } catch (e) { 60 | print(e); 61 | } 62 | } 63 | 64 | requestRestart() { 65 | _server.sendNotification('preview.restart'); 66 | } 67 | 68 | String get _defaultFileName { 69 | final now = DateTime.now(); 70 | return 'Preview ${now.year}-${now.month}-${now.day} ${now.hour}:${now.minute}:${now.second}.png'; 71 | } 72 | 73 | saveScreenshot(Uint8List bytes, [String filename]) async { 74 | final uri = Uri.parse('http://$previewAddress:$kPreviewPort/screenshot'); 75 | 76 | final request = new http.MultipartRequest("POST", uri); 77 | filename ??= _defaultFileName; 78 | var multipartFile = new http.MultipartFile.fromBytes( 79 | 'file', 80 | bytes, 81 | filename: filename, 82 | contentType: http.MediaType('image', 'png'), 83 | ); 84 | 85 | request.files.add(multipartFile); 86 | var response = await request.send(); 87 | print(response.statusCode); 88 | response.stream.transform(Utf8Decoder()).listen((value) { 89 | print(value); 90 | }); 91 | print('Saved $filename'); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /flutter-package/example/macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.11' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def parse_KV_file(file, separator='=') 13 | file_abs_path = File.expand_path(file) 14 | if !File.exists? file_abs_path 15 | return []; 16 | end 17 | pods_ary = [] 18 | skip_line_start_symbols = ["#", "/"] 19 | File.foreach(file_abs_path) { |line| 20 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 21 | plugin = line.split(pattern=separator) 22 | if plugin.length == 2 23 | podname = plugin[0].strip() 24 | path = plugin[1].strip() 25 | podpath = File.expand_path("#{path}", file_abs_path) 26 | pods_ary.push({:name => podname, :path => podpath}); 27 | else 28 | puts "Invalid plugin specification: #{line}" 29 | end 30 | } 31 | return pods_ary 32 | end 33 | 34 | def pubspec_supports_macos(file) 35 | file_abs_path = File.expand_path(file) 36 | if !File.exists? file_abs_path 37 | return false; 38 | end 39 | File.foreach(file_abs_path) { |line| 40 | return true if line =~ /^\s*macos:/ 41 | } 42 | return false 43 | end 44 | 45 | target 'Runner' do 46 | use_frameworks! 47 | use_modular_headers! 48 | 49 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 50 | # referring to absolute paths on developers' machines. 51 | ephemeral_dir = File.join('Flutter', 'ephemeral') 52 | symlink_dir = File.join(ephemeral_dir, '.symlinks') 53 | symlink_plugins_dir = File.join(symlink_dir, 'plugins') 54 | system("rm -rf #{symlink_dir}") 55 | system("mkdir -p #{symlink_plugins_dir}") 56 | 57 | # Flutter Pods 58 | generated_xcconfig = parse_KV_file(File.join(ephemeral_dir, 'Flutter-Generated.xcconfig')) 59 | if generated_xcconfig.empty? 60 | puts "Flutter-Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." 61 | end 62 | generated_xcconfig.map { |p| 63 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR' 64 | symlink = File.join(symlink_dir, 'flutter') 65 | File.symlink(File.dirname(p[:path]), symlink) 66 | pod 'FlutterMacOS', :path => File.join(symlink, File.basename(p[:path])) 67 | end 68 | } 69 | 70 | # Plugin Pods 71 | plugin_pods = parse_KV_file('../.flutter-plugins') 72 | plugin_pods.map { |p| 73 | symlink = File.join(symlink_plugins_dir, p[:name]) 74 | File.symlink(p[:path], symlink) 75 | if pubspec_supports_macos(File.join(symlink, 'pubspec.yaml')) 76 | pod p[:name], :path => File.join(symlink, 'macos') 77 | end 78 | } 79 | end 80 | 81 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. 82 | install! 'cocoapods', :disable_input_output_paths => true 83 | -------------------------------------------------------------------------------- /flutter-package/bin/templates.dart: -------------------------------------------------------------------------------- 1 | String generateFile( 2 | String filePath, 3 | List providers, 4 | ) { 5 | final import = filePath.replaceFirst('/lib/', '').replaceFirst('lib/', ''); 6 | return ''' 7 | 8 | import 'package:flutter/widgets.dart'; 9 | import 'package:preview/preview.dart'; 10 | import '$import'; 11 | void main() { 12 | runApp(_PreviewApp()); 13 | } 14 | 15 | class _PreviewApp extends StatelessWidget { 16 | @override 17 | Widget build(BuildContext context) { 18 | return PreviewPage( 19 | path: '$import', 20 | providers: () => [ 21 | ${providers.reversed.fold('', (p, e) => e + '(), \n ' + p)} 22 | ], 23 | ); 24 | } 25 | } 26 | '''; 27 | } 28 | 29 | const String notSeeTemplate = ''' 30 | 31 | import 'package:flutter/widgets.dart'; 32 | import 'package:preview/preview.dart'; 33 | 34 | // 35 | // 36 | // ............. 37 | // ************ 38 | // .************ 39 | // ************ 40 | // .************ 41 | // ************ 42 | // .************ 43 | // ************ 44 | // ************ ************ 45 | // ******* ,************ 46 | // .** ////******** 47 | // *////////**** 48 | // ,//////////%% 49 | // //////%%%%%% 50 | // ,%%%%%%%%%%%% 51 | // %%%%%%%%%%%% 52 | // 53 | // 54 | // 55 | // 56 | 57 | void main() { 58 | runApp(_PreviewApp()); 59 | } 60 | 61 | class _PreviewApp extends StatelessWidget { 62 | @override 63 | Widget build(BuildContext context) { 64 | return PreviewPage( 65 | child: Text('You should not be editing this file 👀') 66 | ); 67 | } 68 | } 69 | '''; 70 | 71 | const String notValidFormatTemplate = ''' 72 | 73 | import 'package:flutter/widgets.dart'; 74 | import 'package:preview/preview.dart'; 75 | 76 | void main() { 77 | runApp(_PreviewApp()); 78 | } 79 | 80 | class _PreviewApp extends StatelessWidget { 81 | @override 82 | Widget build(BuildContext context) { 83 | return PreviewPage( 84 | child: Text('This format does not support preview 👀') 85 | ); 86 | } 87 | } 88 | '''; 89 | 90 | const String notInLibFormatTemplate = ''' 91 | 92 | import 'package:flutter/widgets.dart'; 93 | import 'package:preview/preview.dart'; 94 | 95 | void main() { 96 | runApp(_PreviewApp()); 97 | } 98 | 99 | class _PreviewApp extends StatelessWidget { 100 | @override 101 | Widget build(BuildContext context) { 102 | return PreviewPage( 103 | child: Text('Select a file from /lib folder to see the preview 👀'), 104 | ); 105 | } 106 | } 107 | '''; 108 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /flutter-package/bin/old/run.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'dart:io'; 4 | 5 | import 'package:analyzer/dart/analysis/features.dart'; 6 | import 'package:analyzer/dart/analysis/utilities.dart'; 7 | import 'package:analyzer/dart/ast/ast.dart'; 8 | 9 | import 'package:analyzer/dart/ast/visitor.dart'; 10 | 11 | 12 | import 'preview_daemon.dart'; 13 | import '../templates.dart'; 14 | 15 | final featureSet = FeatureSet.fromEnableFlags([ 16 | 'extension-methods', 17 | //'non-nullable', 18 | ]); 19 | 20 | Future main() async { 21 | final daemon = PreviewDaemonService(); 22 | await daemon.start(); 23 | ProcessSignal.sigint.watch().listen((_) async { 24 | print('onClose'); 25 | await daemon.close(); 26 | exit(0); 27 | }); 28 | await daemon.listen(); 29 | } 30 | 31 | class StreamResponse { 32 | final String stdin; 33 | final HttpRequest request; 34 | 35 | StreamResponse({ 36 | this.stdin, 37 | this.request, 38 | }); 39 | 40 | when({Function(String stdin) stdin, Function(HttpRequest request) request}) { 41 | if (this.stdin != null) stdin?.call(this.stdin); 42 | if (this.request != null) request?.call(this.request); 43 | } 44 | } 45 | 46 | void generatePreview(String filePath) { 47 | if (filePath == 'lib/main.preview.dart') { 48 | File('lib/main.preview.dart').writeAsStringSync(notSeeTemplate); 49 | stdout.write('Needs reload\n'); 50 | return; 51 | } 52 | if (!filePath.startsWith('lib/')) { 53 | File('lib/main.preview.dart').writeAsStringSync(notInLibFormatTemplate); 54 | stdout.write('Needs reload\n'); 55 | return; 56 | } 57 | if (!filePath.endsWith('.dart')) { 58 | File('lib/main.preview.dart').writeAsStringSync(notValidFormatTemplate); 59 | stdout.write('Needs reload\n'); 60 | return; 61 | } 62 | final fileContent = File(filePath).readAsStringSync(); 63 | 64 | final parseResult = parseString( 65 | content: fileContent, 66 | featureSet: featureSet, 67 | path: filePath, 68 | throwIfDiagnostics: false, 69 | ); 70 | final providers = []; 71 | final unit = parseResult.unit; 72 | 73 | final v = ExtractPreviewsVisitor(providers); 74 | unit.visitChildren(v); 75 | File('lib/main.preview.dart') 76 | .writeAsStringSync(generateFile(filePath, providers)); 77 | stdout.write('Needs reload\n'); 78 | } 79 | 80 | class ExtractPreviewsVisitor extends RecursiveAstVisitor { 81 | final List providers; 82 | 83 | ExtractPreviewsVisitor(this.providers); 84 | 85 | @override 86 | visitClassDeclaration(ClassDeclaration node) { 87 | final supportedExtended = 'PreviewProvider'; 88 | final supportedMixin = 'Previewer'; 89 | 90 | bool isExtended() { 91 | final extendedClass = node.extendsClause?.superclass?.toString(); 92 | return supportedExtended == extendedClass; 93 | } 94 | 95 | bool isInMixin() { 96 | final item = node.withClause?.mixinTypes?.firstWhere( 97 | (c) { 98 | return supportedMixin == c.toString(); 99 | }, 100 | orElse: () => null, 101 | ); 102 | return item != null; 103 | } 104 | 105 | if (isExtended() || isInMixin()) { 106 | providers.add(node.name.toString()); 107 | } 108 | 109 | return super.visitClassDeclaration(node); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | generated_key_values = {} 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) do |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | generated_key_values[podname] = podpath 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | end 32 | generated_key_values 33 | end 34 | 35 | target 'Runner' do 36 | use_frameworks! 37 | use_modular_headers! 38 | 39 | # Flutter Pod 40 | 41 | copied_flutter_dir = File.join(__dir__, 'Flutter') 42 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') 43 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') 44 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) 45 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. 46 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. 47 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. 48 | 49 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') 50 | unless File.exist?(generated_xcode_build_settings_path) 51 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" 52 | end 53 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) 54 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; 55 | 56 | unless File.exist?(copied_framework_path) 57 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) 58 | end 59 | unless File.exist?(copied_podspec_path) 60 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) 61 | end 62 | end 63 | 64 | # Keep pod path relative so it can be checked into Podfile.lock. 65 | pod 'Flutter', :path => 'Flutter' 66 | 67 | # Plugin Pods 68 | 69 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 70 | # referring to absolute paths on developers' machines. 71 | system('rm -rf .symlinks') 72 | system('mkdir -p .symlinks/plugins') 73 | plugin_pods = parse_KV_file('../.flutter-plugins') 74 | plugin_pods.each do |name, path| 75 | symlink = File.join('.symlinks', 'plugins', name) 76 | File.symlink(path, symlink) 77 | pod name, :path => File.join(symlink, 'ios') 78 | end 79 | end 80 | 81 | post_install do |installer| 82 | installer.pods_project.targets.each do |target| 83 | target.build_configurations.each do |config| 84 | config.build_settings['ENABLE_BITCODE'] = 'NO' 85 | end 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /flutter-package/example/windows/runner/win32_window.h: -------------------------------------------------------------------------------- 1 | #ifndef WIN32_WINDOW_H_ 2 | #define WIN32_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | // A class abstraction for a high DPI-aware Win32 Window. Intended to be 12 | // inherited from by classes that wish to specialize with custom 13 | // rendering and input handling 14 | class Win32Window { 15 | public: 16 | struct Point { 17 | unsigned int x; 18 | unsigned int y; 19 | Point(unsigned int x, unsigned int y) : x(x), y(y) {} 20 | }; 21 | 22 | struct Size { 23 | unsigned int width; 24 | unsigned int height; 25 | Size(unsigned int width, unsigned int height) 26 | : width(width), height(height) {} 27 | }; 28 | 29 | Win32Window(); 30 | virtual ~Win32Window(); 31 | 32 | // Creates and shows a win32 window with |title| and position and size using 33 | // |origin| and |size|. New windows are created on the default monitor. Window 34 | // sizes are specified to the OS in physical pixels, hence to ensure a 35 | // consistent size to will treat the width height passed in to this function 36 | // as logical pixels and scale to appropriate for the default monitor. Returns 37 | // true if the window was created successfully. 38 | bool CreateAndShow(const std::wstring& title, 39 | const Point& origin, 40 | const Size& size); 41 | 42 | // Release OS resources associated with window. 43 | void Destroy(); 44 | 45 | // Inserts |content| into the window tree. 46 | void SetChildContent(HWND content); 47 | 48 | // Returns the backing Window handle to enable clients to set icon and other 49 | // window properties. Returns nullptr if the window has been destroyed. 50 | HWND GetHandle(); 51 | 52 | // If true, closing this window will quit the application. 53 | void SetQuitOnClose(bool quit_on_close); 54 | 55 | protected: 56 | // Processes and route salient window messages for mouse handling, 57 | // size change and DPI. Delegates handling of these to member overloads that 58 | // inheriting classes can handle. 59 | virtual LRESULT MessageHandler(HWND window, 60 | UINT const message, 61 | WPARAM const wparam, 62 | LPARAM const lparam) noexcept; 63 | 64 | // Called when CreateAndShow is called, allowing subclass window-related 65 | // setup. 66 | virtual void OnCreate(); 67 | 68 | // Called when Destroy is called. 69 | virtual void OnDestroy(); 70 | 71 | private: 72 | friend class WindowClassRegistrar; 73 | 74 | // OS callback called by message pump. Handles the WM_NCCREATE message which 75 | // is passed when the non-client area is being created and enables automatic 76 | // non-client DPI scaling so that the non-client area automatically 77 | // responsponds to changes in DPI. All other messages are handled by 78 | // MessageHandler. 79 | static LRESULT CALLBACK WndProc(HWND const window, 80 | UINT const message, 81 | WPARAM const wparam, 82 | LPARAM const lparam) noexcept; 83 | 84 | // Retrieves a class instance pointer for |window| 85 | static Win32Window* GetThisFromHandle(HWND const window) noexcept; 86 | 87 | bool quit_on_close_ = false; 88 | 89 | // window handle for top level window. 90 | HWND window_handle_ = nullptr; 91 | 92 | // window handle for hosted content. 93 | HWND child_content_ = nullptr; 94 | }; 95 | 96 | #endif // WIN32_WINDOW_H_ 97 | -------------------------------------------------------------------------------- /flutter-package/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /flutter-package/example/windows/flutter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | 3 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") 4 | 5 | # Configuration provided via flutter tool. 6 | include(${EPHEMERAL_DIR}/generated_config.cmake) 7 | 8 | # TODO: Move the rest of this into files in ephemeral. See 9 | # https://github.com/flutter/flutter/issues/57146. 10 | set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") 11 | 12 | # === Flutter Library === 13 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") 14 | 15 | # Published to parent scope for install step. 16 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 17 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 18 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 19 | set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) 20 | 21 | list(APPEND FLUTTER_LIBRARY_HEADERS 22 | "flutter_export.h" 23 | "flutter_windows.h" 24 | "flutter_messenger.h" 25 | "flutter_plugin_registrar.h" 26 | ) 27 | list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") 28 | add_library(flutter INTERFACE) 29 | target_include_directories(flutter INTERFACE 30 | "${EPHEMERAL_DIR}" 31 | ) 32 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") 33 | add_dependencies(flutter flutter_assemble) 34 | 35 | # === Wrapper === 36 | list(APPEND CPP_WRAPPER_SOURCES_CORE 37 | "engine_method_result.cc" 38 | "standard_codec.cc" 39 | ) 40 | list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") 41 | list(APPEND CPP_WRAPPER_SOURCES_PLUGIN 42 | "plugin_registrar.cc" 43 | ) 44 | list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") 45 | list(APPEND CPP_WRAPPER_SOURCES_APP 46 | "flutter_view_controller.cc" 47 | ) 48 | list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") 49 | 50 | # Wrapper sources needed for a plugin. 51 | add_library(flutter_wrapper_plugin STATIC 52 | ${CPP_WRAPPER_SOURCES_CORE} 53 | ${CPP_WRAPPER_SOURCES_PLUGIN} 54 | ) 55 | apply_standard_settings(flutter_wrapper_plugin) 56 | set_target_properties(flutter_wrapper_plugin PROPERTIES 57 | POSITION_INDEPENDENT_CODE ON) 58 | set_target_properties(flutter_wrapper_plugin PROPERTIES 59 | CXX_VISIBILITY_PRESET hidden) 60 | target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) 61 | target_include_directories(flutter_wrapper_plugin PUBLIC 62 | "${WRAPPER_ROOT}/include" 63 | ) 64 | add_dependencies(flutter_wrapper_plugin flutter_assemble) 65 | 66 | # Wrapper sources needed for the runner. 67 | add_library(flutter_wrapper_app STATIC 68 | ${CPP_WRAPPER_SOURCES_CORE} 69 | ${CPP_WRAPPER_SOURCES_APP} 70 | ) 71 | apply_standard_settings(flutter_wrapper_app) 72 | target_link_libraries(flutter_wrapper_app PUBLIC flutter) 73 | target_include_directories(flutter_wrapper_app PUBLIC 74 | "${WRAPPER_ROOT}/include" 75 | ) 76 | add_dependencies(flutter_wrapper_app flutter_assemble) 77 | 78 | # === Flutter tool backend === 79 | # _phony_ is a non-existent file to force this command to run every time, 80 | # since currently there's no way to get a full input/output list from the 81 | # flutter tool. 82 | add_custom_command( 83 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 84 | ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} 85 | ${CPP_WRAPPER_SOURCES_APP} 86 | ${CMAKE_CURRENT_BINARY_DIR}/_phony_ 87 | COMMAND ${CMAKE_COMMAND} -E env 88 | ${FLUTTER_TOOL_ENVIRONMENT} 89 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" 90 | windows-x64 $ 91 | ) 92 | add_custom_target(flutter_assemble DEPENDS 93 | "${FLUTTER_LIBRARY}" 94 | ${FLUTTER_LIBRARY_HEADERS} 95 | ${CPP_WRAPPER_SOURCES_CORE} 96 | ${CPP_WRAPPER_SOURCES_PLUGIN} 97 | ${CPP_WRAPPER_SOURCES_APP} 98 | ) 99 | -------------------------------------------------------------------------------- /flutter-package/example/windows/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.15) 2 | project(example LANGUAGES CXX) 3 | 4 | set(BINARY_NAME "example") 5 | 6 | cmake_policy(SET CMP0063 NEW) 7 | 8 | set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") 9 | 10 | # Configure build options. 11 | get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) 12 | if(IS_MULTICONFIG) 13 | set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" 14 | CACHE STRING "" FORCE) 15 | else() 16 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 17 | set(CMAKE_BUILD_TYPE "Debug" CACHE 18 | STRING "Flutter build mode" FORCE) 19 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS 20 | "Debug" "Profile" "Release") 21 | endif() 22 | endif() 23 | 24 | set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") 25 | set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") 26 | set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") 27 | set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") 28 | 29 | # Use Unicode for all projects. 30 | add_definitions(-DUNICODE -D_UNICODE) 31 | 32 | # Compilation settings that should be applied to most targets. 33 | function(APPLY_STANDARD_SETTINGS TARGET) 34 | target_compile_features(${TARGET} PUBLIC cxx_std_17) 35 | target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") 36 | target_compile_options(${TARGET} PRIVATE /EHsc) 37 | target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") 38 | target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") 39 | endfunction() 40 | 41 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") 42 | 43 | # Flutter library and tool build rules. 44 | add_subdirectory(${FLUTTER_MANAGED_DIR}) 45 | 46 | # Application build 47 | add_subdirectory("runner") 48 | 49 | # Generated plugin build rules, which manage building the plugins and adding 50 | # them to the application. 51 | include(flutter/generated_plugins.cmake) 52 | 53 | 54 | # === Installation === 55 | # Support files are copied into place next to the executable, so that it can 56 | # run in place. This is done instead of making a separate bundle (as on Linux) 57 | # so that building and running from within Visual Studio will work. 58 | set(BUILD_BUNDLE_DIR "$") 59 | # Make the "install" step default, as it's required to run. 60 | set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) 61 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 62 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) 63 | endif() 64 | 65 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") 66 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") 67 | 68 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" 69 | COMPONENT Runtime) 70 | 71 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 72 | COMPONENT Runtime) 73 | 74 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 75 | COMPONENT Runtime) 76 | 77 | if(PLUGIN_BUNDLED_LIBRARIES) 78 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" 79 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 80 | COMPONENT Runtime) 81 | endif() 82 | 83 | # Fully re-copy the assets directory on each build to avoid having stale files 84 | # from a previous install. 85 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets") 86 | install(CODE " 87 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") 88 | " COMPONENT Runtime) 89 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" 90 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) 91 | 92 | # Install the AOT library on non-Debug builds only. 93 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 94 | CONFIGURATIONS Profile;Release 95 | COMPONENT Runtime) 96 | -------------------------------------------------------------------------------- /flutter-package/bin/daemon_service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | import 'dart:io'; 4 | 5 | import 'package:json_rpc_2/json_rpc_2.dart'; 6 | import 'package:stream_channel/stream_channel.dart'; 7 | import 'package:web_socket_channel/web_socket_channel.dart'; 8 | 9 | import 'preview.dart'; 10 | 11 | class DaemonService extends MultiplePeer { 12 | final int port; 13 | DaemonService(this.port); 14 | 15 | @override 16 | registerMethods(Peer server) { 17 | server.registerMethod('preview.getPort', () { 18 | return port; 19 | }); 20 | 21 | server.registerMethod('preview.setActiveFile', (Parameters params) { 22 | final path = params['path'].asString; 23 | changeActiveFile(path); 24 | return true; 25 | }); 26 | 27 | server.registerMethod('preview.restart', (Parameters params) { 28 | _server.sendNotification('preview.restart'); 29 | return true; 30 | }); 31 | } 32 | } 33 | 34 | class Stoutsink extends StreamSink { 35 | @override 36 | void add(String event) { 37 | stdout.writeln(event); 38 | } 39 | 40 | @override 41 | void addError(Object error, [StackTrace stackTrace]) { 42 | stdout.addError(error, stackTrace); 43 | } 44 | 45 | @override 46 | Future addStream(Stream stream) { 47 | return stdout.addStream(stream.transform(Utf8Encoder())); 48 | } 49 | 50 | @override 51 | Future close() { 52 | return stdout.close(); 53 | } 54 | 55 | @override 56 | Future get done => stdout.close(); 57 | } 58 | 59 | abstract class MultiplePeer { 60 | Peer _server; 61 | Map sockets = {}; 62 | 63 | //StreamChannel _socket; 64 | 65 | bool isListening = false; 66 | 67 | addWebSocket(WebSocketChannel webSocket) { 68 | assert(sockets[webSocket] == null); 69 | final peer = Peer(webSocket.cast(), strictProtocolChecks: false); 70 | sockets[webSocket] = peer; 71 | registerMethods(peer); 72 | if (isListening) { 73 | peer.listen(); 74 | } 75 | } 76 | 77 | removeWebSocket(WebSocketChannel webSocket) { 78 | final peer = sockets[webSocket]; 79 | peer.close(); 80 | sockets[webSocket] = null; 81 | } 82 | 83 | Future run() async { 84 | // assert(port != null && webSocket != null); 85 | try { 86 | /* _socket = webSocket ?? 87 | WebSocketChannel.connect(Uri.parse('ws://127.0.0.1:$port/ws')) 88 | .cast(); */ 89 | } catch (e, s) { 90 | stderr.addError(e, s); 91 | } 92 | 93 | final channel = StreamChannel( 94 | stdin.transform(Utf8Decoder()).transform(LineSplitter()), 95 | Stoutsink(), 96 | ); 97 | 98 | _server = Peer(channel, strictProtocolChecks: false, 99 | onUnhandledError: (error, stacktrace) { 100 | stdout.write('Error $error'); 101 | }); 102 | 103 | registerMethods(_server); 104 | } 105 | 106 | Future listen() async { 107 | isListening = true; 108 | for (final socket in sockets.entries) { 109 | socket.value.listen().then( 110 | (value) { 111 | removeWebSocket(socket.key); 112 | }, 113 | ); 114 | } 115 | return await _server.listen(); 116 | } 117 | 118 | Future close() async { 119 | for (final peer in sockets.values) { 120 | await peer.close(); 121 | } 122 | return _server.close(); 123 | } 124 | 125 | /* void registerMethod(String name, Function callback) => 126 | _server.registerMethod(name, callback); */ 127 | 128 | void sendNotification(String method, [dynamic parameters]) { 129 | _server.sendNotification(method, parameters); 130 | sockets.values.forEach((e) { 131 | e.sendNotification(method, parameters); 132 | }); 133 | } 134 | 135 | registerMethods(Peer server); 136 | } 137 | -------------------------------------------------------------------------------- /flutter-package/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /flutter-package/lib/src/controls.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:flutter/foundation.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:preview/src/persist.dart'; 7 | import 'package:preview/src/screenshot.dart'; 8 | import 'package:preview/src/utils.dart'; 9 | import 'package:preview/src/vm/preview_service.dart'; 10 | 11 | import 'preview_icons.dart'; 12 | 13 | class PreviewControls extends StatefulWidget { 14 | final PersistController controller; 15 | final ScreenshotController screenshotController; 16 | 17 | PreviewControls({Key key, this.controller, this.screenshotController}) 18 | : assert(debugAssertPreviewModeRequired(runtimeType)), 19 | super(key: key); 20 | @override 21 | _PreviewControlsState createState() => _PreviewControlsState(); 22 | } 23 | 24 | class _PreviewControlsState extends State { 25 | PersistController get controller => widget.controller; 26 | 27 | @override 28 | void initState() { 29 | controller.addListener(update); 30 | super.initState(); 31 | } 32 | 33 | update() => setState(() {}); 34 | 35 | @override 36 | Widget build(BuildContext context) { 37 | return Column( 38 | mainAxisAlignment: MainAxisAlignment.end, 39 | crossAxisAlignment: CrossAxisAlignment.start, 40 | children: [ 41 | // Scene.toImage is not implemented for web 42 | // Screenshot is disable for web until this is implemented 43 | // https://github.com/flutter/flutter/issues/42767 44 | if (!kIsWeb) 45 | AnimatedContainer( 46 | height: 20, 47 | decoration: BoxDecoration( 48 | color: Colors.grey[800], 49 | shape: BoxShape.circle, 50 | ), 51 | duration: Duration(milliseconds: 200), 52 | child: IconButton( 53 | // splashRadius: 12, 54 | tooltip: 'Screenshot', 55 | iconSize: 10, 56 | padding: EdgeInsets.all(2), 57 | icon: Icon( 58 | Icons.photo_camera, 59 | color: Colors.white.withOpacity(0.8), 60 | ), 61 | onPressed: () async { 62 | final controller = widget.screenshotController; 63 | final image = await controller.takeScreenshot(); 64 | print('done'); 65 | try { 66 | PreviewService() 67 | .saveScreenshot(image, controller.settings.filename); 68 | } catch (e, s) { 69 | log('fail', error: e, stackTrace: s); 70 | } 71 | }), 72 | ), 73 | SizedBox(height: 8), 74 | if (!controller.isHotRestart) 75 | AnimatedContainer( 76 | height: 20, 77 | decoration: BoxDecoration( 78 | color: Colors.grey[800], 79 | shape: BoxShape.circle, 80 | ), 81 | duration: Duration(milliseconds: 200), 82 | child: IconButton( 83 | // splashRadius: 12, 84 | tooltip: 'Hot restart', 85 | iconSize: 12, 86 | padding: EdgeInsets.all(2), 87 | icon: Icon( 88 | PreviewIcons.lightning_bolt, 89 | color: Colors.yellow[600], 90 | ), 91 | onPressed: () => controller.restart()), 92 | ), 93 | SizedBox(height: 8), 94 | AnimatedContainer( 95 | height: 20, 96 | decoration: BoxDecoration( 97 | color: controller.isHotRestart ? Colors.blue : Colors.grey, 98 | shape: BoxShape.circle), 99 | duration: Duration(milliseconds: 200), 100 | child: IconButton( 101 | // splashRadius: 12, Not on master yet 102 | tooltip: controller.isHotRestart 103 | ? 'Disable Auto Hot Restart' 104 | : 'Enable Auto Hot Restart', 105 | iconSize: 12, 106 | padding: EdgeInsets.all(2), 107 | icon: Icon(Icons.play_arrow), 108 | onPressed: () { 109 | setState( 110 | () => controller.isHotRestart = !controller.isHotRestart); 111 | }), 112 | ) 113 | ], 114 | ); 115 | } 116 | 117 | @override 118 | void dispose() { 119 | controller.removeListener(update); 120 | super.dispose(); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /flutter-package/bin/old/daemon_service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | import 'dart:io'; 4 | 5 | import 'package:async/async.dart'; 6 | import 'package:json_rpc_2/json_rpc_2.dart'; 7 | import 'package:stream_channel/stream_channel.dart'; 8 | import 'package:web_socket_channel/web_socket_channel.dart'; 9 | 10 | import '../preview.dart'; 11 | 12 | class Stoutsink extends StreamSink { 13 | @override 14 | void add(String event) { 15 | stdout.writeln(event); 16 | } 17 | 18 | @override 19 | void addError(Object error, [StackTrace stackTrace]) { 20 | stdout.addError(error, stackTrace); 21 | } 22 | 23 | @override 24 | Future addStream(Stream stream) { 25 | return stdout.addStream(stream.transform(Utf8Encoder())); 26 | } 27 | 28 | @override 29 | Future close() { 30 | return stdout.close(); 31 | } 32 | 33 | @override 34 | Future get done => stdout.close(); 35 | } 36 | 37 | class MultipleSink extends StreamSink { 38 | final Iterable> _sinks; 39 | 40 | MultipleSink([this._sinks = const []]); 41 | 42 | @override 43 | void add(T event) { 44 | _sinks.forEach((sink) => sink.add(event)); 45 | } 46 | 47 | @override 48 | void addError(Object error, [StackTrace stackTrace]) { 49 | _sinks.forEach((sink) => sink.addError(error, stackTrace)); 50 | } 51 | 52 | @override 53 | Future addStream(Stream stream) async { 54 | for (final sink in _sinks) { 55 | await sink.addStream(stream); 56 | } 57 | } 58 | 59 | @override 60 | Future close() async { 61 | for (final sink in _sinks) { 62 | await sink.close(); 63 | } 64 | } 65 | 66 | @override 67 | Future get done => Future.wait(_sinks.map((e) => e.done)); 68 | } 69 | 70 | class DaemonService extends MultiplePeer { 71 | final int port; 72 | DaemonService(this.port); 73 | 74 | @override 75 | registerMethods(Peer server) { 76 | server.registerMethod('preview.getPort', () { 77 | return port; 78 | }); 79 | 80 | server.registerMethod('preview.setActiveFile', (Parameters params) { 81 | final path = params['path'].asString; 82 | changeActiveFile(path); 83 | return true; 84 | }); 85 | 86 | server.registerMethod('preview.restart', (Parameters params) { 87 | _server.sendNotification('preview.restart'); 88 | return true; 89 | }); 90 | } 91 | } 92 | 93 | abstract class MultiplePeer { 94 | Peer _server; 95 | Map sockets = {}; 96 | 97 | //StreamChannel _socket; 98 | 99 | bool isListening = false; 100 | 101 | addWebSocket(WebSocketChannel webSocket) { 102 | assert(sockets[webSocket] == null); 103 | final peer = Peer(webSocket.cast(), strictProtocolChecks: false); 104 | sockets[webSocket] = peer; 105 | registerMethods(peer); 106 | if (isListening) { 107 | peer.listen(); 108 | } 109 | } 110 | 111 | removeWebSocket(WebSocketChannel webSocket) { 112 | final peer = sockets[webSocket]; 113 | peer.close(); 114 | sockets[webSocket] = null; 115 | } 116 | 117 | Future run() async { 118 | // assert(port != null && webSocket != null); 119 | try { 120 | /* _socket = webSocket ?? 121 | WebSocketChannel.connect(Uri.parse('ws://127.0.0.1:$port/ws')) 122 | .cast(); */ 123 | } catch (e, s) { 124 | stderr.addError(e, s); 125 | } 126 | 127 | final stream = StreamGroup.merge([ 128 | // _socket.stream, 129 | stdin.transform(Utf8Decoder()).transform(LineSplitter()) 130 | ]); 131 | 132 | final channel = StreamChannel( 133 | stream, 134 | MultipleSink([ 135 | // _socket.sink, 136 | Stoutsink(), 137 | ]), 138 | ); 139 | 140 | _server = Peer(channel, strictProtocolChecks: false, 141 | onUnhandledError: (error, stacktrace) { 142 | stdout.write('Error $error'); 143 | }); 144 | 145 | // Any string may be used as a method name. JSON-RPC 2.0 methods are 146 | // case-sensitive. 147 | var i = 0; 148 | _server.registerMethod('count', () { 149 | // Just return the value to be sent as a response to the client. This can 150 | // be anything JSON-serializable, or a Future that completes to something 151 | // JSON-serializable. 152 | return i++; 153 | }); 154 | 155 | registerMethods(_server); 156 | } 157 | 158 | Future listen() async { 159 | isListening = true; 160 | for (final socket in sockets.entries) { 161 | socket.value.listen().then( 162 | (value) { 163 | removeWebSocket(socket.key); 164 | }, 165 | ); 166 | } 167 | return await _server.listen(); 168 | } 169 | 170 | Future close() async { 171 | for (final peer in sockets.values) { 172 | await peer.close(); 173 | } 174 | return _server.close(); 175 | } 176 | 177 | /* void registerMethod(String name, Function callback) => 178 | _server.registerMethod(name, callback); */ 179 | 180 | void sendNotification(String method, [dynamic parameters]) { 181 | _server.sendNotification(method, parameters); 182 | sockets.values.forEach((e) { 183 | e.sendNotification(method, parameters); 184 | }); 185 | } 186 | 187 | registerMethods(Peer server); 188 | } 189 | -------------------------------------------------------------------------------- /flutter-package/example/lib/external/preview.dart: -------------------------------------------------------------------------------- 1 | import 'package:device_preview/device_preview.dart'; 2 | import 'package:flutter/foundation.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:preview/preview.dart'; 5 | import 'package:random_color/random_color.dart'; 6 | 7 | void main() { 8 | runApp(MyApp()); 9 | } 10 | 11 | class MyApp extends StatelessWidget { 12 | @override 13 | Widget build(BuildContext context) { 14 | return MaterialApp( 15 | debugShowCheckedModeBanner: false, 16 | title: 'Flutter Storyboard Example', 17 | theme: ThemeData.light().copyWith( 18 | visualDensity: VisualDensity.adaptivePlatformDensity, 19 | ), 20 | builder: DevicePreview.appBuilder, 21 | darkTheme: ThemeData.dark().copyWith( 22 | visualDensity: VisualDensity.adaptivePlatformDensity, 23 | ), 24 | themeMode: ThemeMode.light, 25 | // home: HomeScreen(), 26 | initialRoute: '/settings', 27 | routes: { 28 | '/': (_) => HomeScreen(), 29 | '/counter': (_) => CounterScreen(), 30 | '/settings': (_) => SettingsScreen(), 31 | for (var i = 0; i < 25; i++) 32 | '/screen_$i': (_) => _generateScreen( 33 | title: Text('Screen$i'), 34 | color: RandomColor(i).randomColor(), 35 | ), 36 | }, 37 | onGenerateRoute: (settings) { 38 | return MaterialPageRoute( 39 | settings: settings, 40 | builder: (context) { 41 | if (settings.name == '/about') return AboutScreen(); 42 | return UnknownScreen(); 43 | }, 44 | ); 45 | }, 46 | ); 47 | } 48 | } 49 | 50 | Widget _generateScreen({ 51 | Text title, 52 | FloatingActionButton fab, 53 | Color color, 54 | }) { 55 | return Builder( 56 | builder: (context) { 57 | final Map args = 58 | ModalRoute.of(context).settings.arguments; 59 | return Scaffold( 60 | appBar: AppBar(title: title), 61 | backgroundColor: color, 62 | body: args == null ? null : Center(child: Text(args.toString())), 63 | floatingActionButton: fab, 64 | ); 65 | }, 66 | ); 67 | } 68 | 69 | class HomeScreen extends StatelessWidget { 70 | const HomeScreen({Key key}) : super(key: key); 71 | 72 | @override 73 | Widget build(BuildContext context) { 74 | final _size = MediaQuery.of(context).size; 75 | return Scaffold( 76 | appBar: AppBar( 77 | title: Text('Home Screen '), 78 | ), 79 | body: Center( 80 | child: Text(_size.toString()), 81 | ), 82 | floatingActionButton: FloatingActionButton( 83 | child: Icon(Icons.info), 84 | onPressed: () { 85 | Navigator.of(context).push(MaterialPageRoute( 86 | builder: (_) => SettingsScreen(), 87 | )); 88 | }, 89 | ), 90 | ); 91 | } 92 | } 93 | 94 | class CounterScreen extends StatefulWidget { 95 | const CounterScreen({Key key}) : super(key: key); 96 | 97 | @override 98 | _CounterScreenState createState() => _CounterScreenState(); 99 | } 100 | 101 | class _CounterScreenState extends State { 102 | int _counter = 0; 103 | @override 104 | Widget build(BuildContext context) { 105 | return Scaffold( 106 | appBar: AppBar( 107 | title: Text('Counter Example'), 108 | ), 109 | body: Center( 110 | child: Text('Counter: $_counter'), 111 | ), 112 | floatingActionButton: FloatingActionButton( 113 | child: Icon(Icons.add), 114 | onPressed: () { 115 | if (mounted) 116 | setState(() { 117 | _counter++; 118 | }); 119 | }, 120 | ), 121 | ); 122 | } 123 | } 124 | 125 | class SettingsScreen extends StatelessWidget { 126 | @override 127 | Widget build(BuildContext context) { 128 | return Scaffold( 129 | appBar: AppBar( 130 | title: Text('Settings 2'), 131 | ), 132 | backgroundColor: Colors.blue.shade300, 133 | ); 134 | } 135 | } 136 | 137 | class AboutScreen extends StatelessWidget { 138 | @override 139 | Widget build(BuildContext context) { 140 | return Scaffold( 141 | appBar: AppBar( 142 | title: Text('About'), 143 | ), 144 | backgroundColor: Colors.purple.shade300, 145 | ); 146 | } 147 | } 148 | 149 | class UnknownScreen extends StatelessWidget { 150 | @override 151 | Widget build(BuildContext context) { 152 | return Scaffold( 153 | appBar: AppBar( 154 | title: Text('404'), 155 | ), 156 | backgroundColor: Colors.red.shade300, 157 | ); 158 | } 159 | } 160 | 161 | class DevicePreviewProvider extends StatelessWidget with Previewer { 162 | @override 163 | String get title => 'Device Preview'; 164 | 165 | @override 166 | Widget build(BuildContext context) { 167 | return DevicePreview( 168 | builder: (context) => MyApp(), 169 | ); 170 | } 171 | } 172 | 173 | class DevicePreviewPreview2 extends PreviewProvider with Previewer { 174 | @override 175 | String get title => 'iPad Pro'; 176 | 177 | @override 178 | Widget build(BuildContext context) { 179 | return DevicePreview( 180 | builder: (context) => MyApp(), 181 | ); 182 | } 183 | 184 | @override 185 | List get previews => []; 186 | } 187 | -------------------------------------------------------------------------------- /flutter-package/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | 6 |

7 |
8 | Create samples of you widgets and preview them in real time 9 |
10 |
11 | 12 | 13 |

14 | 15 | 16 | 17 | ## Getting Started 18 | 19 | ### Install 20 | 21 | - Install the vscode Flutter Preview extension. [Instructions here](https://marketplace.visualstudio.com/items?itemName=jamesblasco.flutter-preview) 22 | - Add the `preview package` to your flutter project. [Instructions here](https://pub.dev/packages/preview#-installing-tab-) 23 | 24 | ### Run the preview 25 | 26 | 27 | 28 | - Open a dart file in vscode and the preview button will appear 29 | 30 | - Click the button to launch Flutter Preview 31 | 32 | ### Adding a preview 33 | 34 | A vscode snippet is availabe for creating a preview, just type `preview` and it will appear. 35 | 36 | - Create a new class that extends `PreviewProvider` 37 | 38 | ```dart 39 | 40 | class MyPreview extends PreviewProvider { 41 | 42 | List get previews { 43 | return [ 44 | 45 | ]; 46 | } 47 | } 48 | ``` 49 | 50 | - Add as many Preview widgets as samples you want to display 51 | ```dart 52 | List get previews { 53 | return [ 54 | Preview( 55 | frame: Frames.ipadPro12, 56 | child: MyApp(), 57 | ), 58 | Preview( 59 | frame: Frames.iphoneX, 60 | child: MyApp(), 61 | ), 62 | ]; 63 | } 64 | 65 | ``` 66 | 67 | And and the examples will appear in the preview window as soon as you save your file. 68 | 69 | They will appear there every time you come back to that file. 70 | 71 | ## Taking the most of Flutter Preview 72 | 73 | ### Preview Widget 74 | 75 | The `Preview` widget allows you to give default values that will impact your widget inside. The current availabe values are: 76 | - theme: Add your app theme to see your widget with your styles. 77 | - height, width: Set the size you want to set to the widget in case the widget has not size specified. 78 | - frame: See widget in different device scenarios: an android phone? or maybe an apple watch? More than 20 models and you can create your own 79 | (This is done thanks to the amazing package [device_frame](https://pub.dev/packages/device_frame) built by Aloïs Deniel 80 | - Need more? We are working to add more in a close future: Locale, Brightness, constraints... 81 | 82 | Also you can set a update mode for each preview from hot-reload to hot-restart; 83 | 84 | ### PreviewProvider 85 | 86 | 87 | You can use multiple classes that extend `PreviewProvider` and they will be displayed in different tabs. 88 | 89 | By default the name of the tab will be the class name but you can override the `title` param to customize it. 90 | 91 | ### Custom Providers 92 | 93 | PreviewProvider allows you to group different `Previews` in a single file. While this can be enough for most, you might want to create your own previews. 94 | For that you can extend any widget that extends `StatelessWidget` and make it implement the mixin `Previewer`; 95 | 96 | ```dart 97 | class MyCustomPreview extends StatelessWidget with Previewer { 98 | @override 99 | Widget build(BuildContext context) { 100 | return Container(); 101 | } 102 | } 103 | ``` 104 | 105 | It is important to add `with Previewer` always when extending any class, otherwise it won't be recognized by Flutter Preview. 106 | 107 | A already built-in custom provider is `ResizablePreviewProvider` that gives you the freedom to resize a widget to see how it could look in different scenarios. 108 | 109 | ```dart 110 | class Resizable extends ResizablePreviewProvider with Previewer { 111 | @override 112 | Preview get preview { 113 | return Preview( 114 | mode: UpdateMode.hotReload, 115 | child: MusicCard( 116 | title: 'Blond', 117 | singer: 'Frank Ocean', 118 | image: PreviewImage.asset('preview_assets/cover1.jpg'), 119 | onTap: () => {}, 120 | ), 121 | ); 122 | } 123 | } 124 | ``` 125 | 126 | You can build any other previews or use any packages if you respect this two important rules 127 | - All preview providers except the default one needs to have `with Previewer` 128 | - They need to have an empty constructor without any params. 129 | 130 | Let's see a cool example using the [device_preview](https://pub.dev/packages/device_preview) package 131 | 132 | 133 | 134 | 152 | 153 | 154 | 155 | 156 |
135 | 136 | ```dart 137 | class DevicePreviewProvider extends StatelessWidget with Previewer { 138 | @override 139 | String get title => 'Device Preview'; 140 | 141 | @override 142 | Widget build(BuildContext context) { 143 | return DevicePreview( 144 | builder: (context) => MyApp(), 145 | ); 146 | } 147 | } 148 | ``` 149 | 150 | 151 |
157 | 158 | 159 | ### Something is not working as expected? 160 | 161 | Create a [new issue](https://github.com/jamesblasco/flutter_preview/issues/new) and I will take it a look 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /vscode-extension/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | 6 |

7 |
8 | Create samples of you widgets and preview them in real time 9 |
10 |
11 | 12 | 13 |

14 | 15 | 16 | 17 | ## Getting Started 18 | 19 | ### Install 20 | 21 | - Install the vscode Flutter Preview extension. [Instructions here](https://marketplace.visualstudio.com/items?itemName=jamesblasco.flutter-preview) 22 | - Add the `preview package` to your flutter project. [Instructions here](https://pub.dev/packages/preview#-installing-tab-) 23 | 24 | ### Run the preview 25 | 26 | 27 | 28 | - Open a dart file in vscode and the preview button will appear 29 | 30 | - Click the button to launch Flutter Preview 31 | 32 | ### Adding a preview 33 | 34 | A vscode snippet is availabe for creating a preview, just type `preview` and it will appear. 35 | 36 | - Create a new class that extends `PreviewProvider` 37 | 38 | ```dart 39 | 40 | class MyPreview extends PreviewProvider { 41 | 42 | List get previews { 43 | return [ 44 | 45 | ]; 46 | } 47 | } 48 | ``` 49 | 50 | - Add as many Preview widgets as samples you want to display 51 | ```dart 52 | List get previews { 53 | return [ 54 | Preview( 55 | frame: Frames.ipadPro12, 56 | child: MyApp(), 57 | ), 58 | Preview( 59 | frame: Frames.iphoneX, 60 | child: MyApp(), 61 | ), 62 | ]; 63 | } 64 | 65 | ``` 66 | 67 | And and the examples will appear in the preview window as soon as you save your file. 68 | 69 | They will appear there every time you come back to that file. 70 | 71 | ## Taking the most of Flutter Preview 72 | 73 | ### Preview Widget 74 | 75 | The `Preview` widget allows you to give default values that will impact your widget inside. The current availabe values are: 76 | - theme: Add your app theme to see your widget with your styles. 77 | - height, width: Set the size you want to set to the widget in case the widget has not size specified. 78 | - frame: See widget in different device scenarios: an android phone? or maybe an apple watch? More than 20 models and you can create your own 79 | (This is done thanks to the amazing package [device_frame](https://pub.dev/packages/device_frame) built by Aloïs Deniel 80 | - Need more? We are working to add more in a close future: Locale, Brightness, constraints... 81 | 82 | Also you can set a update mode for each preview from hot-reload to hot-restart; 83 | 84 | ### PreviewProvider 85 | 86 | 87 | You can use multiple classes that extend `PreviewProvider` and they will be displayed in different tabs. 88 | 89 | By default the name of the tab will be the class name but you can override the `title` param to customize it. 90 | 91 | ### Custom Providers 92 | 93 | PreviewProvider allows you to group different `Previews` in a single file. While this can be enough for most, you might want to create your own previews. 94 | For that you can extend any widget that extends `StatelessWidget` and make it implement the mixin `Previewer`; 95 | 96 | ```dart 97 | class MyCustomPreview extends StatelessWidget with Previewer { 98 | @override 99 | Widget build(BuildContext context) { 100 | return Container(); 101 | } 102 | } 103 | ``` 104 | 105 | It is important to add `with Previewer` always when extending any class, otherwise it won't be recognized by Flutter Preview. 106 | 107 | A already built-in custom provider is `ResizablePreviewProvider` that gives you the freedom to resize a widget to see how it could look in different scenarios. 108 | 109 | ```dart 110 | class Resizable extends ResizablePreviewProvider with Previewer { 111 | @override 112 | Preview get preview { 113 | return Preview( 114 | mode: UpdateMode.hotReload, 115 | child: MusicCard( 116 | title: 'Blond', 117 | singer: 'Frank Ocean', 118 | image: PreviewImage.asset('preview_assets/cover1.jpg'), 119 | onTap: () => {}, 120 | ), 121 | ); 122 | } 123 | } 124 | ``` 125 | 126 | You can build any other previews or use any packages if you respect this two important rules 127 | - All preview providers except the default one needs to have `with Previewer` 128 | - They need to have an empty constructor without any params. 129 | 130 | Let's see a cool example using the [device_preview](https://pub.dev/packages/device_preview) package 131 | 132 | 133 | 134 | 152 | 153 | 154 | 155 | 156 |
135 | 136 | ```dart 137 | class DevicePreviewProvider extends StatelessWidget with Previewer { 138 | @override 139 | String get title => 'Device Preview'; 140 | 141 | @override 142 | Widget build(BuildContext context) { 143 | return DevicePreview( 144 | builder: (context) => MyApp(), 145 | ); 146 | } 147 | } 148 | ``` 149 | 150 | 151 |
157 | 158 | 159 | ### Something is not working as expected? 160 | 161 | Create a [new issue](https://github.com/jamesblasco/flutter_preview/issues/new) and I will take it a look 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /vscode-extension/src/preview.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import * as vscode from 'vscode'; 4 | 5 | import * as cp from 'child_process'; 6 | import { RcpService } from './rcp'; 7 | const kill = require('tree-kill'); 8 | 9 | 10 | const isActiveContext = 'flutter_preview.isActive'; 11 | var rcpService: RcpService; 12 | 13 | export class PreviewService { 14 | private readonly disposables: vscode.Disposable[] = []; 15 | 16 | private readonly workspaceUri: vscode.Uri; 17 | private childProcess: cp.ChildProcess | undefined; 18 | public isActive: Boolean = false; 19 | 20 | 21 | private currentDocument: vscode.Uri | undefined; 22 | 23 | private rcpService: RcpService | undefined; 24 | 25 | constructor(workspaceUri: vscode.Uri) { 26 | this.workspaceUri = workspaceUri; 27 | } 28 | 29 | async start() { 30 | let self = this; 31 | if (this.isActive && vscode.debug.activeDebugSession?.name === 'Flutter Preview') { 32 | vscode.window.showInformationMessage('Flutter preview is already running'); 33 | return; 34 | } 35 | this.isActive = true; 36 | vscode.commands.executeCommand("setContext", isActiveContext, true); 37 | await this.launchDartPreviewProccess(); 38 | 39 | let disp = vscode.workspace.onDidSaveTextDocument((e) => { self.onDidSaveTextEditor(e); }); 40 | let disp2 = vscode.window.onDidChangeActiveTextEditor((e) => { 41 | self.onDidUpdateActiveTextEditor(); 42 | }); 43 | this.disposables.push(disp, disp2); 44 | this.onDidUpdateActiveTextEditor(); 45 | } 46 | 47 | async launchDartPreviewProccess() { 48 | let self = this; 49 | console.log('Set up dart process'); 50 | try { 51 | 52 | 53 | this.childProcess = cp.spawn('flutter', [ 54 | 'pub', 55 | 'run', 56 | 'preview:preview' 57 | ], { cwd: this.workspaceUri.fsPath, shell: true }); 58 | 59 | rcpService = new RcpService(this.childProcess!.stdout!, this.childProcess!.stdin!); 60 | var sr = this.rcpService; 61 | var ch = this.childProcess; 62 | 63 | rcpService.onNotification((data) => { 64 | if (data['method'] === 'preview.restart') { 65 | vscode.commands.executeCommand('flutter.hotRestart'); 66 | } else if (data['method'] === 'preview.launch') { 67 | let port = data['params']['port']; 68 | self.launchDebugSession(port); 69 | 70 | } 71 | }); 72 | console.log('Finish Set up dart process'); 73 | this.childProcess?.on('error', (err) => { 74 | // this.cancel(); 75 | console.log('Error dart process: ', err.toString()); 76 | }); 77 | 78 | 79 | 80 | this.childProcess?.stderr?.on('data', 81 | function (data) { 82 | console.log('err data: ' + data); 83 | } 84 | ); 85 | } catch (e) { 86 | console.log(e); 87 | } 88 | } 89 | 90 | 91 | 92 | 93 | 94 | private async launchDebugSession(port: number) { 95 | 96 | const launchConfiguration = { 97 | type: "dart", 98 | name: "Flutter Preview", 99 | request: "launch", 100 | // deviceId: "macOS", 101 | cwd: "", 102 | internalConsoleOptions: "neverOpen", 103 | args: [ 104 | "--target=lib/main.preview.dart", 105 | "--dart-define=flutter.preview=true", 106 | `--dart-define=preview.port=${port}` 107 | ], 108 | }; 109 | 110 | const launched = await vscode.debug.startDebugging(vscode.workspace.workspaceFolders![0], launchConfiguration); 111 | if (!launched) { 112 | vscode.window.showInformationMessage('Flutter is not ready'); 113 | this.cancel(); 114 | return; 115 | } 116 | let disp = vscode.debug.onDidTerminateDebugSession((e) => 117 | this.cancel() 118 | ); 119 | this.disposables.push(disp); 120 | } 121 | 122 | 123 | cancel() { 124 | console.log('cancel session'); 125 | 126 | this.isActive = false; 127 | this.rcpService?.dispose(); 128 | this.rcpService = undefined; 129 | if (this.childProcess !== undefined) { 130 | kill(this.childProcess.pid, 'SIGKILL'); 131 | } 132 | this.childProcess = undefined; 133 | this.disposables.forEach((s) => s.dispose()); 134 | vscode.commands.executeCommand("setContext", isActiveContext, false); 135 | } 136 | 137 | 138 | 139 | 140 | 141 | 142 | onDidSaveTextEditor(document: vscode.TextDocument) { 143 | if (document.languageId === "dart" && document.uri === this.currentDocument) { 144 | this.onDidUpdateActiveTextEditor(); 145 | } 146 | }; 147 | 148 | 149 | 150 | onDidUpdateActiveTextEditor() { 151 | const editor = vscode.window.activeTextEditor; 152 | this.currentDocument = editor?.document?.uri; 153 | 154 | let relativePath = vscode.Uri.file(this.currentDocument!.fsPath.replace(this.workspaceUri.fsPath, '')); 155 | const path = relativePath.path.toString().replace('/', ''); 156 | 157 | rcpService.request('preview.setActiveFile', { path: path }).then((needsHotReload) => { 158 | 159 | if (needsHotReload) { 160 | vscode.commands.executeCommand('flutter.hotReload'); 161 | } 162 | }); 163 | }; 164 | 165 | dispose() { 166 | 167 | this.cancel(); 168 | } 169 | } -------------------------------------------------------------------------------- /flutter-package/bin/preview.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:io'; 3 | 4 | import 'package:analyzer/dart/analysis/utilities.dart'; 5 | import 'package:shelf_static/shelf_static.dart'; 6 | import 'package:web_socket_channel/web_socket_channel.dart'; 7 | 8 | import 'daemon_service.dart'; 9 | 10 | import 'old/run.dart'; 11 | import 'templates.dart'; 12 | import 'utils.dart'; 13 | 14 | import 'package:shelf/shelf.dart' as shelf; 15 | import 'package:shelf/shelf_io.dart' as io; 16 | import 'package:shelf_router/shelf_router.dart' as route; 17 | import 'package:shelf_web_socket/shelf_web_socket.dart' as ws; 18 | 19 | import 'package:http_server/http_server.dart'; 20 | import 'package:mime/mime.dart'; 21 | 22 | class Server { 23 | HttpServer _server; 24 | 25 | Server(this.port); 26 | 27 | Future serve(Function(WebSocketChannel) websocketHandler) async { 28 | final router = route.Router() 29 | ..get('/ws', ws.webSocketHandler(websocketHandler)) 30 | ..post('/screenshot', (shelf.Request request) async { 31 | final contentType = ContentType.parse(request.headers["content-type"]); 32 | final transformer = 33 | MimeMultipartTransformer(contentType.parameters['boundary']); 34 | 35 | final bodyStream = request.read(); 36 | final parts = await transformer.bind(bodyStream).toList(); 37 | var params; 38 | for (var part in parts) { 39 | HttpMultipartFormData multipart = HttpMultipartFormData.parse(part); 40 | 41 | //final ContentType contentType = multipart.contentType; 42 | final contentDisposition = multipart.contentDisposition; 43 | final filename = contentDisposition.parameters['filename']; 44 | 45 | final content = multipart.cast>(); 46 | 47 | final filePath = "preview/screenshots/" + filename; 48 | 49 | if (!await Directory('preview').exists()) { 50 | await Directory('preview').create(); 51 | } 52 | 53 | if (!await Directory('preview/screenshots').exists()) { 54 | await Directory('preview/screenshots').create(); 55 | } 56 | 57 | IOSink sink = File(filePath).openWrite(); 58 | await for (List item in content) { 59 | sink.add(item); 60 | } 61 | await sink.flush(); 62 | await sink.close(); 63 | } 64 | 65 | return shelf.Response.ok(params.toString()); 66 | }); 67 | 68 | final shelf.Handler staticHandler = (shelf.Request request) { 69 | final urlPath = request.url.path; 70 | final isGet = request.method == 'GET'; 71 | final isAsset = urlPath.startsWith('asset/'); 72 | 73 | if (isGet && isAsset) { 74 | final path = urlPath.replaceFirst('asset/', ''); 75 | return createFileHandler(path, url: urlPath)(request); 76 | } else { 77 | return shelf.Response.notFound(''); 78 | } 79 | }; 80 | 81 | shelf.Handler safeNotFoundHandler(shelf.Handler handler) { 82 | return (shelf.Request request) async { 83 | var resp = await handler(request); 84 | return Future.value(resp == null ? shelf.Response.notFound('') : resp); 85 | }; 86 | } 87 | 88 | final cascade = 89 | shelf.Cascade().add(staticHandler).add(router.handler).handler; 90 | 91 | var handler = const shelf.Pipeline() 92 | .addMiddleware(shelf.logRequests()) 93 | .addHandler(safeNotFoundHandler(cascade)); 94 | 95 | _server = await io.serve(handler, '127.0.0.1', port); 96 | 97 | _server.defaultResponseHeaders.remove('x-frame-options', 'SAMEORIGIN'); 98 | } 99 | 100 | final int port; 101 | InternetAddress get address => _server?.address; 102 | 103 | Future close() { 104 | return _server.close(); 105 | } 106 | } 107 | 108 | void main() async { 109 | final localAddress = InternetAddress('127.0.0.1'); 110 | final port = await getUnusedPort(localAddress); 111 | final daemonService = DaemonService(port); 112 | 113 | final server = Server(port); 114 | await server.serve((webSocket) { 115 | daemonService.addWebSocket(webSocket); 116 | }); 117 | 118 | print('Preview running on http://${server.address.host}:${server.port}'); 119 | 120 | await daemonService.run(); 121 | 122 | ProcessSignal.sigint.watch().listen((_) async { 123 | print('onClose'); 124 | await server.close(); 125 | await daemonService.close(); 126 | exit(0); 127 | }); 128 | 129 | daemonService.listen(); 130 | daemonService.sendNotification('preview.launch', {'port': port}); 131 | } 132 | 133 | String activeFilePath; 134 | 135 | void changeActiveFile(String _activeFilePath) { 136 | activeFilePath = _activeFilePath; 137 | generatePreview(activeFilePath); 138 | } 139 | 140 | void generatePreview(String filePath) { 141 | if (filePath == 'lib/main.preview.dart') { 142 | File('lib/main.preview.dart').writeAsStringSync(notSeeTemplate); 143 | return; 144 | } 145 | if (!filePath.startsWith('lib/')) { 146 | File('lib/main.preview.dart').writeAsStringSync(notInLibFormatTemplate); 147 | return; 148 | } 149 | if (!filePath.endsWith('.dart')) { 150 | File('lib/main.preview.dart').writeAsStringSync(notValidFormatTemplate); 151 | return; 152 | } 153 | final fileContent = File(filePath).readAsStringSync(); 154 | 155 | final parseResult = parseString( 156 | content: fileContent, 157 | featureSet: featureSet, 158 | path: filePath, 159 | throwIfDiagnostics: false, 160 | ); 161 | final providers = []; 162 | final unit = parseResult.unit; 163 | 164 | final v = ExtractPreviewsVisitor(providers); 165 | unit.visitChildren(v); 166 | File('lib/main.preview.dart') 167 | .writeAsStringSync(generateFile(filePath, providers)); 168 | } 169 | --------------------------------------------------------------------------------