diff --git a/packages/flutter/lib/src/widgets/global_key_watcher.dart b/packages/flutter/lib/src/widgets/global_key_watcher.dart new file mode 100644 index 0000000000..b3d06fe57f --- /dev/null +++ b/packages/flutter/lib/src/widgets/global_key_watcher.dart @@ -0,0 +1,78 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:sky/src/widgets/framework.dart'; + +abstract class GlobalKeyWatcher extends StatefulComponent { + GlobalKeyWatcher({ + Key key, + this.watchedKey + }); + + GlobalKey watchedKey; + + void syncConstructorArguments(GlobalKeyWatcher source) { + if (source != source.watchedKey) { + _removeListeners(); + watchedKey = source.watchedKey; + if (mounted) + _setWatchedWidget(GlobalKey.getWidget(watchedKey)); + _addListeners(); + } + } + + Widget get watchedWidget => _watchedWidget; + Widget _watchedWidget; + void _setWatchedWidget(Widget value) { + assert(mounted || value == null); + if (watchedWidget != value) { + if (watchedWidget != null) + stopWatching(); + assert(debugValidateWatchedWidget(value)); + setState(() { + _watchedWidget = value; + }); + if (watchedWidget != null) + startWatching(); + } + } + + bool debugValidateWatchedWidget(Widget candidate) => true; + + void didMount() { + super.didMount(); + _setWatchedWidget(GlobalKey.getWidget(watchedKey)); + _addListeners(); + } + + void didUnmount() { + super.didUnmount(); + _removeListeners(); + _setWatchedWidget(null); + } + + void _addListeners() { + GlobalKey.registerSyncListener(watchedKey, didSyncWatchedKey); + GlobalKey.registerRemoveListener(watchedKey, didRemoveWatchedKey); + } + + void _removeListeners() { + GlobalKey.unregisterSyncListener(watchedKey, didSyncWatchedKey); + GlobalKey.unregisterRemoveListener(watchedKey, didRemoveWatchedKey); + } + + void didSyncWatchedKey(GlobalKey key, Widget widget) { + assert(key == watchedKey); + _setWatchedWidget(widget); + } + + void didRemoveWatchedKey(GlobalKey key) { + assert(key == watchedKey); + _setWatchedWidget(null); + } + + void stopWatching() { } + void startWatching() { } + +} diff --git a/packages/flutter/lib/src/widgets/mimic.dart b/packages/flutter/lib/src/widgets/mimic.dart index 6d5f29a96f..a8ed50d84b 100644 --- a/packages/flutter/lib/src/widgets/mimic.dart +++ b/packages/flutter/lib/src/widgets/mimic.dart @@ -4,51 +4,7 @@ import 'package:sky/src/widgets/basic.dart'; import 'package:sky/src/widgets/framework.dart'; - -abstract class GlobalKeyWatcher extends StatefulComponent { - GlobalKeyWatcher({ - Key key, - this.watchedKey - }); - - GlobalKey watchedKey; - - void syncConstructorArguments(GlobalKeyWatcher source) { - if (source != source.watchedKey) { - _removeListeners(); - watchedKey = source.watchedKey; - _addListeners(); - } - } - - void didMount() { - super.didMount(); - _addListeners(); - } - - void didUnmount() { - super.didUnmount(); - _removeListeners(); - } - - void didSyncWatchedKey(GlobalKey key, Widget widget) { - assert(key == watchedKey); - } - - void didRemoveWatchedKey(GlobalKey key) { - assert(key == watchedKey); - } - - void _addListeners() { - GlobalKey.registerSyncListener(watchedKey, didSyncWatchedKey); - GlobalKey.registerRemoveListener(watchedKey, didRemoveWatchedKey); - } - - void _removeListeners() { - GlobalKey.unregisterSyncListener(watchedKey, didSyncWatchedKey); - GlobalKey.unregisterRemoveListener(watchedKey, didRemoveWatchedKey); - } -} +import 'package:sky/src/widgets/global_key_watcher.dart'; typedef MimicReadyCallback(); @@ -66,50 +22,26 @@ class Mimic extends GlobalKeyWatcher { super.syncConstructorArguments(source); } - Mimicable _mimicable; - - void didMount() { - super.didMount(); - if (_mimicable == null) - _setMimicable(GlobalKey.getWidget(watchedKey)); + bool debugValidateWatchedWidget(Widget candidate) { + return candidate is Mimicable; } - void didUnmount() { - super.didUnmount(); - _stopMimic(); - } + Mimicable get _mimicable => watchedWidget; void didSyncWatchedKey(GlobalKey key, Widget widget) { - super.didSyncWatchedKey(key, widget); - _setMimicable(widget); - } - - void didRemoveWatchedKey(GlobalKey key) { - super.didRemoveWatchedKey(key); - _setMimicable(null); - } - - void _stopMimic() { - if (_mimicable != null) { - _mimicable.stopMimic(); - _mimicable = null; - } - } - - void _setMimicable(widget) { - if (_mimicable != widget) { - _stopMimic(); - if (widget != null) { - widget.startMimic(); - } - } - setState(() { - _mimicable = widget; - }); - if (onMimicReady != null && _mimicable != null && _mimicable._didBuildPlaceholder) + super.didSyncWatchedKey(key, widget); // calls startWatching() + if (onMimicReady != null && _mimicable._didBuildPlaceholder) onMimicReady(); } + void startWatching() { + _mimicable.startMimic(); + } + + void stopWatching() { + _mimicable.stopMimic(); + } + Widget build() { if (_mimicable == null || !_mimicable._didBuildPlaceholder) return new Container(); diff --git a/packages/flutter/lib/widgets.dart b/packages/flutter/lib/widgets.dart index 5b6e898cf7..e36bc975f4 100644 --- a/packages/flutter/lib/widgets.dart +++ b/packages/flutter/lib/widgets.dart @@ -28,6 +28,7 @@ export 'package:sky/src/widgets/floating_action_button.dart'; export 'package:sky/src/widgets/focus.dart'; export 'package:sky/src/widgets/framework.dart'; export 'package:sky/src/widgets/gesture_detector.dart'; +export 'package:sky/src/widgets/global_key_watcher.dart'; export 'package:sky/src/widgets/homogeneous_viewport.dart'; export 'package:sky/src/widgets/icon.dart'; export 'package:sky/src/widgets/icon_button.dart';