using System; using System.Collections.Generic; using System.Linq; using System.Text; using Unity.UIWidgets.async2; using Unity.UIWidgets.foundation; using Unity.UIWidgets.gestures; using Unity.UIWidgets.painting; using Unity.UIWidgets.services; using Unity.UIWidgets.ui; using UnityEngine; using Color = Unity.UIWidgets.ui.Color; using TextStyle = Unity.UIWidgets.painting.TextStyle; namespace Unity.UIWidgets.widgets { public delegate Locale LocaleListResolutionCallback(List locales, List supportedLocales); public delegate Locale LocaleResolutionCallback(Locale locale, List supportedLocales); public delegate string GenerateAppTitle(BuildContext context); public delegate PageRoute PageRouteFactory(RouteSettings settings, WidgetBuilder builder); public delegate List InitialRouteListFactory(string initialRoute); public class WidgetsApp : StatefulWidget { public static bool showPerformanceOverlayOverride = false; public static bool debugShowWidgetInspectorOverride = false; public static bool debugAllowBannerOverride = true; public static readonly Dictionary _defaultShortcuts = new Dictionary { // Activation {new LogicalKeySet(key1: LogicalKeyboardKey.enter), new Intent(key: ActivateAction.key)}, {new LogicalKeySet(key1: LogicalKeyboardKey.space), new Intent(key: ActivateAction.key)}, {new LogicalKeySet(key1: LogicalKeyboardKey.gameButtonA), new Intent(key: ActivateAction.key)}, // Keyboard traversal. {new LogicalKeySet(key1: LogicalKeyboardKey.tab), new Intent(key: NextFocusAction.key)}, { new LogicalKeySet(key1: LogicalKeyboardKey.shift, key2: LogicalKeyboardKey.tab), new Intent(key: PreviousFocusAction.key) }, { new LogicalKeySet(key1: LogicalKeyboardKey.arrowLeft), new DirectionalFocusIntent(direction: TraversalDirection.left) }, { new LogicalKeySet(key1: LogicalKeyboardKey.arrowRight), new DirectionalFocusIntent(direction: TraversalDirection.right) }, { new LogicalKeySet(key1: LogicalKeyboardKey.arrowDown), new DirectionalFocusIntent(direction: TraversalDirection.down) }, {new LogicalKeySet(key1: LogicalKeyboardKey.arrowUp), new DirectionalFocusIntent()}, // Scrolling { new LogicalKeySet(key1: LogicalKeyboardKey.control, key2: LogicalKeyboardKey.arrowUp), new ScrollIntent(direction: AxisDirection.up) }, { new LogicalKeySet(key1: LogicalKeyboardKey.control, key2: LogicalKeyboardKey.arrowDown), new ScrollIntent(direction: AxisDirection.down) }, { new LogicalKeySet(key1: LogicalKeyboardKey.control, key2: LogicalKeyboardKey.arrowLeft), new ScrollIntent(direction: AxisDirection.left) }, { new LogicalKeySet(key1: LogicalKeyboardKey.control, key2: LogicalKeyboardKey.arrowRight), new ScrollIntent(direction: AxisDirection.right) }, { new LogicalKeySet(key1: LogicalKeyboardKey.pageUp), new ScrollIntent(direction: AxisDirection.up, type: ScrollIncrementType.page) }, { new LogicalKeySet(key1: LogicalKeyboardKey.pageDown), new ScrollIntent(direction: AxisDirection.down, type: ScrollIncrementType.page) } }; // Default shortcuts for the web platform. public static readonly Dictionary _defaultWebShortcuts = new Dictionary { // Activation {new LogicalKeySet(key1: LogicalKeyboardKey.space), new Intent(key: ActivateAction.key)}, // Keyboard traversal. {new LogicalKeySet(key1: LogicalKeyboardKey.tab), new Intent(key: NextFocusAction.key)}, { new LogicalKeySet(key1: LogicalKeyboardKey.shift, key2: LogicalKeyboardKey.tab), new Intent(key: PreviousFocusAction.key) }, // Scrolling {new LogicalKeySet(key1: LogicalKeyboardKey.arrowUp), new ScrollIntent(direction: AxisDirection.up)}, { new LogicalKeySet(key1: LogicalKeyboardKey.arrowDown), new ScrollIntent(direction: AxisDirection.down) }, { new LogicalKeySet(key1: LogicalKeyboardKey.arrowLeft), new ScrollIntent(direction: AxisDirection.left) }, { new LogicalKeySet(key1: LogicalKeyboardKey.arrowRight), new ScrollIntent(direction: AxisDirection.right) }, { new LogicalKeySet(key1: LogicalKeyboardKey.pageUp), new ScrollIntent(direction: AxisDirection.up, type: ScrollIncrementType.page) }, { new LogicalKeySet(key1: LogicalKeyboardKey.pageDown), new ScrollIntent(direction: AxisDirection.down, type: ScrollIncrementType.page) } }; // Default shortcuts for the macOS platform. public static readonly Dictionary _defaultMacOsShortcuts = new Dictionary { // Activation {new LogicalKeySet(key1: LogicalKeyboardKey.enter), new Intent(key: ActivateAction.key)}, {new LogicalKeySet(key1: LogicalKeyboardKey.space), new Intent(key: ActivateAction.key)}, // Keyboard traversal {new LogicalKeySet(key1: LogicalKeyboardKey.tab), new Intent(key: NextFocusAction.key)}, { new LogicalKeySet(key1: LogicalKeyboardKey.shift, key2: LogicalKeyboardKey.tab), new Intent(key: PreviousFocusAction.key) }, { new LogicalKeySet(key1: LogicalKeyboardKey.arrowLeft), new DirectionalFocusIntent(direction: TraversalDirection.left) }, { new LogicalKeySet(key1: LogicalKeyboardKey.arrowRight), new DirectionalFocusIntent(direction: TraversalDirection.right) }, { new LogicalKeySet(key1: LogicalKeyboardKey.arrowDown), new DirectionalFocusIntent(direction: TraversalDirection.down) }, {new LogicalKeySet(key1: LogicalKeyboardKey.arrowUp), new DirectionalFocusIntent()}, // Scrolling { new LogicalKeySet(key1: LogicalKeyboardKey.meta, key2: LogicalKeyboardKey.arrowUp), new ScrollIntent(direction: AxisDirection.up) }, { new LogicalKeySet(key1: LogicalKeyboardKey.meta, key2: LogicalKeyboardKey.arrowDown), new ScrollIntent(direction: AxisDirection.down) }, { new LogicalKeySet(key1: LogicalKeyboardKey.meta, key2: LogicalKeyboardKey.arrowLeft), new ScrollIntent(direction: AxisDirection.left) }, { new LogicalKeySet(key1: LogicalKeyboardKey.meta, key2: LogicalKeyboardKey.arrowRight), new ScrollIntent(direction: AxisDirection.right) }, { new LogicalKeySet(key1: LogicalKeyboardKey.pageUp), new ScrollIntent(direction: AxisDirection.up, type: ScrollIncrementType.page) }, { new LogicalKeySet(key1: LogicalKeyboardKey.pageDown), new ScrollIntent(direction: AxisDirection.down, type: ScrollIncrementType.page) } }; /// The default value of [WidgetsApp.actions]. public static readonly Dictionary defaultActions = new Dictionary { {DoNothingAction.key, () => new DoNothingAction()}, {RequestFocusAction.key, () => new RequestFocusAction()}, {NextFocusAction.key, () => new NextFocusAction()}, {PreviousFocusAction.key, () => new PreviousFocusAction()}, {DirectionalFocusAction.key, () => new DirectionalFocusAction()}, {ScrollAction.key, () => new ScrollAction()} }; public readonly Dictionary actions; public readonly TransitionBuilder builder; public readonly bool checkerboardOffscreenLayers; public readonly bool checkerboardRasterCacheImages; public readonly Color color; public readonly bool debugShowCheckedModeBanner; public readonly bool debugShowWidgetInspector; public readonly Widget home; public readonly string initialRoute; public readonly InspectorSelectButtonBuilder inspectorSelectButtonBuilder; public readonly Locale locale; public readonly LocaleListResolutionCallback localeListResolutionCallback; public readonly LocaleResolutionCallback localeResolutionCallback; public readonly List localizationsDelegates; public readonly GlobalKey navigatorKey; public readonly List navigatorObservers; public readonly InitialRouteListFactory onGenerateInitialRoutes; public readonly RouteFactory onGenerateRoute; public readonly GenerateAppTitle onGenerateTitle; public readonly RouteFactory onUnknownRoute; public readonly PageRouteFactory pageRouteBuilder; public readonly Dictionary routes; public readonly Dictionary shortcuts; public readonly bool showPerformanceOverlay; public readonly bool showSemanticsDebugger; public readonly List supportedLocales; public readonly TextStyle textStyle; public readonly string title; public readonly Window window; public WidgetsApp( Key key = null, GlobalKey navigatorKey = null, RouteFactory onGenerateRoute = null, InitialRouteListFactory onGenerateInitialRoutes = null, RouteFactory onUnknownRoute = null, List navigatorObservers = null, string initialRoute = null, PageRouteFactory pageRouteBuilder = null, Widget home = null, Dictionary routes = null, TransitionBuilder builder = null, string title = "", GenerateAppTitle onGenerateTitle = null, TextStyle textStyle = null, Color color = null, Locale locale = null, List localizationsDelegates = null, LocaleListResolutionCallback localeListResolutionCallback = null, LocaleResolutionCallback localeResolutionCallback = null, List supportedLocales = null, bool showPerformanceOverlay = false, bool checkerboardRasterCacheImages = false, bool checkerboardOffscreenLayers = false, bool showSemanticsDebugger = false, bool debugShowWidgetInspector = false, bool debugShowCheckedModeBanner = true, InspectorSelectButtonBuilder inspectorSelectButtonBuilder = null, Dictionary shortcuts = null, Dictionary actions = null ) : base(key: key) { routes = routes ?? new Dictionary(); supportedLocales = supportedLocales ?? new List {new Locale("en", "US")}; window = Window.instance; D.assert(routes != null); D.assert(color != null); D.assert(supportedLocales != null && supportedLocales.isNotEmpty()); this.home = home; this.navigatorKey = navigatorKey; this.onGenerateRoute = onGenerateRoute; this.onGenerateInitialRoutes = onGenerateInitialRoutes; this.onUnknownRoute = onUnknownRoute; this.pageRouteBuilder = pageRouteBuilder; this.routes = routes; this.navigatorObservers = navigatorObservers ?? new List(); this.initialRoute = initialRoute; this.builder = builder; this.textStyle = textStyle; this.locale = locale; this.localizationsDelegates = localizationsDelegates; this.localeListResolutionCallback = localeListResolutionCallback; this.localeResolutionCallback = localeResolutionCallback; this.supportedLocales = supportedLocales; this.showPerformanceOverlay = showPerformanceOverlay; this.checkerboardOffscreenLayers = checkerboardOffscreenLayers; this.checkerboardRasterCacheImages = checkerboardRasterCacheImages; this.showSemanticsDebugger = showSemanticsDebugger; this.debugShowWidgetInspector = debugShowWidgetInspector; this.debugShowCheckedModeBanner = debugShowCheckedModeBanner; this.onGenerateTitle = onGenerateTitle; this.title = title; this.color = color; this.inspectorSelectButtonBuilder = inspectorSelectButtonBuilder; this.shortcuts = shortcuts; this.actions = actions; D.assert( home == null || onGenerateInitialRoutes == null, () => "If onGenerateInitialRoutes is specifiied, the home argument will be redundant." ); D.assert( home == null || !this.routes.ContainsKey(key: Navigator.defaultRouteName), () => "If the home property is specified, the routes table " + "cannot include an entry for \" / \", since it would be redundant." ); D.assert( builder != null || home != null || this.routes.ContainsKey(key: Navigator.defaultRouteName) || onGenerateRoute != null || onUnknownRoute != null, () => "Either the home property must be specified, " + "or the routes table must include an entry for \"/\", " + "or there must be on onGenerateRoute callback specified, " + "or there must be an onUnknownRoute callback specified, " + "or the builder property must be specified, " + "because otherwise there is nothing to fall back on if the " + "app is started with an intent that specifies an unknown route." ); D.assert( home != null || routes.isNotEmpty() || onGenerateRoute != null || onUnknownRoute != null || builder != null && navigatorKey == null && initialRoute == null && navigatorObservers.isEmpty(), () => "If no route is provided using " + "home, routes, onGenerateRoute, or onUnknownRoute, " + "a non-null callback for the builder property must be provided, " + "and the other navigator-related properties, " + "navigatorKey, initialRoute, and navigatorObservers, " + "must have their initial values " + "(null, null, and the empty list, respectively)."); D.assert( builder != null || onGenerateRoute != null || pageRouteBuilder != null, () => "If neither builder nor onGenerateRoute are provided, the " + "pageRouteBuilder must be specified so that the default handler " + "will know what kind of PageRoute transition to build." ); } public static Dictionary defaultShortcuts { get { if (foundation_.kIsWeb) { return _defaultWebShortcuts; } switch (Application.platform) { case RuntimePlatform.Android: //case TargetPlatform.fuchsia: case RuntimePlatform.LinuxPlayer: case RuntimePlatform.WindowsPlayer: return _defaultShortcuts; case RuntimePlatform.OSXPlayer: return _defaultMacOsShortcuts; case RuntimePlatform.IPhonePlayer: // No keyboard support on iOS yet. break; } return new Dictionary(); } } public override State createState() { return new _WidgetsAppState(); } } class _WidgetsAppState : State, WidgetsBindingObserver { Locale _locale; GlobalKey _navigator; List _localizationsDelegates { get { var _delegates = new List(); if (widget.localizationsDelegates != null) { _delegates.AddRange(collection: widget.localizationsDelegates); } _delegates.Add(item: DefaultWidgetsLocalizations.del); return _delegates; } } public void didChangeMetrics() { setState(); } public void didChangeTextScaleFactor() { setState(); } public void didChangePlatformBrightness() { setState(() => { }); } public void didChangeLocales(List locale) { var newLocale = _resolveLocales(preferredLocales: locale, supportedLocales: widget.supportedLocales); if (newLocale != _locale) { setState(() => { _locale = newLocale; }); } } public Future didPopRoute() { ///async D.assert(result: mounted); var navigator = _navigator?.currentState; if (navigator == null) { return Future.value(false).to(); } return navigator.maybePop(); } public Future didPushRoute(string route) { D.assert(result: mounted); var navigator = _navigator?.currentState; if (navigator == null) { return Future.value(false).to(); } navigator.pushNamed(routeName: route); return Future.value(true).to(); } public void didChangeAccessibilityFeatures() { } public override void initState() { base.initState(); _updateNavigator(); _locale = _resolveLocales(new List {new Locale("en", "US")}, supportedLocales: widget.supportedLocales); WidgetsBinding.instance.addObserver(this); } public override void didUpdateWidget(StatefulWidget oldWidget) { base.didUpdateWidget(oldWidget: oldWidget); if (widget.navigatorKey != ((WidgetsApp) oldWidget).navigatorKey) { _updateNavigator(); } } public override void dispose() { WidgetsBinding.instance.removeObserver(this); base.dispose(); } void _updateNavigator() { _navigator = widget.navigatorKey ?? new GlobalObjectKey(this); } Route _onGenerateRoute(RouteSettings settings) { var name = settings.name; var pageContentBuilder = name == Navigator.defaultRouteName && widget.home != null ? context => widget.home : widget.routes.getOrDefault(key: name); if (pageContentBuilder != null) { D.assert(widget.pageRouteBuilder != null, () => "The default onGenerateRoute handler for WidgetsApp must have a " + "pageRouteBuilder set if the home or routes properties are set."); var route = widget.pageRouteBuilder( settings: settings, builder: pageContentBuilder ); D.assert(route != null, () => "The pageRouteBuilder for WidgetsApp must return a valid non-null Route."); return route; } if (widget.onGenerateRoute != null) { return widget.onGenerateRoute(settings: settings); } return null; } Route _onUnknownRoute(RouteSettings settings) { D.assert(() => { if (widget.onUnknownRoute == null) { throw new UIWidgetsError( $"Could not find a generator for route {settings} in the {GetType()}.\n" + "Generators for routes are searched for in the following order:\n" + " 1. For the \"/\" route, the \"home\" property, if non-null, is used.\n" + " 2. Otherwise, the \"routes\" table is used, if it has an entry for " + "the route.\n" + " 3. Otherwise, onGenerateRoute is called. It should return a " + "non-null value for any valid route not handled by \"home\" and \"routes\".\n" + " 4. Finally if all else fails onUnknownRoute is called.\n" + "Unfortunately, onUnknownRoute was not set." ); } return true; }); var result = widget.onUnknownRoute(settings: settings) as Route; D.assert(() => { if (result == null) { throw new UIWidgetsError( "The onUnknownRoute callback returned null.\n" + "When the $runtimeType requested the route $settings from its " + "onUnknownRoute callback, the callback returned null. Such callbacks " + "must never return null." ); } return true; }); return result; } Locale _resolveLocales(List preferredLocales, List supportedLocales) { if (widget.localeListResolutionCallback != null) { var locale = widget.localeListResolutionCallback(locales: preferredLocales, supportedLocales: widget.supportedLocales); if (locale != null) { return locale; } } if (widget.localeResolutionCallback != null) { var locale = widget.localeResolutionCallback( preferredLocales != null && preferredLocales.isNotEmpty() ? preferredLocales.first() : null, supportedLocales: widget.supportedLocales ); if (locale != null) { return locale; } } return basicLocaleListResolution(preferredLocales: preferredLocales, supportedLocales: supportedLocales); } static Locale basicLocaleListResolution(List preferredLocales, List supportedLocales) { if (preferredLocales == null || preferredLocales.isEmpty()) { return supportedLocales.first(); } var allSupportedLocales = new Dictionary(); var languageAndCountryLocales = new Dictionary(); var languageAndScriptLocales = new Dictionary(); var languageLocales = new Dictionary(); var countryLocales = new Dictionary(); foreach (var locale in supportedLocales) { allSupportedLocales.putIfAbsent( locale.languageCode + "_" + locale.scriptCode + "_" + locale.countryCode, () => locale); languageLocales.putIfAbsent(key: locale.languageCode, () => locale); countryLocales.putIfAbsent(key: locale.countryCode, () => locale); languageAndScriptLocales.putIfAbsent(locale.languageCode + "_" + locale.scriptCode, () => locale); languageAndCountryLocales.putIfAbsent(locale.languageCode + "_" + locale.countryCode, () => locale); } Locale matchesLanguageCode = null; Locale matchesCountryCode = null; for (var localeIndex = 0; localeIndex < preferredLocales.Count; localeIndex++) { var userLocale = preferredLocales[index: localeIndex]; if (allSupportedLocales.ContainsKey(userLocale.languageCode + "_" + userLocale.scriptCode + "_" + userLocale.countryCode)) { return userLocale; } if (userLocale.scriptCode != null) { Locale match = null; if (languageAndScriptLocales.TryGetValue(userLocale.languageCode + "_" + userLocale.scriptCode, value: out match)) { if (match != null) { return match; } } } if (userLocale.countryCode != null) { //Locale match = languageAndCountryLocales['${userLocale.languageCode}_${userLocale.countryCode}']; Locale match = null; if (languageAndCountryLocales.TryGetValue(userLocale.languageCode + "_" + userLocale.countryCode, value: out match)) { if (match != null) { return match; } } } if (matchesLanguageCode != null) { return matchesLanguageCode; } if (languageLocales.ContainsKey(key: userLocale.languageCode)) { matchesLanguageCode = languageLocales[key: userLocale.languageCode]; if (localeIndex == 0 && !(localeIndex + 1 < preferredLocales.Count && preferredLocales[localeIndex + 1].languageCode == userLocale.languageCode)) { return matchesLanguageCode; } } if (matchesCountryCode == null && userLocale.countryCode != null) { if (countryLocales.ContainsKey(key: userLocale.countryCode)) { matchesCountryCode = countryLocales[key: userLocale.countryCode]; } } } var resolvedLocale = matchesLanguageCode ?? matchesCountryCode ?? supportedLocales.first(); return resolvedLocale; } void inspectorShowChanged() { setState(); } bool _debugCheckLocalizations(Locale appLocale) { D.assert(() => { var unsupportedTypes = new HashSet(); foreach (var _delegate in _localizationsDelegates) { unsupportedTypes.Add(item: _delegate.type); } foreach (var _delegate in _localizationsDelegates) { if (!unsupportedTypes.Contains(item: _delegate.type)) { continue; } if (_delegate.isSupported(locale: appLocale)) { unsupportedTypes.Remove(item: _delegate.type); } } if (unsupportedTypes.isEmpty()) { return true; } var list = new List {"CupertinoLocalizations"}; var unsupportedTypesList = new List(); foreach (var type in unsupportedTypes) { unsupportedTypesList.Add(type.ToString()); } if (unsupportedTypesList.SequenceEqual(second: list)) { return true; } var message = new StringBuilder(); message.Append('\u2550' * 8); message.Append( "Warning: This application's locale, $appLocale, is not supported by all of its\n" + "localization delegates." ); foreach (var unsupportedType in unsupportedTypes) { if (unsupportedType.ToString() == "CupertinoLocalizations") { continue; } message.Append( "> A " + unsupportedType + " delegate that supports the " + appLocale + "locale was not found." ); } message.Append( "See https://flutter.dev/tutorials/internationalization/ for more\n" + "information about configuring an app's locale, supportedLocales,\n" + "and localizationsDelegates parameters." ); message.Append('\u2550' * 8); return true; }); return true; } public override Widget build(BuildContext context) { Widget navigator = null; if (_navigator != null) { RouteListFactory routeListFactory = (state, route) => { return widget.onGenerateInitialRoutes(initialRoute: route); }; navigator = new Navigator( key: _navigator, initialRoute: WidgetsBinding.instance.window.defaultRouteName != Navigator.defaultRouteName ? WidgetsBinding.instance.window.defaultRouteName : widget.initialRoute ?? WidgetsBinding.instance.window.defaultRouteName, onGenerateRoute: _onGenerateRoute, onGenerateInitialRoutes: widget.onGenerateInitialRoutes == null ? Navigator.defaultGenerateInitialRoutes : routeListFactory, onUnknownRoute: _onUnknownRoute, observers: widget.navigatorObservers ); } Widget result; if (widget.builder != null) { result = new Builder( builder: context1 => { return widget.builder(context: context1, child: navigator); }); } else { D.assert(navigator != null); result = navigator; } if (widget.textStyle != null) { result = new DefaultTextStyle( style: widget.textStyle, child: result ); } PerformanceOverlay performanceOverlay = null; if (widget.showPerformanceOverlay || WidgetsApp.showPerformanceOverlayOverride) { performanceOverlay = PerformanceOverlay.allEnabled( checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages, checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers ); } else if (widget.checkerboardRasterCacheImages || widget.checkerboardOffscreenLayers) { performanceOverlay = new PerformanceOverlay( checkerboardRasterCacheImages: widget.checkerboardRasterCacheImages, checkerboardOffscreenLayers: widget.checkerboardOffscreenLayers ); } if (performanceOverlay != null) { result = new Stack( children: new List { result, new Positioned(top: 0.0f, left: 0.0f, right: 0.0f, child: performanceOverlay) } ); } D.assert(() => { if (widget.debugShowWidgetInspector || WidgetsApp.debugShowWidgetInspectorOverride) { result = new WidgetInspector( child: result, selectButtonBuilder: widget.inspectorSelectButtonBuilder ); } if (widget.debugShowCheckedModeBanner && WidgetsApp.debugAllowBannerOverride) { result = new CheckedModeBanner( child: result ); } return true; }); //Fix Me !! //TODO: the following line is a work-around for some potential TextDirection bug //In the home page of the Shrine sample, the positions of the buttons are not correct, which is //determined by the TextDirection of some widget. we should fix it! result = new Directionality(child: result, TextDirection.ltr); Widget title = null; if (widget.onGenerateTitle != null) { title = new Builder( builder: context2 => { var _title = widget.onGenerateTitle(context: context2); D.assert(_title != null, () => "onGenerateTitle must return a non-null String"); return new Title( title: _title, color: widget.color, child: result ); } ); } else { title = new Title( title: widget.title, color: widget.color, child: result ); } var appLocale = widget.locale != null ? _resolveLocales(new List {widget.locale}, supportedLocales: widget.supportedLocales) : _locale; D.assert(_debugCheckLocalizations(appLocale: appLocale)); return new Shortcuts( shortcuts: widget.shortcuts ?? WidgetsApp.defaultShortcuts, debugLabel: "", child: new Actions( actions: widget.actions ?? WidgetsApp.defaultActions, child: new FocusTraversalGroup( policy: new ReadingOrderTraversalPolicy(), child: new _MediaQueryFromWindow( child: new Localizations( locale: appLocale, delegates: _localizationsDelegates.ToList(), child: title ) ) ) ) ); } Widget _InspectorSelectButtonBuilder(BuildContext context, VoidCallback onPressed) { return new _InspectorSelectButton(onPressed: onPressed); } } public class _MediaQueryFromWindow : StatefulWidget { public readonly Widget child; public _MediaQueryFromWindow(Key key = null, Widget child = null) : base(key: key) { this.child = child; } public override State createState() { return new _MediaQueryFromWindowsState(); } } class _MediaQueryFromWindowsState : State<_MediaQueryFromWindow>, WidgetsBindingObserver { public void didChangeAccessibilityFeatures() { setState(() => { }); } public void didChangeMetrics() { setState(() => { }); } public void didChangeTextScaleFactor() { setState(() => { }); } public void didChangePlatformBrightness() { setState(() => { }); } public void didChangeLocales(List locale) { throw new NotImplementedException(); } public Future didPopRoute() { throw new NotImplementedException(); } public Future didPushRoute(string route) { throw new NotImplementedException(); } public override void initState() { base.initState(); WidgetsBinding.instance.addObserver(this); } public override Widget build(BuildContext context) { return new MediaQuery( data: MediaQueryData.fromWindow(window: WidgetsBinding.instance.window), child: widget.child ); } public override void dispose() { WidgetsBinding.instance.removeObserver(this); base.dispose(); } } class _InspectorSelectButton : StatelessWidget { public readonly GestureTapCallback onPressed; public _InspectorSelectButton( VoidCallback onPressed, Key key = null ) : base(key: key) { this.onPressed = () => onPressed(); } public override Widget build(BuildContext context) { return new GestureDetector( onTap: onPressed, child: new Container( color: Color.fromARGB(255, 0, 0, 255), padding: EdgeInsets.all(10), child: new Text("Select", style: new TextStyle(color: Color.fromARGB(255, 255, 255, 255))) ) ); } } }