[cleanup] remove unused story shells from experiences
- //src/experiences/story_shells/mondiran
This CL removes unused story shell code and is part of a multi-repo change.
This CL needs to land before the corresponding change in topaz that removes
`//topaz/lib/story_shell` (fxr/377833)
Integration verified with:
fx make-integration-patch
Change-Id: Id130fce7676490b5b10abf146e4c1db45938eeea
Reviewed-on: https://fuchsia-review.googlesource.com/c/experiences/+/377730
Reviewed-by: Chase Latta <chaselatta@google.com>
Commit-Queue: Jason Campbell <jasoncampbell@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 84f80a8..d9f34ef 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -9,7 +9,6 @@
"examples",
"session_shells",
"settings",
- "story_shells",
]
}
@@ -39,6 +38,5 @@
"examples:dart_unittests",
"session_shells:dart_unittests",
"settings:dart_unittests",
- "story_shells:dart_unittests",
]
}
diff --git a/story_shells/BUILD.gn b/story_shells/BUILD.gn
deleted file mode 100644
index ea88c2e..0000000
--- a/story_shells/BUILD.gn
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2019 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-group("story_shells") {
- testonly = true
- public_deps = [
- "mondrian",
- ]
-}
-
-group("dart_unittests") {
- testonly = true
-
- # TODO(fxb/41505): Temporarily disable flutter_tester tests on mac hosts.
- _flutter_tester_tests = []
- if (host_os != "mac") {
- _flutter_tester_tests +=
- [ "mondrian:mondrian_story_shell_tests($host_toolchain)" ]
- }
-
- deps = _flutter_tester_tests
-}
diff --git a/story_shells/OWNERS b/story_shells/OWNERS
deleted file mode 100644
index a8641b2..0000000
--- a/story_shells/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-cligh@google.com
-djmurphy@google.com
diff --git a/story_shells/mondrian/.gitignore b/story_shells/mondrian/.gitignore
deleted file mode 100644
index 09ea26a..0000000
--- a/story_shells/mondrian/.gitignore
+++ /dev/null
@@ -1,22 +0,0 @@
-*.iml
-*.pyc
-*~
-.*.sw?
-.DS_Store
-.checkstyle
-.clang_complete
-.classpath
-.cproject
-.gdb_history
-.gdbinit
-.landmines
-.packages
-.project
-.pub
-.pubspec.lock
-pubspec.lock
-.pydevproject
-packages
-**/.atom/
-**/.idea/
-settings.json
diff --git a/story_shells/mondrian/BUILD.gn b/story_shells/mondrian/BUILD.gn
deleted file mode 100644
index 0f3d4d6..0000000
--- a/story_shells/mondrian/BUILD.gn
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright 2018 The Fuchsia 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("//topaz/runtime/dart/flutter_test.gni")
-import("//topaz/runtime/flutter_runner/flutter_app.gni")
-
-flutter_app("mondrian") {
- package_name = "mondrian"
- main_dart = "lib/main.dart"
-
- meta = [
- {
- path = rebase_path("meta/mondrian.cmx")
- dest = "mondrian.cmx"
- },
- ]
-
- sources = [
- "anim/flux.dart",
- "anim/sim.dart",
- "layout/copresent_layout.dart",
- "layout/pattern_layout.dart",
- "models/depth_model.dart",
- "models/inset_manager.dart",
- "models/layout_model.dart",
- "models/surface/positioned_surface.dart",
- "models/surface/surface.dart",
- "models/surface/surface_form.dart",
- "models/surface/surface_graph.dart",
- "models/surface/surface_properties.dart",
- "models/surface/surface_relation_util.dart",
- "models/surface/surface_transition.dart",
- "models/tree/spanning_tree.dart",
- "models/tree/tree.dart",
- "story_shell_impl.dart",
- "widgets/breathing_placeholder.dart",
- "widgets/gestures.dart",
- "widgets/isometric_widget.dart",
- "widgets/mondrian.dart",
- "widgets/mondrian_child_view.dart",
- "widgets/mondrian_logo.dart",
- "widgets/overview.dart",
- "widgets/surface_director.dart",
- "widgets/surface_frame.dart",
- "widgets/surface_relationships.dart",
- "widgets/surface_resize.dart",
- "widgets/surface_stage.dart",
- ]
-
- deps = [
- "//sdk/fidl/fuchsia.modular",
- "//sdk/fidl/fuchsia.ui.gfx",
- "//sdk/fidl/fuchsia.ui.input",
- "//sdk/fidl/fuchsia.ui.policy",
- "//sdk/fidl/fuchsia.ui.views",
- "//third_party/dart-pkg/git/flutter/packages/flutter",
- "//third_party/dart-pkg/pub/meta",
- "//third_party/dart-pkg/pub/quiver",
- "//topaz/lib/story_shell:lib.story_shell",
- "//topaz/public/dart/fidl",
- "//topaz/public/dart/fuchsia",
- "//topaz/public/dart/fuchsia_modular",
- "//topaz/public/dart/fuchsia_scenic_flutter",
- "//topaz/public/dart/widgets:lib.widgets",
- ]
-}
-
-flutter_test("mondrian_story_shell_tests") {
- sources = [
- "layout/pattern_layout_test.dart",
- "layout/surface_relationship_test.dart",
- "layout_test_utils.dart",
- "model/surface/surface_graph_test.dart",
- "model/surface/surface_test.dart",
- "model/tree/spanning_tree_test.dart",
- "model/tree/tree_test.dart",
- ]
-
- deps = [
- ":mondrian_dart_library",
- "//sdk/fidl/fuchsia.modular",
- "//third_party/dart-pkg/git/flutter/packages/flutter_test",
- "//third_party/dart-pkg/pub/mockito",
- "//third_party/dart-pkg/pub/test",
- ]
-}
diff --git a/story_shells/mondrian/OWNERS b/story_shells/mondrian/OWNERS
deleted file mode 100644
index 21fc800..0000000
--- a/story_shells/mondrian/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-djmurphy@google.com
-jphsiao@google.com
-*
diff --git a/story_shells/mondrian/README.md b/story_shells/mondrian/README.md
deleted file mode 100644
index 066e53e..0000000
--- a/story_shells/mondrian/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-Mondrian
-=======================================
-A story shell that pleasantly arranges rectangular views.
diff --git a/story_shells/mondrian/analysis_options.yaml b/story_shells/mondrian/analysis_options.yaml
deleted file mode 100644
index 97cdb2a..0000000
--- a/story_shells/mondrian/analysis_options.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-include: ../../analysis_options.yaml
diff --git a/story_shells/mondrian/lib/anim/flux.dart b/story_shells/mondrian/lib/anim/flux.dart
deleted file mode 100644
index 98ee46c..0000000
--- a/story_shells/mondrian/lib/anim/flux.dart
+++ /dev/null
@@ -1,498 +0,0 @@
-// Copyright 2017 The Fuchsia 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:flutter/scheduler.dart';
-import 'package:flutter/widgets.dart';
-import 'package:meta/meta.dart';
-
-import 'sim.dart';
-
-/// An Animation<T> that carries an intrinsic velocity.
-///
-/// Having velocity is useful in making non-jerky animation transitions.
-abstract class FluxAnimation<T> extends Animation<T> {
- /// Default constructor
- const FluxAnimation();
-
- /// Wrap an Animation as a FluxAnimation. Will
- factory FluxAnimation.fromAnimation(Animation<T> animation, T velocity) =>
- animation is FluxAnimation
- ? animation
- : _FluxAnimationWrapper<T>(animation, velocity);
-
- /// The instantaneous change in the value in natural units per second.
- T get velocity;
-}
-
-/// A function which returns a FluxAnimation from an initial value and velocity.
-typedef FluxAnimationInit<T> = FluxAnimation<T> Function(T value, T velocity);
-
-class _FluxAnimationWrapper<T> extends FluxAnimation<T> {
- _FluxAnimationWrapper(this.animation, this._velocity)
- : assert(animation != null),
- assert(_velocity != null);
- final Animation<T> animation;
- final T _velocity;
-
- @override
- AnimationStatus get status => animation.status;
-
- @override
- T get value => animation.value;
-
- @override
- T get velocity => _velocity;
-
- @override
- void addListener(VoidCallback listener) => animation.addListener(listener);
-
- @override
- void removeListener(VoidCallback listener) =>
- animation.removeListener(listener);
-
- @override
- void addStatusListener(AnimationStatusListener listener) =>
- animation.addStatusListener(listener);
-
- @override
- void removeStatusListener(AnimationStatusListener listener) =>
- animation.removeStatusListener(listener);
-}
-
-/// A FluxAnimation provided by a Sim.
-class SimAnimationController<T> extends FluxAnimation<T>
- with
- AnimationLocalStatusListenersMixin,
- AnimationLocalListenersMixin,
- AnimationEagerListenerMixin {
- /// Create a SimAnimation with given Sim
- SimAnimationController({
- @required TickerProvider vsync,
- @required this.sim,
- }) : _value = sim.value(0.0),
- _velocity = sim.velocity(0.0),
- _elapsed = Duration.zero,
- _elapsedOffset = Duration.zero {
- _ticker = vsync.createTicker(_tick);
- }
-
- /// The Sim for this animation.
- final Sim<T> sim;
-
- Ticker _ticker;
-
- @override
- AnimationStatus get status => _ticker.isActive
- ? AnimationStatus.forward
- : sim.isDone(_elapsedInSeconds)
- ? AnimationStatus.completed
- : AnimationStatus.dismissed;
-
- @override
- T get value => _value;
- T _value;
-
- @override
- T get velocity => _velocity;
- T _velocity;
-
- /// The elapsed duration for this simulation. Stops animation if manually set.
- Duration get elapsed => _elapsed + _elapsedOffset;
- Duration _elapsed;
- Duration _elapsedOffset;
- set elapsed(Duration duration) {
- assert(duration != null);
- stop();
- _elapsedOffset = duration;
- _tick(Duration.zero);
- }
-
- double get _elapsedInSeconds =>
- (_elapsed + _elapsedOffset).inMicroseconds.toDouble() /
- Duration.microsecondsPerSecond;
-
- /// Start the animation.
- TickerFuture start() {
- TickerFuture future = _ticker.start()
- ..whenCompleteOrCancel(_sendStatusUpdate);
- _sendStatusUpdate();
- return future;
- }
-
- /// Stop the animation, optionally marking it as cancelled.
- void stop({bool canceled = false}) {
- _ticker.stop(canceled: canceled);
- _elapsedOffset = elapsed;
- _elapsed = Duration.zero;
- }
-
- @override
- void dispose() {
- _ticker.dispose();
- super.dispose();
- }
-
- void _tick(Duration elapsed) {
- _elapsed = elapsed;
- double elapsedSeconds = _elapsedInSeconds;
- _value = sim.value(elapsedSeconds);
- _velocity = sim.velocity(elapsedSeconds);
- if (sim.isDone(elapsedSeconds)) {
- _ticker.stop();
- }
- notifyListeners();
- }
-
- AnimationStatus _lastSentStatus;
- void _sendStatusUpdate() {
- if (status != _lastSentStatus) {
- _lastSentStatus = status;
- notifyStatusListeners(status);
- }
- }
-}
-
-/// A manually controllable FluxAnimation
-///
-/// The value and velocity of this animation can be manually controlled, also
-/// a secondary delegate animation can be provided to continue the animation
-/// upon completion.
-class ManualAnimation<T> extends FluxAnimation<T>
- with
- AnimationLocalStatusListenersMixin,
- AnimationLocalListenersMixin,
- AnimationLazyListenerMixin {
- /// Constructs with initial value and velocity.
- ManualAnimation({
- @required T value,
- @required T velocity,
- FluxAnimationInit<T> builder,
- }) : _value = value,
- _velocity = velocity,
- _builder = builder,
- _delegate = null,
- _done = false,
- assert(value != null),
- assert(velocity != null);
-
- /// Constructs with value and velocity provided by delegate to start.
- ManualAnimation.withDelegate({@required FluxAnimation<T> delegate})
- : _delegate = delegate,
- _builder = null,
- _done = true,
- assert(delegate != null);
-
- final FluxAnimationInit<T> _builder;
- FluxAnimation<T> _delegate;
-
- @override
- T get value => _done ? (_delegate?.value ?? _value) : _value;
- T _value;
-
- @override
- T get velocity => _done ? (_delegate?.velocity ?? _velocity) : _velocity;
- T _velocity;
-
- bool _done;
-
- @override
- AnimationStatus get status => _done
- ? (_delegate?.status ?? AnimationStatus.completed)
- : AnimationStatus.forward;
-
- /// Manually change the value and velocity of this animation
- void update({@required T value, @required T velocity}) {
- assert(value != null);
- assert(velocity != null);
- AnimationStatus oldStatus = status;
- if (_done) {
- _stopDelegating();
- _done = false;
- }
- _value = value;
- _velocity = velocity;
- if (oldStatus != status) {
- notifyStatusListeners(status);
- }
- notifyListeners();
- }
-
- /// Signal the end of manually changing this animation.
- ///
- /// This either returns control back to the delegate, or signals an
- /// AnimationStatus.complete if no delegate is provided.
- void done() {
- if (_done) {
- return;
- }
- AnimationStatus oldStatus = status;
- _done = true;
- _startDelegating();
- if (status != oldStatus) {
- notifyStatusListeners(status);
- }
- notifyListeners();
- }
-
- @override
- void didStartListening() {
- _startDelegating();
- }
-
- @override
- void didStopListening() {
- _stopDelegating();
- }
-
- void _startDelegating() {
- if (_done) {
- if (_builder != null) {
- _delegate = _builder(_value, _velocity);
- }
- _delegate?.addListener(notifyListeners);
- _delegate?.addStatusListener(notifyStatusListeners);
- }
- }
-
- void _stopDelegating() {
- if (_done) {
- _delegate?.removeListener(notifyListeners);
- _delegate?.removeStatusListener(notifyStatusListeners);
- }
- }
-}
-
-/// Animation that animates to the target value according to the given Simulate.
-class MovingTargetAnimation<T> extends FluxAnimation<T>
- with
- AnimationLocalStatusListenersMixin,
- AnimationLocalListenersMixin,
- AnimationLazyListenerMixin {
- /// Constructs using the provided target, simulate, and initial values.
- MovingTargetAnimation({
- @required TickerProvider vsync,
- @required Animation<T> target,
- @required this.simulate,
- @required T value,
- @required T velocity,
- }) : _vsync = vsync,
- assert(target != null),
- target = FluxAnimation<T>.fromAnimation(target, velocity),
- assert(vsync != null),
- assert(simulate != null) {
- _value = value;
- _velocity = velocity;
- }
-
- /// The simulation generator for moving to target.
- final Simulate<T> simulate;
-
- /// The moving target.
- final FluxAnimation<T> target;
-
- final TickerProvider _vsync;
- SimAnimationController<T> _animation;
- T _value;
- T _velocity;
- int _lastUpdateCallbackId;
-
- @override
- AnimationStatus get status =>
- _animation?.status ??
- (simulate(value, target.value, velocity).isDone(0.0)
- ? AnimationStatus.completed
- : AnimationStatus.forward);
-
- @override
- T get value => _animation?.value ?? _value;
-
- @override
- T get velocity => _animation?.velocity ?? _velocity;
-
- /// Like this animation except stays in lockstep with target once reached.
- FluxAnimation<T> get stickyAnimation => target.value == _value
- // HACK(alangardner): Using '==' is fragile. We should instead use
- // simulate(value, target.value, velocityOrigin).isDone(0.0)
- // where velocityOrigin is the 'zero' velocity. However, this introduces
- // a zeroVelocity parameter complexity to the API and may be confusing.
- ? target
- : ChainedAnimation<T>(this, then: target);
-
- void _scheduleUpdate() {
- if (_lastUpdateCallbackId != null) {
- SchedulerBinding.instance
- .cancelFrameCallbackWithId(_lastUpdateCallbackId);
- }
- _lastUpdateCallbackId =
- SchedulerBinding.instance.scheduleFrameCallback((Duration timestamp) {
- _update();
- _lastUpdateCallbackId = null;
- });
- }
-
- void _update() {
- Sim<T> sim = simulate(value, target.value, velocity);
- _disposeAnimation();
- _animation = SimAnimationController<T>(vsync: _vsync, sim: sim)
- ..addListener(notifyListeners)
- ..addStatusListener(notifyStatusListeners);
- if (!_animation.isCompleted) {
- _animation.start();
- }
- }
-
- void _disposeAnimation() {
- if (_animation != null) {
- _value = _animation.value;
- _velocity = _animation.velocity;
- _animation
- ..removeListener(notifyListeners)
- ..removeStatusListener(notifyStatusListeners)
- ..dispose();
- _animation = null;
- }
- }
-
- @override
- void didStartListening() {
- _update();
- target.addListener(_scheduleUpdate);
- }
-
- @override
- void didStopListening() {
- target.removeListener(_scheduleUpdate);
- _disposeAnimation();
- if (_lastUpdateCallbackId != null) {
- SchedulerBinding.instance
- .cancelFrameCallbackWithId(_lastUpdateCallbackId);
- _lastUpdateCallbackId = null;
- }
- }
-}
-
-/// A generic transform function from one value to another of the same type.
-typedef Transform<T> = T Function(T value);
-
-/// A transformation wrapper for an animation.
-class TransformedAnimation<T> extends FluxAnimation<T>
- with
- AnimationLocalStatusListenersMixin,
- AnimationLocalListenersMixin,
- AnimationLazyListenerMixin {
- /// Construct using a delegate animation and tranformation function.
- TransformedAnimation({
- @required this.animation,
- @required this.valueTransform,
- @required this.velocityTransform,
- });
-
- /// The delegate animation.
- final FluxAnimation<T> animation;
-
- /// The value transform function.
- final Transform<T> valueTransform;
-
- /// The velocity transform function.
- final Transform<T> velocityTransform;
-
- @override
- AnimationStatus get status => animation.status;
-
- @override
- T get value => valueTransform(animation.value);
-
- @override
- T get velocity => velocityTransform(animation.velocity);
-
- @override
- void didStartListening() {
- animation
- ..addListener(notifyListeners)
- ..addStatusListener(notifyStatusListeners);
- }
-
- @override
- void didStopListening() {
- animation
- ..removeListener(notifyListeners)
- ..removeStatusListener(notifyStatusListeners);
- }
-}
-
-/// A FluxAnimation that chains flux animations in succession.
-///
-/// First the initial animation is active until its status turns to Completed,
-/// then the next animation becomes active. If any animation along the way is
-/// dismissed, then it stops the chain until it completes.
-///
-/// If a previously completed animation in the chain changes status, this only
-/// effects the chained animation if it is the final animation in the chain.
-class ChainedAnimation<T> extends FluxAnimation<T>
- with
- AnimationLocalStatusListenersMixin,
- AnimationLocalListenersMixin,
- AnimationLazyListenerMixin {
- /// Construct a chained animation starting with animation followed by then.
- ChainedAnimation(this._animation, {FluxAnimation<T> then})
- : _next = (then == null) ? null : ChainedAnimation<T>(then) {
- _active = (_next != null && _animation.isCompleted) ? _next : _animation;
- }
-
- final FluxAnimation<T> _animation;
- final ChainedAnimation<T> _next;
- FluxAnimation<T> _active;
-
- /// Returns a new FluxAnimation that runs the current animation,
- /// followed by the one specified in the argument when it is complete.
- ChainedAnimation<T> then(FluxAnimation<T> next) =>
- ChainedAnimation<T>(_animation, then: next);
-
- @override
- AnimationStatus get status => _active.status;
-
- @override
- T get value => _active.value;
-
- @override
- T get velocity => _active.velocity;
-
- AnimationStatusListener get _currentStatusListener =>
- _active == _animation && _next != null
- ? _animationStatusListener
- : notifyStatusListeners;
-
- void _animationStatusListener(AnimationStatus status) {
- if (_active == _animation &&
- _next != null &&
- (_animation.isCompleted || _animation.isDismissed)) {
- _animation
- ..removeListener(notifyListeners)
- ..removeStatusListener(_animationStatusListener);
- _active = _next
- ..addListener(notifyListeners)
- ..addStatusListener(notifyStatusListeners);
- }
- if (status != AnimationStatus.completed) {
- notifyStatusListeners(status);
- }
- }
-
- @override
- void didStartListening() {
- _active = (((_animation.isCompleted || _animation.isDismissed)
- ? _next
- : _animation) ??
- _animation)
- ..addListener(notifyListeners)
- ..addStatusListener(_currentStatusListener);
- }
-
- @override
- void didStopListening() {
- _active
- ..removeListener(notifyListeners)
- ..removeStatusListener(_currentStatusListener);
- }
-}
diff --git a/story_shells/mondrian/lib/anim/sim.dart b/story_shells/mondrian/lib/anim/sim.dart
deleted file mode 100644
index d5e6776..0000000
--- a/story_shells/mondrian/lib/anim/sim.dart
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2017 The Fuchsia 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 'dart:ui';
-
-import 'package:flutter/physics.dart';
-import 'package:flutter/widgets.dart';
-import 'package:meta/meta.dart';
-
-/// The base class for all generic immutable simulations.
-abstract class Sim<T> {
- /// Construct with given tolerance.
- Sim({Tolerance tolerance})
- : _tolerance = tolerance ?? Tolerance.defaultTolerance;
-
- /// The output of the object in the simulation at the given time.
- T value(double time);
-
- /// The change in value of the object in the simulation at the given time.
- T velocity(double time);
-
- /// Whether the simulation is "done" at the given time.
- bool isDone(double time);
-
- /// How close to the actual end of the simulation a value at a particular time
- /// must be before [isDone] considers the simulation to be "done".
- ///
- /// A simulation with an asymptotic curve would never technically be "done",
- /// but once the difference from the value at a particular time and the
- /// asymptote itself could not be seen, it would be pointless to continue. The
- /// tolerance defines how to determine if the difference could not be seen.
- Tolerance get tolerance => _tolerance;
- final Tolerance _tolerance;
-
- @override
- String toString() => '$runtimeType';
-}
-
-/// Generates a Sim with given params.
-typedef Simulate<T> = Sim<T> Function(T start, T end, T velocity);
-
-// TODO(alangardner): Chaining operations
-
-/// Convenience wrapper for Flutter simulation.
-class SimDouble extends Sim<double> {
- /// Construct wrapper using a Simulation
- SimDouble({@required this.simulation})
- : super(tolerance: simulation.tolerance);
-
- /// The Simulation that is wrapped
- final Simulation simulation;
-
- @override
- double value(double time) => simulation.x(time);
-
- @override
- double velocity(double time) => simulation.dx(time);
-
- @override
- bool isDone(double time) => simulation.isDone(time);
-}
-
-/// A Simulation that never changes its value.
-class StaticSimulation extends Simulation {
- /// Constructor with fixed value.
- StaticSimulation({@required double value}) : _value = value;
-
- final double _value;
-
- @override
- double x(double time) => _value;
-
- @override
- double dx(double time) => 0.0;
-
- @override
- bool isDone(double time) => true;
-}
-
-/// 2D Sim where each axis is independent of the other
-class Independent2DSim extends Sim<Offset> {
- /// 2D Sim where the axis are indepenent simulations.
- Independent2DSim({
- @required this.xSim,
- @required this.ySim,
- Tolerance tolerance,
- }) : super(tolerance: tolerance);
-
- /// Convenience constructor when the simulation is symetric on each axis.
- Independent2DSim.symmetric({
- @required Simulation sim,
- Tolerance tolerance,
- }) : xSim = sim,
- ySim = sim,
- super(tolerance: tolerance);
-
- /// Convenience constructor when the value is fixed.
- Independent2DSim.static({@required Offset value})
- : xSim = StaticSimulation(value: value.dx),
- ySim = StaticSimulation(value: value.dy);
-
- /// The Simulation used for the x axis.
- final Simulation xSim;
-
- /// The Simulation used for the y axis.
- final Simulation ySim;
-
- @override
- Offset value(double time) => Offset(xSim.x(time), ySim.x(time));
-
- @override
- Offset velocity(double time) => Offset(xSim.dx(time), ySim.dx(time));
-
- @override
- bool isDone(double time) => xSim.isDone(time) && ySim.isDone(time);
-}
-
-/// Rect Sim with independent size and position simulators.
-class IndependentRectSim extends Sim<Rect> {
- /// Constructor
- IndependentRectSim({
- @required this.sizeSim,
- @required this.positionSim,
- FractionalOffset origin,
- Tolerance tolerance,
- }) : origin = origin ?? FractionalOffset.center,
- super(tolerance: tolerance);
-
- /// The Size Sim
- final Sim<Offset> sizeSim;
-
- /// The Position Sim
- final Sim<Offset> positionSim;
-
- /// The Origin of The Rect
- final FractionalOffset origin;
-
- @override
- Rect value(double time) {
- Size size = Size.zero + sizeSim.value(time);
- return (positionSim.value(time) - origin.alongSize(size)) & size;
- }
-
- @override
- Rect velocity(double time) =>
- positionSim.velocity(time) & (Size.zero + sizeSim.velocity(time));
-
- @override
- bool isDone(double time) => positionSim.isDone(time) && sizeSim.isDone(time);
-}
diff --git a/story_shells/mondrian/lib/layout/copresent_layout.dart b/story_shells/mondrian/lib/layout/copresent_layout.dart
deleted file mode 100644
index 4d322d6..0000000
--- a/story_shells/mondrian/lib/layout/copresent_layout.dart
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2017 The Fuchsia 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 'dart:math';
-
-import 'package:fidl_fuchsia_modular/fidl_async.dart';
-import 'package:flutter/widgets.dart';
-
-import '../models/layout_model.dart';
-import '../models/surface/positioned_surface.dart';
-import '../models/surface/surface.dart';
-import '../models/surface/surface_graph.dart';
-import '../models/tree/spanning_tree.dart';
-import '../models/tree/tree.dart';
-
-// Convenience comparator used to ensure more focused items get higher priority
-int _compareByOtherList(Surface l, Surface r, List<Surface> otherList) {
- int li = otherList.indexOf(l);
- int ri = otherList.indexOf(r);
- if (li < 0) {
- li = otherList.length;
- }
- if (ri < 0) {
- ri = otherList.length;
- }
- return ri - li;
-}
-
-/// Returns in the order they should be stacked
-List<PositionedSurface> layoutSurfaces(
- BuildContext context,
- SurfaceGraph graph,
- List<Surface> focusStack,
- LayoutModel layoutModel,
-) {
- Surface focused = focusStack.lastWhere((Surface surface) {
- return surface.connection != null;
- }, orElse: () => null);
- if (focusStack.isEmpty || focused == null) {
- return <PositionedSurface>[];
- }
- SurfaceArrangement focusedArrangement = focused.relation.arrangement;
-
- Tree<Surface> copresTree = getCopresentSpanningTree(focused);
-
- // Ontop only applies if the currently focused mod has a parent. If there's
- // only one sutface in the stack, fall through to the logic below.
- if (focusedArrangement == SurfaceArrangement.ontop && focusStack.length > 1) {
- // Determine the parent's position and then place the focused surface on top.
- List<PositionedSurface> surfaces = layoutSurfaces(context, graph,
- focusStack.sublist(0, focusStack.length - 1), layoutModel);
- PositionedSurface parentSurface =
- surfaces.firstWhere((PositionedSurface positioned) {
- return positioned.surface == focused.parent;
- });
- PositionedSurface ontopSurface = PositionedSurface(
- surface: focused,
- position: parentSurface.position,
- );
- surfaces.add(ontopSurface);
- return surfaces;
- }
-
- int focusOrder(Tree<Surface> l, Tree<Surface> r) =>
- _compareByOtherList(l.value, r.value, focusStack);
-
- // Remove dismissed surfaces and surfaces without views and collapse tree
- for (Tree<Surface> node in copresTree) {
- if (node.value.dismissed || node.value.connection == null) {
- node.children.forEach(node.parent.add);
- node.detach();
- }
- }
-
- // Prune less focused surfaces where their min constraints do not fit
- double totalMinWidth = 0.0;
- for (Tree<Surface> node
- in copresTree.flatten(orderChildren: focusOrder).skipWhile(
- (Tree<Surface> node) {
- double minWidth = node.value.minWidth(min: layoutModel.minScreenRatio);
- if (totalMinWidth + minWidth > 1.0) {
- return false;
- }
- totalMinWidth += minWidth;
- return true;
- },
- )) {
- node.detach();
- }
-
- // Prune less focused surfaces where emphasis values cannot be respected
- double totalEmphasis = 0.0;
- Surface top = focused;
- Surface tightestFit = focused;
- for (Tree<Surface> node
- in copresTree.flatten(orderChildren: focusOrder).skipWhile(
- (Tree<Surface> node) {
- Surface prevTop = top;
- double prevTotalEmphasis = totalEmphasis;
-
- // Update top
- if (top.ancestors.contains(node.value)) {
- top = node.value;
- totalEmphasis *= prevTop.absoluteEmphasis(top);
- }
- double emphasis = node.value.absoluteEmphasis(top);
- totalEmphasis += emphasis;
-
- // Calculate min width available
- double tightestFitEmphasis = tightestFit.absoluteEmphasis(top);
- double extraWidth = emphasis / totalEmphasis -
- node.value.minWidth(min: layoutModel.minScreenRatio);
- double tightestFitExtraWidth = tightestFitEmphasis / totalEmphasis -
- tightestFit.minWidth(min: layoutModel.minScreenRatio);
-
- // Break if smallest or this doesn't fit
- if (min(tightestFitExtraWidth, extraWidth) < 0.0) {
- // Restore previous values
- top = prevTop;
- totalEmphasis = prevTotalEmphasis;
- return false;
- }
-
- // Update tightest fit
- if (extraWidth < tightestFitExtraWidth) {
- tightestFit = node.value;
- }
- return true;
- },
- )) {
- node.detach();
- }
-
- List<Surface> surfacesToDisplay =
- copresTree.map((Tree<Surface> t) => t.value).toList(growable: false);
-
- Iterable<Surface> arrangement =
- top.flattened.where((Surface s) => surfacesToDisplay.contains(s));
-
- // Layout rects for arrangement
- final List<PositionedSurface> layout = <PositionedSurface>[];
- double fractionalWidthOffset = 0.0;
- for (Surface surface in arrangement) {
- double fractionalWidth = surface.absoluteEmphasis(top) / totalEmphasis;
- double fractionalHeight = 1.0;
- layout.add(
- PositionedSurface(
- surface: surface,
- position: Rect.fromLTWH(
- fractionalWidthOffset,
- 0.0,
- fractionalWidth,
- fractionalHeight,
- ),
- ),
- );
- fractionalWidthOffset += fractionalWidth;
- }
- return layout;
-}
diff --git a/story_shells/mondrian/lib/layout/pattern_layout.dart b/story_shells/mondrian/lib/layout/pattern_layout.dart
deleted file mode 100644
index dd516b7..0000000
--- a/story_shells/mondrian/lib/layout/pattern_layout.dart
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2018 The Fuchsia 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 'dart:math';
-
-import 'package:flutter/widgets.dart';
-import 'package:fuchsia_logger/logger.dart';
-
-import '../models/layout_model.dart';
-import '../models/surface/positioned_surface.dart';
-import '../models/surface/surface.dart';
-
-const String _parentId = 'parent';
-const String _tickerPattern = 'ticker';
-const String _commentsRightPattern = 'comments-right';
-
-const double _tickerHeightRatio = 0.15;
-const double _commentsWidthRatio = 0.30;
-
-/// Returns in the order they should stacked
-List<PositionedSurface> layoutSurfaces(
- BuildContext context,
- List<Surface> focusStack,
- LayoutModel layoutModel,
-) {
- if (focusStack.isEmpty) {
- return <PositionedSurface>[];
- }
-
- final List<PositionedSurface> layout = <PositionedSurface>[];
- Surface focused = focusStack.last;
- String pattern = focused.compositionPattern;
-
- if (!_isSupportedPattern(pattern)) {
- log.warning('unrecognized pattern $pattern');
-
- layout.add(
- PositionedSurface(
- surface: focused,
- position: Rect.fromLTWH(0.0, 0.0, 1.0, 1.0),
- ),
- );
- return layout;
- }
-
- Map<String, Surface> patternSurfaces = <String, Surface>{};
- // This is really a list not a stack. Reverse it to get to the 'top' items first.
- for (Surface surface in focusStack.reversed) {
- if (surface.compositionPattern != null &&
- surface.compositionPattern.isNotEmpty) {
- String pattern = surface.compositionPattern;
- patternSurfaces.putIfAbsent(pattern, () => surface);
- } else {
- // TODO (jphsiao): Once we have better signals for figuring out which module
- // to compose the pattern module with we can identify the 'source' more definitively.
- // For now, the surface without a pattern is likely the source.
- patternSurfaces.putIfAbsent(_parentId, () => surface);
- }
- }
-
- if (patternSurfaces.containsKey(_commentsRightPattern)) {
- // Comments-right gets laid out first
- _layoutCommentsRight(
- patternSurfaces[_parentId],
- patternSurfaces[_commentsRightPattern],
- ).forEach(layout.add);
- }
- if (patternSurfaces.containsKey(_tickerPattern)) {
- double availableWidth = 1.0;
- double availableHeight = 1.0;
- if (layout.isNotEmpty && layout[0].surface == patternSurfaces[_parentId]) {
- availableHeight = layout[0].position.height;
- availableWidth = layout[0].position.width;
- }
- List<PositionedSurface> tickerSurfaces = _layoutTicker(
- patternSurfaces[_parentId],
- patternSurfaces[_tickerPattern],
- availableHeight,
- availableWidth,
- );
- if (layout.isNotEmpty) {
- layout[0] = tickerSurfaces[0];
- } else {
- layout.add(tickerSurfaces[0]);
- }
- layout.add(tickerSurfaces[1]);
- }
- return layout;
-}
-
-bool _isSupportedPattern(String pattern) {
- return pattern == _tickerPattern || pattern == _commentsRightPattern;
-}
-
-List<PositionedSurface> _layoutTicker(Surface tickerSource, Surface ticker,
- double availableHeight, double availableWidth) {
- return <PositionedSurface>[
- PositionedSurface(
- surface: tickerSource,
- position: Rect.fromLTWH(
- 0.0,
- 0.0,
- availableWidth,
- availableHeight * (1.0 - _tickerHeightRatio),
- ),
- ),
- PositionedSurface(
- surface: ticker,
- position: Rect.fromLTWH(
- 0.0,
- availableHeight * (1.0 - _tickerHeightRatio),
- availableWidth,
- availableHeight * _tickerHeightRatio,
- ),
- ),
- ];
-}
-
-List<PositionedSurface> _layoutCommentsRight(
- Surface commentsSource,
- Surface comments,
-) {
- return <PositionedSurface>[
- PositionedSurface(
- surface: commentsSource,
- position: Rect.fromLTWH(
- 0.0,
- 0.0,
- 1.0 - _commentsWidthRatio,
- 1.0,
- ),
- ),
- PositionedSurface(
- surface: comments,
- position: Rect.fromLTWH(
- 1.0 - _commentsWidthRatio,
- 0.0,
- _commentsWidthRatio,
- 1.0,
- ),
- ),
- ];
-}
diff --git a/story_shells/mondrian/lib/main.dart b/story_shells/mondrian/lib/main.dart
deleted file mode 100644
index 47cdaf1..0000000
--- a/story_shells/mondrian/lib/main.dart
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2017 The Fuchsia 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 'dart:convert' show ascii;
-import 'dart:developer' show Timeline;
-import 'dart:ui' show window;
-
-import 'package:fidl_fuchsia_ui_input/fidl_async.dart'
- show KeyboardEvent, kModifierLeftAlt, KeyboardEventPhase;
-import 'package:flutter/widgets.dart';
-import 'package:fuchsia_logger/logger.dart';
-import 'package:lib.widgets/model.dart';
-import 'package:lib.widgets/widgets.dart';
-import 'package:lib.story_shell/common.dart';
-import 'models/inset_manager.dart';
-import 'models/layout_model.dart';
-import 'models/surface/surface_graph.dart';
-import 'story_shell_impl.dart';
-import 'widgets/mondrian.dart';
-import 'widgets/surface_relationships.dart';
-
-/// This is used for keeping the reference around.
-// ignore: unused_element
-StoryShellImpl _storyShellImpl;
-
-/// Entry point.
-void main() {
- setupLogger(name: 'Mondrian');
- Timeline.instantSync('starting');
- log.info('Started');
-
- LayoutModel layoutModel = LayoutModel();
- final ValueNotifier overviewNotifier = ValueNotifier(false);
- InsetManager insetManager = InsetManager();
- KeyListener keyListener = KeyListener()
- ..registerKeyboardEventCallback(
- event: KeyboardEvent(
- deviceId: 0,
- eventTime: 0,
- hidUsage: 0,
- codePoint: ascii.encode('o')[0],
- modifiers: kModifierLeftAlt,
- phase: KeyboardEventPhase.pressed),
- callback: () => overviewNotifier.value = !overviewNotifier.value,
- );
-
- final surfaceGraph = SurfaceGraph();
- surfaceGraph.addListener(() {
- insetManager.onSurfacesChanged(surfaces: surfaceGraph.size);
- });
-
- void onWindowMetricsChanged() {
- Timeline.instantSync(
- 'Mondrian: onWindowMetricsChanged '
- '${MediaQueryData.fromWindow(window).size.width},'
- '${MediaQueryData.fromWindow(window).size.height}',
- );
- }
-
- // Note: This implementation only supports one StoryShell at a time.
- // Initialize the one Flutter application we support
- runApp(
- Directionality(
- textDirection: TextDirection.ltr,
- child: WindowMediaQuery(
- onWindowMetricsChanged: onWindowMetricsChanged,
- child: ScopedModel<LayoutModel>(
- model: layoutModel,
- child: ScopedModel<InsetManager>(
- model: insetManager,
- child: ScopedModel<SurfaceGraph>(
- model: surfaceGraph,
- child: AnimatedBuilder(
- animation: overviewNotifier,
- builder: (BuildContext context, Widget child) =>
- overviewNotifier.value
- ? SurfaceRelationships()
- : Mondrian(),
- ),
- ),
- ),
- ),
- ),
- ),
- );
-
- _storyShellImpl =
- StoryShellImpl(surfaceGraph: surfaceGraph, keyListener: keyListener)
- ..advertise();
- Timeline.instantSync('started');
-}
diff --git a/story_shells/mondrian/lib/models/depth_model.dart b/story_shells/mondrian/lib/models/depth_model.dart
deleted file mode 100644
index b9cecc8..0000000
--- a/story_shells/mondrian/lib/models/depth_model.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 The Fuchsia 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:lib.widgets/model.dart';
-
-export 'package:lib.widgets/model.dart'
- show ScopedModel, Model, ScopedModelDescendant;
-
-/// Gathers the max and min depths of the surface frames being displayed.
-class DepthModel extends Model {
- final double minDepth;
- final double maxDepth;
-
- /// Constructor.
- DepthModel({this.minDepth, this.maxDepth});
-}
diff --git a/story_shells/mondrian/lib/models/inset_manager.dart b/story_shells/mondrian/lib/models/inset_manager.dart
deleted file mode 100644
index 9a0ad4d..0000000
--- a/story_shells/mondrian/lib/models/inset_manager.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018 The Fuchsia 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:lib.widgets/model.dart';
-import 'package:lib.widgets/widgets.dart';
-
-export 'package:lib.widgets/model.dart'
- show ScopedModel, Model, ScopedModelDescendant;
-
-const RK4SpringDescription _kSimulationDesc =
- RK4SpringDescription(tension: 450.0, friction: 50.0);
-
-/// Frame for child views
-class InsetManager extends SpringModel {
- /// Constructor.
- InsetManager() : super(springDescription: _kSimulationDesc);
-
- /// Call with the number of surfaces that are in the graph.
- void onSurfacesChanged({int surfaces}) {
- target = surfaces > 1 ? 12.0 : 0.0;
- }
-}
diff --git a/story_shells/mondrian/lib/models/layout_model.dart b/story_shells/mondrian/lib/models/layout_model.dart
deleted file mode 100644
index b70fe58..0000000
--- a/story_shells/mondrian/lib/models/layout_model.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2017 The Fuchsia 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:lib.widgets/model.dart';
-
-const String _kMode = 'mode';
-const String _kModeNormal = 'normal';
-const String _kModeEdgeToEdge = 'edgeToEdge';
-
-const double _kMinScreenWidth = 200.0;
-const double _kMinScreenRatio = 1.0 / 5.0;
-
-const double _kMinScreenWidthEdgeToEdge = 200.0;
-const double _kMinScreenRatioEdgeToEdge = 1.0 / 3.0;
-
-/// Manages layout constants.
-class LayoutModel extends Model {
- double _minScreenWidth = _kMinScreenWidth;
- double _minScreenRatio = _kMinScreenRatio;
-
- /// The minimum width for copresentation.
- double get minScreenWidth => _minScreenWidth;
-
- /// The minimum screen ratio for copresentation.
- double get minScreenRatio => _minScreenRatio;
-
- /// Called when the device profile changes.
- void onDeviceProfileChanged(Map<String, String> deviceProfile) {
- switch (deviceProfile[_kMode]) {
- case _kModeNormal:
- if (_minScreenWidth != _kMinScreenWidth ||
- _minScreenRatio != _kMinScreenRatio) {
- _minScreenWidth = _kMinScreenWidth;
- _minScreenRatio = _kMinScreenRatio;
- notifyListeners();
- }
- break;
- case _kModeEdgeToEdge:
- if (_minScreenWidth != _kMinScreenWidthEdgeToEdge ||
- _minScreenRatio != _kMinScreenRatioEdgeToEdge) {
- _minScreenWidth = _kMinScreenWidthEdgeToEdge;
- _minScreenRatio = _kMinScreenRatioEdgeToEdge;
- notifyListeners();
- }
- break;
- default:
- // Unknown mode.
- break;
- }
- }
-}
diff --git a/story_shells/mondrian/lib/models/surface/positioned_surface.dart b/story_shells/mondrian/lib/models/surface/positioned_surface.dart
deleted file mode 100644
index a0aadd2..0000000
--- a/story_shells/mondrian/lib/models/surface/positioned_surface.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Fuchsia 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:flutter/widgets.dart';
-
-import 'surface.dart';
-
-/// A pair of Surface and a Rect position.
-class PositionedSurface {
- /// The constructor
- PositionedSurface({this.surface, this.position});
-
- /// The Surface
- final Surface surface;
-
- /// The Position
- final Rect position;
-
- @override
- String toString() => 'PositionedSurface('
- 'surface: $surface, position: $position)';
-
- @override
- bool operator ==(Object o) => o is PositionedSurface && surface == o.surface;
-
- @override
- int get hashCode => surface.hashCode;
-}
diff --git a/story_shells/mondrian/lib/models/surface/surface.dart b/story_shells/mondrian/lib/models/surface/surface.dart
deleted file mode 100644
index d595a22..0000000
--- a/story_shells/mondrian/lib/models/surface/surface.dart
+++ /dev/null
@@ -1,207 +0,0 @@
-// Copyright 2017 The Fuchsia 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 'dart:math' as math;
-
-import 'package:fidl_fuchsia_modular/fidl_async.dart';
-import 'package:fuchsia_scenic_flutter/child_view_connection.dart'
- show ChildViewConnection;
-import 'package:fuchsia_logger/logger.dart';
-import 'package:lib.widgets/model.dart';
-
-import '../../models/surface/surface_transition.dart';
-import '../tree/tree.dart';
-import 'surface_graph.dart';
-import 'surface_properties.dart';
-import 'surface_relation_util.dart';
-
-/// The parentId that means no parent
-const String kNoParent = '';
-
-/// Details of a surface child view
-class Surface extends Model {
- /// Public constructor
- Surface(this._graph, this.node, this.properties, this.relation,
- this.compositionPattern, this.placeholderColor) {
- transitionModel = SurfaceTransitionModel()
-
- // notify listeners of Surface model to changes that happen in
- // surface_transition, so we can use the same model in builders
- /// ignore: unnecessary_lambdas
- ..addListener(() => notifyListeners());
- }
-
- Surface.fromJson(Map<String, dynamic> json, this._graph)
- : node = Tree<String>(value: json['id']),
- compositionPattern = json['compositionPattern'],
- properties = SurfaceProperties.fromJson(
- json['surfaceProperties'].cast<String, dynamic>()),
- relation = SurfaceRelationUtil.decode(
- json['surfaceRelation'].cast<String, String>()),
- childIds = json['children'].cast<String>(),
- isParentRoot = json['parentId'] == null,
- placeholderColor = json['placeholderColor'];
-
- final SurfaceGraph _graph;
- final Tree<String> node;
-
- /// The transitionModel handling placeholder timinggit
- SurfaceTransitionModel transitionModel;
-
- /// Connection to underlying view
- ChildViewConnection connection;
-
- /// The properties of this surface
- final SurfaceProperties properties;
-
- /// The relationship this node has with its parent
- final SurfaceRelation relation;
-
- /// The pattern with which to compose this node with its parent
- final String compositionPattern;
-
- /// The placeholder color to use if the surface is focused before the
- /// module is ready to display. This comes in as a hex string on the
- /// module manifest.
- final String placeholderColor;
-
- // Used to track whether this node is attached to the root of the graph
- bool isParentRoot = false;
-
- // Used for constructing the surface and its associated graph from json.
- // Note: these ids will not stay up to date with what's in the node.
- // Use the _children method below after the graph has been updated.
- List<String> childIds;
-
- /// Whether or not this surface is currently dismissed
- bool get dismissed => _graph.isDismissed(node.value);
-
- /// Return the min width of this Surface
- double minWidth({double min = 0.0}) => math.max(0.0, min);
-
- /// Return the absolute emphasis given some root displayed Surface
- double absoluteEmphasis(Surface relative) {
- assert(root == relative.root);
- Iterable<Surface> relativeAncestors = relative.ancestors;
- Surface ancestor = this;
- double emphasis = 1.0;
- while (ancestor != relative && !relativeAncestors.contains(ancestor)) {
- emphasis *= ancestor.relation.emphasis;
- ancestor = ancestor.parent;
- }
- Surface aRelative = relative;
- while (ancestor != aRelative) {
- emphasis /= aRelative.relation.emphasis;
- aRelative = aRelative.parent;
- }
- return emphasis;
- }
-
- /// The parent of this node
- Surface get parent => _surface(node.parent);
-
- /// The parentId of this node
- String get parentId => node.parent.value;
-
- /// The root surface
- Surface get root {
- List<Tree<String>> nodeAncestors = node.ancestors;
- return _surface(nodeAncestors.length > 1
- ? nodeAncestors[nodeAncestors.length - 2]
- : node);
- }
-
- /// The children of this node
- Iterable<Surface> get children => _surfaces(node.children);
-
- /// The siblings of this node
- Iterable<Surface> get siblings => _surfaces(node.siblings);
-
- /// The ancestors of this node
- Iterable<Surface> get ancestors => _surfaces(node.ancestors);
-
- /// This node and its descendents flattened into an Iterable
- Iterable<Surface> get flattened => _surfaces(node);
-
- /// Returns a Tree for this surface
- Tree<Surface> get tree {
- Tree<Surface> t = Tree<Surface>(value: this);
- for (Surface child in children) {
- t.add(child.tree);
- }
- return t;
- }
-
- /// Dismiss this node hiding it from layouts
- bool dismiss() => _graph.dismissSurface(node.value);
-
- /// Returns true if this surface can be dismissed
- bool canDismiss() => _graph.canDismissSurface(node.value);
-
- /// Remove this node from graph
- /// Returns true if this was removed
- bool remove() {
- // Only allow non-root surfaces to be removed
- if (node.parent?.value != null) {
- _graph.removeSurface(node.value);
- return true;
- }
- return false;
- }
-
- // Get the surface for this node
- Surface _surface(Tree<String> node) =>
- (node == null || node.value == null) ? null : _graph.getNode(node.value);
-
- Iterable<Surface> _surfaces(Iterable<Tree<String>> nodes) => nodes
- .where((Tree<String> node) => node != null && node.value != null)
- .map(_surface);
-
- @override
- String toString() {
- String edgeLabel = relation?.arrangement?.toString() ?? '';
- String edgeArrow = '$edgeLabel->'.padLeft(6, '-');
- String disconnected = connection == null ? '[DISCONNECTED]' : '';
- return '${edgeArrow}Surface ${node.value} $disconnected';
- }
-
- List<String> _children() {
- List<String> ids = [];
- for (Tree<String> child in node.children) {
- ids.add(child.value);
- }
- return ids;
- }
-
- Map<String, dynamic> toJson() {
- return {
- 'id': node.value,
- 'parentId': parentId,
- 'surfaceRelation': SurfaceRelationUtil.toMap(relation),
- 'surfaceProperties': properties,
- 'compositionPattern': compositionPattern,
- 'isDismissed': dismissed ? 'true' : 'false',
- 'children': _children(),
- 'placeholderColor': placeholderColor,
- };
- }
-}
-
-/// Defines a Container root in the [Surface Graph], holds the layout description
-class SurfaceContainer extends Surface {
- SurfaceContainer(
- SurfaceGraph graph,
- Tree<String> node,
- SurfaceProperties properties,
- SurfaceRelation relation,
- String compositionPattern)
- : super(graph, node, properties, relation, compositionPattern, '') {
- super.connection = null;
- }
-
- @override
- set connection(ChildViewConnection value) {
- log.warning('Cannot set a child view connection on a Container');
- }
-}
diff --git a/story_shells/mondrian/lib/models/surface/surface_form.dart b/story_shells/mondrian/lib/models/surface/surface_form.dart
deleted file mode 100644
index b72a3c2..0000000
--- a/story_shells/mondrian/lib/models/surface/surface_form.dart
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2017 The Fuchsia 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:flutter/foundation.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/scheduler.dart';
-import 'package:flutter/widgets.dart';
-import 'package:meta/meta.dart';
-
-/// A Form is a description of a thing in a Space
-class SurfaceForm {
- /// Simple, single child SurfaceForm
- SurfaceForm.single({
- @required Key key,
- @required Widget child,
- @required Rect position,
- @required Rect initPosition,
- double depth,
- DragFriction friction,
- VoidCallback onPositioned,
- VoidCallback onDragStarted,
- DragCallback onDrag,
- DragCallback onDragFinished,
- }) : this.withParts(
- key: key,
- parts: <Widget, Rect>{child: Offset.zero & position.size},
- position: position,
- initPosition: initPosition,
- depth: depth,
- friction: friction,
- onPositioned: onPositioned,
- onDragStarted: onDragStarted,
- onDrag: onDrag,
- onDragFinished: onDragFinished);
-
- /// Constructed out of multiple rectancular parts
- SurfaceForm.withParts({
- @required this.key,
- @required this.parts,
- @required this.position,
- @required this.initPosition,
- this.depth = 0.0,
- DragFriction friction,
- VoidCallback onPositioned,
- VoidCallback onDragStarted,
- DragCallback onDrag,
- DragCallback onDragFinished,
- }) : dragFriction = friction ?? kDragFrictionNone,
- onPositioned = onPositioned ?? (() {}),
- onDragStarted = onDragStarted ?? (() {}),
- onDrag = onDrag ?? kDragCallbackNone,
- onDragFinished = onDragFinished ?? kDragCallbackNone;
-
- /// The Key to use when instantiating widgets from this form
- final Key key;
-
- /// Map of widgets to their rect shape, relative to position.offset.
- /// Determines the shape of the form.
- final Map<Widget, Rect> parts;
-
- /// The position of this form in the space.
- final Rect position;
-
- /// The summon position of this form in the space.
- final Rect initPosition;
-
- /// The z depth of this form in the space.
- final double depth;
-
- /// Friction for manipulation.
- final DragFriction dragFriction;
-
- /// Callbacks once desired position is reached
- final VoidCallback onPositioned;
-
- /// Called on drag events.
- final VoidCallback onDragStarted;
-
- /// Called on drag events.
- final DragCallback onDrag;
-
- /// Called when surface no longer being dragged
- final DragCallback onDragFinished;
-
- @override
- String toString() =>
- 'SurfaceForm($key) with initPosition:$initPosition position:$position depth:$depth';
-}
-
-/// Generates a movement delta from a manipulation delta.
-/// offset: the form offset vector from the target position
-/// delta: the incremental manipulation vector
-/// returns the form incremental offset
-typedef DragFriction = Offset Function(Offset offset, Offset delta);
-
-/// No friction. Moves exactly with cursor.
-Offset kDragFrictionNone(Offset offset, Offset delta) => delta;
-
-/// Infinite friction. Will not move.
-Offset kDragFrictionInfinite(Offset offset, Offset delta) => Offset.zero;
-
-/// The position of the form relative to its target position.
-typedef DragCallback = void Function(Offset offset, Velocity velocity);
-
-/// No callback.
-void kDragCallbackNone(Offset offset, Velocity velocity) {}
diff --git a/story_shells/mondrian/lib/models/surface/surface_graph.dart b/story_shells/mondrian/lib/models/surface/surface_graph.dart
deleted file mode 100644
index 64288e7..0000000
--- a/story_shells/mondrian/lib/models/surface/surface_graph.dart
+++ /dev/null
@@ -1,298 +0,0 @@
-// Copyright 2018 The Fuchsia 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 'dart:developer' show Timeline;
-
-import 'package:fidl_fuchsia_modular/fidl_async.dart';
-import 'package:fidl_fuchsia_ui_views/fidl_async.dart';
-import 'package:fuchsia_scenic_flutter/child_view_connection.dart';
-import 'package:fuchsia_logger/logger.dart';
-import 'package:lib.widgets/model.dart';
-
-import '../tree/spanning_tree.dart';
-import '../tree/tree.dart';
-import 'surface.dart';
-import 'surface_properties.dart';
-
-// Data structure to manage the relationships and relative focus of surfaces
-class SurfaceGraph extends Model {
- SurfaceGraph() {
- setupLogger(name: 'Mondrian');
- }
-
- SurfaceGraph.fromJson(Map<String, dynamic> json) {
- reload(json);
- }
-
- /// Cache of surfaces
- final Map<String, Surface> _surfaces = <String, Surface>{};
-
- /// Surface relationship tree
- final Tree<String> _tree = Tree<String>(value: null);
-
- /// The stack of previous focusedSurfaces, most focused at end
- final List<String> _focusedSurfaces = <String>[];
-
- /// The stack of previous focusedSurfaces, most focused at end
- final Set<String> _dismissedSurfaces = <String>{};
-
- /// A mapping between surfaces that were brought in as ModuleSource::External
- /// surfaces (e.g. suggestions) and surfaces that were visually present at
- /// their introduction, in order to track where to provide a shell affordance
- /// for resummoning external surfaces that have been dismissed
- /// (surfaces are identified by ID)
- final Map<String, String> _visualAssociation = <String, String>{};
-
- Tree<String> get root => _tree;
-
- /// The node corresponding to the given id.
- Surface getNode(String id) => _surfaces[id];
-
- /// The last focused surface.
- Surface _lastFocusedSurface;
-
- /// The currently most focused [Surface]
- Surface get focused =>
- _focusedSurfaces.isEmpty ? null : _surfaces[_focusedSurfaces.last];
-
- /// The history of focused [Surface]s
- Iterable<Surface> get focusStack => _focusedSurfaces
- .where(_surfaces.containsKey)
- .map((String id) => _surfaces[id]);
-
- /// Add a [Surface] to the graph with the given parameters.
- ///
- /// Returns the surface that was added to the graph.
- Surface addSurface(
- String id,
- SurfaceProperties properties,
- String parentId,
- SurfaceRelation relation,
- String pattern,
- String placeholderColor,
- ) {
- Tree<String> node = _tree.find(id) ?? Tree<String>(value: id);
- Tree<String> parent =
- (parentId == kNoParent) ? _tree : _tree.find(parentId);
- assert(parent != null);
- assert(relation != null);
- Surface oldSurface = _surfaces[id];
- Surface updatedSurface =
- Surface(this, node, properties, relation, pattern, placeholderColor);
- // if this is an external surface, create an association between this and
- // the most focused surface.
- if (properties.source == ModuleSource.external &&
- _focusedSurfaces.isNotEmpty) {
- _visualAssociation[_focusedSurfaces.last] = id;
- }
- if (oldSurface != null) {
- // TODO (jphsiao): this is a hack to handle the adding of a surface with
- // the same view id. In this case we assume the view is going to be
- // reused.
- updatedSurface.connection = oldSurface.connection;
- }
- _surfaces[id] = updatedSurface;
- // Do not add the child again if the parent already knows about it.
- if (!parent.children.contains(node)) {
- parent.add(node);
- }
-
- notifyListeners();
- return updatedSurface;
- }
-
- /// Removes [Surface] from graph
- void removeSurface(String id) {
- if (_surfaces.keys.contains(id)) {
- Tree<String> node = _tree.find(id);
- if (node != null) {
- node.detach();
- // Remove orphaned children
- for (Tree<String> child in node.children) {
- child.detach();
- // As a temporary policy, remove child surfaces when surfaces are
- // removed. This policy will be revisited when we have a better sense
- // of what to do with orphaned children.
- _surfaces[child.value].remove();
- _focusedSurfaces.remove(child.value);
- _dismissedSurfaces.remove(child.value);
- }
- _focusedSurfaces.remove(id);
- _dismissedSurfaces.remove(id);
- _surfaces.remove(id);
- notifyListeners();
- }
- }
- }
-
- /// Move the surface up in the focus stack, undismissing it if needed.
- void focusSurface(String id) {
- if (!_surfaces.containsKey(id)) {
- log.warning('Invalid surface id "$id"');
- return;
- }
- _dismissedSurfaces.remove(id);
- _focusedSurfaces
- ..remove(id)
- ..add(id);
-
- // Also request the input focus through the child view connection.
- ChildViewConnection connection = _surfaces[id].connection;
- if (connection != null) {
- _surfaces[id].connection.requestFocus();
- _lastFocusedSurface = _surfaces[id];
- notifyListeners();
- }
- }
-
- /// Returns the list of surfaces that would be dismissed if this surface
- /// were dismissed - e.g. as a result of dependency - including this surface
- List<String> dismissedSet(String id) {
- Surface dismissed = _surfaces[id];
- List<Surface> ancestors = dismissed.ancestors.toList();
- List<Surface> dependentTree = getDependentSpanningTree(dismissed)
- .map((Tree<Surface> t) => t.value)
- .toList()
- // TODO(djmurphy) - when codependent comes in this needs to change
- // this only removes down the tree, codependents would remove their
- // ancestors
- ..removeWhere((Surface s) => ancestors.contains(s));
- List<String> depIds =
- dependentTree.map((Surface s) => s.node.value).toList();
- return depIds;
- }
-
- /// Check if given surface can be dismissed
- bool canDismissSurface(String id) {
- List<String> wouldDismiss = dismissedSet(id);
- return _focusedSurfaces
- .where((String fid) => !wouldDismiss.contains(fid))
- .isNotEmpty;
- }
-
- /// When called surface is no longer displayed
- bool dismissSurface(String id) {
- if (!canDismissSurface(id)) {
- return false;
- }
- List<String> depIds = dismissedSet(id);
- _focusedSurfaces.removeWhere((String fid) => depIds.contains(fid));
- _dismissedSurfaces.addAll(depIds);
- notifyListeners();
- return true;
- }
-
- /// True if surface has been dismissed and not subsequently focused
- bool isDismissed(String id) => _dismissedSurfaces.contains(id);
-
- /// Used to update a [Surface] with a live ChildViewConnection
- void connectView(String id, ViewHolderToken viewHolderToken) {
- final Surface surface = _surfaces[id];
- if (surface != null) {
- if (surface.connection != null) {
- // TODO(jphsiao): remove this hack once story shell API has been
- // change to accomodate view reusage
- return;
- }
- log.fine('connectView $surface');
- surface
- ..connection = ChildViewConnection(
- viewHolderToken,
- onAvailable: (ChildViewConnection connection) {
- Timeline.instantSync('surface available', arguments: {'id': '$id'});
-
- // If this surface is the last focused one, also request input focus
- if (_lastFocusedSurface == surface) {
- connection.requestFocus();
- }
- surface.notifyListeners();
- },
- onUnavailable: (ChildViewConnection connection) {
- Timeline.instantSync('surface $id unavailable');
- surface.connection = null;
- if (_surfaces.containsValue(surface)) {
- removeSurface(id);
- notifyListeners();
- }
- // Also any existing listener
- surface.notifyListeners();
- },
- )
- ..notifyListeners();
- }
- }
-
- void reload(Map<String, dynamic> json) {
- List<dynamic> decodedSurfaceList = json['surfaceList'];
- for (dynamic s in decodedSurfaceList) {
- Map<String, dynamic> item = s.cast<String, dynamic>();
- Surface surface = Surface.fromJson(item, this);
-
- _surfaces.putIfAbsent(surface.node.value, () {
- return surface;
- });
- }
- _surfaces.forEach((String id, Surface surface) {
- Tree<String> node = surface.node;
- if (surface.isParentRoot) {
- _tree.add(node);
- }
- if (surface.childIds != null) {
- for (String id in surface.childIds) {
- node.add(_surfaces[id].node);
- }
- }
- });
- dynamic list = json['focusStack'];
- List<String> focusStack = list.cast<String>();
- _focusedSurfaces.addAll(focusStack);
- }
-
- // Get the SurfaceIds of associated external surfaces
- // (surfaces originating from outside the current story)
- // that are dismissed and associated with the current Surface
- Set<String> externalSurfaces({String surfaceId}) {
- // Case1: An external child has a relationship with this surface
- // and the child has been dismissed
- Surface parent = getNode(surfaceId);
- List<Surface> externalSurfaces = parent.children.toList()
- ..retainWhere(
- (Surface s) => s.properties.source == ModuleSource.external);
- Set<String> externalIds =
- externalSurfaces.map((Surface s) => s.node.value).toSet();
- // Case2: The focused surface has a recorded visual association with an
- // external surface
- if (_visualAssociation[surfaceId].isNotEmpty) {
- externalIds.add(_visualAssociation[surfaceId]);
- }
- return externalIds;
- }
-
- /// Returns the amount of [Surface]s in the graph
- int get size => _surfaces.length;
-
- /// The tree size includes the root node which has no surface
- int get treeSize => _tree.flatten().length;
-
- @override
- String toString() =>
- 'Tree:\n${_tree.children.map(_toString).join('\n')}\nfocusStack length ${focusStack.length}';
-
- String _toString(Tree<String> node, {String prefix = ''}) {
- String nodeString = '$prefix${_surfaces[node.value]}';
- if (node.children.isNotEmpty) {
- nodeString =
- '$nodeString\n${node.children.map((Tree<String> node) => _toString(node, prefix: '$prefix ')).join('\n')}';
- }
- return '$nodeString';
- }
-
- Map<String, dynamic> toJson() {
- return {
- 'surfaceList': _surfaces.values.toList(),
- 'focusStack': _focusedSurfaces,
- 'links': [], // TODO(jphsiao): plumb through link data
- };
- }
-}
diff --git a/story_shells/mondrian/lib/models/surface/surface_properties.dart b/story_shells/mondrian/lib/models/surface/surface_properties.dart
deleted file mode 100644
index a88c8fc..0000000
--- a/story_shells/mondrian/lib/models/surface/surface_properties.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2017 The Fuchsia 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:fidl_fuchsia_modular/fidl_async.dart';
-
-/// Inherent properties of a surface
-class SurfaceProperties {
- /// Const constructor
- SurfaceProperties({this.containerLabel, this.source});
-
- SurfaceProperties.fromJson(Map<String, dynamic> json) {
- containerLabel = json['containerLabel'];
- containerMembership = json['containerMembership'];
- source = moduleSourceFromString(json['source']);
- }
-
- /// Belongs to a container with label containerLabel
- String containerLabel;
-
- /// List of the containers this Surface is a member of
- /// (To be able to support container-to-container transitions)
- /// The container this Surface is currently participating in is
- /// end of list. If this Surface is focused, that is the container that
- /// will be laid out.
- List<String> containerMembership;
-
- /// Was the module producing this surface launched from inside the current
- /// story - e.g. by a parent module in the story, or externally e.g. via a
- /// suggestion
- ModuleSource source;
-
- Map<String, dynamic> toJson() => {
- 'containerLabel': containerLabel,
- 'containerMembership': containerMembership,
- 'source': source.toString(),
- };
-
- ModuleSource moduleSourceFromString(String str) {
- if (str == ModuleSource.internal.toString()) {
- return ModuleSource.internal;
- } else if (str == ModuleSource.external.toString()) {
- return ModuleSource.external;
- } else if (str == 'null') {
- return null;
- } else {
- throw ArgumentError.value(str);
- }
- }
-}
diff --git a/story_shells/mondrian/lib/models/surface/surface_relation_util.dart b/story_shells/mondrian/lib/models/surface/surface_relation_util.dart
deleted file mode 100644
index f389af8..0000000
--- a/story_shells/mondrian/lib/models/surface/surface_relation_util.dart
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2018 The Fuchsia 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:fidl_fuchsia_modular/fidl_async.dart';
-
-// Contains methods for converting between SurfaceRelation and strings.
-class SurfaceRelationUtil {
- static Map<String, String> toMap(SurfaceRelation relation) {
- String dependency = relation.dependency.toString();
- String arrangement = relation.arrangement.toString();
- double emphasis = relation.emphasis;
- return {
- 'arrangement': arrangement,
- 'dependency': dependency,
- 'emphasis': emphasis.toString(),
- };
- }
-
- static SurfaceRelation decode(Map<String, String> encoded) {
- return SurfaceRelation(
- emphasis: double.parse(encoded['emphasis']),
- arrangement: arrangementFromString(encoded['arrangement']),
- dependency: dependencyFromString(encoded['dependency']),
- );
- }
-
- static SurfaceArrangement arrangementFromString(String arrangement) {
- if (arrangement == SurfaceArrangement.copresent.toString()) {
- return SurfaceArrangement.copresent;
- } else if (arrangement == SurfaceArrangement.sequential.toString()) {
- return SurfaceArrangement.sequential;
- } else if (arrangement == SurfaceArrangement.ontop.toString()) {
- return SurfaceArrangement.ontop;
- } else {
- return SurfaceArrangement.none;
- }
- }
-
- static SurfaceDependency dependencyFromString(String dependency) {
- if (dependency == SurfaceDependency.dependent.toString()) {
- return SurfaceDependency.dependent;
- } else {
- return SurfaceDependency.none;
- }
- }
-}
diff --git a/story_shells/mondrian/lib/models/surface/surface_transition.dart b/story_shells/mondrian/lib/models/surface/surface_transition.dart
deleted file mode 100644
index b065cad..0000000
--- a/story_shells/mondrian/lib/models/surface/surface_transition.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Fuchsia 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 'dart:async';
-import 'dart:developer' show Timeline;
-
-import 'package:lib.widgets/model.dart';
-
-const Duration _kPlaceholderDuration = Duration(milliseconds: 2700);
-
-/// A model for handling the transition of placeholders to Surfaces.
-/// This implementation does not do a crossfade as labelling nodes non-shadow
-/// casting with opacity enabled is not yet plumbed, but the transition timer
-/// is in place.
-class SurfaceTransitionModel extends SpringModel {
- // If the Surface has just been added, run the transition to cover
- // the module startup
- SurfaceTransitionModel() {
- Timer(_kPlaceholderDuration, _start);
- }
-
- double get opacity => value;
-
- void _start() {
- Timeline.instantSync('starting placeholder transition');
- target = 1.0; // start ticking
- }
-}
diff --git a/story_shells/mondrian/lib/models/tree/spanning_tree.dart b/story_shells/mondrian/lib/models/tree/spanning_tree.dart
deleted file mode 100644
index 4ab986c..0000000
--- a/story_shells/mondrian/lib/models/tree/spanning_tree.dart
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2018 The Fuchsia 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:fidl_fuchsia_modular/fidl_async.dart';
-import '../surface/surface.dart';
-import '../surface/surface_graph.dart';
-import 'tree.dart';
-
-/// Provides methods for finding spanning trees
-
-// Creates a spanning tree with a given condition
-Tree<Surface> _spanningTree(
- Surface previous, Surface current, bool condition(Surface s)) {
- assert(current != null);
- Tree<Surface> tree = Tree<Surface>(value: current);
- if (current.parent != previous &&
- current.parent != null &&
- condition(current)) {
- tree.add(_spanningTree(current, current.parent, condition));
- }
- for (Surface child in current.children) {
- if (child != previous && condition(child)) {
- tree.add(
- _spanningTree(current, child, condition),
- );
- }
- }
- return tree;
-}
-
-/// Gets the dependent spanning tree the current widget is part of
-Tree<Surface> getDependentSpanningTree(Surface surface) {
- Tree<Surface> root = Tree<Surface>(value: surface);
- while (root.ancestors.isNotEmpty &&
- root.value.relation.dependency == SurfaceDependency.dependent) {
- root = root.ancestors.first;
- }
- return _spanningTree(null, root.value,
- (Surface s) => s.relation.dependency == SurfaceDependency.dependent);
-}
-
-/// Returns the List (forest) of DependentSpanningTrees in the current graph
-List<Tree<Surface>> getDependentSpanningTrees(Surface surface) {
- List<Tree<Surface>> queue = <Tree<Surface>>[];
- Forest<Surface> forest = Forest<Surface>();
-
- Tree<Surface> tree = _spanningTree(null, surface, (Surface s) => true);
-
- queue.add(tree);
- while (queue.isNotEmpty) {
- Tree<Surface> t = queue.removeAt(0);
- List<Tree<Surface>> ends = _endsOfChain(current: t);
- queue.addAll(ends);
- for (Tree<Surface> s in ends) {
- t.find(s.value).detach();
- }
- forest.add(t);
- }
- return forest.roots.toList();
-}
-
-List<Tree<Surface>> _endsOfChain({Tree<Surface> current}) {
- List<Tree<Surface>> ends = <Tree<Surface>>[];
- for (Tree<Surface> s in current.children) {
- if (s.value.relation.dependency != SurfaceDependency.dependent) {
- ends.add(s);
- } else {
- ends.addAll(_endsOfChain(current: s));
- }
- }
- return ends;
-}
-
-/// Spans the full tree of all copresenting surfaces starting with this
-Tree<Surface> getCopresentSpanningTree(Surface surface) {
- return _spanningTree(
- null,
- surface, // default to co-present if no opinion presented
- (Surface s) =>
- s.relation.arrangement == SurfaceArrangement.copresent ||
- s.relation.arrangement == SurfaceArrangement.none);
-}
-
-/// Gets the pattern spanning tree the current widget is part of
-Tree<Surface> patternSpanningTree(
- SurfaceGraph graph, Tree<String> node, String pattern) {
- Tree<Surface> root = Tree<Surface>(value: graph.getNode(node.value));
- while (
- root.ancestors.isNotEmpty && root.value.compositionPattern == pattern) {
- root = root.ancestors.first;
- }
- return _spanningTree(
- null, root.value, (Surface s) => s.compositionPattern == pattern);
-}
-
-/// Gets the spanning tree of Surfaces participating in the Container
-/// identified by containerId
-Tree<Surface> getContainerSpanningTree(
- SurfaceGraph graph, Surface surface, String containerId) {
- Tree<String> containerNode = surface.node.root.find(containerId);
- // log.info('found: $node');
- Tree<Surface> root =
- Tree<Surface>(value: graph.getNode(containerNode.value));
- if (root.value is SurfaceContainer) {
- return _spanningTree(
- null,
- root.value,
- (Surface s) =>
- // TODO: (djmurphy) this will fail nested containers
- s.properties.containerMembership != null &&
- s.properties.containerMembership.contains(containerId),
- );
- } else {
- return root;
- }
-}
diff --git a/story_shells/mondrian/lib/models/tree/tree.dart b/story_shells/mondrian/lib/models/tree/tree.dart
deleted file mode 100644
index c04afc8..0000000
--- a/story_shells/mondrian/lib/models/tree/tree.dart
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2017 The Fuchsia 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 'dart:math';
-
-import 'package:meta/meta.dart';
-
-/// Simple mutable tree data structure
-class Tree<T> extends Iterable<Tree<T>> {
- /// Construct [Tree]
- Tree({@required this.value, Iterable<Tree<T>> children}) {
- children?.forEach(add);
- }
-
- /// The nodes value
- final T value;
-
- /// The longest path of edges to a leaf
- int get height {
- int h = 0;
- for (Tree<T> t in _children) {
- h = max(h, t.height + 1);
- }
- return h;
- }
-
- /// Direct descendents of this
- Iterable<Tree<T>> get children => _children.toList(growable: false);
- final List<Tree<T>> _children = <Tree<T>>[];
-
- /// Direct descendents of parent, except this
- Iterable<Tree<T>> get siblings => (_parent == null)
- ? Iterable<Tree<T>>.empty() // ignore: prefer_const_constructors
- : _parent.children.where((Tree<T> node) => node != this);
-
- /// Direct ancestors of this, starting at parent to root
- Iterable<Tree<T>> get ancestors {
- List<Tree<T>> ancestors = <Tree<T>>[];
- Tree<T> ancestor = this;
- while (ancestor._parent != null) {
- ancestor = ancestor._parent;
- ancestors.add(ancestor);
- }
- return ancestors;
- }
-
- /// Direct ancestor of this
- Tree<T> get parent => _parent;
- Tree<T> _parent;
-
- /// The root of the tree this node is a part of
- Tree<T> get root {
- Tree<T> node = this;
- while (node._parent != null) {
- node = node._parent;
- }
- return node;
- }
-
- @override
- Iterator<Tree<T>> get iterator {
- return flatten().iterator;
- }
-
- /// Breadth first flattening of tree
- Iterable<Tree<T>> flatten({
- int orderChildren(Tree<T> l, Tree<T> r),
- }) {
- List<Tree<T>> nodes = <Tree<T>>[this];
- for (int i = 0; i < nodes.length; i++) {
- Tree<T> node = nodes[i];
- if (orderChildren == null) {
- nodes.addAll(node._children);
- } else {
- nodes.addAll(node._children.toList()..sort(orderChildren));
- }
- }
- return nodes;
- }
-
- /// Detach this tree from its parents tree
- void detach() {
- if (parent != null) {
- _parent._children.remove(this);
- _parent = null;
- }
- }
-
- /// Add a child to this tree
- void add(Tree<T> child) {
- assert(child != null);
- _children.add(child);
- child._parent = this;
- }
-
- /// Find the single Tree node with the following value
- ///
- /// Note: Search order not specified (so make sure values are unique)
- Tree<T> find(T value) =>
- firstWhere((Tree<T> node) => node.value == value, orElse: () => null);
-
- /// Generate a new tree with the same structure with transformed values
- Tree<V> mapTree<V>(V f(T value)) => Tree<V>(
- value: f(value),
- children: _children.map((Tree<T> n) => n.mapTree(f)),
- );
-
- /// Reduces a tree to some other object using passed in function.
- V reduceTree<V>(V f(T value, Iterable<V> children)) =>
- f(value, children.map((Tree<T> child) => child.reduceTree(f)));
-
- /// Get a flattened iterable of all of the values in the tree
- Iterable<T> get values => flatten().map((Tree<T> t) => t.value);
-
- @override
- String toString() => 'Tree($values)';
-}
-
-/// A collection of trees
-class Forest<T> extends Iterable<Tree<T>> {
- /// Construct [Forest]
- Forest({Iterable<Tree<T>> roots}) {
- roots?.forEach(add);
- }
-
- /// Root nodes of this forest
- Iterable<Tree<T>> get roots => _roots.toList(growable: false);
- final List<Tree<T>> _roots = <Tree<T>>[];
-
- /// The longest path of edges to a leaf
- int get height => _roots.isEmpty
- ? 0
- : _roots.fold(0, (int h, Tree<T> t) => max(h, t.height));
-
- /// Add a root node to this forest
- void add(Tree<T> node) {
- assert(node != null);
- node.detach();
- _roots.add(node);
- }
-
- /// Removes the node from the tree, and reparents children.
- ///
- /// Reparents its children to the nodes parent or as root nodes.
- void remove(Tree<T> node) {
- assert(node != null);
- if (contains(node)) {
- Tree<T> parent = node.parent;
- if (parent == null) {
- node.children.forEach(add);
- _roots.remove(node);
- } else {
- node.detach();
- node.children.forEach(parent.add);
- }
- }
- }
-
- @override
- Iterator<Tree<T>> get iterator {
- return flatten().iterator;
- }
-
- /// Breadth first flattening of tree
- Iterable<Tree<T>> flatten({
- int orderChildren(Tree<T> l, Tree<T> r),
- }) {
- List<Tree<T>> roots = _roots.toList();
- if (orderChildren != null) {
- roots.sort(orderChildren);
- }
- List<Tree<T>> nodes = <Tree<T>>[];
- for (Tree<T> node in roots) {
- nodes.addAll(node.flatten(orderChildren: orderChildren));
- }
- return nodes;
- }
-
- /// Find the single Tree node with the following value
- ///
- /// Note: Search order not specified (so make sure values are unique)
- Tree<T> find(T value) =>
- firstWhere((Tree<T> node) => node.value == value, orElse: () => null);
-
- /// Generate a new forest with the same structure with transformed values
- Forest<V> mapForest<V>(V f(T value)) => Forest<V>(
- roots: _roots.map((Tree<T> n) => n.mapTree(f)),
- );
-
- /// Reduces a Forest to a list of objects.
- Iterable<V> reduceForest<V>(V f(T value, Iterable<V> children)) =>
- roots.map((Tree<T> t) => t.reduceTree(f));
-
- /// Get a flattened iterable of all of the values in the forest
- Iterable<T> get values => flatten().map((Tree<T> t) => t.value);
-
- @override
- String toString() => 'Forest($roots)';
-}
diff --git a/story_shells/mondrian/lib/story_shell_impl.dart b/story_shells/mondrian/lib/story_shell_impl.dart
deleted file mode 100644
index 3f09cc4..0000000
--- a/story_shells/mondrian/lib/story_shell_impl.dart
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2017 The Fuchsia 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 'dart:async';
-import 'dart:developer' show Timeline;
-
-import 'package:fidl/fidl.dart';
-import 'package:fidl_fuchsia_modular/fidl_async.dart';
-import 'package:fidl_fuchsia_ui_views/fidl_async.dart' show ViewHolderToken;
-import 'package:fuchsia_logger/logger.dart';
-import 'package:fuchsia_modular/lifecycle.dart' as lifecycle;
-import 'package:fuchsia_services/services.dart';
-import 'package:lib.story_shell/common.dart';
-
-import 'models/surface/surface_graph.dart';
-import 'models/surface/surface_properties.dart';
-import 'visual_state_watcher.dart';
-
-/// An implementation of the [StoryShell] interface.
-class StoryShellImpl extends StoryShell {
- final StoryShellBinding _storyShellBinding = StoryShellBinding();
- final StoryShellContextProxy _storyShellContext = StoryShellContextProxy();
- final KeyListener keyListener;
- final StoryVisualStateWatcherBinding _visualStateWatcherBinding =
- StoryVisualStateWatcherBinding();
- final SurfaceGraph surfaceGraph;
- final StreamController<String> _focusEventStreamController =
- StreamController.broadcast();
- String _lastFocusedSurfaceId;
- lifecycle.Lifecycle _lifecycle;
- VisualStateWatcher _storyVisualStateWatcher;
-
- StoryShellImpl({this.surfaceGraph, this.keyListener});
-
- /// StoryShell
- @override
- Future<void> initialize(
- InterfaceHandle<StoryShellContext> contextHandle) async {
- _storyVisualStateWatcher = VisualStateWatcher(
- keyListener: keyListener, storyShellContext: _storyShellContext);
- _storyShellContext.ctrl.bind(contextHandle);
- await _storyShellContext.watchVisualState(
- _visualStateWatcherBinding.wrap(_storyVisualStateWatcher));
- surfaceGraph.addListener(() {
- String surfaceId = surfaceGraph.focused?.node?.value;
- if (surfaceId != null && surfaceId != _lastFocusedSurfaceId) {
- _focusEventStreamController.add(surfaceId);
- _lastFocusedSurfaceId = surfaceId;
- }
- });
- }
-
- /// Bind an [InterfaceRequest] for a [StoryShell] interface to this object.
- void bindStoryShell(InterfaceRequest<StoryShell> request) {
- _storyShellBinding.bind(this, request);
- }
-
- /// Introduce a new Surface and corresponding [ViewHolderToken] to this Story.
- ///
- /// The Surface may have a relationship with its parent surface.
- @override
- Future<void> addSurface(
- ViewConnection viewConnection,
- SurfaceInfo surfaceInfo,
- ) async {
- Timeline.instantSync(
- 'connecting surface ${viewConnection.surfaceId} with parent ${surfaceInfo.parentId}');
- log.fine(
- 'Connecting surface ${viewConnection.surfaceId} with parent ${surfaceInfo.parentId}');
-
- /// ignore: cascade_invocations
- log.fine('Were passed manifest: $surfaceInfo.moduleManifest');
- surfaceGraph
- ..addSurface(
- viewConnection.surfaceId,
- SurfaceProperties(source: surfaceInfo.moduleSource),
- surfaceInfo.parentId,
- surfaceInfo.surfaceRelation ?? const SurfaceRelation(),
- surfaceInfo.moduleManifest != null
- ? surfaceInfo.moduleManifest.compositionPattern
- : '',
- surfaceInfo.moduleManifest != null
- ? surfaceInfo.moduleManifest.placeholderColor
- : '',
- )
- ..connectView(viewConnection.surfaceId, viewConnection.viewHolderToken);
- }
-
- /// DEPRECATED: For transition purposes only.
- @override
- Future<void> addSurface2(
- ViewConnection2 viewConnection,
- SurfaceInfo surfaceInfo,
- ) async {
- return addSurface(
- ViewConnection(
- surfaceId: viewConnection.surfaceId,
- viewHolderToken: viewConnection.viewHolderToken),
- surfaceInfo);
- }
-
- /// Focus the surface with this id
- @override
- Future<void> focusSurface(String surfaceId) async {
- Timeline.instantSync('focusing view',
- arguments: {'surfaceId': '$surfaceId'});
- surfaceGraph.focusSurface(surfaceId);
- }
-
- /// Defocus the surface with this id
- @override
- Future<void> defocusSurface(String surfaceId) async {
- Timeline.instantSync('defocusing view',
- arguments: {'surfaceId': '$surfaceId'});
- surfaceGraph.dismissSurface(surfaceId);
- }
-
- @override
- Future<void> removeSurface(String surfaceId) async {
- return surfaceGraph.removeSurface(surfaceId);
- }
-
- @override
- Future<void> updateSurface(
- ViewConnection viewConnection,
- SurfaceInfo surfaceInfo,
- ) async {
- // TODO (jphsiao): implement
- }
-
- @override
- Stream<String> get onSurfaceFocused => _focusEventStreamController.stream;
-
- /// Start advertising the StoryShell service, and bind lifecycle to
- /// termination
- void advertise() {
- StartupContext.fromStartupInfo().outgoing.addPublicService(
- (InterfaceRequest<StoryShell> request) {
- Timeline.instantSync('story shell request');
- log.fine('Received binding request for StoryShell');
- bindStoryShell(request);
- },
- StoryShell.$serviceName,
- );
- _lifecycle ??= lifecycle.Lifecycle();
- }
-}
diff --git a/story_shells/mondrian/lib/visual_state_watcher.dart b/story_shells/mondrian/lib/visual_state_watcher.dart
deleted file mode 100644
index 1eaf764..0000000
--- a/story_shells/mondrian/lib/visual_state_watcher.dart
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2019 The Fuchsia 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:fidl_fuchsia_modular/fidl_async.dart'
- show StoryVisualStateWatcher, StoryVisualState, StoryShellContext;
-import 'package:fidl_fuchsia_ui_policy/fidl_async.dart';
-import 'package:lib.story_shell/common.dart';
-import 'package:lib.widgets/utils.dart';
-
-class VisualStateWatcher extends StoryVisualStateWatcher {
- StoryVisualState _visualState;
- final PointerEventsListener pointerEventsListener = PointerEventsListener();
- final KeyListener keyListener;
- final StoryShellContext storyShellContext;
-
- VisualStateWatcher({
- this.keyListener,
- this.storyShellContext,
- });
-
- @override
- Future<void> onVisualStateChange(StoryVisualState visualState) async {
- if (_visualState == visualState) {
- return;
- }
- _visualState = visualState;
-
- pointerEventsListener.stop();
- if (visualState == StoryVisualState.maximized) {
- PresentationProxy presentationProxy = PresentationProxy();
- await storyShellContext.getPresentation(presentationProxy.ctrl.request());
- pointerEventsListener.listen(presentationProxy);
- keyListener?.listen(presentationProxy);
- presentationProxy.ctrl.close();
- } else {
- pointerEventsListener.stop();
- keyListener?.stop();
- }
- }
-}
diff --git a/story_shells/mondrian/lib/widgets/breathing_placeholder.dart b/story_shells/mondrian/lib/widgets/breathing_placeholder.dart
deleted file mode 100644
index 20725da..0000000
--- a/story_shells/mondrian/lib/widgets/breathing_placeholder.dart
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2018 The Fuchsia 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 'dart:async';
-import 'package:flutter/widgets.dart';
-import 'package:flutter/material.dart' show Colors;
-
-/// A widget that 'breaths' from grey to white, to use as a placeholder
-/// for incoming Surfaces. The transition begins with a pause for _kPausePeriod,
-/// then a forward curve for _kBreathPeriod, then a pause, then a reverse curve
-/// modulating opacity _kTopColor between _kLowerBound and _kUpperBound -
-/// the effect is the basecolor bleeds through in a breathing motion.
-const Color _kBaseColor = Colors.white;
-final Color _kTopColor = Colors.grey[200];
-const _kBreathPeriod = 300; //ms
-const _kPausePeriod = 400; //ms
-const double _kLowerBound = 0.2;
-const double _kUpperBound = 0.8;
-
-class BreathingPlaceholder extends StatefulWidget {
- @override
- BreathingState createState() => BreathingState();
-}
-
-class BreathingState extends State<BreathingPlaceholder>
- with TickerProviderStateMixin {
- AnimationController _opacityController;
- Animation _opacity;
- Timer _timer;
- bool _forward = false;
-
- @override
- void initState() {
- super.initState();
- pause();
- _opacityController = AnimationController(
- vsync: this,
- duration: Duration(milliseconds: _kBreathPeriod),
- lowerBound: _kLowerBound,
- upperBound: _kUpperBound,
- );
- _opacity = CurvedAnimation(
- parent: _opacityController,
- curve: Curves.easeIn,
- )..addStatusListener(
- (AnimationStatus status) {
- if (status == AnimationStatus.completed) {
- pause();
- }
- },
- );
- }
-
- void pause() {
- _timer = Timer(Duration(milliseconds: _kPausePeriod), animate);
- }
-
- void animate() {
- if (_forward) {
- // check for null in case timer happens to callback after dispose()
- _opacityController?.reverse();
- _forward = false;
- } else {
- _opacityController?.forward();
- _forward = true;
- }
- }
-
- @override
- void dispose() {
- super.dispose();
- _opacityController.dispose();
- }
-
- @override
- void deactivate() {
- super.deactivate();
- _timer.cancel();
- _opacityController.stop();
- }
-
- @override
- Widget build(BuildContext context) {
- return Stack(
- children: <Widget>[
- Container(
- color: _kBaseColor,
- ),
- FadeTransition(
- child: Container(
- color: _kTopColor,
- ),
- opacity: _opacity,
- ),
- ],
- );
- }
-}
diff --git a/story_shells/mondrian/lib/widgets/gestures.dart b/story_shells/mondrian/lib/widgets/gestures.dart
deleted file mode 100644
index b704bcd..0000000
--- a/story_shells/mondrian/lib/widgets/gestures.dart
+++ /dev/null
@@ -1,321 +0,0 @@
-// Copyright 2018 The Fuchsia 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:flutter/gestures.dart' as gestures;
-import 'package:flutter/widgets.dart';
-
-enum _DragState {
- ready,
- possible,
- accepted,
-}
-
-enum Direction {
- left,
- right,
-}
-
-const double _kTouchSlop = 4.0;
-
-class UnidirectionalHorizontalDragGestureRecognizer
- extends DragGestureRecognizer {
- Direction direction;
-
- /// Create a gesture recognizer for interactions in the horizontal axis.
- UnidirectionalHorizontalDragGestureRecognizer(
- {Object debugOwner, this.direction})
- : super(debugOwner: debugOwner);
-
- @override
- bool _isFlingGesture(gestures.VelocityEstimate estimate) {
- final double minVelocity = minFlingVelocity ?? gestures.kMinFlingVelocity;
- final double minDistance = minFlingDistance ?? _kTouchSlop;
- return ((direction == Direction.left ? -1.0 : 1.0) *
- estimate.pixelsPerSecond.dx) >
- minVelocity &&
- ((direction == Direction.left ? -1.0 : 1.0) * estimate.offset.dx) >
- minDistance;
- }
-
- @override
- bool get _hasSufficientPendingDragDeltaToAccept {
- return ((direction == Direction.left ? -1.0 : 1.0) *
- _pendingDragOffset.dx) >
- _kTouchSlop;
- }
-
- @override
- Offset _getDeltaForDetails(Offset delta) => Offset(delta.dx, delta.dy);
-
- @override
- double _getPrimaryValueFromOffset(Offset value) => value.dx;
-
- @override
- String get debugDescription => 'uni directional horizontal drag';
-}
-
-abstract class DragGestureRecognizer
- extends gestures.OneSequenceGestureRecognizer {
- /// Initialize the object.
- DragGestureRecognizer({Object debugOwner}) : super(debugOwner: debugOwner);
-
- /// A pointer has contacted the screen and has begun to move.
- ///
- /// The position of the pointer is provided in the callback's `details`
- /// argument, which is a [DragStartDetails] object.
- GestureDragStartCallback onStart;
-
- /// A pointer that is in contact with the screen and moving has moved again.
- ///
- /// The distance travelled by the pointer since the last update is provided in
- /// the callback's `details` argument, which is a [DragUpdateDetails] object.
- GestureDragUpdateCallback onUpdate;
-
- /// A pointer that was previously in contact with the screen and moving is no
- /// longer in contact with the screen and was moving at a specific velocity
- /// when it stopped contacting the screen.
- ///
- /// The velocity is provided in the callback's `details` argument, which is a
- /// [DragEndDetails] object.
- GestureDragEndCallback onEnd;
-
- /// The minimum distance an input pointer drag must have moved to
- /// to be considered a fling gesture.
- ///
- /// This value is typically compared with the distance traveled along the
- /// scrolling axis. If null then [gestures.kTouchSlop] is used.
- double minFlingDistance;
-
- /// The minimum velocity for an input pointer drag to be considered fling.
- ///
- /// This value is typically compared with the magnitude of fling gesture's
- /// velocity along the scrolling axis. If null then [gestures.kMinFlingVelocity]
- /// is used.
- double minFlingVelocity;
-
- /// Fling velocity magnitudes will be clamped to this value.
- ///
- /// If null then [gestures.kMaxFlingVelocity] is used.
- double maxFlingVelocity;
-
- _DragState _state = _DragState.ready;
- Offset _initialPosition;
- Offset _pendingDragOffset;
- Duration _lastPendingEventTimestamp;
-
- bool _isFlingGesture(gestures.VelocityEstimate estimate);
- Offset _getDeltaForDetails(Offset delta);
- double _getPrimaryValueFromOffset(Offset value);
- bool get _hasSufficientPendingDragDeltaToAccept;
-
- final Map<int, gestures.VelocityTracker> _velocityTrackers =
- <int, gestures.VelocityTracker>{};
-
- @override
- void addPointer(PointerEvent event) {
- startTrackingPointer(event.pointer);
- _velocityTrackers[event.pointer] = gestures.VelocityTracker();
- if (_state == _DragState.ready) {
- _state = _DragState.possible;
- _initialPosition = event.position;
- _pendingDragOffset = Offset.zero;
- _lastPendingEventTimestamp = event.timeStamp;
- } else if (_state == _DragState.accepted) {
- resolve(gestures.GestureDisposition.accepted);
- }
- }
-
- @override
- void handleEvent(PointerEvent event) {
- assert(_state != _DragState.ready);
- if (!event.synthesized &&
- (event is PointerDownEvent || event is PointerMoveEvent)) {
- final gestures.VelocityTracker tracker = _velocityTrackers[event.pointer];
- assert(tracker != null);
- tracker.addPosition(event.timeStamp, event.position);
- }
-
- if (event is PointerMoveEvent) {
- final Offset delta = event.delta;
- if (_state == _DragState.accepted) {
- if (onUpdate != null) {
- invokeCallback<void>(
- 'onUpdate',
- () => onUpdate(
- DragUpdateDetails(
- sourceTimeStamp: event.timeStamp,
- delta: _getDeltaForDetails(delta),
- primaryDelta: null,
- globalPosition: event.position,
- ),
- ),
- );
- }
- } else {
- _pendingDragOffset += delta;
- _lastPendingEventTimestamp = event.timeStamp;
- if (_hasSufficientPendingDragDeltaToAccept) {
- resolve(gestures.GestureDisposition.accepted);
- }
- }
- }
- stopTrackingIfPointerNoLongerDown(event);
- }
-
- @override
- void acceptGesture(int pointer) {
- if (_state != _DragState.accepted) {
- _state = _DragState.accepted;
- final Duration timestamp = _lastPendingEventTimestamp;
- _pendingDragOffset = Offset.zero;
- _lastPendingEventTimestamp = null;
- if (onStart != null) {
- invokeCallback<void>(
- 'onStart',
- () => onStart(
- DragStartDetails(
- sourceTimeStamp: timestamp,
- globalPosition: _initialPosition,
- ),
- ),
- );
- }
- }
- }
-
- @override
- void rejectGesture(int pointer) {
- stopTrackingPointer(pointer);
- }
-
- @override
- void didStopTrackingLastPointer(int pointer) {
- if (_state == _DragState.possible) {
- resolve(gestures.GestureDisposition.rejected);
- _state = _DragState.ready;
- return;
- }
- final bool wasAccepted = _state == _DragState.accepted;
- _state = _DragState.ready;
- if (wasAccepted && onEnd != null) {
- final gestures.VelocityTracker tracker = _velocityTrackers[pointer];
- assert(tracker != null);
-
- final gestures.VelocityEstimate estimate = tracker.getVelocityEstimate();
- if (estimate != null && _isFlingGesture(estimate)) {
- final Velocity velocity =
- Velocity(pixelsPerSecond: estimate.pixelsPerSecond)
- .clampMagnitude(minFlingVelocity ?? gestures.kMinFlingVelocity,
- maxFlingVelocity ?? gestures.kMaxFlingVelocity);
- invokeCallback<void>(
- 'onEnd',
- () => onEnd(DragEndDetails(
- velocity: velocity,
- primaryVelocity:
- _getPrimaryValueFromOffset(velocity.pixelsPerSecond),
- )), debugReport: () {
- return '$estimate; fling at $velocity.';
- });
- } else {
- invokeCallback<void>(
- 'onEnd',
- () => onEnd(DragEndDetails(
- velocity: Velocity.zero,
- primaryVelocity: 0.0,
- )), debugReport: () {
- if (estimate == null) {
- return 'Could not estimate velocity.';
- }
- return '$estimate; judged to not be a fling.';
- });
- }
- }
- _velocityTrackers.clear();
- }
-
- @override
- void dispose() {
- _velocityTrackers.clear();
- super.dispose();
- }
-}
-
-class UnidirectionalHorizontalGestureDetector extends StatelessWidget {
- const UnidirectionalHorizontalGestureDetector({
- Key key,
- this.child,
- this.direction,
- this.onHorizontalDragStart,
- this.onHorizontalDragUpdate,
- this.onHorizontalDragEnd,
- this.behavior,
- this.excludeFromSemantics = false,
- }) : assert(excludeFromSemantics != null),
- super(key: key);
-
- final Direction direction;
-
- /// The widget below this widget in the tree.
- ///
- /// {@macro flutter.widgets.child}
- final Widget child;
-
- /// A pointer has contacted the screen and has begun to move horizontally.
- final GestureDragStartCallback onHorizontalDragStart;
-
- /// A pointer that is in contact with the screen and moving horizontally has
- /// moved in the horizontal direction.
- final GestureDragUpdateCallback onHorizontalDragUpdate;
-
- /// A pointer that was previously in contact with the screen and moving
- /// horizontally is no longer in contact with the screen and was moving at a
- /// specific velocity when it stopped contacting the screen.
- final GestureDragEndCallback onHorizontalDragEnd;
-
- /// How this gesture detector should behave during hit testing.
- ///
- /// This defaults to [HitTestBehavior.deferToChild] if [child] is not null and
- /// [HitTestBehavior.translucent] if child is null.
- final HitTestBehavior behavior;
-
- /// Whether to exclude these gestures from the semantics tree. For
- /// example, the long-press gesture for showing a tooltip is
- /// excluded because the tooltip itself is included in the semantics
- /// tree directly and so having a gesture to show it would result in
- /// duplication of information.
- final bool excludeFromSemantics;
-
- @override
- Widget build(BuildContext context) {
- final Map<Type, GestureRecognizerFactory> gestures =
- <Type, GestureRecognizerFactory>{};
-
- if (onHorizontalDragStart != null ||
- onHorizontalDragUpdate != null ||
- onHorizontalDragEnd != null) {
- gestures[UnidirectionalHorizontalDragGestureRecognizer] =
- GestureRecognizerFactoryWithHandlers<
- UnidirectionalHorizontalDragGestureRecognizer>(
- () => UnidirectionalHorizontalDragGestureRecognizer(
- direction: direction,
- debugOwner: this,
- ),
- (UnidirectionalHorizontalDragGestureRecognizer instance) {
- instance
- ..direction = direction
- ..onStart = onHorizontalDragStart
- ..onUpdate = onHorizontalDragUpdate
- ..onEnd = onHorizontalDragEnd;
- },
- );
- }
-
- return RawGestureDetector(
- gestures: gestures,
- behavior: behavior,
- excludeFromSemantics: excludeFromSemantics,
- child: child,
- );
- }
-}
diff --git a/story_shells/mondrian/lib/widgets/isometric_widget.dart b/story_shells/mondrian/lib/widgets/isometric_widget.dart
deleted file mode 100644
index 7ce75cd..0000000
--- a/story_shells/mondrian/lib/widgets/isometric_widget.dart
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2017 The Fuchsia 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 'dart:math';
-
-import 'package:flutter/widgets.dart';
-import 'package:meta/meta.dart';
-
-/// 60-30 isometric projection matrix
-final Matrix4 _iso = Matrix4.identity()
- ..rotateX(60 * pi / 180.0)
- ..rotateZ(30 * pi / 180.0);
-
-/// Widget that performs an isometric transformation on a Widget,
-/// scaling it so that it fits within the bounds of its original rectangle
-class IsoMetric extends StatelessWidget {
- /// The child to transform
- final Widget child;
-
- /// This size to draw the widget in orthographic projection
- final double scaleFactor;
-
- /// Constructor
- const IsoMetric({@required this.child, this.scaleFactor = 4.0});
-
- @override
- Widget build(BuildContext context) => LayoutBuilder(
- builder: (BuildContext context, BoxConstraints constraints) {
- BoxConstraints _scaledConstraints = constraints * scaleFactor;
- return FittedBox(
- fit: BoxFit.scaleDown,
- child: Container(
- constraints: _scaledConstraints,
- child: Transform(
- child: child,
- transform: _getTransformation(constraints: _scaledConstraints),
- origin: _scaledConstraints.biggest.center(Offset.zero),
- ),
- ),
- );
- },
- );
-
- /// Get the isometric transformation to apply to the views
- Matrix4 _getTransformation({BoxConstraints constraints}) {
- // Scale the transformation so the views fit in the original rectangles
- Rect constraintsRect = Offset.zero & constraints.biggest;
- Rect transRect = MatrixUtils.transformRect(
- _iso,
- constraintsRect,
- );
- double isoScale = min(constraintsRect.height / transRect.height,
- constraintsRect.width / transRect.width);
- return Matrix4.copy(_iso)..scale(isoScale);
- }
-}
diff --git a/story_shells/mondrian/lib/widgets/mondrian.dart b/story_shells/mondrian/lib/widgets/mondrian.dart
deleted file mode 100644
index 749d95e..0000000
--- a/story_shells/mondrian/lib/widgets/mondrian.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2017 The Fuchsia 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 'dart:developer' show Timeline;
-import 'dart:ui' show window;
-
-import 'package:flutter/material.dart';
-import 'package:flutter/scheduler.dart';
-import 'package:flutter/widgets.dart';
-
-import '../story_shell_impl.dart';
-import 'surface_director.dart';
-
-/// This is used for keeping the reference around.
-// ignore: unused_element
-StoryShellImpl _storyShellImpl;
-
-/// High level class for choosing between presentations
-class Mondrian extends StatefulWidget {
- /// Constructor
- const Mondrian({Key key}) : super(key: key);
-
- @override
- MondrianState createState() => MondrianState();
-}
-
-/// State
-class MondrianState extends State<Mondrian> {
- @override
- Widget build(BuildContext context) {
- _traceFrame();
- return SurfaceDirector();
- }
-}
-
-int _frameCounter = 1;
-void _traceFrame() {
- Size size = window.physicalSize / window.devicePixelRatio;
- Timeline.instantSync('building, size: $size');
- SchedulerBinding.instance.addPostFrameCallback(_frameCallback);
-}
-
-void _frameCallback(Duration duration) {
- Size size = window.physicalSize / window.devicePixelRatio;
- Timeline.instantSync('frame $_frameCounter, size: $size');
- _frameCounter++;
- if (size.isEmpty) {
- SchedulerBinding.instance.addPostFrameCallback(_frameCallback);
- }
-}
diff --git a/story_shells/mondrian/lib/widgets/mondrian_child_view.dart b/story_shells/mondrian/lib/widgets/mondrian_child_view.dart
deleted file mode 100644
index c031c1a..0000000
--- a/story_shells/mondrian/lib/widgets/mondrian_child_view.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2017 The Fuchsia 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:flutter/material.dart';
-import 'package:flutter/widgets.dart';
-import 'package:fuchsia_scenic_flutter/child_view.dart' show ChildView;
-import 'package:fuchsia_logger/logger.dart';
-import '../models/surface/surface.dart';
-
-import 'breathing_placeholder.dart';
-
-/// Frame for child views
-class MondrianChildView extends StatelessWidget {
- /// Constructor
- const MondrianChildView({this.surface, this.interactable = true});
-
- /// If true then ChildView hit tests will go through
- final bool interactable;
-
- final Surface surface;
-
- @override
- Widget build(BuildContext context) => AnimatedBuilder(
- animation: surface,
- builder: (BuildContext context, Widget child) =>
- surface.transitionModel.opacity != 1.0
- ? Stack(
- children: <Widget>[
- ChildView(
- connection: surface.connection,
- hitTestable: interactable,
- ),
- BreathingPlaceholder()
- ],
- )
- : ChildView(
- connection: surface.connection,
- hitTestable: interactable,
- ),
- );
-
-// Convert from HTML color code format to 0xAARRGGBB.
-// Placeholder colors are specified as and checked for conformance as HTML to
-// HTML color codes format (see: peridot/build/module_manifest_schema.json)
-//
-// Defaults to white in cases where no hexColorString or an invalid
-// hexColorString are presented.
- Color getColor(String hexColorString) {
- Color placeholderColor = Colors.white;
- if (hexColorString != null && hexColorString.isNotEmpty) {
- try {
- String parseString = hexColorString.replaceAll('#', '');
- int colorInt = int.parse(parseString, radix: 16);
- placeholderColor = Color(colorInt).withOpacity(1.0);
- } on FormatException {
- log.fine('hexColorString conversion error for string $hexColorString');
- }
- }
- return placeholderColor;
- }
-}
diff --git a/story_shells/mondrian/lib/widgets/mondrian_logo.dart b/story_shells/mondrian/lib/widgets/mondrian_logo.dart
deleted file mode 100644
index 02a76cd..0000000
--- a/story_shells/mondrian/lib/widgets/mondrian_logo.dart
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2017 The Fuchsia 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:flutter/material.dart';
-import 'package:flutter/widgets.dart';
-
-/// Logo Yellow
-const Color yellow = Color(0xFFFFFD3B);
-
-/// Logo Red
-const Color red = Color(0xFFFC5D60);
-
-/// Logo Blue
-const Color blue = Color(0xFF4D8AE9);
-
-/// Logo Border
-const Color borderColor = Color(0xFF353535);
-
-/// Programmatic implementation of Static Mondrian Logo
-class MondrianLogo extends StatelessWidget {
- /// A Programmatic Mondrian Logo
- const MondrianLogo();
-
- @override
- Widget build(BuildContext context) {
- return LayoutBuilder(
- builder: (BuildContext layoutContext, BoxConstraints constraints) {
- double fontPoint = constraints.maxHeight / 2.3;
- double borderWidth = constraints.maxWidth / 37.5;
- double borderRadius = constraints.maxWidth * 0.0625;
- return Material(
- child: Container(
- child: Row(
- children: <Widget>[
- Flexible(
- flex: 1,
- child: Container(
- decoration: BoxDecoration(
- color: blue,
- border: Border(
- right: BorderSide(
- color: borderColor, width: borderWidth),
- ),
- ),
- ),
- ),
- Flexible(
- flex: 1,
- child: Column(
- children: <Widget>[
- Flexible(
- flex: 1,
- child: Container(
- decoration: BoxDecoration(
- color: red,
- border: Border(
- bottom: BorderSide(
- color: borderColor, width: borderWidth),
- ),
- ),
- ),
- ),
- Flexible(
- flex: 1,
- child: Container(
- child: Center(
- child: Text(
- 'M',
- style: TextStyle(
- fontFamily: 'Kanit', // ToDo - djmurphy
- fontStyle: FontStyle.normal,
- fontSize: fontPoint),
- ),
- ),
- decoration: BoxDecoration(color: yellow),
- ),
- )
- ],
- ),
- ),
- ],
- ),
- foregroundDecoration: BoxDecoration(
- borderRadius: BorderRadius.all(
- Radius.circular(borderRadius),
- ),
- border: Border.all(width: borderWidth, color: borderColor),
- ),
- ),
- borderRadius: BorderRadius.all(
- Radius.circular(borderRadius),
- ),
- );
- },
- );
- }
-}
diff --git a/story_shells/mondrian/lib/widgets/overview.dart b/story_shells/mondrian/lib/widgets/overview.dart
deleted file mode 100644
index 391353e..0000000
--- a/story_shells/mondrian/lib/widgets/overview.dart
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2017 The Fuchsia 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 'dart:math' as math;
-
-import 'package:fidl_fuchsia_modular/fidl_async.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
-import 'package:fuchsia_scenic_flutter/child_view.dart' show ChildView;
-import 'package:fuchsia_logger/logger.dart';
-import 'package:lib.widgets/model.dart';
-
-import '../models/surface/surface.dart';
-import '../models/surface/surface_graph.dart';
-import 'isometric_widget.dart';
-
-/// Printable names for relation arrangement
-const Map<SurfaceArrangement, String> relName =
- <SurfaceArrangement, String>{
- SurfaceArrangement.none: 'no opinion',
- SurfaceArrangement.copresent: 'co-present',
-};
-
-/// Printable names for relation dependency
-const Map<SurfaceDependency, String> depName =
- <SurfaceDependency, String>{
- SurfaceDependency.dependent: 'dependent',
- SurfaceDependency.none: 'independent',
-};
-
-/// Show overview of all currently active surfaces in a story
-/// and their relationships
-class Overview extends StatelessWidget {
- /// Constructor
- const Overview({Key key}) : super(key: key);
-
- /// Build the ListView of Surface views in SurfaceGraph
- Widget buildGraphList(BoxConstraints constraints, SurfaceGraph graph) {
- return ListView.builder(
- itemCount: graph.focusStack.toList().length,
- scrollDirection: Axis.vertical,
- itemExtent: constraints.maxHeight / 3.5,
- itemBuilder: (BuildContext context, int index) {
- Surface s = graph.focusStack.toList().reversed.elementAt(index);
- String arrangement = relName[s.relation.arrangement] ?? 'unknown';
- String dependency = depName[s.relation.dependency] ?? 'unknown';
- return Row(
- children: <Widget>[
- Flexible(
- flex: 1,
- child: Center(
- child: index < graph.focusStack.length - 1
- ? Text('Presentation: $arrangement'
- '\nDependency: $dependency'
- '\nEmphasis: ${s.relation.emphasis}')
- : null,
- ),
- ),
- Flexible(
- flex: 2,
- child: Container(
- child: Center(
- child: IsoMetric(
- child: ChildView(
- connection: s.connection, hitTestable: false),
- ),
- ),
- ),
- ),
- ],
- );
- },
- );
- }
-
- @override
- Widget build(BuildContext context) => LayoutBuilder(
- builder: (BuildContext context, BoxConstraints constraints) {
- return Container(
- alignment: FractionalOffset.center,
- width: math.min(constraints.maxWidth, constraints.maxHeight),
- height: constraints.maxHeight,
- padding: EdgeInsets.symmetric(horizontal: 44.0),
- child: Scrollbar(
- child: ScopedModelDescendant<SurfaceGraph>(
- builder:
- (BuildContext context, Widget child, SurfaceGraph graph) {
- if (graph.focusStack.isEmpty) {
- log.warning('focusedSurfaceHistory is empty');
- return Container();
- }
- return buildGraphList(constraints, graph);
- },
- ),
- ),
- );
- },
- );
-}
diff --git a/story_shells/mondrian/lib/widgets/surface_director.dart b/story_shells/mondrian/lib/widgets/surface_director.dart
deleted file mode 100644
index 798937c..0000000
--- a/story_shells/mondrian/lib/widgets/surface_director.dart
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright 2017 The Fuchsia 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 'dart:math' as math;
-
-import 'package:fidl_fuchsia_modular/fidl_async.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/widgets.dart';
-import 'package:lib.widgets/model.dart';
-
-import '../layout/copresent_layout.dart' as copresent;
-import '../layout/pattern_layout.dart' as pattern;
-import '../models/depth_model.dart';
-import '../models/inset_manager.dart';
-import '../models/layout_model.dart';
-import '../models/surface/positioned_surface.dart';
-import '../models/surface/surface.dart';
-import '../models/surface/surface_form.dart';
-import '../models/surface/surface_graph.dart';
-import '../models/tree/spanning_tree.dart';
-import '../models/tree/tree.dart';
-import 'mondrian_child_view.dart';
-
-import 'surface_stage.dart';
-
-/// Directs the layout of the SurfaceSpace
-class SurfaceDirector extends StatefulWidget {
- @override
- _SurfaceDirectorState createState() => _SurfaceDirectorState();
-}
-
-class _SurfaceDirectorState extends State<SurfaceDirector> {
- final Map<Surface, SurfaceForm> _prevForms = <Surface, SurfaceForm>{};
- final List<SurfaceForm> _orphanedForms = <SurfaceForm>[];
-
- SurfaceForm _form(
- PositionedSurface ps,
- double depth,
- FractionalOffset offscreen,
- ) {
- return SurfaceForm.single(
- key: GlobalObjectKey(ps.surface.node),
- child: MondrianChildView(
- surface: ps.surface,
- interactable: depth <= 0.0,
- ),
- position: ps.position,
- initPosition: ps.position.shift(Offset(offscreen.dx, offscreen.dy)),
- depth: depth,
- friction: depth > 0.0
- ? kDragFrictionInfinite
- : ps.surface.canDismiss()
- ? (Offset offset, Offset delta) =>
- Offset(delta.dx * 0.6, delta.dy * 0.2)
- : (Offset offset, Offset delta) =>
- delta / math.max(1.0, offset.distanceSquared / 100.0),
- onDragStarted: () {},
- onDragFinished: (Offset offset, Velocity velocity) {
- Offset expectedOffset = offset + (velocity.pixelsPerSecond / 5.0);
- // Only remove if greater than threshold
- if (expectedOffset.distance > 200.0) {
- // HACK(alangardner): Hardcoded distances for swipe gesture to
- // avoid complicated layout work.
- ps.surface.dismiss();
- }
- },
- );
- }
-
- SurfaceForm _orphanedForm(
- Surface surface, SurfaceForm form, FractionalOffset offscreen) {
- return SurfaceForm.single(
- key: form.key,
- child: MondrianChildView(
- surface: surface,
- interactable: false,
- ),
- position: form.position.shift(Offset(offscreen.dx, offscreen.dy)),
- initPosition: form.initPosition,
- depth: form.depth,
- friction: kDragFrictionInfinite,
- onPositioned: () {
- // TODO(alangardner): Callback to notify framework
- setState(() {
- _orphanedForms.removeWhere((SurfaceForm f) => f.key == form.key);
- });
- },
- );
- }
-
- @override
- Widget build(BuildContext context) => ScopedModelDescendant<InsetManager>(
- builder: (
- BuildContext context,
- Widget child,
- InsetManager insetManager,
- ) =>
- ScopedModelDescendant<LayoutModel>(
- builder: (
- BuildContext context,
- Widget child,
- LayoutModel layoutModel,
- ) =>
- ScopedModelDescendant<SurfaceGraph>(
- builder: (
- BuildContext context,
- Widget child,
- SurfaceGraph graph,
- ) =>
- _buildStage(
- context,
- FractionalOffset.topRight,
- insetManager,
- layoutModel,
- graph,
- ),
- ),
- ),
- );
-
- Widget _buildStage(
- BuildContext context,
- FractionalOffset offscreen,
- InsetManager insetManager,
- LayoutModel layoutModel,
- SurfaceGraph graph,
- ) {
- Map<Surface, SurfaceForm> placedSurfaces = <Surface, SurfaceForm>{};
- List<Surface> focusStack = graph.focusStack.toList();
- double depth = 0.0;
- while (focusStack.isNotEmpty &&
- focusStack.any((surface) {
- return surface.connection != null;
- })) {
- List<PositionedSurface> positionedSurfaces = <PositionedSurface>[];
- if (focusStack.isNotEmpty) {
- Surface last = focusStack.last;
- // purposefully giving compositionPattern top billing
- // here to avoid any codelab surprises but we will have
- // to harmonize this logic in future
- // TODO: (djmurphy, jphsiao)
- if (last.compositionPattern != null &&
- last.compositionPattern.isNotEmpty) {
- positionedSurfaces = pattern.layoutSurfaces(
- context,
- focusStack,
- layoutModel,
- );
- } else {
- positionedSurfaces = copresent.layoutSurfaces(
- context,
- graph,
- focusStack,
- layoutModel,
- );
- }
- }
- List<String> placedViewIds =
- placedSurfaces.keys.map((Surface s) => s.node.value).toList();
- for (PositionedSurface ps in positionedSurfaces) {
- // TODO (jphsiao): Make this check more thorough. A new surface may
- // have the same view id, but not the same arrangement, parent or
- // connection. These may result in animations for surfaces that are
- // already on screen that we do not handle yet.
- if (!placedViewIds.contains(ps.surface.node.value)) {
- _prevForms.removeWhere((Surface surface, SurfaceForm form) =>
- surface.node.value == ps.surface.node.value);
- // if there is already a Surface laid out, then the incoming
- // surface should default to 'summon'. If there is no Surface being
- // displayed, then do not animate.
- FractionalOffset surfaceOrigin = _prevForms.isNotEmpty
- ? offscreen
- : FractionalOffset(0.0, 0.0); //apply no initial translation
- if (ps.surface.relation.arrangement == SurfaceArrangement.ontop) {
- // Surfaces that are ontop will be placed above the current depth
- // TODO(jphsiao): Revisit whether ontop should be placed on top of
- // all surfaces or if it should push its parent back in z.
- placedSurfaces[ps.surface] = _form(ps, -1.0, surfaceOrigin);
- } else {
- placedSurfaces[ps.surface] = _form(ps, depth, surfaceOrigin);
- }
- }
- }
- depth = (depth + 0.1).clamp(0.0, 1.0);
- while (focusStack.isNotEmpty &&
- placedSurfaces.keys.contains(focusStack.last)) {
- focusStack.removeLast();
- }
- }
- Forest<Surface> dependentSpanningTrees = Forest<Surface>();
- if (placedSurfaces.isNotEmpty) {
- // Get the dependent spanning trees for each tree off of the root
- for (Tree<String> childTree in graph.root.children) {
- getDependentSpanningTrees(graph.getNode(childTree.value))
- .forEach(dependentSpanningTrees.add);
- }
-
- /// prune non-visible surfaces
- for (Tree<Surface> t in dependentSpanningTrees.flatten()) {
- if (!placedSurfaces.keys.contains(t.value)) {
- dependentSpanningTrees.remove(t);
- }
- }
- }
-
- // Convert orphaned forms, to animate them out
- Iterable<Key> placedKeys =
- placedSurfaces.values.map((SurfaceForm f) => f.key);
- _orphanedForms.removeWhere((SurfaceForm f) => placedKeys.contains(f.key));
- for (Surface s in _prevForms.keys) {
- _orphanedForms.add(_orphanedForm(s, _prevForms[s], offscreen));
- }
- _prevForms
- ..clear()
- ..addAll(placedSurfaces);
-
- /// Create form forest
- final Forest<SurfaceForm> formForest =
- dependentSpanningTrees.mapForest((Surface s) => placedSurfaces[s]);
-
- for (SurfaceForm orphan in _orphanedForms) {
- formForest.add(Tree<SurfaceForm>(value: orphan));
- }
-
- /// Determine the max and min depths of all visible surfaces.
- double minDepth = double.infinity;
- double maxDepth = -double.infinity;
- for (double depth
- in placedSurfaces.values.map((SurfaceForm f) => f.depth)) {
- if (minDepth > depth) {
- minDepth = depth;
- }
- if (maxDepth < depth) {
- maxDepth = depth;
- }
- }
- for (double depth in _orphanedForms.map((SurfaceForm f) => f.depth)) {
- if (minDepth > depth) {
- minDepth = depth;
- }
- if (maxDepth < depth) {
- maxDepth = depth;
- }
- }
-
- return ScopedModel<DepthModel>(
- model: DepthModel(minDepth: minDepth, maxDepth: maxDepth),
- child: SurfaceStage(forms: formForest),
- );
- }
-}
diff --git a/story_shells/mondrian/lib/widgets/surface_frame.dart b/story_shells/mondrian/lib/widgets/surface_frame.dart
deleted file mode 100644
index 101a6cb..0000000
--- a/story_shells/mondrian/lib/widgets/surface_frame.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2017 The Fuchsia 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 'dart:ui' show lerpDouble;
-
-import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
-
-import '../models/depth_model.dart';
-
-const double _surfaceDepth = 250.0;
-
-/// Frame for child views
-class SurfaceFrame extends StatelessWidget {
- /// Constructor
- const SurfaceFrame(
- {Key key, this.child, this.interactable = true, this.depth = 0.0})
- : assert(-2.5 <= depth && depth <= 1.0),
- super(key: key);
-
- /// The child
- final Widget child;
-
- /// If true then ChildView hit tests will go through
- final bool interactable;
-
- /// How much to scale this surface [-1.0, 1.0]
- /// Negative numbers increase elevation without scaling
- final double depth;
-
- @override
- Widget build(BuildContext context) {
- return Container(
- alignment: FractionalOffset.center,
- child: IgnorePointer(
- child: ScopedModelDescendant<DepthModel>(
- builder: (
- BuildContext context,
- Widget child,
- DepthModel depthModel,
- ) {
- // Note: Currently if you set an elevation of 0.0 scenic will
- // merge this node with other nodes around it at the same elevation.
- // This causes black to be painted when we are displaying a
- // ChildView that hasn't painted yet. We work around this issue by
- // always setting the elevation to something more than 0.0. This
- // will allow 'nothing' to be painted until the child view is ready.
- double elevation = lerpDouble(
- 0.01,
- _surfaceDepth,
- (depthModel.maxDepth - depth) / 2.0,
- ).clamp(0.0, _surfaceDepth);
- return PhysicalModel(
- elevation: elevation,
- color: Color(0x00000000),
- child: child,
- );
- },
- child: child,
- ),
- ),
- );
- }
-}
diff --git a/story_shells/mondrian/lib/widgets/surface_relationships.dart b/story_shells/mondrian/lib/widgets/surface_relationships.dart
deleted file mode 100644
index e7c6da7..0000000
--- a/story_shells/mondrian/lib/widgets/surface_relationships.dart
+++ /dev/null
@@ -1,599 +0,0 @@
-// Copyright 2018 The Fuchsia 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:fidl_fuchsia_modular/fidl_async.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/widgets.dart';
-import 'package:fuchsia_scenic_flutter/child_view.dart' show ChildView;
-import 'package:fuchsia_logger/logger.dart';
-import 'package:lib.widgets/model.dart';
-
-import '../models/surface/surface.dart';
-import '../models/surface/surface_graph.dart';
-
-import 'surface_resize.dart';
-
-/// Debug Flag
-const bool _storytellerDebug = true;
-
-/// Size/Padding/Margin related constants
-const double _labelWidgetHeight = 30.0;
-const double _labelHorizontalPadding = 24.0;
-const double _pageHorizontalPadding = 28.0;
-const double _pageTopPadding = 28.0;
-const double _branchWidth = 160.0;
-const double _branchPadding = 48.0;
-const double _surfaceWidgetWidth = 150.0;
-const double _surfaceWidgetHeight = 100.0;
-const double _surfaceWidgetTextHeight = 30.0;
-const double _relationshipWidgetWidth = 120.0;
-const double _relationshipWidgetHeight = 60.0;
-const double _relationshipTreeFontSize = 10.0;
-const FontWeight _relationshipTreeFontWeight = FontWeight.w200;
-const double _iconSize = 12.0;
-
-const Color _storytellerPrimaryColor = Color(0xFF6315F6);
-
-/// Printable names for relation arrangement
-const Map<SurfaceArrangement, String> relName =
- <SurfaceArrangement, String>{
- SurfaceArrangement.none: 'None',
- SurfaceArrangement.copresent: 'Co-present',
- SurfaceArrangement.sequential: 'Sequential',
- SurfaceArrangement.ontop: 'Ontop',
-};
-
-/// Printable names for relation dependency
-const Map<SurfaceDependency, String> depName =
- <SurfaceDependency, String>{
- SurfaceDependency.dependent: 'Dependent',
- SurfaceDependency.none: 'Independent',
-};
-
-/// A tree graph that shows the surface relationships (StoryTeller).
-///
-/// Shows the depth of the tree, presentational relationships, dependencies,
-/// and emphasis between parent and child surfaces.
-/// Also shows the state of each surface via [_buildStateIndicator].
-class SurfaceRelationships extends StatelessWidget {
- /// Constructor
- const SurfaceRelationships({Key key}) : super(key: key);
-
- @override
- Widget build(BuildContext context) => LayoutBuilder(
- builder: (BuildContext context, BoxConstraints constraints) {
- return Container(
- width: constraints.maxWidth,
- height: constraints.maxHeight,
- color: Colors.grey[100],
- child: ScopedModelDescendant<SurfaceGraph>(
- builder:
- (BuildContext context, Widget child, SurfaceGraph graph) {
- if (graph.focusStack.isEmpty) {
- log.warning('focusedSurfaceHistory is empty');
- return Container();
- }
- return _buildRelationshipsPage(context, constraints, graph);
- },
- ),
- );
- },
- );
-
- Widget _buildRelationshipsPage(
- BuildContext context, BoxConstraints constraints, SurfaceGraph graph) {
- Map<String, GlobalKey> surfaceKeys = <String, GlobalKey>{};
- GlobalKey stackKey = GlobalKey();
- Set<Surface> firstDepthSurfaces = <Surface>{};
-
- for (Surface s in graph.focusStack.toList()) {
- firstDepthSurfaces.add(s.root);
- }
-
- int maxHeight = 0;
- for (Surface s in firstDepthSurfaces) {
- if (s.node.height > maxHeight) {
- maxHeight = s.node.height;
- }
- }
-
- if (_storytellerDebug) {
- log.info('*** The height of the StoryGraph is $maxHeight');
- }
-
- double totalLabelWidth = _pageHorizontalPadding * 2 +
- _surfaceWidgetWidth +
- (_surfaceWidgetWidth + _branchWidth) * (maxHeight);
-
- if (totalLabelWidth < MediaQuery.of(context).size.width) {
- totalLabelWidth = MediaQuery.of(context).size.width;
- }
-
- return SingleChildScrollView(
- scrollDirection: Axis.horizontal,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[
- _buildLabel(totalLabelWidth, maxHeight),
- _buildContent(graph, stackKey, surfaceKeys, firstDepthSurfaces),
- ],
- ),
- );
- }
-
- Widget _buildLabel(double labelWidth, int maxHeight) {
- return Material(
- elevation: 4.0,
- child: Container(
- width: labelWidth,
- child: Row(
- children: _buildLabelWidgetList(maxHeight),
- ),
- ),
- );
- }
-
- Widget _buildContent(SurfaceGraph graph, GlobalKey stackKey,
- Map<String, GlobalKey> surfaceKeys, Set<Surface> firstSurfaces) {
- return Expanded(
- child: SingleChildScrollView(
- scrollDirection: Axis.vertical,
- child: Stack(
- key: stackKey,
- children: <Widget>[
- _buildEdges(stackKey, surfaceKeys, firstSurfaces),
- _buildNodes(graph, surfaceKeys, firstSurfaces),
- ],
- ),
- ),
- );
- }
-
- Widget _buildEdges(GlobalKey stackKey, Map<String, GlobalKey> surfaceKeys,
- Set<Surface> firstSurfaces) {
- return CustomPaint(
- painter: _RelationshipTreeEdges(
- firstSurfaces: firstSurfaces,
- surfaceKeys: surfaceKeys,
- backgroundKey: stackKey,
- ),
- );
- }
-
- Widget _buildNodes(SurfaceGraph graph, Map<String, GlobalKey> surfaceKeys,
- Set<Surface> firstSurfaces) {
- return Container(
- padding: EdgeInsets.only(
- left: _pageHorizontalPadding,
- right: _pageHorizontalPadding,
- top: _pageTopPadding,
- ),
- child: Column(
- children: firstSurfaces
- .map((surface) => _buildTree(surfaceKeys, graph, surface,
- (graph.focusStack.last == surface)))
- .toList(),
- ),
- );
- }
-
- /// Builds the labels that shows the depth of each column.
- List<Widget> _buildLabelWidgetList(int maxHeight) {
- List<Widget> labelWidgets = <Widget>[];
- double totalLength = _pageHorizontalPadding + _surfaceWidgetWidth;
- labelWidgets.add(Container(
- /// Depth 1
- padding: EdgeInsets.only(right: _labelHorizontalPadding),
- width: totalLength,
- height: _labelWidgetHeight,
- decoration: _labelBoxDecoration(true, true),
- alignment: Alignment.centerRight,
- child: Text(
- 'Depth 1',
- style: TextStyle(
- color: Colors.black,
- fontSize: 10.0,
- ),
- ),
- ));
-
- double labelWidgetWidth = _surfaceWidgetWidth + _branchWidth;
-
- // Other labels: Depth 2 ~
- for (int i = 0; i < maxHeight; i++) {
- totalLength += labelWidgetWidth;
-
- labelWidgets.add(Container(
- padding: EdgeInsets.only(right: _labelHorizontalPadding),
- width: labelWidgetWidth,
- height: _labelWidgetHeight,
- decoration: _labelBoxDecoration(true, true),
- alignment: Alignment.centerRight,
- child: Text(
- 'Depth ${i + 2}',
- style: TextStyle(
- color: Colors.black,
- fontSize: 10.0,
- ),
- ),
- ));
- }
-
- labelWidgets.add(Expanded(
- child: Container(
- height: _labelWidgetHeight,
- decoration: _labelBoxDecoration(false, true),
- ),
- ));
-
- return labelWidgets;
- }
-
- BoxDecoration _labelBoxDecoration(bool rightBorder, bool bottomBorder) {
- return BoxDecoration(
- color: Colors.white,
- border: Border(
- right: BorderSide(
- color: rightBorder ? Colors.grey[400] : Colors.transparent,
- width: 0.5,
- ),
- bottom: BorderSide(
- color: bottomBorder ? Colors.grey[400] : Colors.transparent,
- width: 0.5,
- ),
- ),
- );
- }
-
- /// Builds the surface relationship tree recursively.
- ///
- /// The tree's depth grows horizontally.
- /// The sibling nodes are added vertically.
- Widget _buildTree(Map<String, GlobalKey> globalKeys, SurfaceGraph graph,
- Surface surface, bool isFocused) {
- if (_storytellerDebug) {
- if (graph == null) {
- log.shout('*** The storyGraph is null!');
- }
- if (surface == null) {
- log.shout('*** The current surface is null!');
- }
- }
-
- assert(graph != null);
- assert(surface != null);
-
- if (_storytellerDebug) {
- log
- ..info('*** This surface ID: ${surface.node.value}')
- ..info('*** This surface\'s parentId: ${surface.parentId}')
- ..info(
- '*** The length of the focus stack: ${graph.focusStack.toList().length}');
- }
-
- String id = surface.node.value;
- globalKeys[id] = GlobalKey();
-
- Widget thisWidget = _buildChildNode(globalKeys[id], surface, isFocused);
-
- List<Surface> children = List<Surface>.from(surface.children.toList())
- ..removeWhere((child) => child == null);
-
- if (_storytellerDebug) {
- log.info(
- '*** BUILDING TREE... surface($id)\'s global key = ${globalKeys[id]}');
- }
-
- if (_storytellerDebug) {
- log.info('*** The number of children of surface $id: ${children.length}');
- }
-
- if (children.isEmpty) {
- return thisWidget;
- } else {
- if (_storytellerDebug) {
- log.info('*** The first child: ${children[0]}');
- }
- return Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[
- thisWidget,
- (children.length == 1)
- ? _buildTree(globalKeys, graph, children[0],
- (graph.focusStack.toList().last == children[0]))
- : Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: children.map((child) {
- return _buildTree(globalKeys, graph, child,
- (graph.focusStack.toList().last == child));
- }).toList(),
- ),
- ],
- );
- }
- }
-
- /// Returns a container containing a relationship widget and a surface widget
- Widget _buildChildNode(GlobalKey key, Surface surface, bool isFocused) {
- bool isFirstDepthNode = (surface.parentId == null);
-
- return Container(
- padding: EdgeInsets.only(bottom: _branchPadding),
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[
- (isFirstDepthNode)
- ? Container()
- : _buildRelationshipWidget(surface),
- _buildSurfaceWidget(key, surface, isFocused),
- ],
- ),
- );
- }
-
- /// Builds a branch tag of the tree that shows the relationship between
- /// a surface and its parent.
- ///
- /// This tag appears on a branch between two surfaces.
- Widget _buildRelationshipWidget(Surface surface) {
- String presentation = relName[surface.relation.arrangement] ?? 'Unknown';
- String dependency = depName[surface.relation.dependency] ?? 'Unknown';
- String emphasis = surface.relation.emphasis.toStringAsPrecision(2);
-
- return Container(
- width: _branchWidth,
- height: _surfaceWidgetHeight,
- child: Center(
- child: Container(
- padding: EdgeInsets.symmetric(horizontal: 12.0, vertical: 6.0),
- width: _relationshipWidgetWidth,
- height: _relationshipWidgetHeight,
- decoration: _relationshipBoxDeco(dependency),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[
- _buildRelationshipRow(Icons.filter, presentation, dependency),
- _buildRelationshipRow(Icons.link, dependency, dependency),
- _buildRelationshipRow(Icons.data_usage, emphasis, dependency),
- ],
- ),
- ),
- ),
- );
- }
-
- Widget _buildRelationshipRow(IconData icon, String text, String dependency) {
- return Row(
- children: <Widget>[
- _relationshipIcon(icon, dependency),
- Container(
- padding: EdgeInsets.only(left: 10.0),
- child: Text(
- text,
- style: _relationshipTextStyle(dependency),
- ),
- ),
- ],
- );
- }
-
- BoxDecoration _relationshipBoxDeco(String dependency) {
- return BoxDecoration(
- color: (dependency == 'Independent')
- ? Colors.white
- : _storytellerPrimaryColor,
- borderRadius: BorderRadius.circular(10.0),
- border: Border.all(
- color: _storytellerPrimaryColor,
- width: 2.0,
- ),
- );
- }
-
- TextStyle _relationshipTextStyle(String dependency) {
- return TextStyle(
- color: (dependency == 'Independent')
- ? _storytellerPrimaryColor
- : Colors.white,
- fontSize: _relationshipTreeFontSize,
- fontWeight: _relationshipTreeFontWeight,
- );
- }
-
- Icon _relationshipIcon(IconData icon, String dependency) {
- return Icon(
- icon,
- color: (dependency == 'Independent')
- ? _storytellerPrimaryColor
- : Colors.white,
- size: _iconSize,
- );
- }
-
- /// Builds a node of the tree that shows a surface, the surface's id and state.
- Widget _buildSurfaceWidget(GlobalKey key, Surface surface, bool isFocused) {
- return Container(
- height: _surfaceWidgetHeight + _surfaceWidgetTextHeight + 8.0,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: <Widget>[
- _buildSurfaceImage(key, surface),
- _buildSurfaceInfoText(surface, isFocused),
- ],
- ),
- );
- }
-
- Widget _buildSurfaceImage(GlobalKey key, Surface surface) {
- return Material(
- key: key,
- color: Colors.white,
- elevation: 2.0,
- borderRadius: BorderRadius.circular(8.0),
- child: Container(
- width: _surfaceWidgetWidth,
- height: _surfaceWidgetHeight,
- child: Center(
- child: SurfaceResize(
- child: ChildView(
- connection: surface.connection,
- hitTestable: false,
- ),
- ),
- ),
- ),
- );
- }
-
- Widget _buildSurfaceInfoText(Surface surface, bool isFocused) {
- return Container(
- width: _surfaceWidgetWidth,
- height: _surfaceWidgetTextHeight,
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[
- _buildStateIndicator(surface.dismissed, isFocused),
- Expanded(
- child: Text(
- '${surface.node.value}',
- style: TextStyle(
- color: (surface.dismissed) ? Colors.grey[400] : Colors.black,
- fontSize: _relationshipTreeFontSize,
- fontWeight: _relationshipTreeFontWeight,
- ),
- overflow: TextOverflow.ellipsis,
- maxLines: 2,
- textAlign: TextAlign.start,
- ),
- ),
- ],
- ),
- );
- }
-
- /// Shows the state of a surface.
- ///
- /// Focused: A violet circle.
- /// Active: A white circle with violet border.
- /// Dismissed: A grey circle.
- Widget _buildStateIndicator(bool isDismissed, bool isFocused) {
- Color stateFillColor;
- Color stateBorderColor;
- if (isDismissed) {
- stateFillColor = Colors.grey[400];
- stateBorderColor = Colors.grey[400];
- } else if (isFocused) {
- stateFillColor = _storytellerPrimaryColor;
- stateBorderColor = _storytellerPrimaryColor;
- } else {
- stateFillColor = Colors.white;
- stateBorderColor = _storytellerPrimaryColor;
- }
-
- return Padding(
- padding: EdgeInsets.only(top: 4.0, left: 8.0, right: 8.0),
- child: Container(
- width: 6.0,
- height: 6.0,
- decoration: BoxDecoration(
- color: stateFillColor,
- borderRadius: BorderRadius.circular(3.0),
- border: Border.all(
- width: 1.0,
- color: stateBorderColor,
- ),
- ),
- ),
- );
- }
-}
-
-/// The edge lines between parent and child surfaces.
-///
-/// The position of an edge is decided by the positions of the surface widget.
-class _RelationshipTreeEdges extends CustomPainter {
- final Set<Surface> firstSurfaces;
- final Map<String, GlobalKey> surfaceKeys;
- final GlobalKey backgroundKey;
-
- _RelationshipTreeEdges(
- {@required this.firstSurfaces,
- @required this.surfaceKeys,
- @required this.backgroundKey});
-
- @override
- void paint(Canvas canvas, Size size) {
- Paint paint = Paint()
- ..color = _storytellerPrimaryColor
- ..strokeWidth = 1.5
- ..strokeCap = StrokeCap.round
- ..style = PaintingStyle.stroke;
-
- final bgContext = backgroundKey.currentContext;
- final RenderBox bgBox = bgContext.findRenderObject();
-
- Set<Surface> currentSurfaces = Set<Surface>.from(firstSurfaces);
-
- while (currentSurfaces.isNotEmpty) {
- for (Surface surface in currentSurfaces) {
- double startX;
- double endX;
- double minY;
- double maxY;
-
- // Draws horizontal edges
- for (int i = 0; i < surface.children.length; i++) {
- String childId = surface.children.toList()[i].node.value;
- final childSurfaceContext = surfaceKeys[childId].currentContext;
- final RenderBox childSurfaceBox =
- childSurfaceContext.findRenderObject();
- final childSurfaceGlobalPos =
- childSurfaceBox.localToGlobal(Offset(0.0, 0.0));
-
- final childSurfacePos = bgBox.globalToLocal(childSurfaceGlobalPos);
-
- if (_storytellerDebug) {
- log
- ..info('*** x: ${childSurfacePos.dx}')
- ..info('*** y: ${childSurfacePos.dy}');
- }
-
- double y = childSurfacePos.dy + (childSurfaceBox.size.height / 2);
-
- if (i == 0) {
- startX = childSurfacePos.dx - _branchWidth;
- endX = childSurfacePos.dx;
- minY = y;
- } else if (i == 1) {
- startX += (_branchWidth - _relationshipWidgetWidth) / 4;
- }
-
- maxY = y;
-
- canvas.drawLine(Offset(startX, y), Offset(endX, y), paint);
- }
-
- // Draws a vertical edge
- if (surface.children.length > 1) {
- canvas.drawLine(Offset(startX, minY), Offset(startX, maxY), paint);
- }
- }
-
- Set<Surface> nextSurfaces = <Surface>{};
- for (Surface s in currentSurfaces) {
- for (int i = 0; i < s.children.length; i++) {
- nextSurfaces.add(s.children.toList()[i]);
- }
- }
- currentSurfaces = nextSurfaces;
- }
- }
-
- @override
- bool shouldRepaint(_RelationshipTreeEdges oldDelegate) {
- return false;
- }
-}
diff --git a/story_shells/mondrian/lib/widgets/surface_resize.dart b/story_shells/mondrian/lib/widgets/surface_resize.dart
deleted file mode 100644
index 4fa83c3..0000000
--- a/story_shells/mondrian/lib/widgets/surface_resize.dart
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2018 The Fuchsia 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 'dart:math';
-
-import 'package:flutter/widgets.dart';
-import 'package:meta/meta.dart';
-
-/// 60-30 isometric projection matrix
-final Matrix4 _iso = Matrix4.identity();
-
-/// Widget that performs an isometric transformation on a Widget,
-/// scaling it so that it fits within the bounds of its original rectangle
-class SurfaceResize extends StatelessWidget {
- /// The child to transform
- final Widget child;
-
- /// This size to draw the widget in orthographic projection
- final double scaleFactor;
-
- /// Constructor
- const SurfaceResize({@required this.child, this.scaleFactor = 4.0});
-
- @override
- Widget build(BuildContext context) => LayoutBuilder(
- builder: (BuildContext context, BoxConstraints constraints) {
- BoxConstraints _scaledConstraints = constraints * scaleFactor;
-
- return FittedBox(
- fit: BoxFit.scaleDown,
- child: Container(
- constraints: _scaledConstraints,
- child: Transform(
- child: child,
- transform: _getTransformation(constraints: _scaledConstraints),
- origin: _scaledConstraints.biggest.center(Offset.zero),
- ),
- ),
- );
- },
- );
-
- /// Get the isometric transformation to apply to the views
- Matrix4 _getTransformation({BoxConstraints constraints}) {
- // Scale the transformation so the views fit in the original rectangles
- Rect constraintsRect = Offset.zero & constraints.biggest;
- Rect transRect = MatrixUtils.transformRect(
- _iso,
- constraintsRect,
- );
- double isoScale = min(constraintsRect.height / transRect.height,
- constraintsRect.width / transRect.width);
- return Matrix4.copy(_iso)..scale(isoScale);
- }
-}
diff --git a/story_shells/mondrian/lib/widgets/surface_stage.dart b/story_shells/mondrian/lib/widgets/surface_stage.dart
deleted file mode 100644
index 9dd60ef..0000000
--- a/story_shells/mondrian/lib/widgets/surface_stage.dart
+++ /dev/null
@@ -1,390 +0,0 @@
-// Copyright 2017 The Fuchsia 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 'dart:async';
-import 'dart:ui';
-
-import 'package:flutter/foundation.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/rendering.dart';
-import 'package:flutter/physics.dart';
-import 'package:flutter/scheduler.dart';
-import 'package:flutter/widgets.dart';
-import 'package:meta/meta.dart';
-
-import '../anim/flux.dart';
-import '../anim/sim.dart';
-import '../models/surface/surface_form.dart';
-import '../models/tree/tree.dart';
-import '../widgets/gestures.dart';
-import 'surface_frame.dart';
-
-const SpringDescription _kSimSpringDescription = SpringDescription(
- mass: 1.0,
- stiffness: 220.0,
- damping: 29.0,
-);
-
-const double _kGestureWidth = 32.0;
-
-/// Delays the first animation by this amount. This gives new mods time to
-/// load.
-const _introAnimationDelay = Duration(milliseconds: 3000);
-
-/// Stages determine how things move, and how they can be manipulated
-class SurfaceStage extends StatelessWidget {
- /// Construct a SurfaceStage with these forms
- const SurfaceStage({@required this.forms});
-
- /// The forms inside this stage
- final Forest<SurfaceForm> forms;
-
- @override
- Widget build(BuildContext context) {
- // If there is only one surface, do not fight for horizontal gestures,
- // assume Session Shell will handle story dismissal.
- final useGestures = forms.flatten().length > 1;
-
- final children = <Widget>[]..addAll(
- forms
- .reduceForest(
- (SurfaceForm f, Iterable<_SurfaceInstance> children) =>
- _SurfaceInstance(
- form: f,
- dependents: children.toList(),
- useGestures: useGestures,
- ),
- )
- .toList()
- ..sort(
- (_SurfaceInstance a, _SurfaceInstance b) =>
- b.form.depth.compareTo(a.form.depth),
- ),
- );
-
- if (useGestures) {
- // We add ignoring unidirectional horizontal drag detectors on the
- // edges so the ones added by the surfaces along the edges have
- // something to fight in the gesture arena (otherwise they always win
- // and accept gestures in the wrong direction). This prevents drags
- // toward the edges of the screen from moving or dismissing the
- // associated surfaces.
- children.addAll(<Widget>[
- Positioned(
- left: -_kGestureWidth,
- top: _kGestureWidth,
- bottom: _kGestureWidth,
- width: 2.0 * _kGestureWidth,
- child: _createIgnoringGestureDetector(Direction.left),
- ),
- Positioned(
- right: -_kGestureWidth,
- top: _kGestureWidth,
- bottom: _kGestureWidth,
- width: 2.0 * _kGestureWidth,
- child: _createIgnoringGestureDetector(Direction.right),
- ),
- ]);
- }
- return Stack(
- fit: StackFit.expand,
- children: children,
- );
- }
-
- /// This gesture detector fights in the arena and ignores the horizontal drags
- /// in the given [direction] if it wins.
- Widget _createIgnoringGestureDetector(Direction direction) {
- return UnidirectionalHorizontalGestureDetector(
- direction: direction,
- behavior: HitTestBehavior.translucent,
- onHorizontalDragStart: (DragStartDetails details) {},
- onHorizontalDragUpdate: (DragUpdateDetails details) {},
- onHorizontalDragEnd: (DragEndDetails details) {},
- );
- }
-}
-
-/// Instantiation of a Surface in SurfaceStage
-class _SurfaceInstance extends StatefulWidget {
- /// SurfaceLayout
- _SurfaceInstance({
- @required this.form,
- this.isDebugMode = false,
- this.dependents = const <_SurfaceInstance>[],
- this.useGestures,
- }) : super(key: form.key);
-
- /// The form of this Surface
- final SurfaceForm form;
-
- /// Dependent surfaces
- final List<_SurfaceInstance> dependents;
-
- final bool isDebugMode;
-
- final bool useGestures;
-
- @override
- _SurfaceInstanceState createState() => _SurfaceInstanceState();
-}
-
-class DummyTickerProvider implements TickerProvider {
- @override
- Ticker createTicker(TickerCallback onTick) => Ticker((_) {});
-}
-
-class _SurfaceInstanceState extends State<_SurfaceInstance>
- with TickerProviderStateMixin {
- FluxAnimation<Rect> get animation => _animation;
- ManualAnimation<Rect> _animation;
-
- bool isDragging = false;
- double depth = 0.0;
-
- @override
- void initState() {
- super.initState();
- //TODO:(alangardner): figure out elevation layering
-
- /// Delay the first animation to give time for the mod to load. We do this
- /// with a dummy ticker that doesn't tick for the delay period.
- _animation = _createAnimation(DummyTickerProvider());
- Timer(_introAnimationDelay, () {
- setState(() {
- _animation = _createAnimation(this);
- });
- });
- }
-
- ManualAnimation<Rect> _createAnimation(TickerProvider tickerProvider) {
- return ManualAnimation<Rect>(
- value: widget.form.initPosition,
- velocity: Rect.zero,
- builder: (Rect value, Rect velocity) => MovingTargetAnimation<Rect>(
- vsync: tickerProvider,
- simulate: _kFormSimulate,
- target: _target,
- value: value,
- velocity: velocity)
- .stickyAnimation,
- )..done();
- }
-
- @override
- void didUpdateWidget(_SurfaceInstance oldWidget) {
- super.didUpdateWidget(oldWidget);
- _animation
- ..update(value: _animation.value, velocity: _animation.velocity)
- ..done();
- }
-
- FluxAnimation<Rect> get _target {
- final SurfaceForm f = widget.form;
- final _SurfaceInstanceState parentSurfaceState = context
- ?.findAncestorStateOfType<_SurfaceInstanceState>();
- return parentSurfaceState == null
- ? ManualAnimation<Rect>(value: f.position, velocity: Rect.zero)
- : TransformedAnimation<Rect>(
- animation: parentSurfaceState.animation,
- valueTransform: (Rect r) => f.position.shift(
- r.center - parentSurfaceState.widget.form.position.center),
- velocityTransform: (Rect r) => r,
- );
- }
-
- @override
- Widget build(BuildContext context) {
- return AnimatedBuilder(
- animation: _animation,
- builder: (BuildContext context, Widget child) {
- Size parentSize = MediaQuery.of(context).size;
- final SurfaceForm form = widget.form;
- Offset fractionalOffset =
- (animation.value.center - animation.value.size.center(Offset.zero));
- double left = parentSize.width * fractionalOffset.dx;
- double top = parentSize.height * fractionalOffset.dy;
- double right = parentSize.width *
- (1.0 - (fractionalOffset.dx + animation.value.size.width));
- double bottom = parentSize.height *
- (1.0 - (fractionalOffset.dy + animation.value.size.height));
-
- double surfaceDepth = isDragging
- ? -2.0
- : lerpDouble(
- form.depth,
- depth,
- fractionalOffset.dy.abs(),
- );
-
- final stackChildren = <Widget>[
- Positioned(
- left: left,
- top: top,
- bottom: bottom,
- right: right,
- child: SurfaceFrame(
- child: form.parts.keys.first,
- depth: surfaceDepth,
- // HACK(alangardner): May need explicit interactable parameter
- interactable: form.dragFriction != kDragFrictionInfinite,
- ),
- )
- ];
-
- if (widget.useGestures) {
- stackChildren.addAll([
- Positioned(
- left: left - _kGestureWidth,
- top: top + _kGestureWidth,
- bottom: bottom + _kGestureWidth,
- width: 2.0 * _kGestureWidth,
- child: _createGestureDetector(
- parentSize,
- form,
- Direction.right,
- ),
- ),
- Positioned(
- right: right - _kGestureWidth,
- top: top + _kGestureWidth,
- bottom: bottom + _kGestureWidth,
- width: 2.0 * _kGestureWidth,
- child: _createGestureDetector(
- parentSize,
- form,
- Direction.left,
- ),
- ),
- ]);
- }
- return Stack(
- fit: StackFit.expand,
- children: stackChildren..addAll(widget.dependents),
- );
- },
- );
- }
-
- Widget _createGestureDetector(
- Size parentSize,
- SurfaceForm form,
- Direction direction,
- ) {
- return UnidirectionalHorizontalGestureDetector(
- direction: direction,
- behavior: HitTestBehavior.translucent,
- onHorizontalDragStart: (DragStartDetails details) {
- _animation.update(
- value: animation.value,
- velocity: Rect.zero,
- );
- form.onDragStarted();
- isDragging = true;
- },
- onHorizontalDragUpdate: (DragUpdateDetails details) {
- _animation.update(
- value: animation.value.shift(
- _toFractional(
- form.dragFriction(
- _toAbsolute(
- animation.value.center - form.position.center,
- parentSize,
- ),
- details.delta,
- ),
- parentSize,
- ),
- ),
- velocity: Rect.zero,
- );
- },
- onHorizontalDragEnd: (DragEndDetails details) {
- _animation
- ..update(
- value: animation.value,
- velocity: Rect.zero.shift(
- _toFractional(
- form.dragFriction(
- _toAbsolute(
- animation.value.center - form.position.center,
- parentSize,
- ),
- details.velocity.pixelsPerSecond,
- ),
- parentSize,
- ),
- ),
- )
- ..done();
- form.onDragFinished(
- _toAbsolute(
- animation.value.center - form.position.center,
- parentSize,
- ),
- details.velocity,
- );
- isDragging = false;
- depth = -2.0;
- },
- );
- }
-
- Offset _toFractional(Offset absoluteOffset, Size size) {
- return Offset(
- absoluteOffset.dx / size.width,
- absoluteOffset.dy / size.height,
- );
- }
-
- Offset _toAbsolute(Offset fractionalOffset, Size size) {
- return Offset(
- fractionalOffset.dx * size.width,
- fractionalOffset.dy * size.height,
- );
- }
-}
-
-const double _kEpsilon = 1e-3;
-const Tolerance _kTolerance = Tolerance(
- distance: _kEpsilon,
- time: _kEpsilon,
- velocity: _kEpsilon,
-);
-
-Sim<Rect> _kFormSimulate(Rect value, Rect target, Rect velocity) =>
- IndependentRectSim(
- positionSim: Independent2DSim(
- xSim: SpringSimulation(
- _kSimSpringDescription,
- value.center.dx,
- target.center.dx,
- velocity.center.dx,
- tolerance: _kTolerance,
- ),
- ySim: SpringSimulation(
- _kSimSpringDescription,
- value.center.dy,
- target.center.dy,
- velocity.center.dy,
- tolerance: _kTolerance,
- ),
- ),
- sizeSim: Independent2DSim(
- xSim: SpringSimulation(
- _kSimSpringDescription,
- value.size.width,
- target.size.width,
- velocity.size.width,
- tolerance: _kTolerance,
- ),
- ySim: SpringSimulation(
- _kSimSpringDescription,
- value.size.height,
- target.size.height,
- velocity.size.height,
- tolerance: _kTolerance,
- ),
- ),
- );
diff --git a/story_shells/mondrian/meta/mondrian.cmx b/story_shells/mondrian/meta/mondrian.cmx
deleted file mode 100644
index 519e7ff..0000000
--- a/story_shells/mondrian/meta/mondrian.cmx
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "program": {
- "data": "data/mondrian"
- },
- "sandbox": {
- "services": [
- "fuchsia.cobalt.LoggerFactory",
- "fuchsia.fonts.Provider",
- "fuchsia.logger.LogSink",
- "fuchsia.modular.ContextWriter",
- "fuchsia.modular.ModuleContext",
- "fuchsia.netstack.Netstack",
- "fuchsia.sys.Environment",
- "fuchsia.ui.input.ImeService",
- "fuchsia.ui.policy.Presenter",
- "fuchsia.ui.scenic.Scenic",
- "fuchsia.wlan.service.Wlan"
- ]
- }
-}
diff --git a/story_shells/mondrian/pubspec.yaml b/story_shells/mondrian/pubspec.yaml
deleted file mode 100644
index 5a69671..0000000
--- a/story_shells/mondrian/pubspec.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2017 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-name: mondrian
-dev_dependencies:
- flutter_test:
- sdk: flutter
- test: ^0.12.15
\ No newline at end of file
diff --git a/story_shells/mondrian/test/layout/pattern_layout_test.dart b/story_shells/mondrian/test/layout/pattern_layout_test.dart
deleted file mode 100644
index 22de9de..0000000
--- a/story_shells/mondrian/test/layout/pattern_layout_test.dart
+++ /dev/null
@@ -1,221 +0,0 @@
-// Copyright 2018 The Fuchsia 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:flutter/widgets.dart';
-import 'package:flutter_test/flutter_test.dart';
-import 'package:fuchsia_logger/logger.dart';
-import 'package:mockito/mockito.dart';
-import 'package:mondrian/models/layout_model.dart';
-import 'package:mondrian/layout/pattern_layout.dart' as pattern_layout;
-import 'package:mondrian/models/surface/positioned_surface.dart';
-import 'package:mondrian/models/surface/surface.dart';
-import '../layout_test_utils.dart' as test_util;
-
-class MockSurface extends Mock implements Surface {}
-
-void main() {
- // pattern layout logs warnings
- setupLogger(name: 'mondrain_story_shell_tests');
- Surface firstSurface = MockSurface();
- LayoutModel layoutModel = LayoutModel();
- test('Ticker pattern with 2 surfaces', () {
- Surface patternSurface = MockSurface();
- when(patternSurface.compositionPattern).thenReturn('ticker');
- List<Surface> surfaces = [
- firstSurface,
- patternSurface,
- ];
- List<PositionedSurface> positionedSurfaces = pattern_layout.layoutSurfaces(
- null /* BuildContext */, surfaces, layoutModel);
- expect(positionedSurfaces.length, 2);
-
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 0.85, width: 1.0, topLeft: Offset(0.0, 0.0));
-
- test_util.assertSurfaceProperties(positionedSurfaces[1],
- height: 0.15, width: 1.0, topLeft: Offset(0.0, 0.85));
- });
-
- test('Ticker pattern with 2 surfaces and empty composition pattern', () {
- when(firstSurface.compositionPattern).thenReturn('');
- Surface patternSurface = MockSurface();
- when(patternSurface.compositionPattern).thenReturn('ticker');
- List<Surface> surfaces = [
- firstSurface,
- patternSurface,
- ];
- List<PositionedSurface> positionedSurfaces = pattern_layout.layoutSurfaces(
- null /* BuildContext */, surfaces, layoutModel);
- expect(positionedSurfaces.length, 2);
-
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 0.85, width: 1.0, topLeft: Offset(0.0, 0.0));
-
- test_util.assertSurfaceProperties(positionedSurfaces[1],
- height: 0.15, width: 1.0, topLeft: Offset(0.0, 0.85));
- });
-
- test('Multiple tickers', () {
- Surface tickerSurface = MockSurface();
- when(tickerSurface.compositionPattern).thenReturn('ticker');
- Surface tickerSurface2 = MockSurface();
- when(tickerSurface2.compositionPattern).thenReturn('ticker');
- Surface tickerSurface3 = MockSurface();
- when(tickerSurface3.compositionPattern).thenReturn('ticker');
- List<Surface> surfaces = [
- firstSurface,
- tickerSurface,
- tickerSurface2,
- tickerSurface3,
- ];
- List<PositionedSurface> positionedSurfaces = pattern_layout.layoutSurfaces(
- null /* BuildContext */, surfaces, layoutModel);
- expect(positionedSurfaces.length, 2);
-
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 0.85, width: 1.0, topLeft: Offset(0.0, 0.0));
-
- test_util.assertSurfaceProperties(positionedSurfaces[1],
- height: 0.15, width: 1.0, topLeft: Offset(0.0, 0.85));
- expect(positionedSurfaces[1].surface, tickerSurface3);
- });
-
- test('Comments-right pattern with 2 surfaces', () {
- Surface patternSurface = MockSurface();
- when(patternSurface.compositionPattern).thenReturn('comments-right');
- List<Surface> surfaces = [
- firstSurface,
- patternSurface,
- ];
- List<PositionedSurface> positionedSurfaces = pattern_layout.layoutSurfaces(
- null /* BuildContext */, surfaces, layoutModel);
- expect(positionedSurfaces.length, 2);
-
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 1.0, width: 0.7, topLeft: Offset(0.0, 0.0));
-
- test_util.assertSurfaceProperties(positionedSurfaces[1],
- height: 1.0, width: 0.3, topLeft: Offset(0.7, 0.0));
- });
-
- test('Multiple comments-right', () {
- Surface commentsSurface = MockSurface();
- when(commentsSurface.compositionPattern).thenReturn('comments-right');
- Surface commentsSurface2 = MockSurface();
- when(commentsSurface2.compositionPattern).thenReturn('comments-right');
- Surface commentsSurface3 = MockSurface();
- when(commentsSurface3.compositionPattern).thenReturn('comments-right');
- List<Surface> surfaces = [
- firstSurface,
- commentsSurface,
- commentsSurface2,
- commentsSurface3,
- ];
- List<PositionedSurface> positionedSurfaces = pattern_layout.layoutSurfaces(
- null /* BuildContext */, surfaces, layoutModel);
- expect(positionedSurfaces.length, 2);
-
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 1.0, width: 0.7, topLeft: Offset(0.0, 0.0));
-
- test_util.assertSurfaceProperties(positionedSurfaces[1],
- height: 1.0, width: 0.3, topLeft: Offset(0.7, 0.0));
- expect(positionedSurfaces[1].surface, commentsSurface3);
- });
-
- test('Undefined pattern', () {
- Surface patternSurface = MockSurface();
- when(patternSurface.compositionPattern).thenReturn('undefined');
- List<Surface> surfaces = [
- firstSurface,
- patternSurface,
- ];
- List<PositionedSurface> positionedSurfaces = pattern_layout.layoutSurfaces(
- null /* BuildContext */, surfaces, layoutModel);
- expect(positionedSurfaces.length, 1);
-
- test_util.assertSurfaceProperties(positionedSurfaces.first,
- height: 1.0, width: 1.0, topLeft: Offset(0.0, 0.0));
- });
-
- test('Comments and ticker', () {
- Surface commentsSurface = MockSurface();
- when(commentsSurface.compositionPattern).thenReturn('comments-right');
- Surface tickerSurface = MockSurface();
- when(tickerSurface.compositionPattern).thenReturn('ticker');
- List<Surface> surfaces = [
- firstSurface,
- commentsSurface,
- tickerSurface,
- ];
- List<PositionedSurface> positionedSurfaces = pattern_layout.layoutSurfaces(
- null /* BuildContext */, surfaces, layoutModel);
- expect(positionedSurfaces.length, 3);
-
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 0.85, width: 0.7, topLeft: Offset(0.0, 0.0));
-
- test_util.assertSurfaceProperties(positionedSurfaces[1],
- height: 1.0, width: 0.3, topLeft: Offset(0.7, 0.0));
-
- test_util.assertSurfaceProperties(positionedSurfaces[2],
- height: 0.15, width: 0.7, topLeft: Offset(0.0, 0.85));
- });
-
- test('Ticker and comments', () {
- Surface commentsSurface = MockSurface();
- when(commentsSurface.compositionPattern).thenReturn('comments-right');
- Surface tickerSurface = MockSurface();
- when(tickerSurface.compositionPattern).thenReturn('ticker');
- List<Surface> surfaces = [
- firstSurface,
- tickerSurface,
- commentsSurface,
- ];
- List<PositionedSurface> positionedSurfaces = pattern_layout.layoutSurfaces(
- null /* BuildContext */, surfaces, layoutModel);
- expect(positionedSurfaces.length, 3);
-
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 0.85, width: 0.7, topLeft: Offset(0.0, 0.0));
-
- test_util.assertSurfaceProperties(positionedSurfaces[1],
- height: 1.0, width: 0.3, topLeft: Offset(0.7, 0.0));
-
- test_util.assertSurfaceProperties(positionedSurfaces[2],
- height: 0.15, width: 0.7, topLeft: Offset(0.0, 0.85));
- });
-
- test('Multiple ticker and comments', () {
- Surface commentsSurface = MockSurface();
- when(commentsSurface.compositionPattern).thenReturn('comments-right');
- Surface commentsSurface2 = MockSurface();
- when(commentsSurface2.compositionPattern).thenReturn('comments-right');
- Surface tickerSurface = MockSurface();
- when(tickerSurface.compositionPattern).thenReturn('ticker');
- Surface tickerSurface2 = MockSurface();
- when(tickerSurface2.compositionPattern).thenReturn('ticker');
- List<Surface> surfaces = [
- firstSurface,
- tickerSurface,
- commentsSurface,
- tickerSurface2,
- commentsSurface2,
- ];
- List<PositionedSurface> positionedSurfaces = pattern_layout.layoutSurfaces(
- null /* BuildContext */, surfaces, layoutModel);
- expect(positionedSurfaces.length, 3);
-
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 0.85, width: 0.7, topLeft: Offset(0.0, 0.0));
-
- test_util.assertSurfaceProperties(positionedSurfaces[1],
- height: 1.0, width: 0.3, topLeft: Offset(0.7, 0.0));
- expect(positionedSurfaces[1].surface, commentsSurface2);
-
- test_util.assertSurfaceProperties(positionedSurfaces[2],
- height: 0.15, width: 0.7, topLeft: Offset(0.0, 0.85));
- expect(positionedSurfaces[2].surface, tickerSurface2);
- });
-}
diff --git a/story_shells/mondrian/test/layout/surface_relationship_test.dart b/story_shells/mondrian/test/layout/surface_relationship_test.dart
deleted file mode 100644
index 3f6957a..0000000
--- a/story_shells/mondrian/test/layout/surface_relationship_test.dart
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright 2018 The Fuchsia 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:fidl_fuchsia_modular/fidl_async.dart';
-import 'package:fidl_fuchsia_ui_views/fidl_async.dart';
-import 'package:flutter/widgets.dart';
-import 'package:flutter_test/flutter_test.dart';
-import 'package:mondrian/models/layout_model.dart';
-import 'package:mondrian/layout/copresent_layout.dart' as copresent_layout;
-import 'package:mondrian/models/surface/positioned_surface.dart';
-import 'package:mondrian/models/surface/surface.dart';
-import 'package:mondrian/models/surface/surface_graph.dart';
-import 'package:mondrian/models/surface/surface_properties.dart';
-import 'package:zircon/zircon.dart' show EventPair;
-
-import '../layout_test_utils.dart' as test_util;
-
-void main() {
- LayoutModel layoutModel = LayoutModel();
-
- test('Single surface', () {
- SurfaceGraph graph = SurfaceGraph();
-
- SurfaceProperties properties = SurfaceProperties();
- SurfaceRelation surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.none,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface root = graph.addSurface(
- 'root_of_test', properties, '', surfaceRelation, '', '');
- graph.connectView('root_of_test', ViewHolderToken(value: EventPair(null)));
-
- List<Surface> surfaces = [
- root,
- ];
- List<PositionedSurface> positionedSurfaces = copresent_layout
- .layoutSurfaces(null /* BuildContext */, graph, surfaces, layoutModel);
- expect(positionedSurfaces.length, 1);
-
- expect(positionedSurfaces[0].surface, root);
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 1.0, width: 1.0, topLeft: Offset(0.0, 0.0));
- });
-
- test('Copresent 2 surfaces', () {
- SurfaceGraph graph = SurfaceGraph();
-
- // properties for root surface
- SurfaceProperties properties = SurfaceProperties();
- SurfaceRelation surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.none,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface root = graph.addSurface(
- 'root_of_test', properties, '', surfaceRelation, '', '');
- graph.connectView('root_of_test', ViewHolderToken(value: EventPair(null)));
-
- // properties for the copresent surface
- properties = SurfaceProperties();
- surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface copresentSurface = graph.addSurface('copresentSurface', properties,
- 'root_of_test', surfaceRelation, '', '');
- graph.connectView(
- 'copresentSurface', ViewHolderToken(value: EventPair(null)));
-
- List<Surface> surfaces = [
- root,
- copresentSurface,
- ];
- List<PositionedSurface> positionedSurfaces = copresent_layout
- .layoutSurfaces(null /* BuildContext */, graph, surfaces, layoutModel);
- expect(positionedSurfaces.length, 2);
-
- expect(positionedSurfaces[0].surface, root);
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 1.0, width: 0.5, topLeft: Offset(0.0, 0.0));
-
- expect(positionedSurfaces[1].surface, copresentSurface);
- test_util.assertSurfaceProperties(positionedSurfaces[1],
- height: 1.0, width: 0.5, topLeft: Offset(0.5, 0.0));
- });
-
- test('Sequential surfaces', () {
- SurfaceGraph graph = SurfaceGraph();
-
- // properties for root surface
- SurfaceProperties properties = SurfaceProperties();
- SurfaceRelation surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.none,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface root = graph.addSurface(
- 'root_of_test', properties, '', surfaceRelation, '', '');
- graph.connectView('root_of_test', ViewHolderToken(value: EventPair(null)));
-
- // properties for the sequential surface
- properties = SurfaceProperties();
- surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.sequential,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface sequentialSurface = graph.addSurface('copresentSurface', properties,
- 'root_of_test', surfaceRelation, '', '');
- graph.connectView(
- 'copresentSurface', ViewHolderToken(value: EventPair(null)));
-
- List<Surface> surfaces = [
- root,
- sequentialSurface,
- ];
- List<PositionedSurface> positionedSurfaces = copresent_layout
- .layoutSurfaces(null /* BuildContext */, graph, surfaces, layoutModel);
- expect(positionedSurfaces.length, 1);
-
- expect(positionedSurfaces[0].surface, sequentialSurface);
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 1.0, width: 1.0, topLeft: Offset(0.0, 0.0));
- });
-
- test('one surface ontop of another surface', () {
- SurfaceGraph graph = SurfaceGraph();
-
- // properties for root surface
- SurfaceProperties properties = SurfaceProperties();
- SurfaceRelation surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.none,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface root = graph.addSurface(
- 'root_of_test', properties, '', surfaceRelation, '', '');
- graph.connectView('root_of_test', ViewHolderToken(value: EventPair(null)));
-
- // properties for the ontop surface
- properties = SurfaceProperties();
- surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.ontop,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface ontopSurface = graph.addSurface(
- 'ontop', properties, 'root_of_test', surfaceRelation, '', '');
- graph.connectView('ontop', ViewHolderToken(value: EventPair(null)));
-
- List<Surface> surfaces = [
- root,
- ontopSurface,
- ];
- List<PositionedSurface> positionedSurfaces = copresent_layout
- .layoutSurfaces(null /* BuildContext */, graph, surfaces, layoutModel);
- expect(positionedSurfaces.length, 2);
-
- expect(positionedSurfaces[0].surface, root);
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 1.0, width: 1.0, topLeft: Offset(0.0, 0.0));
-
- expect(positionedSurfaces[1].surface, ontopSurface);
- test_util.assertSurfaceProperties(positionedSurfaces[1],
- height: 1.0, width: 1.0, topLeft: Offset(0.0, 0.0));
- });
-
- test('two surfaces in copresent and one brought ontop of the root surface',
- () {
- SurfaceGraph graph = SurfaceGraph();
-
- // properties for root surface
- SurfaceProperties properties = SurfaceProperties();
- SurfaceRelation surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.none,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface root = graph.addSurface(
- 'root_of_test', properties, '', surfaceRelation, '', '');
- graph.connectView('root_of_test', ViewHolderToken(value: EventPair(null)));
-
- // properties for root surface
- properties = SurfaceProperties();
- surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface copresentSurface = graph.addSurface(
- 'copresent', properties, 'root_of_test', surfaceRelation, '', '');
- graph.connectView('copresent', ViewHolderToken(value: EventPair(null)));
-
- // properties for the ontop surface
- properties = SurfaceProperties();
- surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.ontop,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface ontopSurface = graph.addSurface(
- 'ontop', properties, 'root_of_test', surfaceRelation, '', '');
- graph.connectView('ontop', ViewHolderToken(value: EventPair(null)));
-
- List<Surface> surfaces = [
- root,
- copresentSurface,
- ontopSurface,
- ];
- List<PositionedSurface> positionedSurfaces = copresent_layout
- .layoutSurfaces(null /* BuildContext */, graph, surfaces, layoutModel);
- expect(positionedSurfaces.length, 3);
-
- expect(positionedSurfaces[0].surface, root);
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 1.0, width: 0.5, topLeft: Offset(0.0, 0.0));
-
- expect(positionedSurfaces[1].surface, copresentSurface);
- test_util.assertSurfaceProperties(positionedSurfaces[1],
- height: 1.0, width: 0.5, topLeft: Offset(0.5, 0.0));
-
- expect(positionedSurfaces[2].surface, ontopSurface);
- test_util.assertSurfaceProperties(positionedSurfaces[2],
- height: 1.0, width: 0.5, topLeft: Offset(0.0, 0.0));
- });
-
- test(
- 'two surfaces in copresent and one brought ontop of the copresent surface',
- () {
- SurfaceGraph graph = SurfaceGraph();
-
- // properties for root surface
- SurfaceProperties properties = SurfaceProperties();
- SurfaceRelation surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.none,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface root = graph.addSurface(
- 'root_of_test', properties, '', surfaceRelation, '', '');
- graph.connectView('root_of_test', ViewHolderToken(value: EventPair(null)));
-
- // properties for root surface
- properties = SurfaceProperties();
- surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface copresentSurface = graph.addSurface(
- 'copresent', properties, 'root_of_test', surfaceRelation, '', '');
- graph.connectView('copresent', ViewHolderToken(value: EventPair(null)));
-
- // properties for the ontop surface
- properties = SurfaceProperties();
- surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.ontop,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface ontopSurface = graph.addSurface(
- 'ontop', properties, 'copresent', surfaceRelation, '', '');
- graph.connectView('ontop', ViewHolderToken(value: EventPair(null)));
-
- List<Surface> surfaces = [
- root,
- copresentSurface,
- ontopSurface,
- ];
- List<PositionedSurface> positionedSurfaces = copresent_layout
- .layoutSurfaces(null /* BuildContext */, graph, surfaces, layoutModel);
- expect(positionedSurfaces.length, 3);
-
- expect(positionedSurfaces[0].surface, root);
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 1.0, width: 0.5, topLeft: Offset(0.0, 0.0));
-
- expect(positionedSurfaces[1].surface, copresentSurface);
- test_util.assertSurfaceProperties(positionedSurfaces[1],
- height: 1.0, width: 0.5, topLeft: Offset(0.5, 0.0));
-
- expect(positionedSurfaces[2].surface, ontopSurface);
- test_util.assertSurfaceProperties(positionedSurfaces[2],
- height: 1.0, width: 0.5, topLeft: Offset(0.5, 0.0));
- });
-
- test('three surfaces on top of each other', () {
- SurfaceGraph graph = SurfaceGraph();
-
- // properties for root surface
- SurfaceProperties properties = SurfaceProperties();
- SurfaceRelation surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.none,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface root = graph.addSurface(
- 'root_of_test', properties, '', surfaceRelation, '', '');
- graph.connectView('root_of_test', ViewHolderToken(value: EventPair(null)));
-
- // properties for root surface
- properties = SurfaceProperties();
- surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.ontop,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface firstOnTop = graph.addSurface(
- 'ontop1', properties, 'root_of_test', surfaceRelation, '', '');
- graph.connectView('ontop1', ViewHolderToken(value: EventPair(null)));
-
- // properties for the ontop surface
- properties = SurfaceProperties();
- surfaceRelation = SurfaceRelation(
- arrangement: SurfaceArrangement.ontop,
- dependency: SurfaceDependency.none,
- emphasis: 1.0,
- );
- Surface secondOntop = graph.addSurface(
- 'ontop2', properties, 'ontop1', surfaceRelation, '', '');
- graph.connectView('ontop2', ViewHolderToken(value: EventPair(null)));
-
- List<Surface> surfaces = [
- root,
- firstOnTop,
- secondOntop,
- ];
- List<PositionedSurface> positionedSurfaces = copresent_layout
- .layoutSurfaces(null /* BuildContext */, graph, surfaces, layoutModel);
- expect(positionedSurfaces.length, 3);
-
- expect(positionedSurfaces[0].surface, root);
- test_util.assertSurfaceProperties(positionedSurfaces[0],
- height: 1.0, width: 1.0, topLeft: Offset(0.0, 0.0));
-
- expect(positionedSurfaces[1].surface, firstOnTop);
- test_util.assertSurfaceProperties(positionedSurfaces[1],
- height: 1.0, width: 1.0, topLeft: Offset(0.0, 0.0));
-
- expect(positionedSurfaces[2].surface, secondOntop);
- test_util.assertSurfaceProperties(positionedSurfaces[2],
- height: 1.0, width: 1.0, topLeft: Offset(0.0, 0.0));
- });
-}
diff --git a/story_shells/mondrian/test/layout_test_utils.dart b/story_shells/mondrian/test/layout_test_utils.dart
deleted file mode 100644
index cf75516..0000000
--- a/story_shells/mondrian/test/layout_test_utils.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-import 'package:flutter/widgets.dart';
-import 'package:flutter_test/flutter_test.dart';
-import 'package:mondrian/models/surface/positioned_surface.dart';
-
-/// Utility function to assert properties of a [PositionedSurface].
-void assertSurfaceProperties(PositionedSurface surface,
- {double height, double width, Offset topLeft, Offset bottomRight}) {
- expect(surface.surface, isNotNull);
- Rect position = surface.position;
- // TODO(jphsiao): remove hacks to make tests pass while width and height
- // are incorrect. Issue is tracked in flutter as #18169
- if (height != null) {
- expect(_isWithinMargin(position.height, height, 0.01), true);
- }
- if (width != null) {
- expect(_isWithinMargin(position.width, width, 0.01), true);
- }
- if (topLeft != null) {
- double x = position.topLeft.dx;
- expect(_isWithinMargin(x, topLeft.dx, 0.01), true);
-
- double y = position.topLeft.dy;
- expect(_isWithinMargin(y, topLeft.dy, 0.01), true);
- }
- if (bottomRight != null) {
- double x = position.bottomRight.dx;
- expect(_isWithinMargin(x, bottomRight.dx, 0.01), true);
-
- double y = position.bottomRight.dy;
- expect(_isWithinMargin(y, bottomRight.dy, 0.01), true);
- }
-}
-
-/// Determines whether two values are within the provided margin
-bool _isWithinMargin(double expected, double actual, double margin) {
- return (expected - actual).abs() < margin;
-}
diff --git a/story_shells/mondrian/test/model/surface/surface_graph_test.dart b/story_shells/mondrian/test/model/surface/surface_graph_test.dart
deleted file mode 100644
index 2d75d92..0000000
--- a/story_shells/mondrian/test/model/surface/surface_graph_test.dart
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2018 The Fuchsia 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 'dart:convert';
-
-import 'package:fidl_fuchsia_modular/fidl_async.dart';
-import 'package:fidl_fuchsia_ui_views/fidl_async.dart';
-import 'package:flutter_test/flutter_test.dart';
-import 'package:mondrian/models/surface/surface.dart';
-import 'package:mondrian/models/surface/surface_graph.dart';
-import 'package:mondrian/models/surface/surface_properties.dart';
-import 'package:zircon/zircon.dart';
-
-void main() {
- test('toJson and back again with a single surface', () {
- SurfaceGraph graph = SurfaceGraph();
- SurfaceProperties properties =
- SurfaceProperties(containerLabel: 'containerLabel');
- SurfaceRelation relation = SurfaceRelation(
- emphasis: 0.12,
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.dependent,
- );
- graph
- ..addSurface('value', properties, '', relation, null, '')
- ..connectView('value', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('value');
- expect(graph.focusStack.length, 1);
- String encoded = json.encode(graph);
-
- Map<String, dynamic> decoded = json.decode(encoded);
- SurfaceGraph decodedGraph = SurfaceGraph.fromJson(decoded);
-
- expect(decodedGraph.focusStack.length, 1);
- Surface surface = decodedGraph.focusStack.first;
- expect(surface.node.value, 'value');
- expect(surface.parent, null);
- expect(surface.relation.arrangement, SurfaceArrangement.copresent);
- expect(surface.relation.dependency, SurfaceDependency.dependent);
- expect(surface.relation.emphasis, 0.12);
- expect(surface.properties.containerLabel, 'containerLabel');
- });
-
- test('toJson and back again with two surfaces', () {
- SurfaceGraph graph = SurfaceGraph();
- SurfaceProperties properties =
- SurfaceProperties(containerLabel: 'containerLabel');
- SurfaceRelation relation = SurfaceRelation(
- emphasis: 0.12,
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.dependent,
- );
- graph
- ..addSurface('parent', properties, '', relation, null, '')
- ..connectView('parent', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('parent');
- expect(graph.focusStack.length, 1);
-
- properties = SurfaceProperties(containerLabel: 'containerLabel');
- relation = SurfaceRelation(
- emphasis: 0.5,
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.dependent,
- );
- graph
- ..addSurface('child', properties, 'parent', relation, null, '')
- ..connectView('child', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('child');
- expect(graph.focusStack.length, 2);
-
- String encoded = json.encode(graph);
-
- Map<String, dynamic> decoded = json.decode(encoded);
- SurfaceGraph decodedGraph = SurfaceGraph.fromJson(decoded);
-
- expect(decodedGraph.focusStack.length, 2);
- Surface surface = decodedGraph.focusStack.first;
- expect(surface.node.value, 'parent');
- expect(surface.node.parent.value, null);
-
- // expect(surface.parentId, null);
- expect(surface.relation.arrangement, SurfaceArrangement.copresent);
- expect(surface.relation.dependency, SurfaceDependency.dependent);
- expect(surface.relation.emphasis, 0.12);
- expect(surface.properties.containerLabel, 'containerLabel');
- expect(surface.children.length, 1);
- expect(surface.children.first.node.value, 'child');
-
- Surface secondSurface = decodedGraph.focusStack.last;
- expect(secondSurface.node.value, 'child');
- expect(secondSurface.parentId, 'parent');
- expect(secondSurface.relation.arrangement, SurfaceArrangement.copresent);
- expect(secondSurface.relation.dependency, SurfaceDependency.dependent);
- expect(secondSurface.relation.emphasis, 0.5);
- expect(secondSurface.properties.containerLabel, 'containerLabel');
- });
-
- test('toJson and back again with one surface with two children', () {
- SurfaceGraph graph = SurfaceGraph();
- SurfaceProperties properties =
- SurfaceProperties(containerLabel: 'containerLabel');
- SurfaceRelation relation = SurfaceRelation(
- emphasis: 0.12,
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.dependent,
- );
- graph
- ..addSurface('parent', properties, '', relation, null, '')
- ..connectView('parent', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('parent');
- expect(graph.focusStack.length, 1);
-
- properties = SurfaceProperties(containerLabel: 'containerLabel');
- relation = SurfaceRelation(
- emphasis: 0.5,
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.dependent,
- );
- graph
- ..addSurface('child1', properties, 'parent', relation, null, '')
- ..connectView('child', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('child1');
- expect(graph.focusStack.length, 2);
-
- properties = SurfaceProperties(containerLabel: 'containerLabel');
- relation = SurfaceRelation(
- emphasis: 0.0,
- arrangement: SurfaceArrangement.ontop,
- dependency: SurfaceDependency.dependent,
- );
- graph
- ..addSurface('child2', properties, 'parent', relation, null, '')
- ..connectView('child2', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('child2');
- expect(graph.focusStack.length, 3);
-
- String encoded = json.encode(graph);
-
- Map<String, dynamic> decoded = json.decode(encoded);
- SurfaceGraph decodedGraph = SurfaceGraph.fromJson(decoded);
-
- expect(decodedGraph.focusStack.length, 3);
- Surface surface = decodedGraph.focusStack.first;
- expect(surface.node.value, 'parent');
- expect(surface.node.parent.value, null);
- expect(surface.relation.arrangement, SurfaceArrangement.copresent);
- expect(surface.relation.dependency, SurfaceDependency.dependent);
- expect(surface.relation.emphasis, 0.12);
- expect(surface.properties.containerLabel, 'containerLabel');
- expect(surface.children.length, 2);
- List<String> children = [];
- for (Surface surface in surface.children) {
- children.add(surface.node.value);
- }
- expect(children.first, 'child1');
- expect(children.last, 'child2');
-
- Surface secondSurface = decodedGraph.focusStack.toList()[1];
- expect(secondSurface.node.value, 'child1');
- expect(secondSurface.parentId, 'parent');
- expect(secondSurface.relation.arrangement, SurfaceArrangement.copresent);
- expect(secondSurface.relation.dependency, SurfaceDependency.dependent);
- expect(secondSurface.relation.emphasis, 0.5);
- expect(secondSurface.properties.containerLabel, 'containerLabel');
-
- Surface thirdSurface = decodedGraph.focusStack.last;
- expect(thirdSurface.node.value, 'child2');
- expect(thirdSurface.parentId, 'parent');
- expect(thirdSurface.relation.arrangement, SurfaceArrangement.ontop);
- expect(thirdSurface.relation.dependency, SurfaceDependency.dependent);
- expect(thirdSurface.relation.emphasis, 0.0);
- expect(thirdSurface.properties.containerLabel, 'containerLabel');
- });
-
- test('external surfaces are found by resummon dismissed checks', () {
- SurfaceGraph graph = SurfaceGraph();
- SurfaceProperties externalProp =
- SurfaceProperties(source: ModuleSource.external);
- graph
- ..addSurface(
- 'parent', SurfaceProperties(), '', SurfaceRelation(), null, '')
- ..connectView('parent', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('parent')
- // Now add external surface
- ..addSurface(
- 'external', externalProp, 'parent', SurfaceRelation(), null, '')
- ..connectView('external', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('external')
- // Now dismiss the external surface
- ..dismissSurface('external');
- // expect that there is a dismissed external associated with the parent
- expect(graph.externalSurfaces(surfaceId: 'parent'), ['external']);
- });
-
- test('duplicate surface add', () {
- SurfaceGraph graph = SurfaceGraph();
- SurfaceProperties properties =
- SurfaceProperties(containerLabel: 'containerLabel');
- SurfaceRelation relation = SurfaceRelation(
- emphasis: 0.12,
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.dependent,
- );
- graph
- ..addSurface('value', properties, '', relation, null, '')
- ..connectView('value', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('value');
- expect(graph.treeSize, 2);
-
- graph
- ..addSurface('value', properties, '', relation, null, '')
- ..connectView('value', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('value');
- expect(graph.treeSize, 2);
- });
-
- test('duplicate child surface add', () {
- SurfaceGraph graph = SurfaceGraph();
- SurfaceProperties properties =
- SurfaceProperties(containerLabel: 'containerLabel');
- SurfaceRelation relation = SurfaceRelation(
- emphasis: 0.12,
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.dependent,
- );
- graph
- ..addSurface('value', properties, '', relation, null, '')
- ..connectView('value', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('value');
- expect(graph.treeSize, 2);
-
- graph
- ..addSurface('value.child', properties, '', relation, null, '')
- ..connectView('value.child', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('value.child');
- expect(graph.treeSize, 3);
-
- graph
- ..addSurface('value.child', properties, '', relation, null, '')
- ..connectView('value.child', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('value.child');
- expect(graph.treeSize, 3);
- });
-
- test('duplicate child surface add', () {
- SurfaceGraph graph = SurfaceGraph();
- SurfaceProperties properties =
- SurfaceProperties(containerLabel: 'containerLabel');
- SurfaceRelation relation = SurfaceRelation(
- emphasis: 0.12,
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.dependent,
- );
- graph
- ..addSurface('value', properties, '', relation, null, '')
- ..connectView('value', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('value');
- expect(graph.treeSize, 2);
-
- graph
- ..addSurface('value.child', properties, '', relation, null, '')
- ..connectView('value.child', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('value.child');
- expect(graph.treeSize, 3);
-
- graph
- ..addSurface('value.child', properties, '', relation, null, '')
- ..connectView('value.child', ViewHolderToken(value: EventPair(null)))
- ..focusSurface('value.child');
- expect(graph.treeSize, 3);
- });
-}
diff --git a/story_shells/mondrian/test/model/surface/surface_test.dart b/story_shells/mondrian/test/model/surface/surface_test.dart
deleted file mode 100644
index fe04f5a..0000000
--- a/story_shells/mondrian/test/model/surface/surface_test.dart
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2018 The Fuchsia 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 'dart:convert';
-
-import 'package:fidl_fuchsia_modular/fidl_async.dart';
-import 'package:flutter_test/flutter_test.dart';
-import 'package:mondrian/models/surface/surface.dart';
-import 'package:mondrian/models/surface/surface_graph.dart';
-import 'package:mondrian/models/surface/surface_properties.dart';
-import 'package:mondrian/models/surface/surface_relation_util.dart';
-import 'package:mondrian/models/tree/tree.dart';
-
-void main() {
- test('toJson and fromJson', () {
- SurfaceGraph graph = SurfaceGraph();
- Tree parent = Tree<String>(value: null);
- Tree node = Tree<String>(value: 'value');
- Tree child = Tree<String>(value: 'childValue');
- parent.add(node);
- node.add(child);
- SurfaceProperties properties = SurfaceProperties(
- containerLabel: 'containerLabel', source: ModuleSource.external);
- SurfaceRelation relation = SurfaceRelation(
- emphasis: 0.12,
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.dependent,
- );
- Surface surface = Surface(graph, node, properties, relation, null, '');
- String encoded = json.encode(surface);
- Map decodedJson = json.decode(encoded);
- Surface decodedSurface = Surface.fromJson(decodedJson, graph);
- expect(decodedSurface.node.value, 'value');
- expect(decodedSurface.isParentRoot, true);
- expect(decodedSurface.relation.emphasis, 0.12);
- expect(decodedSurface.relation.arrangement, SurfaceArrangement.copresent);
- expect(decodedSurface.relation.dependency, SurfaceDependency.dependent);
- expect(decodedSurface.properties.containerLabel, 'containerLabel');
- expect(decodedSurface.properties.source, ModuleSource.external);
- expect(decodedSurface.compositionPattern, null);
- });
-
- test('encode and decode surfaceRelation', () {
- SurfaceRelation relation = SurfaceRelation(
- emphasis: 0.5,
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.dependent,
- );
- Map<String, String> relationMap = SurfaceRelationUtil.toMap(relation);
- SurfaceRelation decodedRelation = SurfaceRelationUtil.decode(relationMap);
- expect(decodedRelation.arrangement, SurfaceArrangement.copresent);
- expect(decodedRelation.dependency, SurfaceDependency.dependent);
- expect(decodedRelation.emphasis, 0.5);
- });
-
- test('toJson and fromJson with empty surface properties', () {
- SurfaceGraph graph = SurfaceGraph();
- Tree parent = Tree<String>(value: null);
- Tree node = Tree<String>(value: 'value');
- Tree child = Tree<String>(value: 'childValue');
- parent.add(node);
- node.add(child);
- SurfaceProperties properties = SurfaceProperties();
- SurfaceRelation relation = SurfaceRelation(
- emphasis: 0.12,
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.dependent,
- );
- Surface surface = Surface(graph, node, properties, relation, null, '');
- String encoded = json.encode(surface);
- Map decodedJson = json.decode(encoded);
- Surface decodedSurface = Surface.fromJson(decodedJson, graph);
- expect(decodedSurface.node.value, 'value');
- expect(decodedSurface.isParentRoot, true);
- expect(decodedSurface.relation.emphasis, 0.12);
- expect(decodedSurface.relation.arrangement, SurfaceArrangement.copresent);
- expect(decodedSurface.relation.dependency, SurfaceDependency.dependent);
- expect(decodedSurface.properties.containerLabel, null);
- expect(decodedSurface.properties.source, null);
- expect(decodedSurface.compositionPattern, null);
- });
-
- test('encode and decode surfaceRelation', () {
- SurfaceRelation relation = SurfaceRelation(
- emphasis: 0.5,
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.dependent,
- );
- Map<String, String> relationMap = SurfaceRelationUtil.toMap(relation);
- SurfaceRelation decodedRelation = SurfaceRelationUtil.decode(relationMap);
- expect(decodedRelation.arrangement, SurfaceArrangement.copresent);
- expect(decodedRelation.dependency, SurfaceDependency.dependent);
- expect(decodedRelation.emphasis, 0.5);
- });
-}
diff --git a/story_shells/mondrian/test/model/tree/spanning_tree_test.dart b/story_shells/mondrian/test/model/tree/spanning_tree_test.dart
deleted file mode 100644
index 35e8211..0000000
--- a/story_shells/mondrian/test/model/tree/spanning_tree_test.dart
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2018 The Fuchsia 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 'dart:convert';
-
-import 'package:fidl_fuchsia_modular/fidl_async.dart';
-import 'package:flutter_test/flutter_test.dart';
-import 'package:mondrian/models/surface/surface.dart';
-import 'package:mondrian/models/surface/surface_graph.dart';
-import 'package:mondrian/models/surface/surface_properties.dart';
-import 'package:mondrian/models/tree/spanning_tree.dart';
-import 'package:mondrian/models/tree/tree.dart';
-
-void main() {
- SurfaceGraph graph;
- SurfaceProperties properties = SurfaceProperties();
- SurfaceRelation depcop = SurfaceRelation(
- emphasis: 0.12,
- arrangement: SurfaceArrangement.copresent,
- dependency: SurfaceDependency.dependent,
- );
- SurfaceRelation cop =
- SurfaceRelation(arrangement: SurfaceArrangement.copresent);
- SurfaceRelation unrelated =
- SurfaceRelation(arrangement: SurfaceArrangement.sequential);
-
- setUp(() {
- graph = SurfaceGraph();
- });
-
- test('getCopresentSpanningTree with one surface in the graph', () {
- Surface parent =
- graph.addSurface('value', properties, '', depcop, null, '');
- Tree<Surface> spanningTree = getCopresentSpanningTree(parent);
- expect(spanningTree.length, 1);
- expect(spanningTree.value, parent);
- });
-
- test('getCopresentSpanningTree from grandchild with 3 surfaces in the graph',
- () {
- Surface parent =
- graph.addSurface('parent', properties, '', depcop, null, '');
- Surface child =
- graph.addSurface('child', properties, 'parent', depcop, null, '');
- Surface grandchild =
- graph.addSurface('grandchild', properties, 'child', depcop, null, '');
- Tree<Surface> spanningTree = getCopresentSpanningTree(grandchild);
-
- expect(spanningTree.length, 3);
- expect(spanningTree.value, grandchild);
- List<Surface> children =
- spanningTree.map((Tree<Surface> node) => node.value).toList();
- expect(children.contains(child), true);
- expect(children.contains(parent), true);
- });
-
- test(
- 'getCopresentSpanningTree from grandchild with 2 other unrelated surfaces in the graph',
- () {
- graph
- ..addSurface('a', properties, '', depcop, null, '')
- ..addSurface('b', properties, '', depcop, null, '');
- Surface grandchild =
- graph.addSurface('c', properties, '', depcop, null, '');
- Tree<Surface> spanningTree = getCopresentSpanningTree(grandchild);
-
- expect(spanningTree.length, 1);
- expect(spanningTree.value, grandchild);
- });
-
- test(
- 'getDependentSpanningTree from node with 2 unrelated surfaces in the graph',
- () {
- graph
- ..addSurface('a', properties, '', depcop, null, '')
- ..addSurface('b', properties, '', depcop, null, '');
- Surface grandchild =
- graph.addSurface('c', properties, '', depcop, null, '');
- Tree<Surface> spanningTree = getDependentSpanningTree(grandchild);
-
- expect(spanningTree.length, 1);
- expect(spanningTree.value, grandchild);
- });
-
- test(
- 'getDependentSpanningTree from grandchild with 2 related surfaces in the graph',
- () {
- graph
- ..addSurface('parent', properties, '', depcop, null, '')
- ..addSurface('child', properties, 'parent', depcop, null, '')
- ..addSurface('unrelated', properties, 'child', unrelated, null, '');
- Surface grandchild =
- graph.addSurface('grandchild', properties, 'child', depcop, null, '');
- Tree<Surface> spanningTree = getDependentSpanningTree(grandchild);
-
- expect(spanningTree.length, 3);
- });
-
- test('getDependentSpanningTrees with 1 tree', () {
- graph
- ..addSurface('parent', properties, '', depcop, null, '')
- ..addSurface('child', properties, 'parent', depcop, null, '');
- Surface grandchild =
- graph.addSurface('grandchild', properties, 'child', depcop, null, '');
- List<Tree<Surface>> spanningTrees = getDependentSpanningTrees(grandchild);
- expect(spanningTrees.length, 1);
- });
-
- test('getDependentSpanningTrees with 2 trees', () {
- Surface firstRoot =
- graph.addSurface('firstRoot', properties, '', depcop, null, '');
- graph
- ..addSurface('child', properties, 'firstRoot', depcop, null, '')
- ..addSurface('grandchild', properties, 'child', depcop, null, '')
- ..addSurface('secondRoot', properties, 'firstRoot', cop, null, '')
- ..addSurface('secondChild', properties, 'secondRoot', depcop, null, '');
- List<Tree<Surface>> spanningTrees = getDependentSpanningTrees(firstRoot);
- expect(spanningTrees.length, 2);
- });
-}
diff --git a/story_shells/mondrian/test/model/tree/tree_test.dart b/story_shells/mondrian/test/model/tree/tree_test.dart
deleted file mode 100644
index 11d23b3..0000000
--- a/story_shells/mondrian/test/model/tree/tree_test.dart
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2017 The Fuchsia 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:flutter_test/flutter_test.dart';
-import 'package:mondrian/models/tree/tree.dart';
-
-/// Convenience function for making trees
-
-Tree<String> t(Tree<String> node, {List<Tree<String>> children}) {
- children?.forEach(node.add);
- return node;
-}
-
-void main() {
- Tree<String> grandparent; // the root
- Tree<String> parent;
- Tree<String> uncle;
- Tree<String> aunt;
- Tree<String> cousin;
- Tree<String> sibling;
- Tree<String> sibling2;
- Tree<String> niece;
- Tree<String> child;
-
- Tree<String> trimmedTree;
- Forest<String> forest;
-
- Tree<String> secondRoot;
- Tree<String> friend;
- Tree<String> childFriend;
-
- List<Tree<String>> expectedTree;
- List<Tree<String>> expectedForest;
-
- setUp(() {
- grandparent = Tree<String>(value: 'grandparent');
- parent = Tree<String>(value: 'parent');
- uncle = Tree<String>(value: 'uncle');
- aunt = Tree<String>(value: 'aunt');
- cousin = Tree<String>(value: 'cousin');
- sibling = Tree<String>(value: 'sibling');
- sibling2 = Tree<String>(value: 'sibling2');
- niece = Tree<String>(value: 'niece');
- child = Tree<String>(value: 'child');
-
- grandparent = t(
- // the root
- grandparent,
- children: <Tree<String>>[
- t(
- parent,
- children: <Tree<String>>[
- sibling,
- child,
- t(
- sibling2,
- children: <Tree<String>>[niece],
- ),
- ],
- ),
- uncle,
- t(
- aunt,
- children: <Tree<String>>[cousin],
- ),
- ],
- );
-
- trimmedTree = t(
- Tree<String>(value: grandparent.value),
- children: <Tree<String>>[uncle, aunt],
- );
-
- forest = Forest<String>()..add(grandparent);
-
- secondRoot = Tree<String>(value: 'parent of friend');
- friend = Tree<String>(value: 'friend');
- childFriend = Tree<String>(value: 'child of friend');
-
- secondRoot = t(
- secondRoot, // the root
- children: <Tree<String>>[
- t(
- friend,
- children: <Tree<String>>[childFriend],
- ),
- ],
- );
-
- expectedTree = <Tree<String>>[
- grandparent,
- parent,
- uncle,
- aunt,
- sibling,
- child,
- sibling2,
- cousin,
- niece
- ];
-
- expectedForest = <Tree<String>>[
- grandparent,
- parent,
- uncle,
- aunt,
- sibling,
- child,
- sibling2,
- cousin,
- niece,
- secondRoot,
- friend,
- childFriend
- ];
-
- forest.add(secondRoot);
- });
-
- group('Test Tree in tree.dart', () {
- test('we can find root', () {
- expect(niece.root.value, equals(grandparent.value));
- });
- test('we can find correct children', () {
- print(grandparent.children);
- expect(grandparent.children, equals(<Tree<String>>[parent, uncle, aunt]));
- });
- test('we can find correct ancestors', () {
- expect(niece.ancestors,
- equals(<Tree<String>>[sibling2, parent, grandparent]));
- });
- test('we can find correct parent', () {
- expect(niece.parent, equals(sibling2));
- });
- test('flatten works as expected (breadth-first)', () {
- // flatten - breadth first
- expect(grandparent.flatten().toList(), equals(expectedTree));
- });
- test('we detach nodes correctly', () {
- parent.detach();
- expect(grandparent.values, equals(trimmedTree.values));
- });
- test('ancestors are correct post-detachement', () {
- parent.detach();
- expect(niece.ancestors, equals(<Tree<String>>[sibling2, parent]));
- });
- test('siblings are found correctly', () {
- expect(child.siblings, equals(<Tree<String>>[sibling, sibling2]));
- });
- test('we can use find tp find subsequent nodes', () {
- expect(grandparent.find('niece'), equals(niece));
- });
- test('find does not search upwards in tree', () {
- expect(niece.find('root'), equals(null));
- });
- });
-
- group('Test Forest in tree.dart', () {
- test('Forest roots found correctly', () {
- expect(forest.roots, equals(<Tree<String>>[grandparent, secondRoot]));
- });
- test('Adding root to Forest', () {
- forest.add(secondRoot);
- expect(forest.roots,
- equals(<Tree<String>>[grandparent, secondRoot, secondRoot]));
- });
- test('Flatten forest is breadth-first', () {
- expect(forest.flatten().toList(), equals(expectedForest));
- });
- test('Forest values', () {
- List<String> evals =
- expectedForest.map((Tree<String> f) => f.value).toList();
- expect(forest.values.toList(), equals(evals));
- });
- test('Remove node from Forest, roots unchanged', () {
- forest.remove(parent);
- expect(forest.roots, equals(<Tree<String>>[grandparent, secondRoot]));
- });
- test('Remove node from Forest, node really removed', () {
- forest.remove(parent);
- expect(forest.find('grandparent').find('parent'), equals(null));
- });
- test('Remove root from Forest', () {
- // remove a root
- forest.remove(grandparent);
- // new roots
- expect(forest.roots,
- equals(<Tree<String>>[secondRoot, parent, uncle, aunt]));
- });
- test('Find a node in Forest', () {
- expect(forest.find('sibling'), equals(sibling));
- });
- test('mapForest to Uppercase', () {
- Forest<String> newForest =
- forest.mapForest((String f) => f.toUpperCase());
- expect(newForest.find('NIECE').parent.parent.parent,
- equals(newForest.find('GRANDPARENT')));
- });
- });
-}