├── .firebaserc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml ├── dependabot.yml ├── pull_request_template.md └── workflows │ ├── build.yml │ ├── release_deploy_play_store.yml │ ├── release_deploy_web.yml │ ├── release_deploy_windows.yml │ ├── release_draft_github_release.yml │ ├── scorecards-analysis.yml │ └── test.yml ├── .gitignore ├── .metadata ├── CHANGELOG.md ├── DEVELOPING.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── ic_launcher-web.png │ │ ├── kotlin │ │ │ └── io │ │ │ │ └── flutter │ │ │ │ └── demo │ │ │ │ └── gallery │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── drawable │ │ │ └── launch_background.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_background.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_background.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_background.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_background.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_background.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── values-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── crane │ ├── build.gradle │ └── src │ │ └── main │ │ └── AndroidManifest.xml ├── fastlane │ ├── Appfile │ ├── Fastfile │ ├── README.md │ └── metadata │ │ └── android │ │ └── en-US │ │ ├── changelogs │ │ └── default.txt │ │ ├── full_description.txt │ │ ├── images │ │ ├── featureGraphic.png │ │ ├── icon.png │ │ └── phoneScreenshots │ │ │ ├── 1_en-US.png │ │ │ ├── 2_en-US.png │ │ │ ├── 3_en-US.png │ │ │ ├── 4_en-US.png │ │ │ ├── 5_en-US.png │ │ │ ├── 6_en-US.png │ │ │ └── 7_en-US.png │ │ ├── short_description.txt │ │ ├── title.txt │ │ └── video.txt ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── deferred_components_loading_units.yaml ├── firebase.json ├── fonts ├── GalleryIcons.ttf └── google_fonts │ ├── Eczar-Regular.ttf │ ├── Eczar-SemiBold.ttf │ ├── LibreFranklin-Bold.ttf │ ├── LibreFranklin-ExtraBold.ttf │ ├── LibreFranklin-Medium.ttf │ ├── LibreFranklin-Regular.ttf │ ├── LibreFranklin-SemiBold.ttf │ ├── Merriweather-BoldItalic.ttf │ ├── Merriweather-Light.ttf │ ├── Merriweather-Regular.ttf │ ├── Montserrat-Bold.ttf │ ├── Montserrat-Medium.ttf │ ├── Montserrat-Regular.ttf │ ├── Montserrat-SemiBold.ttf │ ├── Oswald-Medium.ttf │ ├── Oswald-SemiBold.ttf │ ├── Raleway-Light.ttf │ ├── Raleway-Medium.ttf │ ├── Raleway-Regular.ttf │ ├── Raleway-SemiBold.ttf │ ├── RobotoCondensed-Bold.ttf │ ├── RobotoCondensed-Regular.ttf │ ├── RobotoMono-Regular.ttf │ ├── Rubik-Bold.ttf │ ├── Rubik-Medium.ttf │ └── Rubik-Regular.ttf ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings ├── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h ├── RunnerTests │ └── RunnerTests.swift └── firebase_app_id_file.json ├── l10n.yaml ├── lib ├── codeviewer │ ├── code_displayer.dart │ ├── code_segments.dart │ └── code_style.dart ├── constants.dart ├── data │ ├── demos.dart │ ├── gallery_options.dart │ └── icons.dart ├── deferred_widget.dart ├── demos │ ├── cupertino │ │ ├── cupertino_activity_indicator_demo.dart │ │ ├── cupertino_alert_demo.dart │ │ ├── cupertino_button_demo.dart │ │ ├── cupertino_context_menu_demo.dart │ │ ├── cupertino_demos.dart │ │ ├── cupertino_navigation_bar_demo.dart │ │ ├── cupertino_picker_demo.dart │ │ ├── cupertino_scrollbar_demo.dart │ │ ├── cupertino_search_text_field_demo.dart │ │ ├── cupertino_segmented_control_demo.dart │ │ ├── cupertino_slider_demo.dart │ │ ├── cupertino_switch_demo.dart │ │ ├── cupertino_tab_bar_demo.dart │ │ ├── cupertino_text_field_demo.dart │ │ └── demo_types.dart │ ├── material │ │ ├── app_bar_demo.dart │ │ ├── banner_demo.dart │ │ ├── bottom_app_bar_demo.dart │ │ ├── bottom_navigation_demo.dart │ │ ├── bottom_sheet_demo.dart │ │ ├── button_demo.dart │ │ ├── cards_demo.dart │ │ ├── chip_demo.dart │ │ ├── data_table_demo.dart │ │ ├── dialog_demo.dart │ │ ├── divider_demo.dart │ │ ├── grid_list_demo.dart │ │ ├── list_demo.dart │ │ ├── material_demo_types.dart │ │ ├── material_demos.dart │ │ ├── menu_demo.dart │ │ ├── navigation_drawer.dart │ │ ├── navigation_rail_demo.dart │ │ ├── picker_demo.dart │ │ ├── progress_indicator_demo.dart │ │ ├── selection_controls_demo.dart │ │ ├── sliders_demo.dart │ │ ├── snackbar_demo.dart │ │ ├── tabs_demo.dart │ │ ├── text_field_demo.dart │ │ └── tooltip_demo.dart │ └── reference │ │ ├── colors_demo.dart │ │ ├── motion_demo_container_transition.dart │ │ ├── motion_demo_fade_scale_transition.dart │ │ ├── motion_demo_fade_through_transition.dart │ │ ├── motion_demo_shared_x_axis_transition.dart │ │ ├── motion_demo_shared_y_axis_transition.dart │ │ ├── motion_demo_shared_z_axis_transition.dart │ │ ├── transformations_demo.dart │ │ ├── transformations_demo_board.dart │ │ ├── transformations_demo_color_picker.dart │ │ ├── transformations_demo_edit_board_point.dart │ │ ├── two_pane_demo.dart │ │ └── typography_demo.dart ├── feature_discovery │ ├── animation.dart │ ├── feature_discovery.dart │ └── overlay.dart ├── l10n │ ├── README.md │ ├── intl_af.arb │ ├── intl_am.arb │ ├── intl_ar.arb │ ├── intl_ar_EG.arb │ ├── intl_ar_JO.arb │ ├── intl_ar_MA.arb │ ├── intl_ar_SA.arb │ ├── intl_as.arb │ ├── intl_az.arb │ ├── intl_be.arb │ ├── intl_bg.arb │ ├── intl_bn.arb │ ├── intl_bs.arb │ ├── intl_ca.arb │ ├── intl_cs.arb │ ├── intl_cy.arb │ ├── intl_da.arb │ ├── intl_de.arb │ ├── intl_de_AT.arb │ ├── intl_de_CH.arb │ ├── intl_el.arb │ ├── intl_en.arb │ ├── intl_en_AU.arb │ ├── intl_en_CA.arb │ ├── intl_en_GB.arb │ ├── intl_en_IE.arb │ ├── intl_en_IN.arb │ ├── intl_en_NZ.arb │ ├── intl_en_SG.arb │ ├── intl_en_US.xml │ ├── intl_en_ZA.arb │ ├── intl_es.arb │ ├── intl_es_419.arb │ ├── intl_es_AR.arb │ ├── intl_es_BO.arb │ ├── intl_es_CL.arb │ ├── intl_es_CO.arb │ ├── intl_es_CR.arb │ ├── intl_es_DO.arb │ ├── intl_es_EC.arb │ ├── intl_es_GT.arb │ ├── intl_es_HN.arb │ ├── intl_es_MX.arb │ ├── intl_es_NI.arb │ ├── intl_es_PA.arb │ ├── intl_es_PE.arb │ ├── intl_es_PR.arb │ ├── intl_es_PY.arb │ ├── intl_es_SV.arb │ ├── intl_es_US.arb │ ├── intl_es_UY.arb │ ├── intl_es_VE.arb │ ├── intl_et.arb │ ├── intl_eu.arb │ ├── intl_fa.arb │ ├── intl_fi.arb │ ├── intl_fil.arb │ ├── intl_fr.arb │ ├── intl_fr_CA.arb │ ├── intl_fr_CH.arb │ ├── intl_gl.arb │ ├── intl_gsw.arb │ ├── intl_gu.arb │ ├── intl_he.arb │ ├── intl_hi.arb │ ├── intl_hr.arb │ ├── intl_hu.arb │ ├── intl_hy.arb │ ├── intl_id.arb │ ├── intl_is.arb │ ├── intl_it.arb │ ├── intl_ja.arb │ ├── intl_ka.arb │ ├── intl_kk.arb │ ├── intl_km.arb │ ├── intl_kn.arb │ ├── intl_ko.arb │ ├── intl_ky.arb │ ├── intl_lo.arb │ ├── intl_lt.arb │ ├── intl_lv.arb │ ├── intl_mk.arb │ ├── intl_ml.arb │ ├── intl_mn.arb │ ├── intl_mr.arb │ ├── intl_ms.arb │ ├── intl_my.arb │ ├── intl_nb.arb │ ├── intl_ne.arb │ ├── intl_nl.arb │ ├── intl_or.arb │ ├── intl_pa.arb │ ├── intl_pl.arb │ ├── intl_pt.arb │ ├── intl_pt_BR.arb │ ├── intl_pt_PT.arb │ ├── intl_ro.arb │ ├── intl_ru.arb │ ├── intl_si.arb │ ├── intl_sk.arb │ ├── intl_sl.arb │ ├── intl_sq.arb │ ├── intl_sr.arb │ ├── intl_sr_Latn.arb │ ├── intl_sv.arb │ ├── intl_sw.arb │ ├── intl_ta.arb │ ├── intl_te.arb │ ├── intl_th.arb │ ├── intl_tl.arb │ ├── intl_tr.arb │ ├── intl_uk.arb │ ├── intl_ur.arb │ ├── intl_uz.arb │ ├── intl_vi.arb │ ├── intl_zh.arb │ ├── intl_zh_CN.arb │ ├── intl_zh_HK.arb │ ├── intl_zh_TW.arb │ └── intl_zu.arb ├── layout │ ├── adaptive.dart │ ├── highlight_focus.dart │ ├── image_placeholder.dart │ ├── letter_spacing.dart │ └── text_scale.dart ├── main.dart ├── pages │ ├── about.dart │ ├── backdrop.dart │ ├── category_list_item.dart │ ├── demo.dart │ ├── home.dart │ ├── settings.dart │ ├── settings_icon │ │ ├── icon.dart │ │ └── metrics.dart │ ├── settings_list_item.dart │ └── splash.dart ├── routes.dart ├── studies │ ├── crane │ │ ├── app.dart │ │ ├── backdrop.dart │ │ ├── backlayer.dart │ │ ├── border_tab_indicator.dart │ │ ├── colors.dart │ │ ├── eat_form.dart │ │ ├── fly_form.dart │ │ ├── header_form.dart │ │ ├── item_cards.dart │ │ ├── model │ │ │ ├── data.dart │ │ │ ├── destination.dart │ │ │ └── formatters.dart │ │ ├── routes.dart │ │ ├── sleep_form.dart │ │ └── theme.dart │ ├── fortnightly │ │ ├── app.dart │ │ ├── routes.dart │ │ └── shared.dart │ ├── rally │ │ ├── app.dart │ │ ├── charts │ │ │ ├── line_chart.dart │ │ │ ├── pie_chart.dart │ │ │ └── vertical_fraction_bar.dart │ │ ├── colors.dart │ │ ├── data.dart │ │ ├── finance.dart │ │ ├── formatters.dart │ │ ├── home.dart │ │ ├── login.dart │ │ ├── routes.dart │ │ └── tabs │ │ │ ├── accounts.dart │ │ │ ├── bills.dart │ │ │ ├── budgets.dart │ │ │ ├── overview.dart │ │ │ ├── settings.dart │ │ │ └── sidebar.dart │ ├── reply │ │ ├── adaptive_nav.dart │ │ ├── app.dart │ │ ├── bottom_drawer.dart │ │ ├── colors.dart │ │ ├── compose_page.dart │ │ ├── mail_card_preview.dart │ │ ├── mail_view_page.dart │ │ ├── mailbox_body.dart │ │ ├── model │ │ │ ├── email_model.dart │ │ │ └── email_store.dart │ │ ├── profile_avatar.dart │ │ ├── routes.dart │ │ ├── search_page.dart │ │ └── waterfall_notched_rectangle.dart │ ├── shrine │ │ ├── app.dart │ │ ├── backdrop.dart │ │ ├── category_menu_page.dart │ │ ├── colors.dart │ │ ├── expanding_bottom_sheet.dart │ │ ├── home.dart │ │ ├── login.dart │ │ ├── model │ │ │ ├── app_state_model.dart │ │ │ ├── product.dart │ │ │ └── products_repository.dart │ │ ├── page_status.dart │ │ ├── routes.dart │ │ ├── scrim.dart │ │ ├── shopping_cart.dart │ │ ├── supplemental │ │ │ ├── asymmetric_view.dart │ │ │ ├── balanced_layout.dart │ │ │ ├── cut_corners_border.dart │ │ │ ├── desktop_product_columns.dart │ │ │ ├── layout_cache.dart │ │ │ ├── product_card.dart │ │ │ └── product_columns.dart │ │ ├── theme.dart │ │ └── triangle_category_indicator.dart │ └── starter │ │ ├── app.dart │ │ ├── home.dart │ │ └── routes.dart └── themes │ ├── gallery_theme_data.dart │ └── material_demo_theme_data.dart ├── linux ├── .gitignore ├── CMakeLists.txt ├── flutter │ ├── CMakeLists.txt │ ├── generated_plugin_registrant.cc │ ├── generated_plugin_registrant.h │ └── generated_plugins.cmake ├── main.cc ├── my_application.cc └── my_application.h ├── logs └── flutter_daemon.txt ├── macos ├── .gitignore ├── Flutter │ ├── Flutter-Debug.xcconfig │ ├── Flutter-Release.xcconfig │ └── GeneratedPluginRegistrant.swift ├── Podfile ├── Podfile.lock ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── app_icon_1024.png │ │ │ ├── app_icon_128.png │ │ │ ├── app_icon_16.png │ │ │ ├── app_icon_256.png │ │ │ ├── app_icon_32.png │ │ │ ├── app_icon_512.png │ │ │ └── app_icon_64.png │ ├── Base.lproj │ │ └── MainMenu.xib │ ├── Configs │ │ ├── AppInfo.xcconfig │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── Warnings.xcconfig │ ├── DebugProfile.entitlements │ ├── Info.plist │ ├── MainFlutterWindow.swift │ └── Release.entitlements └── RunnerTests │ └── RunnerTests.swift ├── pubspec.lock ├── pubspec.yaml ├── screenshots.md ├── test ├── code_segments_test.dart ├── demo_descriptions_test.dart ├── l10n_test.dart ├── pages │ └── home_test.dart ├── restoration_test.dart ├── theme_test.dart ├── utils.dart └── widget_test.dart ├── test_benchmarks ├── benchmarks │ ├── README.md │ ├── client.dart │ ├── common.dart │ ├── gallery_automator.dart │ ├── gallery_recorder.dart │ ├── project_root_directory.dart │ ├── run_benchmarks.dart │ └── scroll.dart ├── benchmarks_test.dart └── web_bundle_size_test.dart ├── test_driver ├── transitions_perf.dart └── transitions_perf_test.dart ├── test_goldens ├── README.md ├── demo_test.dart ├── flutter_test_config.dart ├── goldens │ ├── demo_desktop_dark.png │ ├── demo_desktop_light.png │ ├── demo_mobile_dark.png │ ├── demo_mobile_light.png │ ├── home_page_desktop_dark.png │ ├── home_page_desktop_light.png │ ├── home_page_mobile_dark.png │ ├── home_page_mobile_light.png │ ├── shrine_desktop.png │ └── shrine_mobile.png ├── home_test.dart ├── shrine_test.dart └── testing │ ├── font_loader.dart │ ├── fonts │ ├── Roboto-Black.ttf │ ├── Roboto-BlackItalic.ttf │ ├── Roboto-Bold.ttf │ ├── Roboto-BoldItalic.ttf │ ├── Roboto-Italic.ttf │ ├── Roboto-Light.ttf │ ├── Roboto-LightItalic.ttf │ ├── Roboto-Medium.ttf │ ├── Roboto-MediumItalic.ttf │ ├── Roboto-Regular.ttf │ ├── Roboto-Thin.ttf │ └── Roboto-ThinItalic.ttf │ ├── precache_images.dart │ └── util.dart ├── tool ├── codeviewer_cli │ ├── README.md │ ├── main.dart │ ├── prehighlighter.dart │ └── segment_generator.dart ├── grind.dart └── l10n_cli │ ├── README.md │ ├── l10n_cli.dart │ └── main.dart ├── web ├── 404.html ├── favicon.ico ├── favicon.png ├── icons │ ├── Icon-192.png │ ├── Icon-512.png │ ├── Icon-maskable-128.png │ ├── Icon-maskable-192.png │ ├── Icon-maskable-384.png │ ├── Icon-maskable-48.png │ ├── Icon-maskable-512.png │ ├── Icon-maskable-72.png │ └── Icon-maskable-96.png ├── index.html └── manifest.json └── windows ├── .gitignore ├── CMakeLists.txt ├── flutter ├── CMakeLists.txt ├── generated_plugin_registrant.cc ├── generated_plugin_registrant.h └── generated_plugins.cmake └── runner ├── CMakeLists.txt ├── Runner.rc ├── flutter_window.cpp ├── flutter_window.h ├── main.cpp ├── resource.h ├── resources └── app_icon.ico ├── runner.exe.manifest ├── utils.cpp ├── utils.h ├── win32_window.cpp └── win32_window.h /.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "gallery-flutter-dev" 4 | }, 5 | "targets": { 6 | "gallery-flutter-dev": { 7 | "hosting": { 8 | "prod": [ 9 | "gallery-flutter-dev" 10 | ], 11 | "staging": [ 12 | "gallery-flutter-staging" 13 | ] 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: File a bug report. 3 | labels: ["bug", "triage"] 4 | body: 5 | - type: checkboxes 6 | id: is-duplicate 7 | attributes: 8 | label: Existing issue? 9 | options: 10 | - label: I checked the [existing issues](https://github.com/flutter/gallery/issues) 11 | required: true 12 | - type: textarea 13 | id: what-happened 14 | attributes: 15 | label: What happened? 16 | description: What did you expect to happen? What actually happened? How can we reproduce the issue? 17 | value: | 18 | ## Expected vs actual result: 19 | 20 | 21 | ## Steps to reproduce: 22 | 1. 23 | 1. 24 | 1. 25 | 26 | validations: 27 | required: true 28 | - type: textarea 29 | id: logs 30 | attributes: 31 | label: Relevant log output 32 | description: Please copy and paste output of `flutter doctor -v` and other relevant logs. 33 | render: shell 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Flutter issue 4 | url: https://github.com/flutter/flutter/issues/new/choose 5 | about: I'm having an issue with Flutter itself. 6 | - name: Question 7 | url: https://stackoverflow.com/questions/tagged/flutter?tab=Frequent 8 | about: I have a question about Flutter. 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest an enhancement. 3 | labels: ["enhancement", "triage"] 4 | body: 5 | - type: textarea 6 | attributes: 7 | label: Description 8 | value: | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | validations: 21 | required: true 22 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "monthly" 12 | labels: 13 | - "autosubmit" 14 | 15 | - package-ecosystem: "bundler" 16 | directory: "/android" 17 | schedule: 18 | interval: "monthly" 19 | labels: 20 | - "autosubmit" 21 | 22 | - package-ecosystem: "pub" 23 | directory: "/" 24 | schedule: 25 | interval: "monthly" 26 | labels: 27 | - "autosubmit" 28 | versioning-strategy: "increase-if-necessary" 29 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | *Please describe the motivation behind this change.* 4 | 5 | ## Tests 6 | 7 | *Please describe the tests that you added or updated to verify your changes.* 8 | 9 | ## Issues 10 | Fixes # 11 | 12 | --- 13 | 14 | >**Note**: Please find the development and releasing instructions at https://github.com/flutter/gallery#development 15 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Builds 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | 8 | # Declare default permissions as read only. 9 | permissions: read-all 10 | 11 | jobs: 12 | build: 13 | name: Build ${{ matrix.target }} 14 | runs-on: macos-latest 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | target: ["apk --debug", "appbundle --debug", "ios --no-codesign", macos, web] 19 | steps: 20 | - name: Set up JDK 11 21 | uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 22 | with: 23 | java-version: 11 24 | distribution: temurin 25 | # Set up Flutter. 26 | - name: Clone Flutter repository with master channel 27 | uses: subosito/flutter-action@2783a3f08e1baf891508463f8c6653c258246225 28 | with: 29 | channel: master 30 | - run: flutter doctor -v 31 | 32 | # Checkout gallery code and get packages. 33 | - name: Checkout gallery code 34 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 35 | - run: flutter pub get 36 | 37 | - run: flutter build ${{ matrix.target }} 38 | -------------------------------------------------------------------------------- /.github/workflows/release_deploy_web.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to web 2 | on: 3 | # Enable manual run 4 | workflow_dispatch: 5 | inputs: 6 | environment: 7 | description: "Environment to deploy web build" 8 | required: true 9 | default: "staging" 10 | type: choice 11 | options: 12 | - staging 13 | - prod 14 | 15 | # Declare default permissions as read only. 16 | permissions: read-all 17 | 18 | jobs: 19 | build-and-deploy: 20 | runs-on: ubuntu-latest 21 | steps: 22 | # Set up Flutter. 23 | - name: Clone Flutter repository with master channel 24 | uses: subosito/flutter-action@2783a3f08e1baf891508463f8c6653c258246225 25 | with: 26 | channel: master 27 | - run: flutter doctor -v 28 | 29 | - name: Install web dependencies 30 | uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1 31 | with: 32 | node-version: "14" 33 | - run: npm install -g firebase-tools@11.0.1 34 | 35 | # Checkout gallery code and get packages. 36 | - name: Checkout gallery code 37 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 38 | - run: flutter pub get 39 | 40 | # Build and deploy (by default, to staging). 41 | - run: flutter build -v web --release 42 | - run: firebase deploy --only hosting:${{ github.event.inputs.environment || 'staging' }} 43 | env: 44 | FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} 45 | -------------------------------------------------------------------------------- /.github/workflows/release_deploy_windows.yml: -------------------------------------------------------------------------------- 1 | name: Release MSIX to Microsoft Store 2 | 3 | on: workflow_dispatch 4 | 5 | # Declare default permissions as read only. 6 | permissions: read-all 7 | 8 | jobs: 9 | build: 10 | runs-on: windows-latest 11 | 12 | steps: 13 | - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 14 | - uses: subosito/flutter-action@2783a3f08e1baf891508463f8c6653c258246225 # v2.12.0 15 | 16 | - uses: dart-lang/setup-dart@b64355ae6ca0b5d484f0106a033dd1388965d06d # v1.6.0 17 | - uses: microsoft/setup-msstore-cli@3b2ec9136230357ce9abc02b9d056626fb248d3f # v1 18 | 19 | # Instructions on obtaining these secrets can be found at https://github.com/marketplace/actions/windows-store-publish#obtaining-your-credentials 20 | - name: Configure MS CLI 21 | run: msstore reconfigure --tenantId ${{ secrets.AZURE_AD_TENANT_ID }} --clientId ${{ secrets.AZURE_AD_CLIENT_ID }} --clientSecret ${{ secrets.AZURE_AD_CLIENT_SECRET }} --sellerId ${{ secrets.SELLER_ID }} 22 | 23 | - name: Install dependencies 24 | run: flutter pub get 25 | 26 | - name: Create MSIX package 27 | run: msstore package 28 | 29 | - name: Publish MSIX to the Microsoft Store 30 | run: msstore publish -v 31 | -------------------------------------------------------------------------------- /.github/workflows/scorecards-analysis.yml: -------------------------------------------------------------------------------- 1 | name: Scorecards supply-chain security 2 | on: 3 | # Only the default branch is supported. 4 | branch_protection_rule: 5 | push: 6 | branches: [main] 7 | 8 | # Declare default permissions as read only. 9 | permissions: read-all 10 | 11 | jobs: 12 | analysis: 13 | name: Scorecards analysis 14 | runs-on: ubuntu-latest 15 | permissions: 16 | # Needed to upload the results to code-scanning dashboard. 17 | security-events: write 18 | actions: read 19 | contents: read 20 | # Needed to access OIDC token. 21 | id-token: write 22 | 23 | steps: 24 | - name: "Checkout code" 25 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 26 | with: 27 | persist-credentials: false 28 | 29 | - name: "Run analysis" 30 | uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 31 | with: 32 | results_file: results.sarif 33 | results_format: sarif 34 | # Read-only PAT token. To create it, 35 | # follow the steps in https://github.com/ossf/scorecard-action#pat-token-creation. 36 | repo_token: ${{ secrets.SCORECARD_READ_TOKEN }} 37 | # Publish the results to enable scorecard badges. For more details, see 38 | # https://github.com/ossf/scorecard-action#publishing-results. 39 | # For private repositories, `publish_results` will automatically be set to `false`, 40 | # regardless of the value entered here. 41 | publish_results: true 42 | 43 | # Upload the results as artifacts (optional). 44 | - name: "Upload artifact" 45 | uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 46 | with: 47 | name: SARIF file 48 | path: results.sarif 49 | retention-days: 5 50 | 51 | # Upload the results to GitHub's code scanning dashboard. 52 | - name: "Upload to code-scanning" 53 | uses: github/codeql-action/upload-sarif@012739e5082ff0c22ca6d6ab32e07c36df03c4a4 # v3.22.12 54 | with: 55 | sarif_file: results.sarif 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | .firebase/ 12 | .flutter-plugins-dependencies 13 | 14 | # IntelliJ related 15 | *.iml 16 | *.ipr 17 | *.iws 18 | .idea/ 19 | 20 | # The .vscode folder contains launch configuration and tasks you configure in 21 | # VS Code which you may wish to be included in version control, so this line 22 | # is commented out by default. 23 | #.vscode/ 24 | 25 | # Flutter/Dart/Pub related 26 | **/doc/api/ 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | test_goldens/failures/ 35 | 36 | # Android related 37 | **/android/**/gradle-wrapper.jar 38 | **/android/.gradle 39 | **/android/captures/ 40 | **/android/gradlew 41 | **/android/gradlew.bat 42 | **/android/local.properties 43 | **/android/**/GeneratedPluginRegistrant.java 44 | 45 | # iOS/XCode related 46 | **/ios/**/*.mode1v3 47 | **/ios/**/*.mode2v3 48 | **/ios/**/*.moved-aside 49 | **/ios/**/*.pbxuser 50 | **/ios/**/*.perspectivev3 51 | **/ios/**/*sync/ 52 | **/ios/**/.sconsign.dblite 53 | **/ios/**/.tags* 54 | **/ios/**/.vagrant/ 55 | **/ios/**/DerivedData/ 56 | **/ios/**/Icon? 57 | **/ios/**/Pods/ 58 | **/ios/**/.symlinks/ 59 | **/ios/**/profile 60 | **/ios/**/xcuserdata 61 | **/ios/.generated/ 62 | **/ios/Flutter/.last_build_id 63 | **/ios/Flutter/App.framework 64 | **/ios/Flutter/Flutter.framework 65 | **/ios/Flutter/Generated.xcconfig 66 | **/ios/Flutter/app.flx 67 | **/ios/Flutter/app.zip 68 | **/ios/Flutter/flutter_assets/ 69 | **/ios/Flutter/flutter_export_environment.sh 70 | **/ios/ServiceDefinitions.json 71 | **/ios/Runner/GeneratedPluginRegistrant.* 72 | 73 | # Exceptions to above rules. 74 | !**/ios/**/default.mode1v3 75 | !**/ios/**/default.mode2v3 76 | !**/ios/**/default.pbxuser 77 | !**/ios/**/default.perspectivev3 78 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 79 | 80 | **/google-services.json 81 | **/GoogleService-Info.plist 82 | -------------------------------------------------------------------------------- /.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. 5 | 6 | version: 7 | revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 8 | channel: main 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 17 | base_revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 18 | - platform: android 19 | create_revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 20 | base_revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 21 | - platform: ios 22 | create_revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 23 | base_revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 24 | - platform: linux 25 | create_revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 26 | base_revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 27 | - platform: macos 28 | create_revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 29 | base_revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 30 | - platform: web 31 | create_revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 32 | base_revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 33 | - platform: windows 34 | create_revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 35 | base_revision: f6b9c4da23f88394ae33a1915da47274a2d705d7 36 | 37 | # User provided section 38 | 39 | # List of Local paths (relative to this file) that should be 40 | # ignored by the migrate tool. 41 | # 42 | # Files that are not part of the templates will be ignored by default. 43 | unmanaged_files: 44 | - 'lib/main.dart' 45 | - 'ios/Runner.xcodeproj/project.pbxproj' 46 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | See https://github.com/flutter/gallery/releases. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2020, Flutter 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Flutter Gallery 2 | 3 | **NOTE**: The Flutter Gallery is now deprecated, and no longer being active maintained. 4 | 5 | Flutter Gallery was a resource to help developers evaluate and use Flutter. 6 | It is now being used primarily for testing. 7 | 8 | We recommend Flutter developers check out the following resources: 9 | 10 | * **Wonderous** 11 | ([web demo](https://wonderous.app/web/), 12 | [App Store](https://apps.apple.com/us/app/wonderous/id1612491897), 13 | [Google Play](https://play.google.com/store/apps/details?id=com.gskinner.flutter.wonders), 14 | [source code](https://github.com/gskinnerTeam/flutter-wonderous-app)):
15 | A Flutter app that showcases Flutter's support for elegant design and rich animations. 16 | 17 | * **Material 3 Demo** 18 | ([web demo](https://flutter.github.io/samples/web/material_3_demo/), 19 | [source code](https://github.com/flutter/samples/tree/main/material_3_demo)):
20 | A Flutter app that showcases Material 3 features in the Flutter Material library. 21 | 22 | * **Flutter Samples** 23 | ([samples](https://flutter.github.io/samples), [source code](https://github.com/flutter/samples)):
24 | A collection of open source samples that illustrate best practices for Flutter. 25 | 26 | * **Widget catalogs** 27 | ([Material](https://docs.flutter.dev/ui/widgets/material), [Cupertino](https://docs.flutter.dev/ui/widgets/cupertino)):
28 | Catalogs for Material, Cupertino, and other widgets available for use in UI. 29 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | linter: 4 | # In addition to the flutter_lints 5 | rules: 6 | - always_declare_return_types 7 | - avoid_types_on_closure_parameters 8 | - avoid_void_async 9 | - cancel_subscriptions 10 | - close_sinks 11 | - directives_ordering 12 | - flutter_style_todos 13 | - package_api_docs 14 | - prefer_single_quotes 15 | - test_types_in_equals 16 | - throw_in_finally 17 | - unawaited_futures 18 | - unnecessary_statements 19 | - unsafe_html 20 | - use_super_parameters 21 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # CD 10 | fastlane/report.xml 11 | 12 | # Remember to never publicly share your keystore. 13 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 14 | key.properties 15 | **/*.keystore 16 | **/*.jks -------------------------------------------------------------------------------- /android/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane" 4 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /android/app/src/main/kotlin/io/flutter/demo/gallery/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package io.flutter.demo.gallery 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | #241E30 11 | 17 | 20 | 21 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | crane 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | #E6EBEB 10 | 16 | 19 | 20 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.7.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.4.2' 10 | // START: FlutterFire Configuration 11 | classpath 'com.google.gms:google-services:4.3.10' 12 | classpath 'com.google.firebase:perf-plugin:1.4.1' 13 | classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1' 14 | // END: FlutterFire Configuration 15 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 16 | } 17 | 18 | configurations.classpath { 19 | resolutionStrategy.activateDependencyLocking() 20 | } 21 | } 22 | 23 | allprojects { 24 | repositories { 25 | google() 26 | mavenCentral() 27 | } 28 | } 29 | 30 | rootProject.buildDir = '../build' 31 | subprojects { 32 | project.buildDir = "${rootProject.buildDir}/${project.name}" 33 | project.evaluationDependsOn(':app') 34 | 35 | dependencyLocking { 36 | ignoredDependencies.add('io.flutter:*') 37 | lockFile = file("${rootProject.projectDir}/project-${project.name}.lockfile") 38 | if (!project.hasProperty('local-engine-repo')) { 39 | lockAllConfigurations() 40 | } 41 | } 42 | } 43 | 44 | tasks.register("clean", Delete) { 45 | delete rootProject.buildDir 46 | } 47 | -------------------------------------------------------------------------------- /android/crane/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.dynamic-feature" 3 | id "kotlin-android" 4 | id "com.google.firebase.crashlytics" 5 | } 6 | 7 | def keystoreProperties = new Properties() 8 | def keystorePropertiesFile = rootProject.file('key.properties') 9 | if (keystorePropertiesFile.exists()) { 10 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) 11 | } 12 | 13 | android { 14 | namespace "io.flutter.demo.gallery.crane" 15 | compileSdkVersion 31 16 | 17 | compileOptions { 18 | sourceCompatibility JavaVersion.VERSION_1_8 19 | targetCompatibility JavaVersion.VERSION_1_8 20 | } 21 | 22 | kotlinOptions { 23 | jvmTarget = '1.8' 24 | } 25 | 26 | sourceSets { 27 | applicationVariants.all { variant -> 28 | main.assets.srcDirs += "${project.buildDir}/intermediates/flutter/${variant.name}/deferred_assets" 29 | main.jniLibs.srcDirs += "${project.buildDir}/intermediates/flutter/${variant.name}/deferred_libs" 30 | } 31 | } 32 | 33 | defaultConfig { 34 | minSdkVersion 21 35 | } 36 | } 37 | 38 | dependencies { 39 | implementation project(":app") 40 | } 41 | -------------------------------------------------------------------------------- /android/crane/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /android/fastlane/Appfile: -------------------------------------------------------------------------------- 1 | package_name("io.flutter.demo.gallery") 2 | -------------------------------------------------------------------------------- /android/fastlane/Fastfile: -------------------------------------------------------------------------------- 1 | # This file contains the fastlane.tools configuration 2 | # You can find the documentation at https://docs.fastlane.tools 3 | # 4 | # For a list of all available actions, check out 5 | # 6 | # https://docs.fastlane.tools/actions 7 | # 8 | # For a list of all available plugins, check out 9 | # 10 | # https://docs.fastlane.tools/plugins/available-plugins 11 | # 12 | 13 | # Uncomment the line if you want fastlane to automatically update itself 14 | # update_fastlane 15 | 16 | default_platform(:android) 17 | 18 | platform :android do 19 | desc "Runs all the tests" 20 | lane :test do 21 | gradle(task: "test") 22 | end 23 | 24 | desc "Submit a new beta build to Google Play" 25 | lane :beta do 26 | # TODO: Re-enable deferred components once https://github.com/flutter/gallery/issues/926 is fixed 27 | sh "flutter build appbundle -v --no-deferred-components" 28 | upload_to_play_store( 29 | track: 'beta', 30 | aab: '../build/app/outputs/bundle/release/app-release.aab', 31 | json_key_data: ENV['PLAY_STORE_CONFIG_JSON'], 32 | ) 33 | end 34 | 35 | desc "Promote beta track to prod" 36 | lane :promote_to_production do 37 | upload_to_play_store( 38 | track: 'beta', 39 | track_promote_to: 'production', 40 | skip_upload_changelogs: true, 41 | json_key_data: ENV['PLAY_STORE_CONFIG_JSON'], 42 | ) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /android/fastlane/README.md: -------------------------------------------------------------------------------- 1 | fastlane documentation 2 | ---- 3 | 4 | # Installation 5 | 6 | Make sure you have the latest version of the Xcode command line tools installed: 7 | 8 | ```sh 9 | xcode-select --install 10 | ``` 11 | 12 | For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane) 13 | 14 | # Available Actions 15 | 16 | ## Android 17 | 18 | ### android test 19 | 20 | ```sh 21 | [bundle exec] fastlane android test 22 | ``` 23 | 24 | Runs all the tests 25 | 26 | ### android beta 27 | 28 | ```sh 29 | [bundle exec] fastlane android beta 30 | ``` 31 | 32 | Submit a new beta build to Google Play 33 | 34 | ### android promote_to_production 35 | 36 | ```sh 37 | [bundle exec] fastlane android promote_to_production 38 | ``` 39 | 40 | Promote beta track to prod 41 | 42 | ---- 43 | 44 | This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run. 45 | 46 | More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools). 47 | 48 | The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools). 49 | -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/changelogs/default.txt: -------------------------------------------------------------------------------- 1 | We made improvements and squashed bugs. 2 | 3 | The complete list of contributions is available at https://github.com/flutter/gallery/releases. 4 | -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/full_description.txt: -------------------------------------------------------------------------------- 1 | A gallery of widgets and behaviors, plus demos and vignettes, all built with Flutter. 2 | 3 | Flutter is Google’s UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase. 4 | 5 | This app is open source. Check out the code to see how this app is built: https://github.com/flutter/gallery. 6 | 7 | Visit https://flutter.dev to learn more. -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/images/featureGraphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/fastlane/metadata/android/en-US/images/featureGraphic.png -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/fastlane/metadata/android/en-US/images/icon.png -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/images/phoneScreenshots/4_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/fastlane/metadata/android/en-US/images/phoneScreenshots/4_en-US.png -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/images/phoneScreenshots/5_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/fastlane/metadata/android/en-US/images/phoneScreenshots/5_en-US.png -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/images/phoneScreenshots/6_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/fastlane/metadata/android/en-US/images/phoneScreenshots/6_en-US.png -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/images/phoneScreenshots/7_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/fastlane/metadata/android/en-US/images/phoneScreenshots/7_en-US.png -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/short_description.txt: -------------------------------------------------------------------------------- 1 | A gallery showcasing apps and widgets built using the Flutter framework -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/title.txt: -------------------------------------------------------------------------------- 1 | Flutter Gallery -------------------------------------------------------------------------------- /android/fastlane/metadata/android/en-US/video.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/android/fastlane/metadata/android/en-US/video.txt -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip 6 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | } 9 | settings.ext.flutterSdkPath = flutterSdkPath() 10 | 11 | includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") 12 | 13 | plugins { 14 | id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false 15 | } 16 | } 17 | 18 | include ":app", ":crane" 19 | 20 | apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle" 21 | -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": [ 3 | { 4 | "site": "flutter-gallery-archive", 5 | "public": "build/web", 6 | "ignore": [ 7 | "firebase.json", 8 | "**/.*", 9 | "**/node_modules/**" 10 | ] 11 | }, 12 | { 13 | "site": "gallery-flutter-dev", 14 | "public": "build/web", 15 | "redirects": [ 16 | { 17 | "source": "/", 18 | "destination": "https://docs.flutter.dev/gallery", 19 | "type": 301 20 | } 21 | ], 22 | "ignore": [ 23 | "firebase.json", 24 | "**/.*", 25 | "**/node_modules/**" 26 | ] 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /fonts/GalleryIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/GalleryIcons.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Eczar-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Eczar-Regular.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Eczar-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Eczar-SemiBold.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/LibreFranklin-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/LibreFranklin-Bold.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/LibreFranklin-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/LibreFranklin-ExtraBold.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/LibreFranklin-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/LibreFranklin-Medium.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/LibreFranklin-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/LibreFranklin-Regular.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/LibreFranklin-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/LibreFranklin-SemiBold.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Merriweather-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Merriweather-BoldItalic.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Merriweather-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Merriweather-Light.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Merriweather-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Merriweather-Regular.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Montserrat-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Montserrat-Bold.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Montserrat-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Montserrat-Medium.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Montserrat-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Montserrat-Regular.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Montserrat-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Montserrat-SemiBold.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Oswald-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Oswald-Medium.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Oswald-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Oswald-SemiBold.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Raleway-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Raleway-Light.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Raleway-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Raleway-Medium.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Raleway-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Raleway-Regular.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Raleway-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Raleway-SemiBold.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/RobotoCondensed-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/RobotoCondensed-Bold.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/RobotoCondensed-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/RobotoCondensed-Regular.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/RobotoMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/RobotoMono-Regular.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Rubik-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Rubik-Bold.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Rubik-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Rubik-Medium.ttf -------------------------------------------------------------------------------- /fonts/google_fonts/Rubik-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/fonts/google_fonts/Rubik-Regular.ttf -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '11.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 flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | target 'RunnerTests' do 36 | inherit! :search_paths 37 | end 38 | end 39 | 40 | post_install do |installer| 41 | installer.pods_project.targets.each do |target| 42 | flutter_additional_ios_build_settings(target) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - path_provider_foundation (0.0.1): 4 | - Flutter 5 | - FlutterMacOS 6 | - url_launcher_ios (0.0.1): 7 | - Flutter 8 | 9 | DEPENDENCIES: 10 | - Flutter (from `Flutter`) 11 | - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) 12 | - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) 13 | 14 | EXTERNAL SOURCES: 15 | Flutter: 16 | :path: Flutter 17 | path_provider_foundation: 18 | :path: ".symlinks/plugins/path_provider_foundation/darwin" 19 | url_launcher_ios: 20 | :path: ".symlinks/plugins/url_launcher_ios/ios" 21 | 22 | SPEC CHECKSUMS: 23 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 24 | path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 25 | url_launcher_ios: 68d46cc9766d0c41dbdc884310529557e3cd7a86 26 | 27 | PODFILE CHECKSUM: 70d9d25280d0dd177a5f637cdb0f0b0b12c6a189 28 | 29 | COCOAPODS: 1.13.0 30 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /ios/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /ios/firebase_app_id_file.json: -------------------------------------------------------------------------------- 1 | { 2 | "file_generated_by": "FlutterFire CLI", 3 | "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", 4 | "GOOGLE_APP_ID": "1:934901241041:ios:8d4c8bde3db3391fe621f0", 5 | "FIREBASE_PROJECT_ID": "gallery-flutter-dev", 6 | "GCM_SENDER_ID": "934901241041" 7 | } -------------------------------------------------------------------------------- /l10n.yaml: -------------------------------------------------------------------------------- 1 | template-arb-file: intl_en.arb 2 | output-localization-file: gallery_localizations.dart 3 | output-class: GalleryLocalizations 4 | preferred-supported-locales: 5 | - en 6 | use-deferred-loading: true 7 | -------------------------------------------------------------------------------- /lib/codeviewer/code_displayer.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | typedef CodeDisplayer = TextSpan Function(BuildContext context); 8 | -------------------------------------------------------------------------------- /lib/codeviewer/code_style.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | class CodeStyle extends InheritedWidget { 8 | const CodeStyle({ 9 | super.key, 10 | this.baseStyle, 11 | this.numberStyle, 12 | this.commentStyle, 13 | this.keywordStyle, 14 | this.stringStyle, 15 | this.punctuationStyle, 16 | this.classStyle, 17 | this.constantStyle, 18 | required super.child, 19 | }); 20 | 21 | final TextStyle? baseStyle; 22 | final TextStyle? numberStyle; 23 | final TextStyle? commentStyle; 24 | final TextStyle? keywordStyle; 25 | final TextStyle? stringStyle; 26 | final TextStyle? punctuationStyle; 27 | final TextStyle? classStyle; 28 | final TextStyle? constantStyle; 29 | 30 | static CodeStyle of(BuildContext context) { 31 | return context.dependOnInheritedWidgetOfExactType()!; 32 | } 33 | 34 | @override 35 | bool updateShouldNotify(CodeStyle oldWidget) => 36 | oldWidget.baseStyle != baseStyle || 37 | oldWidget.numberStyle != numberStyle || 38 | oldWidget.commentStyle != commentStyle || 39 | oldWidget.keywordStyle != keywordStyle || 40 | oldWidget.stringStyle != stringStyle || 41 | oldWidget.punctuationStyle != punctuationStyle || 42 | oldWidget.classStyle != classStyle || 43 | oldWidget.constantStyle != constantStyle; 44 | } 45 | -------------------------------------------------------------------------------- /lib/constants.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // Only put constants shared between files here. 6 | 7 | import 'dart:typed_data'; 8 | 9 | import 'package:transparent_image/transparent_image.dart' as transparent_image; 10 | 11 | // Height of the 'Gallery' header 12 | const double galleryHeaderHeight = 64; 13 | 14 | // The font size delta for headline4 font. 15 | const double desktopDisplay1FontDelta = 16; 16 | 17 | // The width of the settingsDesktop. 18 | const double desktopSettingsWidth = 520; 19 | 20 | // Sentinel value for the system text scale factor option. 21 | const double systemTextScaleFactorOption = -1; 22 | 23 | // The splash page animation duration. 24 | const Duration splashPageAnimationDuration = Duration(milliseconds: 300); 25 | 26 | // Half the splash page animation duration. 27 | const Duration halfSplashPageAnimationDuration = Duration(milliseconds: 150); 28 | 29 | // Duration for settings panel to open on mobile. 30 | const Duration settingsPanelMobileAnimationDuration = 31 | Duration(milliseconds: 200); 32 | 33 | // Duration for settings panel to open on desktop. 34 | const Duration settingsPanelDesktopAnimationDuration = 35 | Duration(milliseconds: 600); 36 | 37 | // Duration for home page elements to fade in. 38 | const Duration entranceAnimationDuration = Duration(milliseconds: 200); 39 | 40 | // The desktop top padding for a page's first header (e.g. Gallery, Settings) 41 | const double firstHeaderDesktopTopPadding = 5.0; 42 | 43 | // A transparent image used to avoid loading images when they are not needed. 44 | final Uint8List kTransparentImage = transparent_image.kTransparentImage; 45 | -------------------------------------------------------------------------------- /lib/demos/cupertino/cupertino_activity_indicator_demo.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/cupertino.dart'; 6 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 7 | 8 | // BEGIN cupertinoActivityIndicatorDemo 9 | 10 | class CupertinoProgressIndicatorDemo extends StatelessWidget { 11 | const CupertinoProgressIndicatorDemo({super.key}); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return CupertinoPageScaffold( 16 | navigationBar: CupertinoNavigationBar( 17 | automaticallyImplyLeading: false, 18 | middle: Text( 19 | GalleryLocalizations.of(context)!.demoCupertinoActivityIndicatorTitle, 20 | ), 21 | ), 22 | child: const Center( 23 | child: CupertinoActivityIndicator(), 24 | ), 25 | ); 26 | } 27 | } 28 | 29 | // END 30 | -------------------------------------------------------------------------------- /lib/demos/cupertino/cupertino_button_demo.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/cupertino.dart'; 6 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 7 | 8 | // BEGIN cupertinoButtonDemo 9 | 10 | class CupertinoButtonDemo extends StatelessWidget { 11 | const CupertinoButtonDemo({super.key}); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | final localizations = GalleryLocalizations.of(context)!; 16 | return CupertinoPageScaffold( 17 | navigationBar: CupertinoNavigationBar( 18 | automaticallyImplyLeading: false, 19 | middle: Text(localizations.demoCupertinoButtonsTitle), 20 | ), 21 | child: Center( 22 | child: Column( 23 | mainAxisAlignment: MainAxisAlignment.center, 24 | children: [ 25 | CupertinoButton( 26 | onPressed: () {}, 27 | child: Text( 28 | localizations.cupertinoButton, 29 | ), 30 | ), 31 | const SizedBox(height: 16), 32 | CupertinoButton.filled( 33 | onPressed: () {}, 34 | child: Text( 35 | localizations.cupertinoButtonWithBackground, 36 | ), 37 | ), 38 | const SizedBox(height: 30), 39 | // Disabled buttons 40 | CupertinoButton( 41 | onPressed: null, 42 | child: Text( 43 | localizations.cupertinoButton, 44 | ), 45 | ), 46 | const SizedBox(height: 16), 47 | CupertinoButton.filled( 48 | onPressed: null, 49 | child: Text( 50 | localizations.cupertinoButtonWithBackground, 51 | ), 52 | ), 53 | ], 54 | ), 55 | ), 56 | ); 57 | } 58 | } 59 | 60 | // END 61 | -------------------------------------------------------------------------------- /lib/demos/cupertino/cupertino_demos.dart: -------------------------------------------------------------------------------- 1 | export 'package:gallery/demos/cupertino/cupertino_activity_indicator_demo.dart'; 2 | export 'package:gallery/demos/cupertino/cupertino_alert_demo.dart'; 3 | export 'package:gallery/demos/cupertino/cupertino_button_demo.dart'; 4 | export 'package:gallery/demos/cupertino/cupertino_context_menu_demo.dart'; 5 | export 'package:gallery/demos/cupertino/cupertino_navigation_bar_demo.dart'; 6 | export 'package:gallery/demos/cupertino/cupertino_picker_demo.dart'; 7 | export 'package:gallery/demos/cupertino/cupertino_scrollbar_demo.dart'; 8 | export 'package:gallery/demos/cupertino/cupertino_search_text_field_demo.dart'; 9 | export 'package:gallery/demos/cupertino/cupertino_segmented_control_demo.dart'; 10 | export 'package:gallery/demos/cupertino/cupertino_slider_demo.dart'; 11 | export 'package:gallery/demos/cupertino/cupertino_switch_demo.dart'; 12 | export 'package:gallery/demos/cupertino/cupertino_tab_bar_demo.dart'; 13 | export 'package:gallery/demos/cupertino/cupertino_text_field_demo.dart'; 14 | -------------------------------------------------------------------------------- /lib/demos/cupertino/cupertino_scrollbar_demo.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/cupertino.dart'; 6 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 7 | 8 | // BEGIN cupertinoScrollbarDemo 9 | 10 | class CupertinoScrollbarDemo extends StatelessWidget { 11 | const CupertinoScrollbarDemo({super.key}); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | final localizations = GalleryLocalizations.of(context)!; 16 | return CupertinoPageScaffold( 17 | navigationBar: CupertinoNavigationBar( 18 | automaticallyImplyLeading: false, 19 | middle: Text(localizations.demoCupertinoScrollbarTitle), 20 | ), 21 | child: CupertinoScrollbar( 22 | thickness: 6.0, 23 | thicknessWhileDragging: 10.0, 24 | radius: const Radius.circular(34.0), 25 | radiusWhileDragging: Radius.zero, 26 | child: ListView.builder( 27 | itemCount: 120, 28 | itemBuilder: (context, index) { 29 | return Center( 30 | child: Text('item $index', 31 | style: CupertinoTheme.of(context).textTheme.textStyle), 32 | ); 33 | }, 34 | ), 35 | ), 36 | ); 37 | } 38 | } 39 | 40 | // END 41 | -------------------------------------------------------------------------------- /lib/demos/cupertino/demo_types.dart: -------------------------------------------------------------------------------- 1 | enum AlertDemoType { 2 | alert, 3 | alertTitle, 4 | alertButtons, 5 | alertButtonsOnly, 6 | actionSheet, 7 | } 8 | -------------------------------------------------------------------------------- /lib/demos/material/app_bar_demo.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 7 | 8 | // BEGIN appbarDemo 9 | 10 | class AppBarDemo extends StatelessWidget { 11 | const AppBarDemo({super.key}); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | var localization = GalleryLocalizations.of(context)!; 16 | return Scaffold( 17 | appBar: AppBar( 18 | leading: IconButton( 19 | tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip, 20 | icon: const Icon(Icons.menu), 21 | onPressed: () {}, 22 | ), 23 | title: Text( 24 | localization.demoAppBarTitle, 25 | ), 26 | actions: [ 27 | IconButton( 28 | tooltip: localization.starterAppTooltipFavorite, 29 | icon: const Icon( 30 | Icons.favorite, 31 | ), 32 | onPressed: () {}, 33 | ), 34 | IconButton( 35 | tooltip: localization.starterAppTooltipSearch, 36 | icon: const Icon( 37 | Icons.search, 38 | ), 39 | onPressed: () {}, 40 | ), 41 | PopupMenuButton( 42 | itemBuilder: (context) { 43 | return [ 44 | PopupMenuItem( 45 | child: Text( 46 | localization.demoNavigationRailFirst, 47 | ), 48 | ), 49 | PopupMenuItem( 50 | child: Text( 51 | localization.demoNavigationRailSecond, 52 | ), 53 | ), 54 | PopupMenuItem( 55 | child: Text( 56 | localization.demoNavigationRailThird, 57 | ), 58 | ), 59 | ]; 60 | }, 61 | ) 62 | ], 63 | ), 64 | body: Center( 65 | child: Text( 66 | localization.cupertinoTabBarHomeTab, 67 | ), 68 | ), 69 | ); 70 | } 71 | } 72 | 73 | // END 74 | -------------------------------------------------------------------------------- /lib/demos/material/list_demo.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 8 | import 'package:gallery/demos/material/material_demo_types.dart'; 9 | 10 | // BEGIN listDemo 11 | 12 | class ListDemo extends StatelessWidget { 13 | const ListDemo({super.key, required this.type}); 14 | 15 | final ListDemoType type; 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | final localizations = GalleryLocalizations.of(context)!; 20 | return Scaffold( 21 | appBar: AppBar( 22 | automaticallyImplyLeading: false, 23 | title: Text(localizations.demoListsTitle), 24 | ), 25 | body: Scrollbar( 26 | child: ListView( 27 | restorationId: 'list_demo_list_view', 28 | padding: const EdgeInsets.symmetric(vertical: 8), 29 | children: [ 30 | for (int index = 1; index < 21; index++) 31 | ListTile( 32 | leading: ExcludeSemantics( 33 | child: CircleAvatar(child: Text('$index')), 34 | ), 35 | title: Text( 36 | localizations.demoBottomSheetItem(index), 37 | ), 38 | subtitle: type == ListDemoType.twoLine 39 | ? Text(localizations.demoListsSecondary) 40 | : null, 41 | ), 42 | ], 43 | ), 44 | ), 45 | ); 46 | } 47 | } 48 | 49 | // END 50 | -------------------------------------------------------------------------------- /lib/demos/material/material_demo_types.dart: -------------------------------------------------------------------------------- 1 | enum BottomNavigationDemoType { 2 | withLabels, 3 | withoutLabels, 4 | } 5 | 6 | enum BottomSheetDemoType { 7 | persistent, 8 | modal, 9 | } 10 | 11 | enum ButtonDemoType { 12 | text, 13 | elevated, 14 | outlined, 15 | toggle, 16 | floating, 17 | } 18 | 19 | enum ChipDemoType { 20 | action, 21 | choice, 22 | filter, 23 | input, 24 | } 25 | 26 | enum DialogDemoType { 27 | alert, 28 | alertTitle, 29 | simple, 30 | fullscreen, 31 | } 32 | 33 | enum GridListDemoType { 34 | imageOnly, 35 | header, 36 | footer, 37 | } 38 | 39 | enum ListDemoType { 40 | oneLine, 41 | twoLine, 42 | } 43 | 44 | enum MenuDemoType { 45 | contextMenu, 46 | sectionedMenu, 47 | simpleMenu, 48 | checklistMenu, 49 | } 50 | 51 | enum PickerDemoType { 52 | date, 53 | time, 54 | range, 55 | } 56 | 57 | enum ProgressIndicatorDemoType { 58 | circular, 59 | linear, 60 | } 61 | 62 | enum SelectionControlsDemoType { 63 | checkbox, 64 | radio, 65 | switches, 66 | } 67 | 68 | enum SlidersDemoType { 69 | sliders, 70 | rangeSliders, 71 | customSliders, 72 | } 73 | 74 | enum TabsDemoType { 75 | scrollable, 76 | nonScrollable, 77 | } 78 | 79 | enum DividerDemoType { 80 | horizontal, 81 | vertical, 82 | } 83 | -------------------------------------------------------------------------------- /lib/demos/material/material_demos.dart: -------------------------------------------------------------------------------- 1 | export 'package:gallery/demos/material/app_bar_demo.dart'; 2 | export 'package:gallery/demos/material/banner_demo.dart'; 3 | export 'package:gallery/demos/material/bottom_app_bar_demo.dart'; 4 | export 'package:gallery/demos/material/bottom_navigation_demo.dart'; 5 | export 'package:gallery/demos/material/bottom_sheet_demo.dart'; 6 | export 'package:gallery/demos/material/button_demo.dart'; 7 | export 'package:gallery/demos/material/cards_demo.dart'; 8 | export 'package:gallery/demos/material/chip_demo.dart'; 9 | export 'package:gallery/demos/material/data_table_demo.dart'; 10 | export 'package:gallery/demos/material/dialog_demo.dart'; 11 | export 'package:gallery/demos/material/divider_demo.dart'; 12 | export 'package:gallery/demos/material/grid_list_demo.dart'; 13 | export 'package:gallery/demos/material/list_demo.dart'; 14 | export 'package:gallery/demos/material/menu_demo.dart'; 15 | export 'package:gallery/demos/material/navigation_drawer.dart'; 16 | export 'package:gallery/demos/material/navigation_rail_demo.dart'; 17 | export 'package:gallery/demos/material/picker_demo.dart'; 18 | export 'package:gallery/demos/material/progress_indicator_demo.dart'; 19 | export 'package:gallery/demos/material/selection_controls_demo.dart'; 20 | export 'package:gallery/demos/material/sliders_demo.dart'; 21 | export 'package:gallery/demos/material/snackbar_demo.dart'; 22 | export 'package:gallery/demos/material/tabs_demo.dart'; 23 | export 'package:gallery/demos/material/text_field_demo.dart'; 24 | export 'package:gallery/demos/material/tooltip_demo.dart'; 25 | -------------------------------------------------------------------------------- /lib/demos/material/navigation_drawer.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 7 | 8 | // BEGIN navDrawerDemo 9 | 10 | // Press the Navigation Drawer button to the left of AppBar to show 11 | // a simple Drawer with two items. 12 | class NavDrawerDemo extends StatelessWidget { 13 | const NavDrawerDemo({super.key}); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | var localization = GalleryLocalizations.of(context)!; 18 | final drawerHeader = UserAccountsDrawerHeader( 19 | accountName: Text( 20 | localization.demoNavigationDrawerUserName, 21 | ), 22 | accountEmail: Text( 23 | localization.demoNavigationDrawerUserEmail, 24 | ), 25 | currentAccountPicture: const CircleAvatar( 26 | child: FlutterLogo(size: 42.0), 27 | ), 28 | ); 29 | final drawerItems = ListView( 30 | children: [ 31 | drawerHeader, 32 | ListTile( 33 | title: Text( 34 | localization.demoNavigationDrawerToPageOne, 35 | ), 36 | leading: const Icon(Icons.favorite), 37 | onTap: () { 38 | Navigator.pop(context); 39 | }, 40 | ), 41 | ListTile( 42 | title: Text( 43 | localization.demoNavigationDrawerToPageTwo, 44 | ), 45 | leading: const Icon(Icons.comment), 46 | onTap: () { 47 | Navigator.pop(context); 48 | }, 49 | ), 50 | ], 51 | ); 52 | return Scaffold( 53 | appBar: AppBar( 54 | title: Text( 55 | localization.demoNavigationDrawerTitle, 56 | ), 57 | ), 58 | body: Semantics( 59 | container: true, 60 | child: Center( 61 | child: Padding( 62 | padding: const EdgeInsets.all(50.0), 63 | child: Text( 64 | localization.demoNavigationDrawerText, 65 | ), 66 | ), 67 | ), 68 | ), 69 | drawer: Drawer( 70 | child: drawerItems, 71 | ), 72 | ); 73 | } 74 | } 75 | 76 | // END 77 | -------------------------------------------------------------------------------- /lib/demos/material/snackbar_demo.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 7 | 8 | // BEGIN snackbarsDemo 9 | 10 | class SnackbarsDemo extends StatelessWidget { 11 | const SnackbarsDemo({super.key}); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | final localizations = GalleryLocalizations.of(context)!; 16 | return Scaffold( 17 | appBar: AppBar( 18 | automaticallyImplyLeading: false, 19 | title: Text(localizations.demoSnackbarsTitle), 20 | ), 21 | body: Center( 22 | child: ElevatedButton( 23 | onPressed: () { 24 | ScaffoldMessenger.of(context).hideCurrentSnackBar(); 25 | ScaffoldMessenger.of(context).showSnackBar(SnackBar( 26 | content: Text(localizations.demoSnackbarsText), 27 | action: SnackBarAction( 28 | label: localizations.demoSnackbarsActionButtonLabel, 29 | onPressed: () { 30 | ScaffoldMessenger.of(context).hideCurrentSnackBar(); 31 | ScaffoldMessenger.of(context).showSnackBar(SnackBar( 32 | content: Text( 33 | localizations.demoSnackbarsAction, 34 | ))); 35 | }, 36 | ), 37 | )); 38 | }, 39 | child: Text(localizations.demoSnackbarsButtonLabel), 40 | ), 41 | ), 42 | ); 43 | } 44 | } 45 | 46 | // END 47 | -------------------------------------------------------------------------------- /lib/demos/material/tooltip_demo.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 7 | 8 | // BEGIN tooltipDemo 9 | 10 | class TooltipDemo extends StatelessWidget { 11 | const TooltipDemo({super.key}); 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | final localizations = GalleryLocalizations.of(context)!; 16 | return Scaffold( 17 | appBar: AppBar( 18 | automaticallyImplyLeading: false, 19 | title: Text(localizations.demoTooltipTitle), 20 | ), 21 | body: Center( 22 | child: Padding( 23 | padding: const EdgeInsets.all(8), 24 | child: Column( 25 | mainAxisAlignment: MainAxisAlignment.center, 26 | children: [ 27 | Text( 28 | localizations.demoTooltipInstructions, 29 | textAlign: TextAlign.center, 30 | ), 31 | const SizedBox(height: 16), 32 | Tooltip( 33 | message: localizations.starterAppTooltipSearch, 34 | child: IconButton( 35 | color: Theme.of(context).colorScheme.primary, 36 | onPressed: () {}, 37 | icon: const Icon(Icons.search), 38 | ), 39 | ), 40 | ], 41 | ), 42 | ), 43 | ), 44 | ); 45 | } 46 | } 47 | 48 | // END 49 | -------------------------------------------------------------------------------- /lib/demos/reference/transformations_demo_color_picker.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | // A generic widget for a list of selectable colors. 8 | @immutable 9 | class ColorPicker extends StatelessWidget { 10 | const ColorPicker({ 11 | super.key, 12 | required this.colors, 13 | required this.selectedColor, 14 | this.onColorSelection, 15 | }); 16 | 17 | final Set colors; 18 | final Color selectedColor; 19 | final ValueChanged? onColorSelection; 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | return Row( 24 | mainAxisAlignment: MainAxisAlignment.center, 25 | children: colors.map((color) { 26 | return _ColorPickerSwatch( 27 | color: color, 28 | selected: color == selectedColor, 29 | onTap: () { 30 | if (onColorSelection != null) { 31 | onColorSelection!(color); 32 | } 33 | }, 34 | ); 35 | }).toList(), 36 | ); 37 | } 38 | } 39 | 40 | // A single selectable color widget in the ColorPicker. 41 | @immutable 42 | class _ColorPickerSwatch extends StatelessWidget { 43 | const _ColorPickerSwatch({ 44 | required this.color, 45 | required this.selected, 46 | this.onTap, 47 | }); 48 | 49 | final Color color; 50 | final bool selected; 51 | final Function? onTap; 52 | 53 | @override 54 | Widget build(BuildContext context) { 55 | return Container( 56 | width: 60, 57 | height: 60, 58 | padding: const EdgeInsets.fromLTRB(2, 0, 2, 0), 59 | child: RawMaterialButton( 60 | fillColor: color, 61 | onPressed: () { 62 | if (onTap != null) { 63 | onTap!(); 64 | } 65 | }, 66 | child: !selected 67 | ? null 68 | : const Icon( 69 | Icons.check, 70 | color: Colors.white, 71 | ), 72 | ), 73 | ); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lib/demos/reference/transformations_demo_edit_board_point.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:gallery/themes/gallery_theme_data.dart'; 7 | import 'transformations_demo_board.dart'; 8 | import 'transformations_demo_color_picker.dart'; 9 | 10 | const backgroundColor = Color(0xFF272727); 11 | 12 | // The panel for editing a board point. 13 | @immutable 14 | class EditBoardPoint extends StatelessWidget { 15 | const EditBoardPoint({ 16 | super.key, 17 | required this.boardPoint, 18 | this.onColorSelection, 19 | }); 20 | 21 | final BoardPoint boardPoint; 22 | final ValueChanged? onColorSelection; 23 | 24 | @override 25 | Widget build(BuildContext context) { 26 | final boardPointColors = { 27 | Colors.white, 28 | GalleryThemeData.darkColorScheme.primary, 29 | GalleryThemeData.darkColorScheme.primaryContainer, 30 | GalleryThemeData.darkColorScheme.secondary, 31 | backgroundColor, 32 | }; 33 | 34 | return Column( 35 | crossAxisAlignment: CrossAxisAlignment.stretch, 36 | children: [ 37 | Text( 38 | '${boardPoint.q}, ${boardPoint.r}', 39 | textAlign: TextAlign.right, 40 | style: const TextStyle(fontWeight: FontWeight.bold), 41 | ), 42 | ColorPicker( 43 | colors: boardPointColors, 44 | selectedColor: boardPoint.color, 45 | onColorSelection: onColorSelection, 46 | ), 47 | ], 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/layout/adaptive.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:adaptive_breakpoints/adaptive_breakpoints.dart'; 6 | import 'package:dual_screen/dual_screen.dart'; 7 | import 'package:flutter/material.dart'; 8 | 9 | /// The maximum width taken up by each item on the home screen. 10 | const maxHomeItemWidth = 1400.0; 11 | 12 | /// Returns a boolean value whether the window is considered medium or large size. 13 | /// 14 | /// When running on a desktop device that is also foldable, the display is not 15 | /// considered desktop. Widgets using this method might consider the display is 16 | /// large enough for certain layouts, which is not the case on foldable devices, 17 | /// where only part of the display is available to said widgets. 18 | /// 19 | /// Used to build adaptive and responsive layouts. 20 | bool isDisplayDesktop(BuildContext context) => 21 | !isDisplayFoldable(context) && 22 | getWindowType(context) >= AdaptiveWindowType.medium; 23 | 24 | /// Returns boolean value whether the window is considered medium size. 25 | /// 26 | /// Used to build adaptive and responsive layouts. 27 | bool isDisplaySmallDesktop(BuildContext context) { 28 | return getWindowType(context) == AdaptiveWindowType.medium; 29 | } 30 | 31 | /// Returns a boolean value whether the display has a hinge that splits the 32 | /// screen into two, left and right sub-screens. Horizontal splits (top and 33 | /// bottom sub-screens) are ignored for this application. 34 | bool isDisplayFoldable(BuildContext context) { 35 | final hinge = MediaQuery.of(context).hinge; 36 | if (hinge == null) { 37 | return false; 38 | } else { 39 | // Vertical 40 | return hinge.bounds.size.aspectRatio < 1; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/layout/letter_spacing.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | import 'package:flutter/foundation.dart'; 5 | 6 | /// Using letter spacing in Flutter for Web can cause a performance drop, 7 | /// see https://github.com/flutter/flutter/issues/51234. 8 | double letterSpacingOrNone(double letterSpacing) => 9 | kIsWeb ? 0.0 : letterSpacing; 10 | -------------------------------------------------------------------------------- /lib/layout/text_scale.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:math'; 6 | 7 | import 'package:flutter/material.dart'; 8 | 9 | import 'package:gallery/data/gallery_options.dart'; 10 | 11 | double _textScaleFactor(BuildContext context) { 12 | return GalleryOptions.of(context).textScaleFactor(context); 13 | } 14 | 15 | // When text is larger, this factor becomes larger, but at half the rate. 16 | // 17 | // | Text scaling | Text scale factor | reducedTextScale(context) | 18 | // |--------------|-------------------|---------------------------| 19 | // | Small | 0.8 | 1.0 | 20 | // | Normal | 1.0 | 1.0 | 21 | // | Large | 2.0 | 1.5 | 22 | // | Huge | 3.0 | 2.0 | 23 | 24 | double reducedTextScale(BuildContext context) { 25 | final textScaleFactor = _textScaleFactor(context); 26 | return textScaleFactor >= 1 ? (1 + textScaleFactor) / 2 : 1; 27 | } 28 | 29 | // When text is larger, this factor becomes larger at the same rate. 30 | // But when text is smaller, this factor stays at 1. 31 | // 32 | // | Text scaling | Text scale factor | cappedTextScale(context) | 33 | // |--------------|-------------------|---------------------------| 34 | // | Small | 0.8 | 1.0 | 35 | // | Normal | 1.0 | 1.0 | 36 | // | Large | 2.0 | 2.0 | 37 | // | Huge | 3.0 | 3.0 | 38 | 39 | double cappedTextScale(BuildContext context) { 40 | final textScaleFactor = _textScaleFactor(context); 41 | return max(textScaleFactor, 1); 42 | } 43 | -------------------------------------------------------------------------------- /lib/studies/crane/app.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 7 | import 'package:gallery/data/gallery_options.dart'; 8 | import 'package:gallery/studies/crane/backdrop.dart'; 9 | import 'package:gallery/studies/crane/eat_form.dart'; 10 | import 'package:gallery/studies/crane/fly_form.dart'; 11 | import 'package:gallery/studies/crane/routes.dart' as routes; 12 | import 'package:gallery/studies/crane/sleep_form.dart'; 13 | import 'package:gallery/studies/crane/theme.dart'; 14 | 15 | class CraneApp extends StatelessWidget { 16 | const CraneApp({super.key}); 17 | 18 | static const String defaultRoute = routes.defaultRoute; 19 | 20 | @override 21 | Widget build(BuildContext context) { 22 | return MaterialApp( 23 | restorationScopeId: 'crane_app', 24 | title: 'Crane', 25 | debugShowCheckedModeBanner: false, 26 | localizationsDelegates: GalleryLocalizations.localizationsDelegates, 27 | supportedLocales: GalleryLocalizations.supportedLocales, 28 | locale: GalleryOptions.of(context).locale, 29 | initialRoute: CraneApp.defaultRoute, 30 | routes: { 31 | CraneApp.defaultRoute: (context) => const _Home(), 32 | }, 33 | theme: craneTheme.copyWith( 34 | platform: GalleryOptions.of(context).platform, 35 | ), 36 | ); 37 | } 38 | } 39 | 40 | class _Home extends StatelessWidget { 41 | const _Home(); 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | return const ApplyTextOptions( 46 | child: Backdrop( 47 | frontLayer: SizedBox(), 48 | backLayerItems: [ 49 | FlyForm(), 50 | SleepForm(), 51 | EatForm(), 52 | ], 53 | frontTitle: Text('CRANE'), 54 | backTitle: Text('MENU'), 55 | ), 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /lib/studies/crane/backlayer.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | abstract class BackLayerItem extends StatefulWidget { 8 | final int index; 9 | 10 | const BackLayerItem({super.key, required this.index}); 11 | } 12 | 13 | class BackLayer extends StatefulWidget { 14 | final List backLayerItems; 15 | final TabController tabController; 16 | 17 | const BackLayer({ 18 | super.key, 19 | required this.backLayerItems, 20 | required this.tabController, 21 | }); 22 | 23 | @override 24 | State createState() => _BackLayerState(); 25 | } 26 | 27 | class _BackLayerState extends State { 28 | @override 29 | void initState() { 30 | super.initState(); 31 | widget.tabController.addListener(() => setState(() {})); 32 | } 33 | 34 | @override 35 | Widget build(BuildContext context) { 36 | final tabIndex = widget.tabController.index; 37 | return IndexedStack( 38 | index: tabIndex, 39 | children: [ 40 | for (BackLayerItem backLayerItem in widget.backLayerItems) 41 | ExcludeFocus( 42 | excluding: backLayerItem.index != tabIndex, 43 | child: backLayerItem, 44 | ) 45 | ], 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/studies/crane/border_tab_indicator.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | class BorderTabIndicator extends Decoration { 8 | const BorderTabIndicator({ 9 | required this.indicatorHeight, 10 | required this.textScaleFactor, 11 | }) : super(); 12 | 13 | final double indicatorHeight; 14 | final double textScaleFactor; 15 | 16 | @override 17 | BorderPainter createBoxPainter([VoidCallback? onChanged]) { 18 | return BorderPainter(this, indicatorHeight, textScaleFactor, onChanged); 19 | } 20 | } 21 | 22 | class BorderPainter extends BoxPainter { 23 | BorderPainter( 24 | this.decoration, 25 | this.indicatorHeight, 26 | this.textScaleFactor, 27 | VoidCallback? onChanged, 28 | ) : assert(indicatorHeight >= 0), 29 | super(onChanged); 30 | 31 | final BorderTabIndicator decoration; 32 | final double indicatorHeight; 33 | final double textScaleFactor; 34 | 35 | @override 36 | void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { 37 | assert(configuration.size != null); 38 | final horizontalInset = 16 - 4 * textScaleFactor; 39 | final rect = Offset(offset.dx + horizontalInset, 40 | (configuration.size!.height / 2) - indicatorHeight / 2 - 1) & 41 | Size(configuration.size!.width - 2 * horizontalInset, indicatorHeight); 42 | final paint = Paint(); 43 | paint.color = Colors.white; 44 | paint.style = PaintingStyle.stroke; 45 | paint.strokeWidth = 2; 46 | canvas.drawRRect( 47 | RRect.fromRectAndRadius(rect, const Radius.circular(56)), 48 | paint, 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/studies/crane/colors.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | const cranePurple700 = Color(0xFF720D5D); 8 | const cranePurple800 = Color(0xFF5D1049); 9 | const cranePurple900 = Color(0xFF4E0D3A); 10 | 11 | const craneRed700 = Color(0xFFE30425); 12 | 13 | const craneWhite60 = Color(0x99FFFFFF); 14 | const cranePrimaryWhite = Color(0xFFFFFFFF); 15 | const craneErrorOrange = Color(0xFFFF9100); 16 | 17 | const craneAlpha = Color(0x00FFFFFF); 18 | 19 | const craneGrey = Color(0xFF747474); 20 | const craneBlack = Color(0xFF1E252D); 21 | -------------------------------------------------------------------------------- /lib/studies/crane/model/formatters.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 7 | 8 | // Duration of time (e.g. 16h 12m) 9 | String formattedDuration(BuildContext context, Duration duration, 10 | {bool? abbreviated}) { 11 | final localizations = GalleryLocalizations.of(context)!; 12 | 13 | final hoursShortForm = localizations.craneHours(duration.inHours.toInt()); 14 | final minutesShortForm = localizations.craneMinutes(duration.inMinutes % 60); 15 | return localizations.craneFlightDuration(hoursShortForm, minutesShortForm); 16 | } 17 | -------------------------------------------------------------------------------- /lib/studies/crane/routes.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | const String defaultRoute = '/crane'; 6 | -------------------------------------------------------------------------------- /lib/studies/crane/sleep_form.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 7 | 8 | import 'package:gallery/studies/crane/backlayer.dart'; 9 | import 'package:gallery/studies/crane/header_form.dart'; 10 | 11 | class SleepForm extends BackLayerItem { 12 | const SleepForm({super.key}) : super(index: 1); 13 | 14 | @override 15 | State createState() => _SleepFormState(); 16 | } 17 | 18 | class _SleepFormState extends State with RestorationMixin { 19 | final travelerController = RestorableTextEditingController(); 20 | final dateController = RestorableTextEditingController(); 21 | final locationController = RestorableTextEditingController(); 22 | 23 | @override 24 | String get restorationId => 'sleep_form'; 25 | 26 | @override 27 | void restoreState(RestorationBucket? oldBucket, bool initialRestore) { 28 | registerForRestoration(travelerController, 'diner_controller'); 29 | registerForRestoration(dateController, 'date_controller'); 30 | registerForRestoration(locationController, 'time_controller'); 31 | } 32 | 33 | @override 34 | void dispose() { 35 | travelerController.dispose(); 36 | dateController.dispose(); 37 | locationController.dispose(); 38 | super.dispose(); 39 | } 40 | 41 | @override 42 | Widget build(BuildContext context) { 43 | final localizations = GalleryLocalizations.of(context)!; 44 | 45 | return HeaderForm( 46 | fields: [ 47 | HeaderFormField( 48 | index: 0, 49 | iconData: Icons.person, 50 | title: localizations.craneFormTravelers, 51 | textController: travelerController.value, 52 | ), 53 | HeaderFormField( 54 | index: 1, 55 | iconData: Icons.date_range, 56 | title: localizations.craneFormDates, 57 | textController: dateController.value, 58 | ), 59 | HeaderFormField( 60 | index: 2, 61 | iconData: Icons.hotel, 62 | title: localizations.craneFormLocation, 63 | textController: locationController.value, 64 | ), 65 | ], 66 | ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /lib/studies/fortnightly/routes.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | const String defaultRoute = '/fortnightly'; 6 | -------------------------------------------------------------------------------- /lib/studies/rally/charts/vertical_fraction_bar.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | class VerticalFractionBar extends StatelessWidget { 8 | const VerticalFractionBar({ 9 | super.key, 10 | this.color, 11 | required this.fraction, 12 | }); 13 | 14 | final Color? color; 15 | final double fraction; 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | return LayoutBuilder(builder: (context, constraints) { 20 | return SizedBox( 21 | height: constraints.maxHeight, 22 | width: 4, 23 | child: Column( 24 | children: [ 25 | SizedBox( 26 | height: (1 - fraction) * constraints.maxHeight, 27 | child: Container( 28 | color: Colors.black, 29 | ), 30 | ), 31 | SizedBox( 32 | height: fraction * constraints.maxHeight, 33 | child: Container(color: color), 34 | ), 35 | ], 36 | ), 37 | ); 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/studies/rally/colors.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:ui'; 6 | 7 | /// Most color assignments in Rally are not like the typical color 8 | /// assignments that are common in other apps. Instead of primarily mapping to 9 | /// component type and part, they are assigned round robin based on layout. 10 | class RallyColors { 11 | static const List accountColors = [ 12 | Color(0xFF005D57), 13 | Color(0xFF04B97F), 14 | Color(0xFF37EFBA), 15 | Color(0xFF007D51), 16 | ]; 17 | 18 | static const List billColors = [ 19 | Color(0xFFFFDC78), 20 | Color(0xFFFF6951), 21 | Color(0xFFFFD7D0), 22 | Color(0xFFFFAC12), 23 | ]; 24 | 25 | static const List budgetColors = [ 26 | Color(0xFFB2F2FF), 27 | Color(0xFFB15DFF), 28 | Color(0xFF72DEFF), 29 | Color(0xFF0082FB), 30 | ]; 31 | 32 | static const Color gray = Color(0xFFD8D8D8); 33 | static const Color gray60 = Color(0x99D8D8D8); 34 | static const Color gray25 = Color(0x40D8D8D8); 35 | static const Color white60 = Color(0x99FFFFFF); 36 | static const Color primaryBackground = Color(0xFF33333D); 37 | static const Color inputBackground = Color(0xFF26282F); 38 | static const Color cardBackground = Color(0x03FEFEFE); 39 | static const Color buttonColor = Color(0xFF09AF79); 40 | static const Color focusColor = Color(0xCCFFFFFF); 41 | static const Color dividerColor = Color(0xAA282828); 42 | 43 | /// Convenience method to get a single account color with position i. 44 | static Color accountColor(int i) { 45 | return cycledColor(accountColors, i); 46 | } 47 | 48 | /// Convenience method to get a single bill color with position i. 49 | static Color billColor(int i) { 50 | return cycledColor(billColors, i); 51 | } 52 | 53 | /// Convenience method to get a single budget color with position i. 54 | static Color budgetColor(int i) { 55 | return cycledColor(budgetColors, i); 56 | } 57 | 58 | /// Gets a color from a list that is considered to be infinitely repeating. 59 | static Color cycledColor(List colors, int i) { 60 | return colors[i % colors.length]; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/studies/rally/formatters.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:gallery/data/gallery_options.dart'; 7 | import 'package:intl/intl.dart'; 8 | 9 | /// Get the locale string for the context. 10 | String locale(BuildContext context) => 11 | GalleryOptions.of(context).locale.toString(); 12 | 13 | /// Currency formatter for USD. 14 | NumberFormat usdWithSignFormat(BuildContext context, {int decimalDigits = 2}) { 15 | return NumberFormat.currency( 16 | locale: locale(context), 17 | name: '\$', 18 | decimalDigits: decimalDigits, 19 | ); 20 | } 21 | 22 | /// Percent formatter with two decimal points. 23 | NumberFormat percentFormat(BuildContext context, {int decimalDigits = 2}) { 24 | return NumberFormat.decimalPercentPattern( 25 | locale: locale(context), 26 | decimalDigits: decimalDigits, 27 | ); 28 | } 29 | 30 | /// Date formatter with year / number month / day. 31 | DateFormat shortDateFormat(BuildContext context) => 32 | DateFormat.yMd(locale(context)); 33 | 34 | /// Date formatter with year / month / day. 35 | DateFormat longDateFormat(BuildContext context) => 36 | DateFormat.yMMMMd(locale(context)); 37 | 38 | /// Date formatter with abbreviated month and day. 39 | DateFormat dateFormatAbbreviatedMonthDay(BuildContext context) => 40 | DateFormat.MMMd(locale(context)); 41 | 42 | /// Date formatter with year and abbreviated month. 43 | DateFormat dateFormatMonthYear(BuildContext context) => 44 | DateFormat.yMMM(locale(context)); 45 | -------------------------------------------------------------------------------- /lib/studies/rally/routes.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | const String loginRoute = '/rally/login'; 6 | const String homeRoute = '/rally'; 7 | -------------------------------------------------------------------------------- /lib/studies/rally/tabs/accounts.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 8 | import 'package:gallery/studies/rally/charts/pie_chart.dart'; 9 | import 'package:gallery/studies/rally/data.dart'; 10 | import 'package:gallery/studies/rally/finance.dart'; 11 | import 'package:gallery/studies/rally/tabs/sidebar.dart'; 12 | 13 | /// A page that shows a summary of accounts. 14 | class AccountsView extends StatelessWidget { 15 | const AccountsView({super.key}); 16 | 17 | @override 18 | Widget build(BuildContext context) { 19 | final items = DummyDataService.getAccountDataList(context); 20 | final detailItems = DummyDataService.getAccountDetailList(context); 21 | final balanceTotal = sumAccountDataPrimaryAmount(items); 22 | 23 | return TabWithSidebar( 24 | restorationId: 'accounts_view', 25 | mainView: FinancialEntityView( 26 | heroLabel: GalleryLocalizations.of(context)!.rallyAccountTotal, 27 | heroAmount: balanceTotal, 28 | segments: buildSegmentsFromAccountItems(items), 29 | wholeAmount: balanceTotal, 30 | financialEntityCards: buildAccountDataListViews(items, context), 31 | ), 32 | sidebarItems: [ 33 | for (UserDetailData item in detailItems) 34 | SidebarItem(title: item.title, value: item.value) 35 | ], 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/studies/rally/tabs/bills.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/widgets.dart'; 6 | 7 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 8 | import 'package:gallery/studies/rally/charts/pie_chart.dart'; 9 | import 'package:gallery/studies/rally/data.dart'; 10 | import 'package:gallery/studies/rally/finance.dart'; 11 | import 'package:gallery/studies/rally/tabs/sidebar.dart'; 12 | 13 | /// A page that shows a summary of bills. 14 | class BillsView extends StatefulWidget { 15 | const BillsView({super.key}); 16 | 17 | @override 18 | State createState() => _BillsViewState(); 19 | } 20 | 21 | class _BillsViewState extends State 22 | with SingleTickerProviderStateMixin { 23 | @override 24 | Widget build(BuildContext context) { 25 | final items = DummyDataService.getBillDataList(context); 26 | final dueTotal = sumBillDataPrimaryAmount(items); 27 | final paidTotal = sumBillDataPaidAmount(items); 28 | final detailItems = DummyDataService.getBillDetailList( 29 | context, 30 | dueTotal: dueTotal, 31 | paidTotal: paidTotal, 32 | ); 33 | 34 | return TabWithSidebar( 35 | restorationId: 'bills_view', 36 | mainView: FinancialEntityView( 37 | heroLabel: GalleryLocalizations.of(context)!.rallyBillsDue, 38 | heroAmount: dueTotal, 39 | segments: buildSegmentsFromBillItems(items), 40 | wholeAmount: dueTotal, 41 | financialEntityCards: buildBillDataListViews(items, context), 42 | ), 43 | sidebarItems: [ 44 | for (UserDetailData item in detailItems) 45 | SidebarItem(title: item.title, value: item.value) 46 | ], 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/studies/rally/tabs/budgets.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/widgets.dart'; 6 | 7 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 8 | import 'package:gallery/studies/rally/charts/pie_chart.dart'; 9 | import 'package:gallery/studies/rally/data.dart'; 10 | import 'package:gallery/studies/rally/finance.dart'; 11 | import 'package:gallery/studies/rally/tabs/sidebar.dart'; 12 | 13 | class BudgetsView extends StatefulWidget { 14 | const BudgetsView({super.key}); 15 | 16 | @override 17 | State createState() => _BudgetsViewState(); 18 | } 19 | 20 | class _BudgetsViewState extends State 21 | with SingleTickerProviderStateMixin { 22 | @override 23 | Widget build(BuildContext context) { 24 | final items = DummyDataService.getBudgetDataList(context); 25 | final capTotal = sumBudgetDataPrimaryAmount(items); 26 | final usedTotal = sumBudgetDataAmountUsed(items); 27 | final detailItems = DummyDataService.getBudgetDetailList( 28 | context, 29 | capTotal: capTotal, 30 | usedTotal: usedTotal, 31 | ); 32 | 33 | return TabWithSidebar( 34 | restorationId: 'budgets_view', 35 | mainView: FinancialEntityView( 36 | heroLabel: GalleryLocalizations.of(context)!.rallyBudgetLeft, 37 | heroAmount: capTotal - usedTotal, 38 | segments: buildSegmentsFromBudgetItems(items), 39 | wholeAmount: capTotal, 40 | financialEntityCards: buildBudgetDataListViews(items, context), 41 | ), 42 | sidebarItems: [ 43 | for (UserDetailData item in detailItems) 44 | SidebarItem(title: item.title, value: item.value) 45 | ], 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/studies/rally/tabs/settings.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:gallery/layout/adaptive.dart'; 7 | import 'package:gallery/studies/rally/colors.dart'; 8 | import 'package:gallery/studies/rally/data.dart'; 9 | import 'package:gallery/studies/rally/routes.dart' as rally_route; 10 | 11 | class SettingsView extends StatefulWidget { 12 | const SettingsView({super.key}); 13 | 14 | @override 15 | State createState() => _SettingsViewState(); 16 | } 17 | 18 | class _SettingsViewState extends State { 19 | @override 20 | Widget build(BuildContext context) { 21 | return FocusTraversalGroup( 22 | child: Container( 23 | padding: EdgeInsets.only(top: isDisplayDesktop(context) ? 24 : 0), 24 | child: ListView( 25 | restorationId: 'settings_list_view', 26 | shrinkWrap: true, 27 | children: [ 28 | for (String title 29 | in DummyDataService.getSettingsTitles(context)) ...[ 30 | _SettingsItem(title), 31 | const Divider( 32 | color: RallyColors.dividerColor, 33 | height: 1, 34 | ) 35 | ] 36 | ], 37 | ), 38 | ), 39 | ); 40 | } 41 | } 42 | 43 | class _SettingsItem extends StatelessWidget { 44 | const _SettingsItem(this.title); 45 | 46 | final String title; 47 | 48 | @override 49 | Widget build(BuildContext context) { 50 | return TextButton( 51 | style: TextButton.styleFrom( 52 | foregroundColor: Colors.white, 53 | padding: EdgeInsets.zero, 54 | ), 55 | onPressed: () { 56 | Navigator.of(context).restorablePushNamed(rally_route.loginRoute); 57 | }, 58 | child: Container( 59 | alignment: AlignmentDirectional.centerStart, 60 | padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 28), 61 | child: Text(title), 62 | ), 63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lib/studies/reply/bottom_drawer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:gallery/studies/reply/colors.dart'; 3 | 4 | class BottomDrawer extends StatelessWidget { 5 | const BottomDrawer({ 6 | super.key, 7 | this.onVerticalDragUpdate, 8 | this.onVerticalDragEnd, 9 | required this.leading, 10 | required this.trailing, 11 | }); 12 | 13 | final GestureDragUpdateCallback? onVerticalDragUpdate; 14 | final GestureDragEndCallback? onVerticalDragEnd; 15 | final Widget leading; 16 | final Widget trailing; 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | final theme = Theme.of(context); 21 | 22 | return GestureDetector( 23 | behavior: HitTestBehavior.opaque, 24 | onVerticalDragUpdate: onVerticalDragUpdate, 25 | onVerticalDragEnd: onVerticalDragEnd, 26 | child: Material( 27 | color: theme.bottomSheetTheme.backgroundColor, 28 | borderRadius: const BorderRadius.only( 29 | topLeft: Radius.circular(12), 30 | topRight: Radius.circular(12), 31 | ), 32 | child: ListView( 33 | padding: const EdgeInsets.all(12), 34 | physics: const NeverScrollableScrollPhysics(), 35 | children: [ 36 | const SizedBox(height: 28), 37 | leading, 38 | const SizedBox(height: 8), 39 | const Divider( 40 | color: ReplyColors.blue200, 41 | thickness: 0.25, 42 | indent: 18, 43 | endIndent: 160, 44 | ), 45 | const SizedBox(height: 16), 46 | Padding( 47 | padding: const EdgeInsetsDirectional.only(start: 18), 48 | child: Text( 49 | 'FOLDERS', 50 | style: theme.textTheme.bodySmall!.copyWith( 51 | color: 52 | theme.navigationRailTheme.unselectedLabelTextStyle!.color, 53 | ), 54 | ), 55 | ), 56 | const SizedBox(height: 4), 57 | trailing, 58 | ], 59 | ), 60 | ), 61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/studies/reply/colors.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ReplyColors { 4 | static const Color white50 = Color(0xFFFFFFFF); 5 | 6 | static const Color black800 = Color(0xFF121212); 7 | static const Color black900 = Color(0xFF000000); 8 | 9 | static const Color blue50 = Color(0xFFEEF0F2); 10 | static const Color blue100 = Color(0xFFD2DBE0); 11 | static const Color blue200 = Color(0xFFADBBC4); 12 | static const Color blue300 = Color(0xFF8CA2AE); 13 | static const Color blue600 = Color(0xFF4A6572); 14 | static const Color blue700 = Color(0xFF344955); 15 | static const Color blue800 = Color(0xFF232F34); 16 | 17 | static const Color orange300 = Color(0xFFFBD790); 18 | static const Color orange400 = Color(0xFFF9BE64); 19 | static const Color orange500 = Color(0xFFF9AA33); 20 | 21 | static const Color red200 = Color(0xFFCF7779); 22 | static const Color red400 = Color(0xFFFF4C5D); 23 | 24 | static const Color white50Alpha060 = Color(0x99FFFFFF); 25 | 26 | static const Color blue50Alpha060 = Color(0x99EEF0F2); 27 | 28 | static const Color black900Alpha020 = Color(0x33000000); 29 | static const Color black900Alpha087 = Color(0xDE000000); 30 | static const Color black900Alpha060 = Color(0x99000000); 31 | 32 | static const Color greyLabel = Color(0xFFAEAEAE); 33 | static const Color darkBottomAppBarBackground = Color(0xFF2D2D2D); 34 | static const Color darkDrawerBackground = Color(0xFF353535); 35 | static const Color darkCardBackground = Color(0xFF1E1E1E); 36 | static const Color darkChipBackground = Color(0xFF2A2A2A); 37 | static const Color lightChipBackground = Color(0xFFE5E5E5); 38 | } 39 | -------------------------------------------------------------------------------- /lib/studies/reply/model/email_model.dart: -------------------------------------------------------------------------------- 1 | class Email { 2 | Email({ 3 | required this.id, 4 | required this.avatar, 5 | this.sender = '', 6 | this.time = '', 7 | this.subject = '', 8 | this.message = '', 9 | this.recipients = '', 10 | this.containsPictures = false, 11 | }); 12 | 13 | final int id; 14 | final String sender; 15 | final String time; 16 | final String subject; 17 | final String message; 18 | final String avatar; 19 | final String recipients; 20 | final bool containsPictures; 21 | } 22 | 23 | class InboxEmail extends Email { 24 | InboxEmail({ 25 | required super.id, 26 | required super.sender, 27 | super.time, 28 | super.subject, 29 | super.message, 30 | required super.avatar, 31 | super.recipients, 32 | super.containsPictures, 33 | this.inboxType = InboxType.normal, 34 | }); 35 | 36 | InboxType inboxType; 37 | } 38 | 39 | // The different mailbox pages that the Reply app contains. 40 | enum MailboxPageType { 41 | inbox, 42 | starred, 43 | sent, 44 | trash, 45 | spam, 46 | drafts, 47 | } 48 | 49 | // Different types of mail that can be sent to the inbox. 50 | enum InboxType { 51 | normal, 52 | spam, 53 | } 54 | -------------------------------------------------------------------------------- /lib/studies/reply/profile_avatar.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class ProfileAvatar extends StatelessWidget { 4 | const ProfileAvatar({ 5 | super.key, 6 | required this.avatar, 7 | this.radius = 20, 8 | }); 9 | 10 | final String avatar; 11 | final double radius; 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Material( 16 | color: Colors.transparent, 17 | child: CircleAvatar( 18 | radius: radius, 19 | backgroundColor: Theme.of(context).cardColor, 20 | child: ClipOval( 21 | child: Image.asset( 22 | avatar, 23 | gaplessPlayback: true, 24 | package: 'flutter_gallery_assets', 25 | height: 42, 26 | width: 42, 27 | fit: BoxFit.cover, 28 | ), 29 | ), 30 | ), 31 | ); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/studies/reply/routes.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | const String homeRoute = '/reply'; 6 | const String composeRoute = '/reply/compose'; 7 | -------------------------------------------------------------------------------- /lib/studies/shrine/colors.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | const Color shrinePink50 = Color(0xFFFEEAE6); 8 | const Color shrinePink100 = Color(0xFFFEDBD0); 9 | const Color shrinePink300 = Color(0xFFFBB8AC); 10 | const Color shrinePink400 = Color(0xFFEAA4A4); 11 | 12 | const Color shrineBrown900 = Color(0xFF442B2D); 13 | const Color shrineBrown600 = Color(0xFF7D4F52); 14 | 15 | const Color shrineErrorRed = Color(0xFFC5032B); 16 | 17 | const Color shrineSurfaceWhite = Color(0xFFFFFBFA); 18 | const Color shrineBackgroundWhite = Colors.white; 19 | -------------------------------------------------------------------------------- /lib/studies/shrine/model/product.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 8 | 9 | class Category { 10 | const Category({ 11 | required this.name, 12 | }); 13 | 14 | // A function taking a BuildContext as input and 15 | // returns the internationalized name of the category. 16 | final String Function(BuildContext) name; 17 | } 18 | 19 | Category categoryAll = Category( 20 | name: (context) => GalleryLocalizations.of(context)!.shrineCategoryNameAll, 21 | ); 22 | 23 | Category categoryAccessories = Category( 24 | name: (context) => 25 | GalleryLocalizations.of(context)!.shrineCategoryNameAccessories, 26 | ); 27 | 28 | Category categoryClothing = Category( 29 | name: (context) => 30 | GalleryLocalizations.of(context)!.shrineCategoryNameClothing, 31 | ); 32 | 33 | Category categoryHome = Category( 34 | name: (context) => GalleryLocalizations.of(context)!.shrineCategoryNameHome, 35 | ); 36 | 37 | List categories = [ 38 | categoryAll, 39 | categoryAccessories, 40 | categoryClothing, 41 | categoryHome, 42 | ]; 43 | 44 | class Product { 45 | const Product({ 46 | required this.category, 47 | required this.id, 48 | required this.isFeatured, 49 | required this.name, 50 | required this.price, 51 | this.assetAspectRatio = 1, 52 | }); 53 | 54 | final Category category; 55 | final int id; 56 | final bool isFeatured; 57 | final double assetAspectRatio; 58 | 59 | // A function taking a BuildContext as input and 60 | // returns the internationalized name of the product. 61 | final String Function(BuildContext) name; 62 | 63 | final int price; 64 | 65 | String get assetName => '$id-0.jpg'; 66 | 67 | String get assetPackage => 'shrine_images'; 68 | } 69 | -------------------------------------------------------------------------------- /lib/studies/shrine/page_status.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | import 'package:gallery/layout/adaptive.dart'; 8 | 9 | class PageStatus extends InheritedWidget { 10 | const PageStatus({ 11 | super.key, 12 | required this.cartController, 13 | required this.menuController, 14 | required super.child, 15 | }); 16 | 17 | final AnimationController cartController; 18 | final AnimationController menuController; 19 | 20 | static PageStatus? of(BuildContext context) { 21 | return context.dependOnInheritedWidgetOfExactType(); 22 | } 23 | 24 | @override 25 | bool updateShouldNotify(PageStatus oldWidget) => 26 | oldWidget.cartController != cartController || 27 | oldWidget.menuController != menuController; 28 | } 29 | 30 | bool productPageIsVisible(BuildContext context) { 31 | return _cartControllerOf(context).isDismissed && 32 | (_menuControllerOf(context).isCompleted || isDisplayDesktop(context)); 33 | } 34 | 35 | bool menuPageIsVisible(BuildContext context) { 36 | return _cartControllerOf(context).isDismissed && 37 | (_menuControllerOf(context).isDismissed || isDisplayDesktop(context)); 38 | } 39 | 40 | bool cartPageIsVisible(BuildContext context) { 41 | return _cartControllerOf(context).isCompleted; 42 | } 43 | 44 | AnimationController _cartControllerOf(BuildContext context) { 45 | return PageStatus.of(context)!.cartController; 46 | } 47 | 48 | AnimationController _menuControllerOf(BuildContext context) { 49 | return PageStatus.of(context)!.menuController; 50 | } 51 | -------------------------------------------------------------------------------- /lib/studies/shrine/routes.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | const String loginRoute = '/shrine/login'; 6 | const String homeRoute = '/shrine'; 7 | -------------------------------------------------------------------------------- /lib/studies/shrine/scrim.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | class Scrim extends StatelessWidget { 8 | const Scrim({super.key, required this.controller}); 9 | 10 | final AnimationController controller; 11 | 12 | @override 13 | Widget build(BuildContext context) { 14 | final deviceSize = MediaQuery.of(context).size; 15 | return ExcludeSemantics( 16 | child: AnimatedBuilder( 17 | animation: controller, 18 | builder: (context, child) { 19 | final color = 20 | const Color(0xFFFFF0EA).withOpacity(controller.value * 0.87); 21 | 22 | final Widget scrimRectangle = Container( 23 | width: deviceSize.width, height: deviceSize.height, color: color); 24 | 25 | final ignorePointer = 26 | (controller.status == AnimationStatus.dismissed); 27 | final tapToRevert = (controller.status == AnimationStatus.completed); 28 | 29 | if (tapToRevert) { 30 | return MouseRegion( 31 | cursor: SystemMouseCursors.click, 32 | child: GestureDetector( 33 | onTap: () { 34 | controller.reverse(); 35 | }, 36 | child: scrimRectangle, 37 | ), 38 | ); 39 | } else if (ignorePointer) { 40 | return IgnorePointer(child: scrimRectangle); 41 | } else { 42 | return scrimRectangle; 43 | } 44 | }, 45 | ), 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/studies/shrine/supplemental/layout_cache.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | class LayoutCache extends InheritedWidget { 8 | const LayoutCache({ 9 | super.key, 10 | required this.layouts, 11 | required super.child, 12 | }); 13 | 14 | static Map>> of(BuildContext context) { 15 | return context.dependOnInheritedWidgetOfExactType()!.layouts; 16 | } 17 | 18 | final Map>> layouts; 19 | 20 | @override 21 | bool updateShouldNotify(LayoutCache oldWidget) => true; 22 | } 23 | -------------------------------------------------------------------------------- /lib/studies/shrine/triangle_category_indicator.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | 7 | import 'package:gallery/studies/shrine/colors.dart'; 8 | 9 | const List _vertices = [ 10 | Offset(0, -14), 11 | Offset(-17, 14), 12 | Offset(17, 14), 13 | Offset(0, -14), 14 | Offset(0, -7.37), 15 | Offset(10.855, 10.48), 16 | Offset(-10.855, 10.48), 17 | Offset(0, -7.37), 18 | ]; 19 | 20 | class TriangleCategoryIndicator extends CustomPainter { 21 | const TriangleCategoryIndicator( 22 | this.triangleWidth, 23 | this.triangleHeight, 24 | ); 25 | 26 | final double triangleWidth; 27 | final double triangleHeight; 28 | 29 | @override 30 | void paint(Canvas canvas, Size size) { 31 | final myPath = Path() 32 | ..addPolygon( 33 | List.from(_vertices.map((vertex) { 34 | return Offset(size.width, size.height) / 2 + 35 | Offset(vertex.dx * triangleWidth / 34, 36 | vertex.dy * triangleHeight / 28); 37 | })), 38 | true, 39 | ); 40 | final myPaint = Paint()..color = shrinePink400; 41 | canvas.drawPath(myPath, myPaint); 42 | } 43 | 44 | @override 45 | bool shouldRepaint(TriangleCategoryIndicator oldDelegate) => false; 46 | 47 | @override 48 | bool shouldRebuildSemantics(TriangleCategoryIndicator oldDelegate) => false; 49 | } 50 | -------------------------------------------------------------------------------- /lib/studies/starter/app.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_gen/gen_l10n/gallery_localizations.dart'; 7 | import 'package:gallery/data/gallery_options.dart'; 8 | import 'package:gallery/studies/starter/home.dart'; 9 | import 'package:gallery/studies/starter/routes.dart' as routes; 10 | 11 | const _primaryColor = Color(0xFF6200EE); 12 | 13 | class StarterApp extends StatelessWidget { 14 | const StarterApp({super.key}); 15 | 16 | static const String defaultRoute = routes.defaultRoute; 17 | 18 | @override 19 | Widget build(BuildContext context) { 20 | return MaterialApp( 21 | restorationScopeId: 'starter_app', 22 | title: GalleryLocalizations.of(context)!.starterAppTitle, 23 | debugShowCheckedModeBanner: false, 24 | localizationsDelegates: GalleryLocalizations.localizationsDelegates, 25 | supportedLocales: GalleryLocalizations.supportedLocales, 26 | locale: GalleryOptions.of(context).locale, 27 | initialRoute: StarterApp.defaultRoute, 28 | routes: { 29 | StarterApp.defaultRoute: (context) => const _Home(), 30 | }, 31 | theme: ThemeData( 32 | highlightColor: Colors.transparent, 33 | colorScheme: const ColorScheme( 34 | primary: _primaryColor, 35 | primaryContainer: Color(0xFF3700B3), 36 | secondary: Color(0xFF03DAC6), 37 | secondaryContainer: Color(0xFF018786), 38 | background: Colors.white, 39 | surface: Colors.white, 40 | onBackground: Colors.black, 41 | error: Color(0xFFB00020), 42 | onError: Colors.white, 43 | onPrimary: Colors.white, 44 | onSecondary: Colors.black, 45 | onSurface: Colors.black, 46 | brightness: Brightness.light, 47 | ), 48 | dividerTheme: const DividerThemeData( 49 | thickness: 1, 50 | color: Color(0xFFE5E5E5), 51 | ), 52 | platform: GalleryOptions.of(context).platform, 53 | ), 54 | ); 55 | } 56 | } 57 | 58 | class _Home extends StatelessWidget { 59 | const _Home(); 60 | 61 | @override 62 | Widget build(BuildContext context) { 63 | return const ApplyTextOptions( 64 | child: HomePage(), 65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lib/studies/starter/routes.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | const String defaultRoute = '/starter'; 6 | -------------------------------------------------------------------------------- /linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | 11 | void fl_register_plugins(FlPluginRegistry* registry) { 12 | g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = 13 | fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); 14 | url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); 15 | } 16 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void fl_register_plugins(FlPluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /linux/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | url_launcher_linux 7 | ) 8 | 9 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 10 | ) 11 | 12 | set(PLUGIN_BUNDLED_LIBRARIES) 13 | 14 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 15 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) 16 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 18 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 19 | endforeach(plugin) 20 | 21 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 22 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) 23 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 24 | endforeach(ffi_plugin) 25 | -------------------------------------------------------------------------------- /linux/main.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | int main(int argc, char** argv) { 4 | g_autoptr(MyApplication) app = my_application_new(); 5 | return g_application_run(G_APPLICATION(app), argc, argv); 6 | } 7 | -------------------------------------------------------------------------------- /linux/my_application.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_MY_APPLICATION_H_ 2 | #define FLUTTER_MY_APPLICATION_H_ 3 | 4 | #include 5 | 6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, 7 | GtkApplication) 8 | 9 | /** 10 | * my_application_new: 11 | * 12 | * Creates a new Flutter-based application. 13 | * 14 | * Returns: a new #MyApplication. 15 | */ 16 | MyApplication* my_application_new(); 17 | 18 | #endif // FLUTTER_MY_APPLICATION_H_ 19 | -------------------------------------------------------------------------------- /macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import path_provider_foundation 9 | import url_launcher_macos 10 | 11 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 12 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) 13 | UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) 14 | } 15 | -------------------------------------------------------------------------------- /macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.14.6' 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 flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | target 'RunnerTests' do 35 | inherit! :search_paths 36 | end 37 | end 38 | 39 | post_install do |installer| 40 | installer.pods_project.targets.each do |target| 41 | flutter_additional_macos_build_settings(target) 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /macos/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FlutterMacOS (1.0.0) 3 | - path_provider_foundation (0.0.1): 4 | - Flutter 5 | - FlutterMacOS 6 | - url_launcher_macos (0.0.1): 7 | - FlutterMacOS 8 | 9 | DEPENDENCIES: 10 | - FlutterMacOS (from `Flutter/ephemeral`) 11 | - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) 12 | - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) 13 | 14 | EXTERNAL SOURCES: 15 | FlutterMacOS: 16 | :path: Flutter/ephemeral 17 | path_provider_foundation: 18 | :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin 19 | url_launcher_macos: 20 | :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos 21 | 22 | SPEC CHECKSUMS: 23 | FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 24 | path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 25 | url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95 26 | 27 | PODFILE CHECKSUM: 16208599a12443d53889ba2270a4985981cfb204 28 | 29 | COCOAPODS: 1.13.0 30 | -------------------------------------------------------------------------------- /macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "app_icon_16.png", 5 | "idiom" : "mac", 6 | "scale" : "1x", 7 | "size" : "16x16" 8 | }, 9 | { 10 | "filename" : "app_icon_32.png", 11 | "idiom" : "mac", 12 | "scale" : "2x", 13 | "size" : "16x16" 14 | }, 15 | { 16 | "filename" : "app_icon_32.png", 17 | "idiom" : "mac", 18 | "scale" : "1x", 19 | "size" : "32x32" 20 | }, 21 | { 22 | "filename" : "app_icon_64.png", 23 | "idiom" : "mac", 24 | "scale" : "2x", 25 | "size" : "32x32" 26 | }, 27 | { 28 | "filename" : "app_icon_128.png", 29 | "idiom" : "mac", 30 | "scale" : "1x", 31 | "size" : "128x128" 32 | }, 33 | { 34 | "filename" : "app_icon_256.png", 35 | "idiom" : "mac", 36 | "scale" : "2x", 37 | "size" : "128x128" 38 | }, 39 | { 40 | "filename" : "app_icon_256.png", 41 | "idiom" : "mac", 42 | "scale" : "1x", 43 | "size" : "256x256" 44 | }, 45 | { 46 | "filename" : "app_icon_512.png", 47 | "idiom" : "mac", 48 | "scale" : "2x", 49 | "size" : "256x256" 50 | }, 51 | { 52 | "filename" : "app_icon_512.png", 53 | "idiom" : "mac", 54 | "scale" : "1x", 55 | "size" : "512x512" 56 | }, 57 | { 58 | "filename" : "app_icon_1024.png", 59 | "idiom" : "mac", 60 | "scale" : "2x", 61 | "size" : "512x512" 62 | } 63 | ], 64 | "info" : { 65 | "author" : "xcode", 66 | "version" : 1 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /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 = Flutter Gallery 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = io.flutter.demo.gallery 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2019 The Flutter team. All rights reserved. 15 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /macos/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import FlutterMacOS 2 | import Cocoa 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /test/code_segments_test.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:test/test.dart'; 6 | 7 | import '../tool/codeviewer_cli/segment_generator.dart'; 8 | import 'utils.dart'; 9 | 10 | void main() { 11 | bool compareCodeSegments(String a, String b) { 12 | return standardizeLineEndings(a) == standardizeLineEndings(b); 13 | } 14 | 15 | test('verify code segments are up to date', () async { 16 | final currentCodeSegments = readCodeSegments(); 17 | var newCodeSegments = await getCodeSegments(); 18 | 19 | expect(compareCodeSegments(currentCodeSegments, newCodeSegments), true, 20 | reason: 'code_segments.dart is not up to date. ' 21 | 'Did you forget to run `dart run grinder update-code-segments`?'); 22 | }, onPlatform: { 23 | 'linux': [ 24 | const Skip('TODO: figure out why this test fails on Linux.'), 25 | ], 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /test/demo_descriptions_test.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:collection/collection.dart'; 6 | import 'package:flutter_gen/gen_l10n/gallery_localizations_en.dart'; 7 | import 'package:flutter_test/flutter_test.dart'; 8 | import 'package:gallery/data/demos.dart'; 9 | 10 | bool _isUnique(List list) { 11 | final covered = {}; 12 | for (final element in list) { 13 | if (covered.contains(element)) { 14 | return false; 15 | } else { 16 | covered.add(element); 17 | } 18 | } 19 | return true; 20 | } 21 | 22 | const _stringListEquality = ListEquality(); 23 | 24 | void main() { 25 | test('_isUnique works correctly', () { 26 | expect(_isUnique(['a', 'b', 'c']), true); 27 | expect(_isUnique(['a', 'c', 'a', 'b']), false); 28 | expect(_isUnique(['a']), true); 29 | expect(_isUnique([]), true); 30 | }); 31 | 32 | test('Demo descriptions are unique and correct', () { 33 | final allDemos = Demos.all(GalleryLocalizationsEn()); 34 | final allDemoDescriptions = allDemos.map((d) => d.describe).toList(); 35 | 36 | expect(_isUnique(allDemoDescriptions), true); 37 | expect( 38 | _stringListEquality.equals( 39 | allDemoDescriptions, 40 | Demos.allDescriptions(), 41 | ), 42 | true, 43 | ); 44 | }); 45 | 46 | test('Special demo descriptions are correct', () { 47 | final allDemos = Demos.allDescriptions(); 48 | 49 | final specialDemos = [ 50 | 'shrine@study', 51 | 'rally@study', 52 | 'crane@study', 53 | 'fortnightly@study', 54 | 'bottom-navigation@material', 55 | 'button@material', 56 | 'card@material', 57 | 'chip@material', 58 | 'dialog@material', 59 | 'pickers@material', 60 | 'cupertino-alerts@cupertino', 61 | 'colors@other', 62 | 'progress-indicator@material', 63 | 'cupertino-activity-indicator@cupertino', 64 | 'colors@other', 65 | ]; 66 | 67 | for (final specialDemo in specialDemos) { 68 | expect(allDemos.contains(specialDemo), true); 69 | } 70 | }); 71 | } 72 | -------------------------------------------------------------------------------- /test/l10n_test.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:test/test.dart'; 6 | 7 | import '../tool/l10n_cli/l10n_cli.dart'; 8 | import 'utils.dart'; 9 | 10 | void main() { 11 | test('verify intl_en_US.xml is up to date', () async { 12 | final currentXml = readEnglishXml(); 13 | final newXml = await generateXmlFromArb(); 14 | 15 | expect(standardizeLineEndings(currentXml), standardizeLineEndings(newXml), 16 | reason: 'intl_en_US.xml is not up to date. ' 17 | 'Did you forget to run `flutter pub run grinder l10n`?'); 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /test/pages/home_test.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_test/flutter_test.dart'; 7 | import 'package:gallery/main.dart'; 8 | 9 | void main() { 10 | testWidgets('Home page hides settings semantics when closed', (tester) async { 11 | await tester.pumpWidget(const GalleryApp()); 12 | 13 | await tester.pump(const Duration(seconds: 1)); 14 | 15 | expect(find.bySemanticsLabel('Settings'), findsOneWidget); 16 | expect(find.bySemanticsLabel('Close settings'), findsNothing); 17 | 18 | await tester.tap(find.bySemanticsLabel('Settings')); 19 | await tester.pump(const Duration(seconds: 1)); 20 | 21 | // The test no longer finds Setting and Close settings since the semantics 22 | // are excluded when settings mode is activated. 23 | expect(find.bySemanticsLabel('Settings'), findsNothing); 24 | expect(find.bySemanticsLabel('Close settings'), findsOneWidget); 25 | }); 26 | 27 | testWidgets('Home page list view is the primary list view', (tester) async { 28 | await tester.pumpWidget(const GalleryApp()); 29 | await tester.pumpAndSettle(); 30 | 31 | ListView listview = 32 | tester.widget(find.byKey(const ValueKey('HomeListView'))); 33 | 34 | expect(listview.primary, true); 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /test/theme_test.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:gallery/themes/material_demo_theme_data.dart'; 7 | import 'package:test/test.dart'; 8 | 9 | void main() { 10 | test('verify former toggleableActiveColor themes are set', () async { 11 | const Color primaryColor = Color(0xFF6200EE); 12 | final ThemeData themeData = MaterialDemoThemeData.themeData; 13 | 14 | expect( 15 | themeData.checkboxTheme.fillColor!.resolve({MaterialState.selected}), 16 | primaryColor, 17 | ); 18 | expect( 19 | themeData.radioTheme.fillColor!.resolve({MaterialState.selected}), 20 | primaryColor, 21 | ); 22 | expect( 23 | themeData.switchTheme.thumbColor!.resolve({MaterialState.selected}), 24 | primaryColor, 25 | ); 26 | expect( 27 | themeData.switchTheme.trackColor!.resolve({MaterialState.selected}), 28 | primaryColor.withOpacity(0.5), 29 | ); 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /test/utils.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // Replace Windows line endings with Unix line endings 6 | String standardizeLineEndings(String str) => str.replaceAll('\r\n', '\n'); 7 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter_test/flutter_test.dart'; 6 | import 'package:gallery/main.dart'; 7 | 8 | void main() { 9 | testWidgets('Smoke test', (tester) async { 10 | await tester.pumpWidget(const GalleryApp()); 11 | await tester.pumpAndSettle(); 12 | expect(find.text('Gallery'), findsOneWidget); 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /test_benchmarks/benchmarks/README.md: -------------------------------------------------------------------------------- 1 | # Web Benchmark Tests 2 | 3 | This directory, `lib/benchmarks/`, is used for performance testing for the Gallery on Web. 4 | 5 | It is used by `web_benchmarks` in the Flutter repository to collect benchmarks that 6 | indicate Gallery's performance. 7 | 8 | For more information, especially how to run these tests, see: 9 | 10 | https://github.com/flutter/flutter/tree/master/dev/benchmarks/macrobenchmarks#web-benchmarks 11 | -------------------------------------------------------------------------------- /test_benchmarks/benchmarks/client.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:web_benchmarks/client.dart'; 6 | 7 | import 'common.dart'; 8 | import 'gallery_automator.dart'; 9 | import 'gallery_recorder.dart'; 10 | 11 | typedef RecorderFactory = Recorder Function(); 12 | 13 | final Map benchmarks = { 14 | galleryStudiesPerf: () => GalleryRecorder( 15 | benchmarkName: galleryStudiesPerf, 16 | shouldRunPredicate: (demo) => typeOfDemo(demo) == DemoType.study, 17 | ), 18 | galleryUnanimatedPerf: () => GalleryRecorder( 19 | benchmarkName: galleryUnanimatedPerf, 20 | shouldRunPredicate: (demo) => 21 | typeOfDemo(demo) == DemoType.unanimatedWidget, 22 | ), 23 | galleryAnimatedPerf: () => GalleryRecorder( 24 | benchmarkName: galleryAnimatedPerf, 25 | shouldRunPredicate: (demo) => 26 | typeOfDemo(demo) == DemoType.animatedWidget, 27 | ), 28 | galleryScrollPerf: () => GalleryRecorder( 29 | benchmarkName: galleryScrollPerf, 30 | testScrollingOnly: true, 31 | ), 32 | }; 33 | 34 | /// Runs the client of the Gallery web benchmarks. 35 | /// 36 | /// When the Gallery web benchmarks are run, the server builds an app with this 37 | /// file as the entry point (see `test/run_benchmarks.dart`). The app automates 38 | /// the gallery, records some performance data, and reports them. 39 | Future main() async { 40 | await runBenchmarks(benchmarks); 41 | } 42 | -------------------------------------------------------------------------------- /test_benchmarks/benchmarks/common.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | const String galleryBenchmarkPrefix = 'gallery_v2'; 6 | 7 | const String galleryStudiesPerf = '${galleryBenchmarkPrefix}_studies_perf'; 8 | const String galleryUnanimatedPerf = 9 | '${galleryBenchmarkPrefix}_unanimated_perf'; 10 | const String galleryAnimatedPerf = '${galleryBenchmarkPrefix}_animated_perf'; 11 | const String galleryScrollPerf = '${galleryBenchmarkPrefix}_scroll_perf'; 12 | 13 | const benchmarkList = [ 14 | galleryStudiesPerf, 15 | galleryUnanimatedPerf, 16 | galleryAnimatedPerf, 17 | galleryScrollPerf, 18 | ]; 19 | -------------------------------------------------------------------------------- /test_benchmarks/benchmarks/gallery_recorder.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Flutter Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:web_benchmarks/client.dart'; 7 | 8 | import 'gallery_automator.dart'; 9 | 10 | /// A recorder that measures frame building durations for the Gallery. 11 | class GalleryRecorder extends WidgetRecorder { 12 | GalleryRecorder({ 13 | required this.benchmarkName, 14 | this.shouldRunPredicate, 15 | this.testScrollingOnly = false, 16 | }) : assert(testScrollingOnly || shouldRunPredicate != null), 17 | super(name: benchmarkName, useCustomWarmUp: true); 18 | 19 | /// The name of the gallery benchmark to be run. 20 | /// 21 | /// See `common.dart` for the list of the names of all benchmarks. 22 | final String benchmarkName; 23 | 24 | /// A function that accepts the name of a demo and returns whether we should 25 | /// run this demo in this benchmark. 26 | /// 27 | /// See `common.dart` for examples. 28 | /// 29 | /// The name of any demo has the format `@`, such as 30 | /// `progress-indicator@material`. 31 | /// A list of all demo names can be obtained using 32 | /// [allGalleryDemoDescriptions]. 33 | final bool Function(String)? shouldRunPredicate; 34 | 35 | /// Whether this benchmark only tests scrolling. 36 | final bool testScrollingOnly; 37 | 38 | GalleryAutomator? _galleryAutomator; 39 | bool get _finished => _galleryAutomator?.finished ?? false; 40 | 41 | /// Whether we should continue recording. 42 | @override 43 | bool shouldContinue() => !_finished || profile.shouldContinue(); 44 | 45 | /// Creates the [GalleryAutomator] widget. 46 | @override 47 | Widget createWidget() { 48 | _galleryAutomator = GalleryAutomator( 49 | benchmarkName: benchmarkName, 50 | shouldRunPredicate: shouldRunPredicate, 51 | testScrollsOnly: testScrollingOnly, 52 | stopWarmingUpCallback: profile.stopWarmingUp, 53 | ); 54 | return _galleryAutomator!.createWidget(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /test_benchmarks/benchmarks/project_root_directory.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:io'; 6 | import 'package:path/path.dart' as path; 7 | 8 | bool _hasPubspec(Directory directory) { 9 | return directory.listSync().any( 10 | (entity) => 11 | FileSystemEntity.isFileSync(entity.path) && 12 | path.basename(entity.path) == 'pubspec.yaml', 13 | ); 14 | } 15 | 16 | Directory projectRootDirectory() { 17 | var current = Directory.current.absolute; 18 | 19 | while (!_hasPubspec(current)) { 20 | if (current.path == current.parent.path) { 21 | throw Exception('Reached file system root when seeking project root.'); 22 | } 23 | 24 | current = current.parent; 25 | } 26 | 27 | return current; 28 | } 29 | -------------------------------------------------------------------------------- /test_benchmarks/benchmarks/run_benchmarks.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:convert' show JsonEncoder; 6 | import 'dart:io'; 7 | 8 | import 'package:web_benchmarks/server.dart'; 9 | 10 | import 'project_root_directory.dart'; 11 | 12 | /// Runs the Gallery web benchmarks and reports the benchmark data. 13 | Future main() async { 14 | stdout.writeln('Starting web benchmark tests ...'); 15 | 16 | final taskResult = await serveWebBenchmark( 17 | benchmarkAppDirectory: projectRootDirectory(), 18 | entryPoint: 'test/benchmarks/client.dart', 19 | useCanvasKit: false, 20 | ); 21 | 22 | stdout.writeln('Web benchmark tests finished.'); 23 | 24 | stdout.writeln('==== Results ===='); 25 | 26 | stdout 27 | .writeln(const JsonEncoder.withIndent(' ').convert(taskResult.toJson())); 28 | 29 | stdout.writeln('==== End of results ===='); 30 | } 31 | -------------------------------------------------------------------------------- /test_benchmarks/benchmarks_test.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:convert' show JsonEncoder; 6 | import 'dart:io'; 7 | 8 | import 'package:test/test.dart'; 9 | import 'package:web_benchmarks/server.dart'; 10 | 11 | import 'benchmarks/common.dart'; 12 | import 'benchmarks/project_root_directory.dart'; 13 | 14 | final metricList = [ 15 | 'preroll_frame', 16 | 'apply_frame', 17 | 'drawFrameDuration', 18 | ]; 19 | 20 | final valueList = [ 21 | 'average', 22 | 'outlierAverage', 23 | 'outlierRatio', 24 | 'noise', 25 | ]; 26 | 27 | /// Tests that the Gallery web benchmarks are run and reported correctly. 28 | Future main() async { 29 | test('Can run a web benchmark', () async { 30 | stdout.writeln('Starting web benchmark tests ...'); 31 | 32 | final taskResult = await serveWebBenchmark( 33 | benchmarkAppDirectory: projectRootDirectory(), 34 | entryPoint: 'test_benchmarks/benchmarks/client.dart', 35 | useCanvasKit: false, 36 | ); 37 | 38 | stdout.writeln('Web benchmark tests finished.'); 39 | 40 | expect(taskResult.scores.keys, hasLength(benchmarkList.length)); 41 | 42 | for (final benchmarkName in benchmarkList) { 43 | expect( 44 | taskResult.scores[benchmarkName], 45 | hasLength(metricList.length * valueList.length + 1), 46 | ); 47 | 48 | for (final metricName in metricList) { 49 | for (final valueName in valueList) { 50 | expect( 51 | taskResult.scores[benchmarkName]?.where( 52 | (score) => score.metric == '$metricName.$valueName', 53 | ), 54 | hasLength(1), 55 | ); 56 | } 57 | } 58 | 59 | expect( 60 | taskResult.scores[benchmarkName]?.where( 61 | (score) => score.metric == 'totalUiFrame.average', 62 | ), 63 | hasLength(1), 64 | ); 65 | } 66 | 67 | expect( 68 | const JsonEncoder.withIndent(' ').convert(taskResult.toJson()), 69 | isA(), 70 | ); 71 | }, 72 | timeout: Timeout.none, 73 | skip: 74 | true); // TODO(guidezpl): re-enable these benchmarks https://github.com/flutter/gallery/issues/903 75 | } 76 | -------------------------------------------------------------------------------- /test_driver/transitions_perf.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:async'; 6 | import 'dart:convert' show JsonEncoder; 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_driver/driver_extension.dart'; 10 | import 'package:gallery/data/demos.dart'; 11 | import 'package:gallery/main.dart' show GalleryApp; 12 | 13 | // See transitions_perf_test.dart for how to run this test. 14 | 15 | Future _handleMessages(String? message) async { 16 | switch (message) { 17 | case 'demoDescriptions': 18 | final demoDescriptions = Demos.allDescriptions(); 19 | return const JsonEncoder.withIndent(' ').convert(demoDescriptions); 20 | case 'isTestingCraneOnly': 21 | return const String.fromEnvironment('onlyCrane', defaultValue: 'false'); 22 | case 'isTestingReplyOnly': 23 | return const String.fromEnvironment('onlyReply', defaultValue: 'false'); 24 | default: 25 | throw 'unknown message'; 26 | } 27 | } 28 | 29 | void main() { 30 | enableFlutterDriverExtension(handler: _handleMessages); 31 | runApp(const GalleryApp(isTestMode: true)); 32 | } 33 | -------------------------------------------------------------------------------- /test_goldens/README.md: -------------------------------------------------------------------------------- 1 | # Golden tests 2 | 3 | Golden tests, also called screenshot tests, let's you write tests to easily 4 | find UI regressions. It compares the UI to saved golden screenshots, and if 5 | there is a pixel difference the tests will fail. It gives us confidence that 6 | code changes does not cause UI regressions. 7 | 8 | ## Updating goldens 9 | 10 | An expected change to the UI will also cause the golden tests to fail. If this 11 | is unintended, you will need to change your code to prevent the UI change. If 12 | it was intended, you will then need to update the goldens by running the 13 | following command on your macOS machine: 14 | 15 | ```bash 16 | flutter test --update-goldens test_goldens 17 | ``` 18 | 19 | Due to slight [differences](https://github.com/flutter/flutter/issues/36667#issuecomment-521335243) 20 | in rendering across platforms, mostly around text, the tests will only be run 21 | on a macOS machine on Github Actions. This means that if you update the tests 22 | on a Linux or Windows machine the golden tests will not pass on Github Actions. 23 | Instead you are recommended to download the goldens directly from the failed 24 | Github Actions job, and use those inside of your branch. 25 | 26 | You can find the goldens from a given test run (e.g. https://github.com/flutter/gallery/actions/runs/6070588209) at 27 | the bottom of the Summary page, under "Artifacts". The `goldens` folder includes the golden image, your test image and the 28 | difference. 29 | 30 | ![Where to download the golden artifacts](https://github.com/flutter/gallery/assets/6655696/f53cab57-7b43-4f62-9594-5df5343a6cac)> 31 | 32 | ## Loading fonts in golden tests 33 | 34 | In Flutter widget tests the font used is the ['Ahem'](https://www.w3.org/Style/CSS/Test/Fonts/Ahem/README)-font. It was built to help 35 | test writers develop predictable tests, by most glyphs being a square box. To 36 | be able to test the rendering of our icons and fonts, the actual fonts are 37 | loaded before the test suites run. See [font_loader.dart](testing/font_loader.dart). 38 | 39 | ## Shadows in golden tests 40 | 41 | In the golden tests the shadows are opaqued, to [reduce the likelihood of 42 | golden file tests being flaky](https://api.flutter.dev/flutter/flutter_test/LiveTestWidgetsFlutterBinding/disableShadows.html). 43 | A side effect of this is that we are not testing the exact rendering of shadows 44 | inside of the goldens. 45 | -------------------------------------------------------------------------------- /test_goldens/flutter_test_config.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:async'; 6 | import 'dart:io'; 7 | 8 | import 'package:flutter_test/flutter_test.dart'; 9 | 10 | import 'testing/font_loader.dart'; 11 | 12 | Future testExecutable(FutureOr Function() testMain) async { 13 | final defaultReportTestException = reportTestException; 14 | reportTestException = (details, testDescription) { 15 | defaultReportTestException(details, testDescription); 16 | stdout.writeln( 17 | '\nThe golden tests failed. Please read test_goldens/README.md for how ' 18 | 'to update them.', 19 | ); 20 | }; 21 | 22 | TestWidgetsFlutterBinding.ensureInitialized(); 23 | await loadFonts(); 24 | await testMain(); 25 | } 26 | -------------------------------------------------------------------------------- /test_goldens/goldens/demo_desktop_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/goldens/demo_desktop_dark.png -------------------------------------------------------------------------------- /test_goldens/goldens/demo_desktop_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/goldens/demo_desktop_light.png -------------------------------------------------------------------------------- /test_goldens/goldens/demo_mobile_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/goldens/demo_mobile_dark.png -------------------------------------------------------------------------------- /test_goldens/goldens/demo_mobile_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/goldens/demo_mobile_light.png -------------------------------------------------------------------------------- /test_goldens/goldens/home_page_desktop_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/goldens/home_page_desktop_dark.png -------------------------------------------------------------------------------- /test_goldens/goldens/home_page_desktop_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/goldens/home_page_desktop_light.png -------------------------------------------------------------------------------- /test_goldens/goldens/home_page_mobile_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/goldens/home_page_mobile_dark.png -------------------------------------------------------------------------------- /test_goldens/goldens/home_page_mobile_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/goldens/home_page_mobile_light.png -------------------------------------------------------------------------------- /test_goldens/goldens/shrine_desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/goldens/shrine_desktop.png -------------------------------------------------------------------------------- /test_goldens/goldens/shrine_mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/goldens/shrine_mobile.png -------------------------------------------------------------------------------- /test_goldens/testing/fonts/Roboto-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/testing/fonts/Roboto-Black.ttf -------------------------------------------------------------------------------- /test_goldens/testing/fonts/Roboto-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/testing/fonts/Roboto-BlackItalic.ttf -------------------------------------------------------------------------------- /test_goldens/testing/fonts/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/testing/fonts/Roboto-Bold.ttf -------------------------------------------------------------------------------- /test_goldens/testing/fonts/Roboto-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/testing/fonts/Roboto-BoldItalic.ttf -------------------------------------------------------------------------------- /test_goldens/testing/fonts/Roboto-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/testing/fonts/Roboto-Italic.ttf -------------------------------------------------------------------------------- /test_goldens/testing/fonts/Roboto-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/testing/fonts/Roboto-Light.ttf -------------------------------------------------------------------------------- /test_goldens/testing/fonts/Roboto-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/testing/fonts/Roboto-LightItalic.ttf -------------------------------------------------------------------------------- /test_goldens/testing/fonts/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/testing/fonts/Roboto-Medium.ttf -------------------------------------------------------------------------------- /test_goldens/testing/fonts/Roboto-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/testing/fonts/Roboto-MediumItalic.ttf -------------------------------------------------------------------------------- /test_goldens/testing/fonts/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/testing/fonts/Roboto-Regular.ttf -------------------------------------------------------------------------------- /test_goldens/testing/fonts/Roboto-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/testing/fonts/Roboto-Thin.ttf -------------------------------------------------------------------------------- /test_goldens/testing/fonts/Roboto-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/test_goldens/testing/fonts/Roboto-ThinItalic.ttf -------------------------------------------------------------------------------- /test_goldens/testing/precache_images.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'package:flutter/widgets.dart'; 6 | import 'package:flutter_test/flutter_test.dart'; 7 | 8 | /// Precache images to make sure they show up in golden tests. 9 | Future pumpWidgetWithImages( 10 | WidgetTester tester, 11 | Widget widget, 12 | List assets, 13 | ) async { 14 | Future? precacheFuture; 15 | await tester.pumpWidget( 16 | Builder(builder: (buildContext) { 17 | precacheFuture = tester.runAsync(() async { 18 | await Future.wait([ 19 | for (final asset in assets) 20 | precacheImage( 21 | asset, 22 | buildContext, 23 | ), 24 | ]); 25 | }); 26 | return widget; 27 | }), 28 | ); 29 | await precacheFuture; 30 | } 31 | -------------------------------------------------------------------------------- /tool/codeviewer_cli/README.md: -------------------------------------------------------------------------------- 1 | # Codeviewer 2 | 3 | A command-line application to highlight dart source code. 4 | 5 | ## Overview 6 | 7 | Code segments are highlighted before the app is compiled. 8 | This is done because the highlighting process can take 300ms to finish, creating 9 | a noticeable delay when the demo switches to code page. 10 | 11 | The highlighter takes all files in the `lib/demos/` folder and scans each. 12 | Highlighted code widgets are stored in the 13 | `lib/codeviewer/code_segments.dart` file. 14 | 15 | ## How to generate code segments 16 | 17 | From the `gallery/` directory: 18 | 1. Make sure you have [grinder](https://pub.dev/packages/grinder) installed by 19 | running `flutter pub get`. 20 | 2. Then run `flutter pub run grinder update-code-segments` to generate code 21 | segments with highlighting. 22 | 23 | ## How to define a block of code to generate highlighting for 24 | 25 | Wrap a block of code with lines `// BEGIN yourDemoName` and `// END` to mark it 26 | for highlighting. The block in between, as well as any copyright notice and 27 | imports at the beginning of the file, are automatically taken and highlighted, 28 | and stored as `static TextSpan yourDemoName(BuildContext context)` in 29 | `gallery/lib/codeviewer/code_segments.dart`. To display the code, go to 30 | `gallery/lib/data/demos.dart`, and add `code: CodeSegments.yourDemoName,` to 31 | your `GalleryDemoConfiguration` object. 32 | 33 | ## Multiple blocks of code 34 | 35 | Use the following method to join multiple blocks of code into a single segment: 36 | ``` 37 | // BEGIN yourDemo#2 38 | a(); 39 | // END 40 | b(); 41 | // BEGIN yourDemo#1 42 | c(); 43 | // END 44 | ``` 45 | The generated code will be 46 | ``` 47 | c(); 48 | a(); 49 | ``` 50 | 51 | Code blocks can nest or overlap. In these cases, specify which file(s) to `END`. 52 | 53 | The following source file 54 | ``` 55 | // BEGIN demoOne 56 | a(); 57 | // BEGIN demoTwo 58 | b(); 59 | // END demoOne 60 | c(); 61 | // END demoTwo 62 | ``` 63 | will create the following segments: 64 | (demoOne) 65 | ``` 66 | a(); 67 | b(); 68 | ``` 69 | (demoTwo) 70 | ``` 71 | b(); 72 | c(); 73 | ``` 74 | -------------------------------------------------------------------------------- /tool/codeviewer_cli/main.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:io'; 6 | 7 | import 'package:args/args.dart'; 8 | 9 | import 'segment_generator.dart'; 10 | 11 | Future main(List arguments) async { 12 | final parser = ArgParser() 13 | ..addOption( 14 | 'target', 15 | help: 'The file path for the output target file.', 16 | defaultsTo: codeSegmentsPath, 17 | ); 18 | final argResults = parser.parse(arguments); 19 | 20 | final codeSegments = await getCodeSegments(); 21 | File(argResults['target'] as String).writeAsStringSync(codeSegments); 22 | } 23 | -------------------------------------------------------------------------------- /tool/grind.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:async'; 6 | import 'dart:io'; 7 | 8 | import 'package:grinder/grinder.dart'; 9 | import 'package:path/path.dart' as path; 10 | 11 | void main(List args) => grind(args); 12 | 13 | @Task('Get packages') 14 | Future pubGet({String? directory}) async { 15 | await _runProcess( 16 | 'flutter', 17 | ['pub', 'get', if (directory != null) directory], 18 | ); 19 | } 20 | 21 | @Task('Format dart files') 22 | Future format({String path = '.'}) async { 23 | await _runProcess('flutter', ['format', path]); 24 | } 25 | 26 | @Task('Transform arb to xml for English') 27 | Future l10n() async { 28 | final l10nPath = 29 | path.join(Directory.current.path, 'tool', 'l10n_cli', 'main.dart'); 30 | Dart.run(l10nPath); 31 | } 32 | 33 | @Task('Update code segments') 34 | Future updateCodeSegments() async { 35 | final codeviewerPath = 36 | path.join(Directory.current.path, 'tool', 'codeviewer_cli', 'main.dart'); 37 | Dart.run(codeviewerPath); 38 | } 39 | 40 | Future _runProcess(String executable, List arguments) async { 41 | final result = await Process.run(executable, arguments); 42 | stdout.write(result.stdout); 43 | stderr.write(result.stderr); 44 | } 45 | -------------------------------------------------------------------------------- /tool/l10n_cli/README.md: -------------------------------------------------------------------------------- 1 | # l10n 2 | 3 | A command-line application that converts .arb files to .xml files for 4 | translation consumption. -------------------------------------------------------------------------------- /tool/l10n_cli/main.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Flutter team. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'l10n_cli.dart'; 6 | 7 | void main(List arguments) { 8 | arbToXml(); 9 | } 10 | -------------------------------------------------------------------------------- /web/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Page Not Found 7 | 8 | 23 | 24 | 25 |
26 |

404

27 |

Page Not Found

28 |

The specified file was not found on this website. Please check the URL for mistakes and try again.

29 |

Why am I seeing this?

30 |

This page was generated by the Firebase Command-Line Interface. To modify it, edit the 404.html file in your project's configured public directory.

31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/web/favicon.ico -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/web/favicon.png -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/web/icons/Icon-maskable-128.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/web/icons/Icon-maskable-384.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/web/icons/Icon-maskable-48.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/web/icons/Icon-maskable-72.png -------------------------------------------------------------------------------- /web/icons/Icon-maskable-96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/web/icons/Icon-maskable-96.png -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Flutter Gallery", 3 | "short_name": "Flutter Gallery", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#030303", 7 | "theme_color": "#030303", 8 | "description": "A resource to help developers evaluate and use Flutter.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-48.png", 24 | "sizes": "48x48", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-72.png", 30 | "sizes": "72x72", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | }, 34 | { 35 | "src": "icons/Icon-maskable-96.png", 36 | "sizes": "96x96", 37 | "type": "image/png", 38 | "purpose": "maskable" 39 | }, 40 | { 41 | "src": "icons/Icon-maskable-128.png", 42 | "sizes": "128x128", 43 | "type": "image/png", 44 | "purpose": "maskable" 45 | }, 46 | { 47 | "src": "icons/Icon-maskable-192.png", 48 | "sizes": "192x192", 49 | "type": "image/png", 50 | "purpose": "maskable" 51 | }, 52 | { 53 | "src": "icons/Icon-maskable-384.png", 54 | "sizes": "384x384", 55 | "type": "image/png", 56 | "purpose": "maskable" 57 | }, 58 | { 59 | "src": "icons/Icon-maskable-512.png", 60 | "sizes": "512x512", 61 | "type": "image/png", 62 | "purpose": "maskable" 63 | } 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | 11 | void RegisterPlugins(flutter::PluginRegistry* registry) { 12 | UrlLauncherWindowsRegisterWithRegistrar( 13 | registry->GetRegistrarForPlugin("UrlLauncherWindows")); 14 | } 15 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | url_launcher_windows 7 | ) 8 | 9 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 10 | ) 11 | 12 | set(PLUGIN_BUNDLED_LIBRARIES) 13 | 14 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 15 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 16 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 18 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 19 | endforeach(plugin) 20 | 21 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 22 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) 23 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 24 | endforeach(ffi_plugin) 25 | -------------------------------------------------------------------------------- /windows/runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(runner LANGUAGES CXX) 3 | 4 | # Define the application target. To change its name, change BINARY_NAME in the 5 | # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer 6 | # work. 7 | # 8 | # Any new source files that you add to the application should be added here. 9 | add_executable(${BINARY_NAME} WIN32 10 | "flutter_window.cpp" 11 | "main.cpp" 12 | "utils.cpp" 13 | "win32_window.cpp" 14 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 15 | "Runner.rc" 16 | "runner.exe.manifest" 17 | ) 18 | 19 | # Apply the standard set of build settings. This can be removed for applications 20 | # that need different build settings. 21 | apply_standard_settings(${BINARY_NAME}) 22 | 23 | # Add preprocessor definitions for the build version. 24 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") 25 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") 26 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") 27 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") 28 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") 29 | 30 | # Disable Windows macros that collide with C++ standard library functions. 31 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") 32 | 33 | # Add dependency libraries and include directories. Add any application-specific 34 | # dependencies here. 35 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) 36 | target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") 37 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") 38 | 39 | # Run the Flutter tool portions of the build. This must not be removed. 40 | add_dependencies(${BINARY_NAME} flutter_assemble) 41 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.cpp: -------------------------------------------------------------------------------- 1 | #include "flutter_window.h" 2 | 3 | #include 4 | 5 | #include "flutter/generated_plugin_registrant.h" 6 | 7 | FlutterWindow::FlutterWindow(const flutter::DartProject& project) 8 | : project_(project) {} 9 | 10 | FlutterWindow::~FlutterWindow() {} 11 | 12 | bool FlutterWindow::OnCreate() { 13 | if (!Win32Window::OnCreate()) { 14 | return false; 15 | } 16 | 17 | RECT frame = GetClientArea(); 18 | 19 | // The size here must match the window dimensions to avoid unnecessary surface 20 | // creation / destruction in the startup path. 21 | flutter_controller_ = std::make_unique( 22 | frame.right - frame.left, frame.bottom - frame.top, project_); 23 | // Ensure that basic setup of the controller was successful. 24 | if (!flutter_controller_->engine() || !flutter_controller_->view()) { 25 | return false; 26 | } 27 | RegisterPlugins(flutter_controller_->engine()); 28 | SetChildContent(flutter_controller_->view()->GetNativeWindow()); 29 | 30 | flutter_controller_->engine()->SetNextFrameCallback([&]() { 31 | this->Show(); 32 | }); 33 | 34 | // Flutter can complete the first frame before the "show window" callback is 35 | // registered. The following call ensures a frame is pending to ensure the 36 | // window is shown. It is a no-op if the first frame hasn't completed yet. 37 | flutter_controller_->ForceRedraw(); 38 | 39 | return true; 40 | } 41 | 42 | void FlutterWindow::OnDestroy() { 43 | if (flutter_controller_) { 44 | flutter_controller_ = nullptr; 45 | } 46 | 47 | Win32Window::OnDestroy(); 48 | } 49 | 50 | LRESULT 51 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message, 52 | WPARAM const wparam, 53 | LPARAM const lparam) noexcept { 54 | // Give Flutter, including plugins, an opportunity to handle window messages. 55 | if (flutter_controller_) { 56 | std::optional result = 57 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, 58 | lparam); 59 | if (result) { 60 | return *result; 61 | } 62 | } 63 | 64 | switch (message) { 65 | case WM_FONTCHANGE: 66 | flutter_controller_->engine()->ReloadSystemFonts(); 67 | break; 68 | } 69 | 70 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam); 71 | } 72 | -------------------------------------------------------------------------------- /windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_FLUTTER_WINDOW_H_ 2 | #define RUNNER_FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "win32_window.h" 10 | 11 | // A window that does nothing but host a Flutter view. 12 | class FlutterWindow : public Win32Window { 13 | public: 14 | // Creates a new FlutterWindow hosting a Flutter view running |project|. 15 | explicit FlutterWindow(const flutter::DartProject& project); 16 | virtual ~FlutterWindow(); 17 | 18 | protected: 19 | // Win32Window: 20 | bool OnCreate() override; 21 | void OnDestroy() override; 22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 23 | LPARAM const lparam) noexcept override; 24 | 25 | private: 26 | // The project to run. 27 | flutter::DartProject project_; 28 | 29 | // The Flutter instance hosted by this window. 30 | std::unique_ptr flutter_controller_; 31 | }; 32 | 33 | #endif // RUNNER_FLUTTER_WINDOW_H_ 34 | -------------------------------------------------------------------------------- /windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "utils.h" 7 | 8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 9 | _In_ wchar_t *command_line, _In_ int show_command) { 10 | // Attach to console when present (e.g., 'flutter run') or create a 11 | // new console when running with a debugger. 12 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 13 | CreateAndAttachConsole(); 14 | } 15 | 16 | // Initialize COM, so that it is available for use in the library and/or 17 | // plugins. 18 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 19 | 20 | flutter::DartProject project(L"data"); 21 | 22 | std::vector command_line_arguments = 23 | GetCommandLineArguments(); 24 | 25 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); 26 | 27 | FlutterWindow window(project); 28 | Win32Window::Point origin(10, 10); 29 | Win32Window::Size size(1280, 720); 30 | if (!window.Create(L"Flutter Gallery", origin, size)) { 31 | return EXIT_FAILURE; 32 | } 33 | window.SetQuitOnClose(true); 34 | 35 | ::MSG msg; 36 | while (::GetMessage(&msg, nullptr, 0, 0)) { 37 | ::TranslateMessage(&msg); 38 | ::DispatchMessage(&msg); 39 | } 40 | 41 | ::CoUninitialize(); 42 | return EXIT_SUCCESS; 43 | } 44 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flutter/gallery/66a69803cc63dfc02878fae1959a2555f26ea25f/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | 24 | std::vector GetCommandLineArguments() { 25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. 26 | int argc; 27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); 28 | if (argv == nullptr) { 29 | return std::vector(); 30 | } 31 | 32 | std::vector command_line_arguments; 33 | 34 | // Skip the first argument as it's the binary name. 35 | for (int i = 1; i < argc; i++) { 36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i])); 37 | } 38 | 39 | ::LocalFree(argv); 40 | 41 | return command_line_arguments; 42 | } 43 | 44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) { 45 | if (utf16_string == nullptr) { 46 | return std::string(); 47 | } 48 | int target_length = ::WideCharToMultiByte( 49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 50 | -1, nullptr, 0, nullptr, nullptr); 51 | std::string utf8_string; 52 | if (target_length == 0 || target_length > utf8_string.max_size()) { 53 | return utf8_string; 54 | } 55 | utf8_string.resize(target_length); 56 | int converted_length = ::WideCharToMultiByte( 57 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 58 | -1, utf8_string.data(), 59 | target_length, nullptr, nullptr); 60 | if (converted_length == 0) { 61 | return std::string(); 62 | } 63 | return utf8_string; 64 | } 65 | -------------------------------------------------------------------------------- /windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | --------------------------------------------------------------------------------