diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 7d0d76459..6e545fe97 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -17,24 +17,12 @@ updates: update-types: ["version-update:semver-minor", "version-update:semver-patch"] labels: - "autosubmit" - - package-ecosystem: "pub" - directory: "add_to_app/android_view/flutter_module_using_plugin/" - schedule: - interval: "daily" - labels: - - "autosubmit" - package-ecosystem: "pub" directory: "add_to_app/books/flutter_module_books/" schedule: interval: "daily" labels: - "autosubmit" - - package-ecosystem: "pub" - directory: "add_to_app/fullscreen/flutter_module/" - schedule: - interval: "daily" - labels: - - "autosubmit" - package-ecosystem: "pub" directory: "add_to_app/multiple_flutters/multiple_flutters_module/" schedule: @@ -77,30 +65,6 @@ updates: interval: "daily" labels: - "autosubmit" - - package-ecosystem: "pub" - directory: "code_sharing/client/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "code_sharing/server/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "code_sharing/shared/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "deeplink_store_example/" - schedule: - interval: "daily" - labels: - - "autosubmit" - package-ecosystem: "pub" directory: "desktop_photo_search/fluent_ui/" schedule: @@ -113,126 +77,24 @@ updates: interval: "daily" labels: - "autosubmit" - - package-ecosystem: "pub" - directory: "experimental/context_menus/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "experimental/federated_plugin/federated_plugin/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "experimental/federated_plugin/federated_plugin/example/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "experimental/federated_plugin/federated_plugin_macos/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "experimental/federated_plugin/federated_plugin_platform_interface/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "experimental/federated_plugin/federated_plugin_web/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "experimental/federated_plugin/federated_plugin_windows/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "experimental/material_3_demo/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "experimental/pedometer/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "experimental/pedometer/example/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "experimental/varfont_shader_puzzle/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "experimental/web_dashboard/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "flutter_maps_firestore/" - schedule: - interval: "daily" - labels: - - "autosubmit" - package-ecosystem: "pub" directory: "form_app/" schedule: interval: "daily" labels: - "autosubmit" - - package-ecosystem: "pub" - directory: "game_template/" - schedule: - interval: "daily" - labels: - - "autosubmit" - package-ecosystem: "pub" directory: "google_maps/" schedule: interval: "daily" labels: - "autosubmit" - - package-ecosystem: "pub" - directory: "infinite_list/" - schedule: - interval: "daily" - labels: - - "autosubmit" - package-ecosystem: "pub" directory: "ios_app_clip/" schedule: interval: "daily" labels: - "autosubmit" - - package-ecosystem: "pub" - directory: "isolate_example/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "jsonexample/" - schedule: - interval: "daily" - labels: - - "autosubmit" - package-ecosystem: "pub" directory: "material_3_demo/" schedule: @@ -245,12 +107,6 @@ updates: interval: "daily" labels: - "autosubmit" - - package-ecosystem: "pub" - directory: "place_tracker/" - schedule: - interval: "daily" - labels: - - "autosubmit" - package-ecosystem: "pub" directory: "platform_channels/" schedule: @@ -270,13 +126,7 @@ updates: labels: - "autosubmit" - package-ecosystem: "pub" - directory: "provider_counter/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "provider_shopper/" + directory: "simple_sdf/" schedule: interval: "daily" labels: @@ -287,42 +137,12 @@ updates: interval: "daily" labels: - "autosubmit" - - package-ecosystem: "pub" - directory: "simplistic_calculator/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "simplistic_editor/" - schedule: - interval: "daily" - labels: - - "autosubmit" - package-ecosystem: "pub" directory: "testing_app/" schedule: interval: "daily" labels: - "autosubmit" - - package-ecosystem: "pub" - directory: "veggieseasons/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "web/_tool/" - schedule: - interval: "daily" - labels: - - "autosubmit" - - package-ecosystem: "pub" - directory: "web/samples_index/" - schedule: - interval: "daily" - labels: - - "autosubmit" - package-ecosystem: "pub" directory: "web_embedding/element_embedding_demo/" schedule: @@ -335,3 +155,4 @@ updates: interval: "daily" labels: - "autosubmit" + diff --git a/.github/workflows/gemini-cli.yml b/.github/workflows/gemini-cli.yml index ed4e1fdfa..b4feae184 100644 --- a/.github/workflows/gemini-cli.yml +++ b/.github/workflows/gemini-cli.yml @@ -91,7 +91,7 @@ jobs: id: 'generate_token' if: |- ${{ vars.APP_ID }} - uses: 'actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42' # ratchet:actions/create-github-app-token@v2 + uses: 'actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1' # ratchet:actions/create-github-app-token@v2 with: app-id: '${{ vars.APP_ID }}' private-key: '${{ secrets.APP_PRIVATE_KEY }}' diff --git a/.github/workflows/gemini-issue-automated-triage.yml b/.github/workflows/gemini-issue-automated-triage.yml index c76997958..9bc4ec054 100644 --- a/.github/workflows/gemini-issue-automated-triage.yml +++ b/.github/workflows/gemini-issue-automated-triage.yml @@ -50,7 +50,7 @@ jobs: id: 'generate_token' if: |- ${{ vars.APP_ID }} - uses: 'actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42' # ratchet:actions/create-github-app-token@v2 + uses: 'actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1' # ratchet:actions/create-github-app-token@v2 with: app-id: '${{ vars.APP_ID }}' private-key: '${{ secrets.APP_PRIVATE_KEY }}' diff --git a/.github/workflows/gemini-issue-scheduled-triage.yml b/.github/workflows/gemini-issue-scheduled-triage.yml index 10f002378..2856ce4d2 100644 --- a/.github/workflows/gemini-issue-scheduled-triage.yml +++ b/.github/workflows/gemini-issue-scheduled-triage.yml @@ -32,7 +32,7 @@ jobs: id: 'generate_token' if: |- ${{ vars.APP_ID }} - uses: 'actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42' # ratchet:actions/create-github-app-token@v2 + uses: 'actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1' # ratchet:actions/create-github-app-token@v2 with: app-id: '${{ vars.APP_ID }}' private-key: '${{ secrets.APP_PRIVATE_KEY }}' diff --git a/.github/workflows/gemini-pr-review.yml b/.github/workflows/gemini-pr-review.yml index 0405735b1..e9ae2a48d 100644 --- a/.github/workflows/gemini-pr-review.yml +++ b/.github/workflows/gemini-pr-review.yml @@ -72,7 +72,7 @@ jobs: id: 'generate_token' if: |- ${{ vars.APP_ID }} - uses: 'actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42' # ratchet:actions/create-github-app-token@v2 + uses: 'actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1' # ratchet:actions/create-github-app-token@v2 with: app-id: '${{ vars.APP_ID }}' private-key: '${{ secrets.APP_PRIVATE_KEY }}' diff --git a/README.md b/README.md index c7ad27a04..2e2f645d0 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Googler's, you can freely add samples to the [flutter/demos] repository. * [`navigation_and_routing`] - A sample that shows how to use [go_router] API to handle common navigation scenarios. * [`pedometer`] - A demo of a plugin that leverages FFIgen & JNIgen to call platform APIs directly from Dart code. * [`platform_design`] - This sample project shows a Flutter app that maximizes application code reuse while adhering to different design patterns on Android and iOS. +* [`simple_sdf`] - A simple [Flutter fragment shaders] sample project showing how to draw Signed Distance Functions with the FragmentShader API. * [`simple_shader`] - A simple [Flutter fragment shaders] sample project. * [`testing_app`] - A sample app that shows different types of testing in Flutter. * [`web_embedding`] - This directory contains examples of how to embed Flutter in web apps (without iframes). @@ -123,6 +124,7 @@ If you run into a bug in one of the samples, please file an issue in the [`navigation_and_routing`]: ./navigation_and_routing [`pedometer`]: ./pedometer [`platform_design`]: ./platform_design +[`simple_sdf`]: ./simple_sdf [`simple_shader`]: ./simple_shader [`testing_app`]: ./testing_app [`web_embedding`]: ./web_embedding diff --git a/add_to_app/ios_content_resizing/flutter_module/lib/main.dart b/add_to_app/ios_content_resizing/flutter_module/lib/main.dart index 97834ef24..24ef27fdb 100644 --- a/add_to_app/ios_content_resizing/flutter_module/lib/main.dart +++ b/add_to_app/ios_content_resizing/flutter_module/lib/main.dart @@ -33,20 +33,21 @@ class _ResizeAppState extends State { mainAxisSize: MainAxisSize.min, children: [ for (int i = 0; i < _listSize; i++) - Container(color: HSVColor.fromAHSV(1, (10.0 * i), 1, 1).toColor(), height: 50, width: 200, + Container( + color: HSVColor.fromAHSV(1, (10.0 * i), 1, 1).toColor(), + height: 50, + width: 200, child: Center( child: Text( 'Flutter Widget $i', style: const TextStyle(fontSize: 16, color: Colors.black), ), - )), - TextButton( - onPressed: _addToList, - child: Text('Listception!'), - ) + ), + ), + TextButton(onPressed: _addToList, child: Text('Listception!')), ], ), ), ); } -} \ No newline at end of file +} diff --git a/add_to_app/ios_content_resizing/ios_content_resizing/flutter_module/lib/main.dart b/add_to_app/ios_content_resizing/ios_content_resizing/flutter_module/lib/main.dart index 875600586..15cfcbaf6 100644 --- a/add_to_app/ios_content_resizing/ios_content_resizing/flutter_module/lib/main.dart +++ b/add_to_app/ios_content_resizing/ios_content_resizing/flutter_module/lib/main.dart @@ -26,7 +26,6 @@ class _MyAppState extends State { @override Widget build(BuildContext context) { - return Center( heightFactor: 1, child: Directionality( @@ -46,7 +45,6 @@ class _MyAppState extends State { child: Text("Add to list"), ), ), - ], ), ), diff --git a/add_to_app/ios_content_resizing/ios_content_resizing/flutter_module/pubspec.yaml b/add_to_app/ios_content_resizing/ios_content_resizing/flutter_module/pubspec.yaml index 2c00a2cb1..e6b38a31d 100644 --- a/add_to_app/ios_content_resizing/ios_content_resizing/flutter_module/pubspec.yaml +++ b/add_to_app/ios_content_resizing/ios_content_resizing/flutter_module/pubspec.yaml @@ -13,7 +13,7 @@ dependencies: dev_dependencies: analysis_defaults: - path: ../../../analysis_defaults + path: ../../../../analysis_defaults flutter_test: sdk: flutter flutter_driver: diff --git a/pubspec.yaml b/pubspec.yaml index e425740e3..a4a3adbf4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,7 @@ workspace: - platform_channels - platform_design - platform_view_swift + - simple_sdf - simple_shader - testing_app - tool diff --git a/simple_sdf/.gitignore b/simple_sdf/.gitignore new file mode 100644 index 000000000..24476c5d1 --- /dev/null +++ b/simple_sdf/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/simple_sdf/README.md b/simple_sdf/README.md new file mode 100644 index 000000000..564c2cdde --- /dev/null +++ b/simple_sdf/README.md @@ -0,0 +1,9 @@ +# `simple_sdf` + +A simple [Flutter fragment shaders][] sample project showing how to draw Signed Distance Functions with the FragmentShader API. + +Use `flutter create --no-overwrite .` to initialize the project. + + [Flutter fragment shaders]: https://docs.flutter.dev/development/ui/advanced/shaders + +![Screenshot of the `simple_sdf` app](screenshot.png) diff --git a/simple_sdf/analysis_options.yaml b/simple_sdf/analysis_options.yaml new file mode 100644 index 000000000..13d6fe105 --- /dev/null +++ b/simple_sdf/analysis_options.yaml @@ -0,0 +1 @@ +include: package:analysis_defaults/flutter.yaml diff --git a/simple_sdf/lib/main.dart b/simple_sdf/lib/main.dart new file mode 100644 index 000000000..214c68783 --- /dev/null +++ b/simple_sdf/lib/main.dart @@ -0,0 +1,63 @@ +// Copyright 2024 The Flutter team. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:ui' as ui; + +import 'package:flutter/material.dart'; +import 'package:flutter_shaders/flutter_shaders.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Simple SDF Demo', + theme: ThemeData(colorSchemeSeed: Colors.blue), + home: const MyHomePage(), + ); + } +} + +class MyHomePage extends StatelessWidget { + const MyHomePage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Simple SDF Demo')), + body: ShaderBuilder( + assetKey: 'shaders/SDF.frag', + (context, shader, child) => CustomPaint( + size: MediaQuery.of(context).size, + painter: ShaderPainter(shader: shader), + ), + child: const Center(child: CircularProgressIndicator()), + ), + ); + } +} + +class ShaderPainter extends CustomPainter { + ShaderPainter({required this.shader}); + ui.FragmentShader shader; + + @override + void paint(Canvas canvas, Size size) { + shader.setFloat(0, size.width); + shader.setFloat(1, size.height); + + final paint = Paint()..shader = shader; + canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), paint); + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) { + return false; + } +} diff --git a/simple_sdf/pubspec.yaml b/simple_sdf/pubspec.yaml new file mode 100644 index 000000000..4aebd30f4 --- /dev/null +++ b/simple_sdf/pubspec.yaml @@ -0,0 +1,23 @@ +name: simple_sdf +description: Using a shader, simply. +publish_to: 'none' +version: 1.0.0+1 +resolution: workspace + +environment: + sdk: ^3.9.0-0 + +dependencies: + flutter: + sdk: flutter + flutter_shaders: ^0.1.0 + +dev_dependencies: + analysis_defaults: + path: ../analysis_defaults + flutter_test: + sdk: flutter +flutter: + uses-material-design: true + shaders: + - shaders/SDF.frag diff --git a/simple_sdf/screenshot.png b/simple_sdf/screenshot.png new file mode 100644 index 000000000..405769e3d Binary files /dev/null and b/simple_sdf/screenshot.png differ diff --git a/simple_sdf/shaders/SDF.frag b/simple_sdf/shaders/SDF.frag new file mode 100644 index 000000000..e854a2272 --- /dev/null +++ b/simple_sdf/shaders/SDF.frag @@ -0,0 +1,66 @@ +// Copyright 2024 The Flutter team. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#version 460 core + +#include + +precision mediump float; + +uniform vec2 resolution; +out vec4 fragColor; + +vec3 pink = vec3(255, 105, 180) / 255; + +// dot2 and sdHeart from https://iquilezles.org/articles/distfunctions2d/ +// +// The MIT License +// Copyright © 2015 Inigo Quilez +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: The above copyright +// notice and this permission notice shall be included in all copies or +// substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", +// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR +// THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// https://www.youtube.com/c/InigoQuilez +// https://iquilezles.org + +float dot2(vec2 v) { return dot(v, v); } +float sdHeart(in vec2 p) { + p.x = abs(p.x); + + if (p.y + p.x > 1.0) + return sqrt(dot2(p - vec2(0.25, 0.75))) - sqrt(2.0) / 4.0; + return sqrt(min(dot2(p - vec2(0.00, 1.00)), + dot2(p - 0.5 * max(p.x + p.y, 0.0)))) * + sign(p.x - p.y); +} + +void main() { + vec2 st = FlutterFragCoord().xy / resolution.xy; + // Remap coordinates. + // Flutter normalized coordinates have range [0,1] but sdHeart expects [-1,1]. + st = (st - vec2(0.5)) * vec2(2.0); + // Center the heart. + // sdHeart is written such that the bottom point is at (0,0) and it's about 1 + // unit tall. + st.y -= 0.5; + // Invert Y coordinate. + st.y *= -1; + + // Calculate the color of this pixel according to the heart SDF, using + // smoothstep to anti-alias the edges. + vec3 color = vec3(0.0); + color = mix(pink, color, smoothstep(0.01, 0.02, sdHeart(st))); + + fragColor = vec4(color, 1); +} diff --git a/simple_sdf/test/widget_test.dart b/simple_sdf/test/widget_test.dart new file mode 100644 index 000000000..50e51b28c --- /dev/null +++ b/simple_sdf/test/widget_test.dart @@ -0,0 +1,13 @@ +// Copyright 2024 The Flutter team. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:simple_sdf/main.dart'; + +void main() { + testWidgets('Smoke test', (tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + }); +} diff --git a/simple_shader/lib/main.dart b/simple_shader/lib/main.dart index e314f91bf..dea7caa88 100644 --- a/simple_shader/lib/main.dart +++ b/simple_shader/lib/main.dart @@ -1,3 +1,7 @@ +// Copyright 2024 The Flutter team. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + import 'dart:ui' as ui; import 'package:flutter/material.dart'; diff --git a/simple_shader/shaders/simple.frag b/simple_shader/shaders/simple.frag index 20075c9ee..8ca802f04 100644 --- a/simple_shader/shaders/simple.frag +++ b/simple_shader/shaders/simple.frag @@ -1,3 +1,7 @@ +// Copyright 2024 The Flutter team. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + #version 460 core #include diff --git a/simple_shader/test/widget_test.dart b/simple_shader/test/widget_test.dart index 97c66d107..8b876a5ef 100644 --- a/simple_shader/test/widget_test.dart +++ b/simple_shader/test/widget_test.dart @@ -1,3 +1,7 @@ +// Copyright 2024 The Flutter team. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + import 'package:flutter_test/flutter_test.dart'; import 'package:simple_shader/main.dart'; diff --git a/testing_app/lib/screens/home.dart b/testing_app/lib/screens/home.dart index 2eac461db..c013a3b98 100644 --- a/testing_app/lib/screens/home.dart +++ b/testing_app/lib/screens/home.dart @@ -30,7 +30,6 @@ class HomePage extends StatelessWidget { ), body: ListView.builder( itemCount: 100, - cacheExtent: 20.0, controller: ScrollController(), padding: const EdgeInsets.symmetric(vertical: 16), itemBuilder: (context, index) => ItemTile(index), diff --git a/web_embedding/ng-flutter/package.json b/web_embedding/ng-flutter/package.json index 2317017d4..ae9112762 100644 --- a/web_embedding/ng-flutter/package.json +++ b/web_embedding/ng-flutter/package.json @@ -36,7 +36,7 @@ "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", - "typescript": "~5.7.2" + "typescript": "~6.0.3" }, "sideEffects": false }