Commit 13f9e91f authored by Adam Barth's avatar Adam Barth

Cleanup the global scope a bit:

- Remove unused FocusChanged typedef.
- Remove unused centerOfAttentionHeroTag.
- Modernize static functions for interacting with Scrollable by moving them
  into the Scrollable class.
parent f58c3d2b
......@@ -85,7 +85,7 @@ class EnsureVisibleAppState extends State<EnsureVisibleApp> {
cardModel: cardModels[index],
selected: index == selectedCardIndex,
onTap: (BuildContext context) {
ensureWidgetIsVisible(context, duration: const Duration(milliseconds: 200))
Scrollable.ensureVisible(context, duration: const Duration(milliseconds: 200))
.then((_) {
setState(() { selectedCardIndex = index; });
});
......
......@@ -129,7 +129,7 @@ class OverlayGeometryAppState extends State<OverlayGeometryApp> {
markers[MarkerType.topLeft] = box.localToGlobal(new Point(0.0, 0.0));
final Size size = box.size;
markers[MarkerType.bottomRight] = box.localToGlobal(new Point(size.width, size.height));
final ScrollableState scrollable = findScrollableAncestor(target.currentContext);
final ScrollableState scrollable = Scrollable.of(target.currentContext);
markersScrollOffset = scrollable.scrollOffset;
});
}
......
......@@ -194,10 +194,10 @@ class DragTarget<T> extends StatefulComponent {
final DragTargetWillAccept<T> onWillAccept;
final DragTargetAccept<T> onAccept;
DragTargetState<T> createState() => new DragTargetState<T>();
_DragTargetState<T> createState() => new _DragTargetState<T>();
}
class DragTargetState<T> extends State<DragTarget<T>> {
class _DragTargetState<T> extends State<DragTarget<T>> {
final List<T> _candidateData = new List<T>();
final List<dynamic> _rejectedData = new List<dynamic>();
......@@ -279,7 +279,7 @@ class _DragAvatar<T> {
final Widget feedback;
final Offset feedbackOffset;
DragTargetState _activeTarget;
_DragTargetState _activeTarget;
bool _activeTargetWillAcceptDrop = false;
Offset _lastOffset;
OverlayEntry _entry;
......@@ -299,7 +299,7 @@ class _DragAvatar<T> {
_lastOffset = globalPosition - dragStartPoint;
_entry.markNeedsBuild();
HitTestResult result = WidgetFlutterBinding.instance.hitTest(globalPosition + feedbackOffset);
DragTargetState target = _getDragTarget(result.path);
_DragTargetState target = _getDragTarget(result.path);
if (target == _activeTarget)
return;
if (_activeTarget != null)
......@@ -308,13 +308,13 @@ class _DragAvatar<T> {
_activeTargetWillAcceptDrop = _activeTarget != null && _activeTarget.didEnter(data);
}
DragTargetState _getDragTarget(List<HitTestEntry> path) {
_DragTargetState _getDragTarget(List<HitTestEntry> path) {
// Look for the RenderBox that corresponds to the hit target (the hit target
// widget builds a RenderMetadata box for us for this purpose).
for (HitTestEntry entry in path) {
if (entry.target is RenderMetaData) {
RenderMetaData renderMetaData = entry.target;
if (renderMetaData.metaData is DragTargetState)
if (renderMetaData.metaData is _DragTargetState)
return renderMetaData.metaData;
}
}
......
......@@ -4,8 +4,6 @@
import 'framework.dart';
typedef void FocusChanged(GlobalKey key);
// _noFocusedScope is used by Focus to track the case where none of the Focus
// component's subscopes (e.g. dialogs) are focused. This is distinct from the
// focused scope being null, which means that we haven't yet decided which scope
......
......@@ -335,7 +335,7 @@ enum _StateLifecycle {
/// The signature of setState() methods.
typedef void StateSetter(VoidCallback fn);
/// The logic and internal state for a StatefulComponent.
/// The logic and internal state for a [StatefulComponent].
abstract class State<T extends StatefulComponent> {
/// The current configuration (an instance of the corresponding
/// StatefulComponent class).
......@@ -439,13 +439,13 @@ abstract class State<T extends StatefulComponent> {
}
}
abstract class ProxyComponent extends Widget {
const ProxyComponent({ Key key, this.child }) : super(key: key);
abstract class _ProxyComponent extends Widget {
const _ProxyComponent({ Key key, this.child }) : super(key: key);
final Widget child;
}
abstract class ParentDataWidget extends ProxyComponent {
abstract class ParentDataWidget extends _ProxyComponent {
const ParentDataWidget({ Key key, Widget child })
: super(key: key, child: child);
......@@ -460,7 +460,7 @@ abstract class ParentDataWidget extends ProxyComponent {
void applyParentData(RenderObject renderObject);
}
abstract class InheritedWidget extends ProxyComponent {
abstract class InheritedWidget extends _ProxyComponent {
const InheritedWidget({ Key key, Widget child })
: super(key: key, child: child);
......@@ -1248,8 +1248,8 @@ class StatefulComponentElement<T extends StatefulComponent, U extends State<T>>
}
}
abstract class ProxyElement<T extends ProxyComponent> extends ComponentElement<T> {
ProxyElement(T widget) : super(widget) {
abstract class _ProxyElement<T extends _ProxyComponent> extends ComponentElement<T> {
_ProxyElement(T widget) : super(widget) {
_builder = (BuildContext context) => this.widget.child;
}
......@@ -1267,7 +1267,7 @@ abstract class ProxyElement<T extends ProxyComponent> extends ComponentElement<T
void notifyDescendants(T oldWidget);
}
class ParentDataElement extends ProxyElement<ParentDataWidget> {
class ParentDataElement extends _ProxyElement<ParentDataWidget> {
ParentDataElement(ParentDataWidget widget) : super(widget);
void mount(Element parent, dynamic slot) {
......@@ -1300,7 +1300,7 @@ class ParentDataElement extends ProxyElement<ParentDataWidget> {
class InheritedElement extends ProxyElement<InheritedWidget> {
class InheritedElement extends _ProxyElement<InheritedWidget> {
InheritedElement(InheritedWidget widget) : super(widget);
void notifyDescendants(InheritedWidget oldWidget) {
......
......@@ -56,8 +56,6 @@ import 'transitions.dart';
// should interpolate the inherited properties from their value at the source to
// their value at the target. See: https://github.com/flutter/flutter/issues/213
final Object centerOfAttentionHeroTag = new Object();
class _HeroManifest {
const _HeroManifest({
this.key,
......
......@@ -52,6 +52,55 @@ abstract class Scrollable extends StatefulComponent {
final SnapOffsetCallback snapOffsetCallback;
final double snapAlignmentOffset;
/// Returns the closest enclosing scrollable for the given context.
static ScrollableState of(BuildContext context) {
return context.ancestorStateOfType(ScrollableState);
}
/// Scrolls the closest enclosing scrollable to make the given context visible.
static Future ensureVisible(BuildContext context, { Duration duration, Curve curve }) {
assert(context.findRenderObject() is RenderBox);
// TODO(abarth): This function doesn't handle nested scrollable widgets.
ScrollableState scrollable = Scrollable.of(context);
if (scrollable == null)
return new Future.value();
RenderBox targetBox = context.findRenderObject();
assert(targetBox.attached);
Size targetSize = targetBox.size;
RenderBox scrollableBox = scrollable.context.findRenderObject();
assert(scrollableBox.attached);
Size scrollableSize = scrollableBox.size;
double scrollOffsetDelta;
switch (scrollable.config.scrollDirection) {
case ScrollDirection.vertical:
Point targetCenter = targetBox.localToGlobal(new Point(0.0, targetSize.height / 2.0));
Point scrollableCenter = scrollableBox.localToGlobal(new Point(0.0, scrollableSize.height / 2.0));
scrollOffsetDelta = targetCenter.y - scrollableCenter.y;
break;
case ScrollDirection.horizontal:
Point targetCenter = targetBox.localToGlobal(new Point(targetSize.width / 2.0, 0.0));
Point scrollableCenter = scrollableBox.localToGlobal(new Point(scrollableSize.width / 2.0, 0.0));
scrollOffsetDelta = targetCenter.x - scrollableCenter.x;
break;
case ScrollDirection.both:
assert(false); // See https://github.com/flutter/engine/issues/888
break;
}
ExtentScrollBehavior scrollBehavior = scrollable.scrollBehavior;
double scrollOffset = (scrollable.scrollOffset + scrollOffsetDelta)
.clamp(scrollBehavior.minScrollOffset, scrollBehavior.maxScrollOffset);
if (scrollOffset != scrollable.scrollOffset)
return scrollable.scrollTo(scrollOffset, duration: duration, curve: curve);
return new Future.value();
}
ScrollableState createState();
}
......@@ -261,69 +310,12 @@ abstract class ScrollableState<T extends Scrollable> extends State<T> {
}
}
ScrollableState findScrollableAncestor(BuildContext context) {
ScrollableState result;
context.visitAncestorElements((Element element) {
if (element is StatefulComponentElement) {
if (element.state is ScrollableState) {
result = element.state;
return false;
}
}
return true;
});
return result;
}
class ScrollNotification extends Notification {
ScrollNotification(this.scrollable, this.position);
final ScrollableState scrollable;
final double position;
}
Future ensureWidgetIsVisible(BuildContext context, { Duration duration, Curve curve }) {
assert(context.findRenderObject() is RenderBox);
// TODO(abarth): This function doesn't handle nested scrollable widgets.
ScrollableState scrollable = findScrollableAncestor(context);
if (scrollable == null)
return new Future.value();
RenderBox targetBox = context.findRenderObject();
assert(targetBox.attached);
Size targetSize = targetBox.size;
RenderBox scrollableBox = scrollable.context.findRenderObject();
assert(scrollableBox.attached);
Size scrollableSize = scrollableBox.size;
double scrollOffsetDelta;
switch (scrollable.config.scrollDirection) {
case ScrollDirection.vertical:
Point targetCenter = targetBox.localToGlobal(new Point(0.0, targetSize.height / 2.0));
Point scrollableCenter = scrollableBox.localToGlobal(new Point(0.0, scrollableSize.height / 2.0));
scrollOffsetDelta = targetCenter.y - scrollableCenter.y;
break;
case ScrollDirection.horizontal:
Point targetCenter = targetBox.localToGlobal(new Point(targetSize.width / 2.0, 0.0));
Point scrollableCenter = scrollableBox.localToGlobal(new Point(scrollableSize.width / 2.0, 0.0));
scrollOffsetDelta = targetCenter.x - scrollableCenter.x;
break;
case ScrollDirection.both:
assert(false); // See https://github.com/flutter/engine/issues/888
break;
}
ExtentScrollBehavior scrollBehavior = scrollable.scrollBehavior;
double scrollOffset = (scrollable.scrollOffset + scrollOffsetDelta)
.clamp(scrollBehavior.minScrollOffset, scrollBehavior.maxScrollOffset);
if (scrollOffset != scrollable.scrollOffset)
return scrollable.scrollTo(scrollOffset, duration: duration, curve: curve);
return new Future.value();
}
/// A simple scrollable widget that has a single child. Use this component if
/// you are not worried about offscreen widgets consuming resources.
class ScrollableViewport extends Scrollable {
......
......@@ -18,10 +18,10 @@ abstract class StatusTransitionComponent extends StatefulComponent {
Widget build(BuildContext context);
StatusTransitionState createState() => new StatusTransitionState();
_StatusTransitionState createState() => new _StatusTransitionState();
}
class StatusTransitionState extends State<StatusTransitionComponent> {
class _StatusTransitionState extends State<StatusTransitionComponent> {
void initState() {
super.initState();
config.performance.addStatusListener(_performanceStatusChanged);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment