From 1368b2e807ce286123608a83dd5a3bc1cc65fc12 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Mon, 5 Jun 2023 17:52:15 +0200 Subject: [PATCH] adaptive_layout use go_router some stuff finalize cleanup --- packages/adaptive_layout/.gitignore | 44 ++ packages/adaptive_layout/.metadata | 45 ++ packages/adaptive_layout/README.md | 16 + .../adaptive_layout/analysis_options.yaml | 6 + packages/adaptive_layout/lib/main.dart | 22 + .../lib/src/app_neon/account_switcher.dart | 43 ++ .../lib/src/app_neon/app_interface.dart | 20 + .../lib/src/app_neon/app_route.dart | 15 + .../lib/src/app_neon/data.dart | 80 +++ .../lib/src/app_neon/destination.dart | 73 +++ .../src/app_neon/widgets/navbar_layout.dart | 30 + .../src/app_neon/widgets/navrail_layout.dart | 87 +++ .../src/app_neon/widgets/tabbar_layout.dart | 26 + .../adaptive_layout/lib/src/files/files.dart | 80 +++ .../lib/src/files/files.g.dart | 32 + .../adaptive_layout/lib/src/files/routes.dart | 15 + .../adaptive_layout/lib/src/main_view.dart | 135 +++++ .../adaptive_layout/lib/src/news/news.dart | 141 +++++ .../adaptive_layout/lib/src/news/news.g.dart | 46 ++ .../adaptive_layout/lib/src/news/routes.dart | 17 + .../adaptive_layout/lib/src/notes/notes.dart | 149 +++++ .../lib/src/notes/notes.g.dart | 32 + .../adaptive_layout/lib/src/notes/routes.dart | 15 + packages/adaptive_layout/lib/src/routes.dart | 26 + packages/adaptive_layout/linux/.gitignore | 1 + packages/adaptive_layout/linux/CMakeLists.txt | 139 +++++ .../linux/flutter/CMakeLists.txt | 88 +++ .../flutter/generated_plugin_registrant.cc | 11 + .../flutter/generated_plugin_registrant.h | 15 + .../linux/flutter/generated_plugins.cmake | 23 + packages/adaptive_layout/linux/main.cc | 6 + .../adaptive_layout/linux/my_application.cc | 104 ++++ .../adaptive_layout/linux/my_application.h | 18 + packages/adaptive_layout/pubspec.lock | 555 ++++++++++++++++++ packages/adaptive_layout/pubspec.yaml | 94 +++ 35 files changed, 2249 insertions(+) create mode 100644 packages/adaptive_layout/.gitignore create mode 100644 packages/adaptive_layout/.metadata create mode 100644 packages/adaptive_layout/README.md create mode 100644 packages/adaptive_layout/analysis_options.yaml create mode 100644 packages/adaptive_layout/lib/main.dart create mode 100644 packages/adaptive_layout/lib/src/app_neon/account_switcher.dart create mode 100644 packages/adaptive_layout/lib/src/app_neon/app_interface.dart create mode 100644 packages/adaptive_layout/lib/src/app_neon/app_route.dart create mode 100644 packages/adaptive_layout/lib/src/app_neon/data.dart create mode 100644 packages/adaptive_layout/lib/src/app_neon/destination.dart create mode 100644 packages/adaptive_layout/lib/src/app_neon/widgets/navbar_layout.dart create mode 100644 packages/adaptive_layout/lib/src/app_neon/widgets/navrail_layout.dart create mode 100644 packages/adaptive_layout/lib/src/app_neon/widgets/tabbar_layout.dart create mode 100644 packages/adaptive_layout/lib/src/files/files.dart create mode 100644 packages/adaptive_layout/lib/src/files/files.g.dart create mode 100644 packages/adaptive_layout/lib/src/files/routes.dart create mode 100644 packages/adaptive_layout/lib/src/main_view.dart create mode 100644 packages/adaptive_layout/lib/src/news/news.dart create mode 100644 packages/adaptive_layout/lib/src/news/news.g.dart create mode 100644 packages/adaptive_layout/lib/src/news/routes.dart create mode 100644 packages/adaptive_layout/lib/src/notes/notes.dart create mode 100644 packages/adaptive_layout/lib/src/notes/notes.g.dart create mode 100644 packages/adaptive_layout/lib/src/notes/routes.dart create mode 100644 packages/adaptive_layout/lib/src/routes.dart create mode 100644 packages/adaptive_layout/linux/.gitignore create mode 100644 packages/adaptive_layout/linux/CMakeLists.txt create mode 100644 packages/adaptive_layout/linux/flutter/CMakeLists.txt create mode 100644 packages/adaptive_layout/linux/flutter/generated_plugin_registrant.cc create mode 100644 packages/adaptive_layout/linux/flutter/generated_plugin_registrant.h create mode 100644 packages/adaptive_layout/linux/flutter/generated_plugins.cmake create mode 100644 packages/adaptive_layout/linux/main.cc create mode 100644 packages/adaptive_layout/linux/my_application.cc create mode 100644 packages/adaptive_layout/linux/my_application.h create mode 100644 packages/adaptive_layout/pubspec.lock create mode 100644 packages/adaptive_layout/pubspec.yaml diff --git a/packages/adaptive_layout/.gitignore b/packages/adaptive_layout/.gitignore new file mode 100644 index 00000000..24476c5d --- /dev/null +++ b/packages/adaptive_layout/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/packages/adaptive_layout/.metadata b/packages/adaptive_layout/.metadata new file mode 100644 index 00000000..e94891d5 --- /dev/null +++ b/packages/adaptive_layout/.metadata @@ -0,0 +1,45 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + channel: stable + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + - platform: android + create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + - platform: ios + create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + - platform: linux + create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + - platform: macos + create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + - platform: web + create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + - platform: windows + create_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + base_revision: 84a1e904f44f9b0e9c4510138010edcc653163f8 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/packages/adaptive_layout/README.md b/packages/adaptive_layout/README.md new file mode 100644 index 00000000..71cb93c3 --- /dev/null +++ b/packages/adaptive_layout/README.md @@ -0,0 +1,16 @@ +# adaptive_layout + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/packages/adaptive_layout/analysis_options.yaml b/packages/adaptive_layout/analysis_options.yaml new file mode 100644 index 00000000..f42e01bc --- /dev/null +++ b/packages/adaptive_layout/analysis_options.yaml @@ -0,0 +1,6 @@ +include: package:nit_picking/flutter.yaml + +linter: + rules: + prefer_final_parameters: false + prefer_expression_function_bodies: false diff --git a/packages/adaptive_layout/lib/main.dart b/packages/adaptive_layout/lib/main.dart new file mode 100644 index 00000000..7f1dae47 --- /dev/null +++ b/packages/adaptive_layout/lib/main.dart @@ -0,0 +1,22 @@ +import 'package:adaptive_layout/src/routes.dart'; +import 'package:flutter/material.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + @override + Widget build(final BuildContext context) { + return MaterialApp.router( + title: 'Adaptive Layout Demo', + theme: ThemeData( + primaryColor: Colors.deepPurple, + useMaterial3: true, + ), + routerConfig: router, + ); + } +} diff --git a/packages/adaptive_layout/lib/src/app_neon/account_switcher.dart b/packages/adaptive_layout/lib/src/app_neon/account_switcher.dart new file mode 100644 index 00000000..c2715c57 --- /dev/null +++ b/packages/adaptive_layout/lib/src/app_neon/account_switcher.dart @@ -0,0 +1,43 @@ +import 'package:adaptive_layout/src/app_neon/data.dart'; +import 'package:flutter/material.dart'; + +class NeonAccountSwitcher extends StatefulWidget { + const NeonAccountSwitcher({super.key}); + + @override + State createState() => _NeonAccountSwitcherState(); +} + +class _NeonAccountSwitcherState extends State { + int _activeAccount = 0; + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; + + return DropdownButtonHideUnderline( + child: DropdownButton( + isExpanded: true, + dropdownColor: colorScheme.primary, + iconEnabledColor: colorScheme.onPrimary, + value: _activeAccount, + items: const [ + DropdownMenuItem( + value: 0, + child: DrawerItem(name: 'John Doe'), + ), + DropdownMenuItem( + value: 1, + child: DrawerItem(name: 'John Doe Work'), + ), + ], + onChanged: (id) { + setState(() { + _activeAccount = id ?? 0; + }); + }, + ), + ); + } +} diff --git a/packages/adaptive_layout/lib/src/app_neon/app_interface.dart b/packages/adaptive_layout/lib/src/app_neon/app_interface.dart new file mode 100644 index 00000000..84ef630c --- /dev/null +++ b/packages/adaptive_layout/lib/src/app_neon/app_interface.dart @@ -0,0 +1,20 @@ +import 'package:adaptive_layout/src/app_neon/destination.dart'; +import 'package:go_router/go_router.dart'; + +class App { + App({ + required this.destination, + required this.route, + String? routeName, + }) : assert( + routeName != null || route is GoRoute && route.name != null, + 'Routename must be specified when the route is not named.', + ), + routeName = route is GoRoute ? route.name! : routeName!; + + final RouteBase route; + + final NeonNavigationDestination destination; + + final String routeName; +} diff --git a/packages/adaptive_layout/lib/src/app_neon/app_route.dart b/packages/adaptive_layout/lib/src/app_neon/app_route.dart new file mode 100644 index 00000000..2ea00ae3 --- /dev/null +++ b/packages/adaptive_layout/lib/src/app_neon/app_route.dart @@ -0,0 +1,15 @@ +import 'package:flutter/widgets.dart'; +import 'package:go_router/go_router.dart'; + +abstract class NeonAppRoute extends GoRouteData { + const NeonAppRoute(); + + @override + Page buildPage(BuildContext context, GoRouterState state) { + return NoTransitionPage( + // Todo: cache the build to avoid duplicate animations. + // might turn out against us having every app cached though :thinking: + child: build(context, state), + ); + } +} diff --git a/packages/adaptive_layout/lib/src/app_neon/data.dart b/packages/adaptive_layout/lib/src/app_neon/data.dart new file mode 100644 index 00000000..867275be --- /dev/null +++ b/packages/adaptive_layout/lib/src/app_neon/data.dart @@ -0,0 +1,80 @@ +import 'package:flutter/material.dart'; + +class DrawerItem extends StatelessWidget { + const DrawerItem({ + required this.name, + super.key, + }); + + final String name; + + @override + Widget build(BuildContext context) { + final colorScheme = Theme.of(context).colorScheme; + return ListTile( + leading: Icon( + Icons.person_outline, + color: colorScheme.onPrimary, + ), + title: Text( + name, + style: TextStyle( + color: colorScheme.onPrimary, + ), + ), + ); + } +} + +class NeonDrawerHeader extends StatelessWidget { + const NeonDrawerHeader({ + this.name = 'NextCloud', + super.key, + }); + + final String name; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 100, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 24), + child: Row( + children: [ + const Icon( + Icons.cloud_outlined, + size: 60, + ), + const SizedBox(width: 10), + Text( + name, + style: const TextStyle(fontSize: 25), + ), + ], + ), + ), + ); + } +} + +class NeonSettingsDrawerItem extends StatelessWidget { + const NeonSettingsDrawerItem({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return const Padding( + // maybe drawerdestination + padding: EdgeInsets.symmetric(horizontal: 28), + child: Row( + children: [ + Icon(Icons.settings_outlined), + SizedBox(width: 12), + Text('settings'), + ], + ), + ); + } +} diff --git a/packages/adaptive_layout/lib/src/app_neon/destination.dart b/packages/adaptive_layout/lib/src/app_neon/destination.dart new file mode 100644 index 00000000..430a6c07 --- /dev/null +++ b/packages/adaptive_layout/lib/src/app_neon/destination.dart @@ -0,0 +1,73 @@ +import 'package:flutter/material.dart'; + +class NeonNavigationDestination { + const NeonNavigationDestination({ + required this.label, + required this.icon, + required this.selectedIcon, + this.notificationCount = 0, + }); + + final String label; + final Widget icon; + final Widget selectedIcon; + final int notificationCount; + + NavigationDestination toDestination() { + return NavigationDestination( + label: label, + icon: icon, + selectedIcon: selectedIcon, + ); + } + + NavigationRailDestination toRailDestination() { + var iconWIdget = icon; + + if (notificationCount > 0) { + iconWIdget = Stack( + alignment: Alignment.bottomRight, + children: [ + Container( + margin: const EdgeInsets.all(5), + child: iconWIdget, + ), + Text(notificationCount.toString()), + ], + ); + } + + return NavigationRailDestination( + label: Text(label), + icon: iconWIdget, + selectedIcon: selectedIcon, + ); + } + + NavigationDrawerDestination toDrawerDestination() { + Widget labelWidget = Text(label); + + if (notificationCount > 0) { + labelWidget = Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + labelWidget, + Text(notificationCount.toString()), + ], + ); + } + + return NavigationDrawerDestination( + label: labelWidget, + icon: icon, + selectedIcon: selectedIcon, + ); + } + + Tab toTab() { + return Tab( + icon: icon, + text: label, + ); + } +} diff --git a/packages/adaptive_layout/lib/src/app_neon/widgets/navbar_layout.dart b/packages/adaptive_layout/lib/src/app_neon/widgets/navbar_layout.dart new file mode 100644 index 00000000..98b5f55f --- /dev/null +++ b/packages/adaptive_layout/lib/src/app_neon/widgets/navbar_layout.dart @@ -0,0 +1,30 @@ +import 'package:adaptive_layout/src/app_neon/destination.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; + +class NeonNavBarLayout extends SlotLayout { + NeonNavBarLayout({ + required List destinations, + required ValueNotifier valueListenable, + super.key, + }) : super( + config: { + Breakpoints.small: SlotLayout.from( + key: const Key('bottomNavigation'), + outAnimation: AdaptiveScaffold.topToBottom, + builder: (_) { + return ValueListenableBuilder( + valueListenable: valueListenable, + builder: (context, value, child) => NavigationBar( + selectedIndex: value, + destinations: + destinations.map((d) => d.toDestination()).toList(), + onDestinationSelected: (index) => + valueListenable.value = index, + ), + ); + }, + ), + }, + ); +} diff --git a/packages/adaptive_layout/lib/src/app_neon/widgets/navrail_layout.dart b/packages/adaptive_layout/lib/src/app_neon/widgets/navrail_layout.dart new file mode 100644 index 00000000..e75a2e64 --- /dev/null +++ b/packages/adaptive_layout/lib/src/app_neon/widgets/navrail_layout.dart @@ -0,0 +1,87 @@ +import 'package:adaptive_layout/src/app_neon/data.dart'; +import 'package:adaptive_layout/src/app_neon/destination.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; + +class NeonNavRailLayout extends SlotLayout { + NeonNavRailLayout({ + required List destinations, + required ValueNotifier valueListenable, + FloatingActionButton? floatingActionButton, + super.key, + }) : super( + config: { + Breakpoints.medium: SlotLayout.from( + key: const Key('primaryNavigation'), + outAnimation: AdaptiveScaffold.leftInOut, + builder: (_) { + final fab = floatingActionButton != null + ? FloatingActionButton( + onPressed: floatingActionButton.onPressed, + tooltip: floatingActionButton.tooltip, + elevation: 0, + child: floatingActionButton.child, + ) + : const SizedBox(height: 56); + + return ValueListenableBuilder( + valueListenable: valueListenable, + builder: (context, value, child) => SizedBox( + width: 80, + child: NavigationRail( + leading: Column( + children: [ + const SizedBox(height: 56), + const DrawerButton(), + const SizedBox(height: 16), + fab, + const SizedBox(height: 80), + ], + ), + destinations: destinations.map((d) => d.toRailDestination()).toList(), + selectedIndex: value, + onDestinationSelected: (index) => valueListenable.value = index, + labelType: NavigationRailLabelType.all, + ), + ), + ); + }, + ), + Breakpoints.large: SlotLayout.from( + key: const Key('Large primaryNavigation'), + builder: (context) { + // this is ugly. We should abstract this in another way + final fab = floatingActionButton != null + ? FloatingActionButton.extended( + onPressed: floatingActionButton.onPressed, + label: Text(floatingActionButton.tooltip!), + icon: floatingActionButton.child, + elevation: 0, + ) + : null; + + return ValueListenableBuilder( + valueListenable: valueListenable, + builder: (context, value, child) => NavigationDrawer( + selectedIndex: value, + onDestinationSelected: (index) => valueListenable.value = index, + children: [ + const NeonDrawerHeader(name: 'coolApp'), + if (fab != null) ...[ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 28, + vertical: 16, + ), + child: fab, + ), + ], + ...destinations.map((d) => d.toDrawerDestination()), + ], + ), + ); + }, + ), + }, + ); +} diff --git a/packages/adaptive_layout/lib/src/app_neon/widgets/tabbar_layout.dart b/packages/adaptive_layout/lib/src/app_neon/widgets/tabbar_layout.dart new file mode 100644 index 00000000..befcd03a --- /dev/null +++ b/packages/adaptive_layout/lib/src/app_neon/widgets/tabbar_layout.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; + +class NeonTabBar extends InheritedWidget { + const NeonTabBar({ + required this.tabBarLayout, + required super.child, + super.key, + }); + + final SlotLayout tabBarLayout; + + static NeonTabBar? maybeOf(BuildContext context) { + return context.dependOnInheritedWidgetOfExactType(); + } + + static NeonTabBar of(BuildContext context) { + final result = maybeOf(context); + assert(result != null, 'No NeonTabBar found in context'); + return result!; + } + + @override + bool updateShouldNotify(NeonTabBar oldWidget) => + tabBarLayout != oldWidget.tabBarLayout; +} diff --git a/packages/adaptive_layout/lib/src/files/files.dart b/packages/adaptive_layout/lib/src/files/files.dart new file mode 100644 index 00000000..a7e2fd3b --- /dev/null +++ b/packages/adaptive_layout/lib/src/files/files.dart @@ -0,0 +1,80 @@ +import 'package:adaptive_layout/src/app_neon/app_interface.dart'; +import 'package:adaptive_layout/src/app_neon/app_route.dart'; +import 'package:adaptive_layout/src/app_neon/destination.dart'; +import 'package:adaptive_layout/src/app_neon/widgets/tabbar_layout.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; +import 'package:go_router/go_router.dart'; + +part 'files.g.dart'; +part 'routes.dart'; + +final view = ListView.builder( + itemBuilder: (context, index) { + return Card( + child: ListTile( + leading: const Icon(Icons.folder_outlined), + title: const Text('item'), + trailing: Text(index.toString()), + ), + ); + }, +); + +final fab = FloatingActionButton( + onPressed: () {}, + child: const Icon(Icons.add), +); + +class FilesAppView extends StatelessWidget { + const FilesAppView({ + super.key, + }); + + @override + Widget build(BuildContext context) { + final topNavigation = NeonTabBar.of(context).tabBarLayout; + + return AdaptiveLayout( + internalAnimations: false, + topNavigation: topNavigation, + body: SlotLayout( + config: { + Breakpoints.standard: SlotLayout.from( + key: const Key('body'), + builder: (context) { + final drawerButton = DrawerButton( + onPressed: Scaffold.of(context).openDrawer, + ); + + return Scaffold( + appBar: AppBar( + leading: drawerButton, + title: const Text('Files'), + ), + body: view, + floatingActionButton: fab, + ); + }, + ), + Breakpoints.large: SlotLayout.from( + key: const Key('body'), + builder: (_) => Scaffold( + body: view, + floatingActionButton: fab, + ), + ), + }, + ), + ); + } +} + +final filesApp = App( + route: $filesAppRoute, + destination: const NeonNavigationDestination( + icon: Icon(Icons.folder_outlined), + selectedIcon: Icon(Icons.folder), + label: 'Files', + ), +); diff --git a/packages/adaptive_layout/lib/src/files/files.g.dart b/packages/adaptive_layout/lib/src/files/files.g.dart new file mode 100644 index 00000000..c2981987 --- /dev/null +++ b/packages/adaptive_layout/lib/src/files/files.g.dart @@ -0,0 +1,32 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'files.dart'; + +// ************************************************************************** +// GoRouterGenerator +// ************************************************************************** + +List get $appRoutes => [ + $filesAppRoute, + ]; + +RouteBase get $filesAppRoute => GoRouteData.$route( + path: '/apps/files', + name: 'filesApp', + factory: $FilesAppRouteExtension._fromState, + ); + +extension $FilesAppRouteExtension on FilesAppRoute { + static FilesAppRoute _fromState(GoRouterState state) => const FilesAppRoute(); + + String get location => GoRouteData.$location( + '/apps/files', + ); + + void go(BuildContext context) => context.go(location); + + Future push(BuildContext context) => context.push(location); + + void pushReplacement(BuildContext context) => + context.pushReplacement(location); +} diff --git a/packages/adaptive_layout/lib/src/files/routes.dart b/packages/adaptive_layout/lib/src/files/routes.dart new file mode 100644 index 00000000..8f68614f --- /dev/null +++ b/packages/adaptive_layout/lib/src/files/routes.dart @@ -0,0 +1,15 @@ +part of 'files.dart'; + +@TypedGoRoute( + path: '/apps/files', + name: 'filesApp', +) +@immutable +class FilesAppRoute extends NeonAppRoute { + const FilesAppRoute(); + + @override + Widget build(BuildContext context, GoRouterState state) { + return const FilesAppView(); + } +} diff --git a/packages/adaptive_layout/lib/src/main_view.dart b/packages/adaptive_layout/lib/src/main_view.dart new file mode 100644 index 00000000..c9ea18ff --- /dev/null +++ b/packages/adaptive_layout/lib/src/main_view.dart @@ -0,0 +1,135 @@ +import 'package:adaptive_layout/src/app_neon/account_switcher.dart'; +import 'package:adaptive_layout/src/app_neon/data.dart'; +import 'package:adaptive_layout/src/app_neon/widgets/tabbar_layout.dart'; +import 'package:adaptive_layout/src/files/files.dart'; +import 'package:adaptive_layout/src/news/news.dart'; +import 'package:adaptive_layout/src/notes/notes.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; +import 'package:go_router/go_router.dart'; + +final apps = [ + filesApp, + notesApp, + newsApp, +]; + +class NeonMainView extends StatefulWidget { + const NeonMainView({ + required this.state, + required this.view, + super.key, + }); + + final GoRouterState state; + final Widget view; + + @override + State createState() => _NeonMainViewState(); +} + +class _NeonMainViewState extends State with SingleTickerProviderStateMixin { + final _scaffoldKey = GlobalKey(); + late TabController _tabController; + + int _activeApp = 0; + + @override + void initState() { + super.initState(); + + _tabController = TabController( + vsync: this, + length: apps.length, + ); + } + + @override + void dispose() { + _tabController.dispose(); + super.dispose(); + } + + void onAppChange(int index) { + context.goNamed(apps[index].routeName); + + setState(() { + _activeApp = index; + }); + + _scaffoldKey.currentState?.closeDrawer(); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; + + final header = DrawerHeader( + decoration: BoxDecoration( + color: colorScheme.primary, + ), + child: Column( + children: [ + Expanded( + child: Center( + child: Icon( + Icons.cloud_outlined, // that's the new NC icon for sure + size: 100, + color: colorScheme.onPrimary, + ), + ), + ), + const NeonAccountSwitcher(), + ], + ), + ); + + final drawer = NavigationDrawer( + selectedIndex: _activeApp, + onDestinationSelected: onAppChange, + children: [ + header, + ...apps.map((app) => app.destination.toDrawerDestination()), + const NeonSettingsDrawerItem(), + ], + ); + + final topNavigation = SlotLayout( + config: { + Breakpoints.large: SlotLayout.from( + key: const Key('Large topNavigation'), + builder: (context) { + return Row( + children: [ + Expanded( + child: TabBar( + tabs: apps.map((a) => a.destination.toTab()).toList(), + onTap: onAppChange, + isScrollable: true, + ), + ), + IconButton( + onPressed: () {}, + icon: const Icon(Icons.person_outline), + ), + ], + ); + }, + ), + }, + ); + + return Scaffold( + key: _scaffoldKey, + drawer: drawer, + body: DefaultTabController( + length: apps.length, + child: NeonTabBar( + tabBarLayout: topNavigation, + child: widget.view, + ), + ), + ); + } +} diff --git a/packages/adaptive_layout/lib/src/news/news.dart b/packages/adaptive_layout/lib/src/news/news.dart new file mode 100644 index 00000000..bdbe7ef5 --- /dev/null +++ b/packages/adaptive_layout/lib/src/news/news.dart @@ -0,0 +1,141 @@ +import 'package:adaptive_layout/src/app_neon/app_interface.dart'; +import 'package:adaptive_layout/src/app_neon/app_route.dart'; +import 'package:adaptive_layout/src/app_neon/destination.dart'; +import 'package:adaptive_layout/src/app_neon/widgets/tabbar_layout.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; +import 'package:go_router/go_router.dart'; + +part 'news.g.dart'; +part 'routes.dart'; + +class NewsAppView extends StatelessWidget { + const NewsAppView({ + this.articleID, + super.key, + }); + + final int? articleID; + + Widget secondaryBodyNuilder(BuildContext context) { + return NewsSecondaryView(id: articleID!); + } + + @override + Widget build(BuildContext context) { + final topNavigation = NeonTabBar.of(context).tabBarLayout; + + final listView = ListView.builder( + itemBuilder: (context, index) { + return Card( + child: ListTile( + leading: const Icon(Icons.article_outlined), + title: const Text('item'), + trailing: Text(index.toString()), + onTap: () => NewsAppRoute(index).go(context), + ), + ); + }, + ); + + return AdaptiveLayout( + internalAnimations: false, + topNavigation: topNavigation, + body: SlotLayout( + config: { + Breakpoints.standard: SlotLayout.from( + key: const Key('body'), + builder: (context) { + final drawerButton = DrawerButton( + onPressed: Scaffold.of(context).openDrawer, + ); + + return Scaffold( + appBar: AppBar( + leading: drawerButton, + title: const Text('News'), + ), + body: listView, + ); + }, + ), + if (articleID != null) ...{ + Breakpoints.small: SlotLayout.from( + key: const Key('body'), + builder: (context) { + return NewsSecondaryView( + id: articleID!, + isPage: true, + ); + }, + ) + }, + Breakpoints.large: SlotLayout.from( + key: const Key('body'), + builder: (_) => Scaffold( + body: listView, + ), + ), + }, + ), + secondaryBody: SlotLayout( + config: { + Breakpoints.mediumAndUp: SlotLayout.from( + key: const Key('secondaryBody'), + builder: articleID != null + ? secondaryBodyNuilder + : AdaptiveScaffold.emptyBuilder, + ), + }, + ), + ); + } +} + +class NewsSecondaryView extends StatelessWidget { + const NewsSecondaryView({ + required this.id, + this.isPage = false, + super.key, + }); + + final int id; + final bool isPage; + + @override + Widget build(BuildContext context) { + final appBar = AppBar( + leading: BackButton( + onPressed: () => const NewsAppRoute().go(context), + ), + title: const Text('NewsItem'), + ); + + return Scaffold( + appBar: isPage ? appBar : null, + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const FlutterLogo(size: 100), + const SizedBox(height: 30), + Text( + id.toString(), + style: Theme.of(context).textTheme.headlineLarge, + ), + ], + ), + ), + ); + } +} + +final newsApp = App( + route: $newsAppRoute, + destination: const NeonNavigationDestination( + icon: Icon(Icons.notes_outlined), + selectedIcon: Icon(Icons.notes), + label: 'News', + notificationCount: 100, + ), +); diff --git a/packages/adaptive_layout/lib/src/news/news.g.dart b/packages/adaptive_layout/lib/src/news/news.g.dart new file mode 100644 index 00000000..c7acb733 --- /dev/null +++ b/packages/adaptive_layout/lib/src/news/news.g.dart @@ -0,0 +1,46 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'news.dart'; + +// ************************************************************************** +// GoRouterGenerator +// ************************************************************************** + +List get $appRoutes => [ + $newsAppRoute, + ]; + +RouteBase get $newsAppRoute => GoRouteData.$route( + path: '/apps/news', + name: 'newsApp', + factory: $NewsAppRouteExtension._fromState, + ); + +extension $NewsAppRouteExtension on NewsAppRoute { + static NewsAppRoute _fromState(GoRouterState state) => NewsAppRoute( + _$convertMapValue('article-i-d', state.queryParameters, int.parse), + ); + + String get location => GoRouteData.$location( + '/apps/news', + queryParams: { + if (articleID != null) 'article-i-d': articleID!.toString(), + }, + ); + + void go(BuildContext context) => context.go(location); + + Future push(BuildContext context) => context.push(location); + + void pushReplacement(BuildContext context) => + context.pushReplacement(location); +} + +T? _$convertMapValue( + String key, + Map map, + T Function(String) converter, +) { + final value = map[key]; + return value == null ? null : converter(value); +} diff --git a/packages/adaptive_layout/lib/src/news/routes.dart b/packages/adaptive_layout/lib/src/news/routes.dart new file mode 100644 index 00000000..5d5f404c --- /dev/null +++ b/packages/adaptive_layout/lib/src/news/routes.dart @@ -0,0 +1,17 @@ +part of 'news.dart'; + +@TypedGoRoute( + path: '/apps/news', + name: 'newsApp', +) +@immutable +class NewsAppRoute extends NeonAppRoute { + const NewsAppRoute([this.articleID]); + + final int? articleID; + + @override + Widget build(BuildContext context, GoRouterState state) { + return NewsAppView(articleID: articleID); + } +} diff --git a/packages/adaptive_layout/lib/src/notes/notes.dart b/packages/adaptive_layout/lib/src/notes/notes.dart new file mode 100644 index 00000000..4d7e3f9b --- /dev/null +++ b/packages/adaptive_layout/lib/src/notes/notes.dart @@ -0,0 +1,149 @@ +import 'package:adaptive_layout/src/app_neon/app_interface.dart'; +import 'package:adaptive_layout/src/app_neon/app_route.dart'; +import 'package:adaptive_layout/src/app_neon/destination.dart'; +import 'package:adaptive_layout/src/app_neon/widgets/navbar_layout.dart'; +import 'package:adaptive_layout/src/app_neon/widgets/navrail_layout.dart'; +import 'package:adaptive_layout/src/app_neon/widgets/tabbar_layout.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_adaptive_scaffold/flutter_adaptive_scaffold.dart'; +import 'package:go_router/go_router.dart'; + +part 'notes.g.dart'; +part 'routes.dart'; + +final _destinations = [ + const NeonNavigationDestination( + icon: Icon(Icons.note_outlined), + selectedIcon: Icon(Icons.note), + label: 'Notes', + ), + const NeonNavigationDestination( + icon: Icon(Icons.label_outline), + selectedIcon: Icon(Icons.label), + label: 'Category', + ), +]; + +final _appNavNotifier = ValueNotifier(0); + +final _listView = ListView.builder( + itemBuilder: (context, index) { + return Card( + child: ListTile( + leading: const Icon(Icons.article_outlined), + title: const Text('item'), + trailing: Text(index.toString()), + ), + ); + }, +); + +final _gridView = GridView.builder( + itemBuilder: (context, index) { + return Card( + child: ListTile( + leading: const Icon(Icons.article_outlined), + title: const Text('item'), + trailing: Text(index.toString()), + ), + ); + }, + gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(maxCrossAxisExtent: 150), +); + +final view = ValueListenableBuilder( + valueListenable: _appNavNotifier, + builder: (context, value, child) { + if (value == 1) { + return _gridView; + } + + return _listView; + }, +); + +final fab = FloatingActionButton( + onPressed: () {}, + tooltip: 'Create Note', + child: const Icon(Icons.add), +); + +class NotesAppView extends StatelessWidget { + const NotesAppView({ + super.key, + }); + + @override + Widget build(BuildContext context) { + final topNavigation = NeonTabBar.of(context).tabBarLayout; + + return AdaptiveLayout( + internalAnimations: false, + topNavigation: topNavigation, + body: SlotLayout( + config: { + Breakpoints.standard: SlotLayout.from( + key: const Key('body'), + builder: (_) => Scaffold( + body: view, + ), + ), + Breakpoints.small: SlotLayout.from( + key: const Key('body'), + builder: (context) { + final drawerButton = DrawerButton( + onPressed: Scaffold.of(context).openDrawer, + ); + + return Scaffold( + appBar: AppBar( + leading: drawerButton, + title: const Text('Notes'), + ), + body: view, + floatingActionButton: fab, + ); + }, + ), + }, + ), + secondaryBody: SlotLayout( + config: { + Breakpoints.mediumAndUp: SlotLayout.from( + key: const Key('body'), + builder: (_) => Scaffold( + body: ListView.builder( + itemBuilder: (context, index) { + return Card( + child: ListTile( + title: const Text('item'), + trailing: Text(index.toString()), + ), + ); + }, + ), + ), + ), + }, + ), + primaryNavigation: NeonNavRailLayout( + destinations: _destinations, + valueListenable: _appNavNotifier, + floatingActionButton: fab, + ), + bottomNavigation: NeonNavBarLayout( + destinations: _destinations, + valueListenable: _appNavNotifier, + ), + ); + } +} + +final notesApp = App( + route: $notesAppRoute, + destination: const NeonNavigationDestination( + icon: Icon(Icons.edit_outlined), + selectedIcon: Icon(Icons.edit), + label: 'Notes', + ), +); diff --git a/packages/adaptive_layout/lib/src/notes/notes.g.dart b/packages/adaptive_layout/lib/src/notes/notes.g.dart new file mode 100644 index 00000000..eb86bc13 --- /dev/null +++ b/packages/adaptive_layout/lib/src/notes/notes.g.dart @@ -0,0 +1,32 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'notes.dart'; + +// ************************************************************************** +// GoRouterGenerator +// ************************************************************************** + +List get $appRoutes => [ + $notesAppRoute, + ]; + +RouteBase get $notesAppRoute => GoRouteData.$route( + path: '/apps/notes', + name: 'notesApp', + factory: $NotesAppRouteExtension._fromState, + ); + +extension $NotesAppRouteExtension on NotesAppRoute { + static NotesAppRoute _fromState(GoRouterState state) => const NotesAppRoute(); + + String get location => GoRouteData.$location( + '/apps/notes', + ); + + void go(BuildContext context) => context.go(location); + + Future push(BuildContext context) => context.push(location); + + void pushReplacement(BuildContext context) => + context.pushReplacement(location); +} diff --git a/packages/adaptive_layout/lib/src/notes/routes.dart b/packages/adaptive_layout/lib/src/notes/routes.dart new file mode 100644 index 00000000..255846be --- /dev/null +++ b/packages/adaptive_layout/lib/src/notes/routes.dart @@ -0,0 +1,15 @@ +part of 'notes.dart'; + +@TypedGoRoute( + path: '/apps/notes', + name: 'notesApp', +) +@immutable +class NotesAppRoute extends NeonAppRoute { + const NotesAppRoute(); + + @override + Widget build(BuildContext context, GoRouterState state) { + return const NotesAppView(); + } +} diff --git a/packages/adaptive_layout/lib/src/routes.dart b/packages/adaptive_layout/lib/src/routes.dart new file mode 100644 index 00000000..b3a9399d --- /dev/null +++ b/packages/adaptive_layout/lib/src/routes.dart @@ -0,0 +1,26 @@ +import 'package:adaptive_layout/src/files/files.dart'; +import 'package:adaptive_layout/src/main_view.dart'; +import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; + +final GlobalKey _rootKey = GlobalKey(); +final GlobalKey _appsKey = GlobalKey(); + +final router = GoRouter( + navigatorKey: _rootKey, + initialLocation: const FilesAppRoute().location, + routes: [ + ShellRoute( + navigatorKey: _appsKey, + builder: (context, state, navigator) { + return NeonMainView( + state: state, + view: navigator, + ); + }, + routes: [ + ...apps.map((a) => a.route), + ], + ), + ], +); diff --git a/packages/adaptive_layout/linux/.gitignore b/packages/adaptive_layout/linux/.gitignore new file mode 100644 index 00000000..d3896c98 --- /dev/null +++ b/packages/adaptive_layout/linux/.gitignore @@ -0,0 +1 @@ +flutter/ephemeral diff --git a/packages/adaptive_layout/linux/CMakeLists.txt b/packages/adaptive_layout/linux/CMakeLists.txt new file mode 100644 index 00000000..4c331738 --- /dev/null +++ b/packages/adaptive_layout/linux/CMakeLists.txt @@ -0,0 +1,139 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.10) +project(runner LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "adaptive_layout") +# The unique GTK application identifier for this application. See: +# https://wiki.gnome.org/HowDoI/ChooseApplicationID +set(APPLICATION_ID "com.example.adaptive_layout") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(SET CMP0063 NEW) + +# Load bundled libraries from the lib/ directory relative to the binary. +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Root filesystem for cross-building. +if(FLUTTER_TARGET_PLATFORM_SYSROOT) + set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endif() + +# Define build configuration options. +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") +endif() + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_14) + target_compile_options(${TARGET} PRIVATE -Wall -Werror) + target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) + +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + +# Define the application target. To change its name, change BINARY_NAME above, +# not the value here, or `flutter run` will no longer work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add dependency libraries. Add any application-specific dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) + +# Only the install-generated bundle's copy of the executable will launch +# correctly, since the resources must in the right relative locations. To avoid +# people trying to run the unbundled copy, put it in a subdirectory instead of +# the default top-level location. +set_target_properties(${BINARY_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" +) + + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# By default, "installing" just makes a relocatable bundle in the build +# directory. +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) + install(FILES "${bundled_library}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endforeach(bundled_library) + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() diff --git a/packages/adaptive_layout/linux/flutter/CMakeLists.txt b/packages/adaptive_layout/linux/flutter/CMakeLists.txt new file mode 100644 index 00000000..d5bd0164 --- /dev/null +++ b/packages/adaptive_layout/linux/flutter/CMakeLists.txt @@ -0,0 +1,88 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) + +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "fl_basic_message_channel.h" + "fl_binary_codec.h" + "fl_binary_messenger.h" + "fl_dart_project.h" + "fl_engine.h" + "fl_json_message_codec.h" + "fl_json_method_codec.h" + "fl_message_codec.h" + "fl_method_call.h" + "fl_method_channel.h" + "fl_method_codec.h" + "fl_method_response.h" + "fl_plugin_registrar.h" + "fl_plugin_registry.h" + "fl_standard_message_codec.h" + "fl_standard_method_codec.h" + "fl_string_codec.h" + "fl_value.h" + "fl_view.h" + "flutter_linux.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE + PkgConfig::GTK + PkgConfig::GLIB + PkgConfig::GIO +) +add_dependencies(flutter flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/_phony_ + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" + ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} +) diff --git a/packages/adaptive_layout/linux/flutter/generated_plugin_registrant.cc b/packages/adaptive_layout/linux/flutter/generated_plugin_registrant.cc new file mode 100644 index 00000000..e71a16d2 --- /dev/null +++ b/packages/adaptive_layout/linux/flutter/generated_plugin_registrant.cc @@ -0,0 +1,11 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + + +void fl_register_plugins(FlPluginRegistry* registry) { +} diff --git a/packages/adaptive_layout/linux/flutter/generated_plugin_registrant.h b/packages/adaptive_layout/linux/flutter/generated_plugin_registrant.h new file mode 100644 index 00000000..e0f0a47b --- /dev/null +++ b/packages/adaptive_layout/linux/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void fl_register_plugins(FlPluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/packages/adaptive_layout/linux/flutter/generated_plugins.cmake b/packages/adaptive_layout/linux/flutter/generated_plugins.cmake new file mode 100644 index 00000000..2e1de87a --- /dev/null +++ b/packages/adaptive_layout/linux/flutter/generated_plugins.cmake @@ -0,0 +1,23 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/packages/adaptive_layout/linux/main.cc b/packages/adaptive_layout/linux/main.cc new file mode 100644 index 00000000..e7c5c543 --- /dev/null +++ b/packages/adaptive_layout/linux/main.cc @@ -0,0 +1,6 @@ +#include "my_application.h" + +int main(int argc, char** argv) { + g_autoptr(MyApplication) app = my_application_new(); + return g_application_run(G_APPLICATION(app), argc, argv); +} diff --git a/packages/adaptive_layout/linux/my_application.cc b/packages/adaptive_layout/linux/my_application.cc new file mode 100644 index 00000000..bd116c96 --- /dev/null +++ b/packages/adaptive_layout/linux/my_application.cc @@ -0,0 +1,104 @@ +#include "my_application.h" + +#include +#ifdef GDK_WINDOWING_X11 +#include +#endif + +#include "flutter/generated_plugin_registrant.h" + +struct _MyApplication { + GtkApplication parent_instance; + char** dart_entrypoint_arguments; +}; + +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) + +// Implements GApplication::activate. +static void my_application_activate(GApplication* application) { + MyApplication* self = MY_APPLICATION(application); + GtkWindow* window = + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + + // Use a header bar when running in GNOME as this is the common style used + // by applications and is the setup most users will be using (e.g. Ubuntu + // desktop). + // If running on X and not using GNOME then just use a traditional title bar + // in case the window manager does more exotic layout, e.g. tiling. + // If running on Wayland assume the header bar will work (may need changing + // if future cases occur). + gboolean use_header_bar = TRUE; +#ifdef GDK_WINDOWING_X11 + GdkScreen* screen = gtk_window_get_screen(window); + if (GDK_IS_X11_SCREEN(screen)) { + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { + use_header_bar = FALSE; + } + } +#endif + if (use_header_bar) { + GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); + gtk_widget_show(GTK_WIDGET(header_bar)); + gtk_header_bar_set_title(header_bar, "adaptive_layout"); + gtk_header_bar_set_show_close_button(header_bar, TRUE); + gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); + } else { + gtk_window_set_title(window, "adaptive_layout"); + } + + gtk_window_set_default_size(window, 1280, 720); + gtk_widget_show(GTK_WIDGET(window)); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); + + FlView* view = fl_view_new(project); + gtk_widget_show(GTK_WIDGET(view)); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus(GTK_WIDGET(view)); +} + +// Implements GApplication::local_command_line. +static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { + MyApplication* self = MY_APPLICATION(application); + // Strip out the first argument as it is the binary name. + self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); + + g_autoptr(GError) error = nullptr; + if (!g_application_register(application, nullptr, &error)) { + g_warning("Failed to register: %s", error->message); + *exit_status = 1; + return TRUE; + } + + g_application_activate(application); + *exit_status = 0; + + return TRUE; +} + +// Implements GObject::dispose. +static void my_application_dispose(GObject* object) { + MyApplication* self = MY_APPLICATION(object); + g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); + G_OBJECT_CLASS(my_application_parent_class)->dispose(object); +} + +static void my_application_class_init(MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = my_application_activate; + G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; + G_OBJECT_CLASS(klass)->dispose = my_application_dispose; +} + +static void my_application_init(MyApplication* self) {} + +MyApplication* my_application_new() { + return MY_APPLICATION(g_object_new(my_application_get_type(), + "application-id", APPLICATION_ID, + "flags", G_APPLICATION_NON_UNIQUE, + nullptr)); +} diff --git a/packages/adaptive_layout/linux/my_application.h b/packages/adaptive_layout/linux/my_application.h new file mode 100644 index 00000000..72271d5e --- /dev/null +++ b/packages/adaptive_layout/linux/my_application.h @@ -0,0 +1,18 @@ +#ifndef FLUTTER_MY_APPLICATION_H_ +#define FLUTTER_MY_APPLICATION_H_ + +#include + +G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, + GtkApplication) + +/** + * my_application_new: + * + * Creates a new Flutter-based application. + * + * Returns: a new #MyApplication. + */ +MyApplication* my_application_new(); + +#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/packages/adaptive_layout/pubspec.lock b/packages/adaptive_layout/pubspec.lock new file mode 100644 index 00000000..ee818364 --- /dev/null +++ b/packages/adaptive_layout/pubspec.lock @@ -0,0 +1,555 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + url: "https://pub.dev" + source: hosted + version: "61.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + url: "https://pub.dev" + source: hosted + version: "5.13.0" + args: + dependency: transitive + description: + name: args + sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a + url: "https://pub.dev" + source: hosted + version: "2.4.1" + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + build: + dependency: transitive + description: + name: build + sha256: "43865b79fbb78532e4bff7c33087aa43b1d488c4fdef014eaef568af6d8016dc" + url: "https://pub.dev" + source: hosted + version: "2.4.0" + build_config: + dependency: transitive + description: + name: build_config + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" + source: hosted + version: "1.1.1" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65" + url: "https://pub.dev" + source: hosted + version: "4.0.0" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: db49b8609ef8c81cca2b310618c3017c00f03a92af44c04d310b907b2d692d95 + url: "https://pub.dev" + source: hosted + version: "2.2.0" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: "220ae4553e50d7c21a17c051afc7b183d28a24a420502e842f303f8e4e6edced" + url: "https://pub.dev" + source: hosted + version: "2.4.4" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: "88a57f2ac99849362e73878334caa9f06ee25f31d2adced882b8337838c84e1e" + url: "https://pub.dev" + source: hosted + version: "7.2.9" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: "7dd62d9faf105c434f3d829bbe9c4be02ec67f5ed94832222116122df67c5452" + url: "https://pub.dev" + source: hosted + version: "8.6.0" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" + source: hosted + version: "2.0.3" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe" + url: "https://pub.dev" + source: hosted + version: "4.4.0" + collection: + dependency: transitive + description: + name: collection + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + url: "https://pub.dev" + source: hosted + version: "1.17.1" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab + url: "https://pub.dev" + source: hosted + version: "3.0.3" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + url: "https://pub.dev" + source: hosted + version: "1.0.5" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: f4f1f73ab3fd2afcbcca165ee601fe980d966af6a21b5970c6c9376955c528ad + url: "https://pub.dev" + source: hosted + version: "2.3.1" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + file: + dependency: transitive + description: + name: file + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + url: "https://pub.dev" + source: hosted + version: "7.0.0" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_adaptive_scaffold: + dependency: "direct main" + description: + name: flutter_adaptive_scaffold + sha256: f9482e41adaf26d6fa9de02b605adc346961cb4bb34fe9420335df591ce3de6d + url: "https://pub.dev" + source: hosted + version: "0.1.3" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + url: "https://pub.dev" + source: hosted + version: "3.2.0" + glob: + dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + go_router: + dependency: "direct main" + description: + name: go_router + sha256: "00d1b67d6e9fa443331da229084dd3eb04407f5a2dff22940bd7bba6af5722c3" + url: "https://pub.dev" + source: hosted + version: "7.1.1" + go_router_builder: + dependency: "direct dev" + description: + name: go_router_builder + sha256: "74c6c12cf80248e97d5555df6fcae38a78e9ab7680689e9b9661bd74bcdda74d" + url: "https://pub.dev" + source: hosted + version: "2.0.1" + graphs: + dependency: transitive + description: + name: graphs + sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 + url: "https://pub.dev" + source: hosted + version: "2.3.1" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + intersperse: + dependency: "direct main" + description: + name: intersperse + sha256: "2f8a905c96f6cbba978644a3d5b31b8d86ddc44917662df7d27a61f3df66a576" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + io: + dependency: transitive + description: + name: io + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" + source: hosted + version: "1.0.4" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" + json_annotation: + dependency: transitive + description: + name: json_annotation + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + url: "https://pub.dev" + source: hosted + version: "4.8.1" + logging: + dependency: transitive + description: + name: logging + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + url: "https://pub.dev" + source: hosted + version: "0.12.15" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + meta: + dependency: transitive + description: + name: meta + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + mime: + dependency: transitive + description: + name: mime + sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + url: "https://pub.dev" + source: hosted + version: "1.0.4" + nit_picking: + dependency: "direct dev" + description: + path: "." + ref: "0b2ee0d" + resolved-ref: "0b2ee0d6d6871a04aaf85e88cd7e877f654d15e3" + url: "https://github.com/stack11/dart_nit_picking" + source: git + version: "0.0.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + path: + dependency: transitive + description: + name: path + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" + source: hosted + version: "1.8.3" + path_to_regexp: + dependency: transitive + description: + name: path_to_regexp + sha256: "169d78fbd55e61ea8873bcca545979f559d22238f66facdd7ef30870c7f53327" + url: "https://pub.dev" + source: hosted + version: "0.4.0" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + url: "https://pub.dev" + source: hosted + version: "1.2.3" + shelf: + dependency: transitive + description: + name: shelf + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 + url: "https://pub.dev" + source: hosted + version: "1.4.1" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" + url: "https://pub.dev" + source: hosted + version: "1.0.4" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "373f96cf5a8744bc9816c1ff41cf5391bbdbe3d7a96fe98c622b6738a8a7bd33" + url: "https://pub.dev" + source: hosted + version: "1.3.2" + source_helper: + dependency: transitive + description: + name: source_helper + sha256: "3b67aade1d52416149c633ba1bb36df44d97c6b51830c2198e934e3fca87ca1f" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + source_span: + dependency: transitive + description: + name: source_span + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" + source: hosted + version: "1.9.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" + source: hosted + version: "1.11.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + url: "https://pub.dev" + source: hosted + version: "0.5.1" + timing: + dependency: transitive + description: + name: timing + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c + url: "https://pub.dev" + source: hosted + version: "1.3.2" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + watcher: + dependency: transitive + description: + name: watcher + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + url: "https://pub.dev" + source: hosted + version: "2.4.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" + source: hosted + version: "3.1.2" +sdks: + dart: ">=3.0.0 <4.0.0" + flutter: ">=3.3.0" diff --git a/packages/adaptive_layout/pubspec.yaml b/packages/adaptive_layout/pubspec.yaml new file mode 100644 index 00000000..8f265ac8 --- /dev/null +++ b/packages/adaptive_layout/pubspec.yaml @@ -0,0 +1,94 @@ +name: adaptive_layout +description: A new Flutter project. +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +# In Windows, build-name is used as the major, minor, and patch parts +# of the product and file versions while build-number is used as the build suffix. +version: 1.0.0+1 + +environment: + sdk: '>=3.0.0 <4.0.0' + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.2 + flutter: + sdk: flutter + flutter_adaptive_scaffold: ^0.1.3 + go_router: ^7.1.1 + intersperse: ^2.0.0 + +dev_dependencies: + build_runner: ^2.4.4 + flutter_test: + sdk: flutter + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + go_router_builder: ^2.0.1 + nit_picking: + git: + url: https://github.com/stack11/dart_nit_picking + ref: 0b2ee0d + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages