Commit 35ac1f71 authored by Adam Barth's avatar Adam Barth

Add dartdoc for base

parent 984a39f4
......@@ -4,6 +4,7 @@
import 'dart:sky' as sky;
/// Indicates whether we're running with asserts enabled.
final bool inDebugBuild = _initInDebugBuild();
bool _initInDebugBuild() {
......@@ -16,16 +17,29 @@ bool _initInDebugBuild() {
return _inDebug;
}
/// Causes each RenderBox to paint a box around its bounds.
bool debugPaintSizeEnabled = false;
/// The color to use when painting RenderObject bounds.
const sky.Color debugPaintSizeColor = const sky.Color(0xFF00FFFF);
/// Causes each RenderBox to paint a line at each of its baselines.
bool debugPaintBaselinesEnabled = false;
/// The color to use when painting alphabetic baselines.
const sky.Color debugPaintAlphabeticBaselineColor = const sky.Color(0xFF00FF00);
/// The color ot use when painting ideographic baselines.
const sky.Color debugPaintIdeographicBaselineColor = const sky.Color(0xFFFFD000);
/// Causes each Layer to paint a box around its bounds.
bool debugPaintLayerBordersEnabled = false;
/// The color to use when painting Layer borders.
const sky.Color debugPaintLayerBordersColor = const sky.Color(0xFFFF9800);
/// Causes RenderObjects to paint warnings when painting outside their bounds.
bool debugPaintBoundsEnabled = false;
/// Slows down animations by this factor to help in development.
double timeDilation = 1.0;
......@@ -4,12 +4,22 @@
import 'dart:sky' as sky;
/// The outcome of running an event handler.
enum EventDisposition {
/// The event handler ignored this event.
ignored,
/// The event handler did not ignore the event but other event handlers should
/// process the event as well.
processed,
/// The event handler did not ignore the event and other event handlers
/// should not process the event.
consumed,
}
/// Merges two [EventDisposition] values such that the result indicates the
/// maximum amount of processing indicated by the two inputs.
EventDisposition combineEventDispositions(EventDisposition left, EventDisposition right) {
if (left == EventDisposition.consumed || right == EventDisposition.consumed)
return EventDisposition.consumed;
......@@ -18,22 +28,42 @@ EventDisposition combineEventDispositions(EventDisposition left, EventDispositio
return EventDisposition.ignored;
}
/// An object that can handle events.
abstract class HitTestTarget {
/// Override this function to receive events.
EventDisposition handleEvent(sky.Event event, HitTestEntry entry);
}
/// Data collected during a hit test about a specific [HitTestTarget].
///
/// Subclass this object to pass additional information from the hit test phase
/// to the event propagation phase.
class HitTestEntry {
const HitTestEntry(this.target);
/// The [HitTestTarget] encountered during the hit test.
final HitTestTarget target;
}
/// The result of performing a hit test.
class HitTestResult {
HitTestResult({ List<HitTestEntry> path })
: path = path != null ? path : new List<HitTestEntry>();
/// The list of [HitTestEntry] objects recorded during the hit test.
///
/// The first entry in the path is the least specific, typically the one at
/// the root of tree being hit tested. Event propagation starts with the most
/// specific (i.e., last) entry and proceeds in reverse order through the
/// path.
final List<HitTestEntry> path;
void add(HitTestEntry data) {
path.add(data);
/// Add a [HitTestEntry] to the path.
///
/// The new entry is added at the end of the path, which means entries should
/// be added in order from last specific to most specific, typically during a
/// downward walk in the tree being hit tested.
void add(HitTestEntry entry) {
path.add(entry);
}
}
......@@ -5,8 +5,14 @@
import 'dart:async';
import 'dart:sky' as sky;
/// A callback for when the image is available.
typedef void ImageListener(sky.Image image);
/// A handle to an image resource
///
/// ImageResource represents a handle to a [sky.Image] object. The underlying
/// image object might change over time, either because the image is animating
/// or because the underlying image resource was mutated.
class ImageResource {
ImageResource(this._futureImage) {
_futureImage.then(_handleImageLoaded, onError: _handleImageError);
......@@ -17,14 +23,22 @@ class ImageResource {
sky.Image _image;
final List<ImageListener> _listeners = new List<ImageListener>();
/// The first concrete [sky.Image] object represented by this handle.
///
/// Instead of receivingly only the first image, most clients will want to
/// [addListener] to be notified whenever a a concrete image is available.
Future<sky.Image> get first => _futureImage;
/// Adds a listener callback that is called whenever a concrete [sky.Image]
/// object is available. Note: If a concrete image is available currently,
/// this object will call the listener synchronously.
void addListener(ImageListener listener) {
_listeners.add(listener);
if (_resolved)
listener(_image);
}
/// Stop listening for new concrete [sky.Image] objects.
void removeListener(ImageListener listener) {
_listeners.remove(listener);
}
......
......@@ -4,6 +4,7 @@
import 'dart:sky';
/// Linearly interpolate between two numbers.
num lerpNum(num a, num b, double t) {
if (a == null && b == null)
return null;
......@@ -18,6 +19,10 @@ Color _scaleAlpha(Color a, double factor) {
return a.withAlpha((a.alpha * factor).round());
}
/// Linearly interpolate between two [Color] objects.
///
/// If either color is null, this function linearly interpolates from a
/// transparent instance of othe other color.
Color lerpColor(Color a, Color b, double t) {
if (a == null && b == null)
return null;
......@@ -33,6 +38,9 @@ Color lerpColor(Color a, Color b, double t) {
);
}
/// Linearly interpolate between two [Offset] objects.
///
/// If either offset is null, this function interpolates from [Offset.zero].
Offset lerpOffset(Offset a, Offset b, double t) {
if (a == null && b == null)
return null;
......@@ -43,6 +51,9 @@ Offset lerpOffset(Offset a, Offset b, double t) {
return new Offset(lerpNum(a.dx, b.dx, t), lerpNum(a.dy, b.dy, t));
}
/// Linearly interpolate between two [Rect] objects.
///
/// If either rect is null, this function interpolates from 0x0x0x0.
Rect lerpRect(Rect a, Rect b, double t) {
if (a == null && b == null)
return null;
......
......@@ -2,45 +2,73 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/// An abstract node in a tree
///
/// AbstractNode has as notion of depth, attachment, and parent, but does not
/// have a model for children.
class AbstractNode {
// AbstractNode represents a node in a tree.
// The AbstractNode protocol is described in README.md.
int _depth = 0;
/// The depth of this node in the tree.
///
/// The depth of nodes in a tree monotonically increases as you traverse down
/// the trees.
int get depth => _depth;
void redepthChild(AbstractNode child) { // internal, do not call
/// Call only from overrides of [redepthChildren]
void redepthChild(AbstractNode child) {
assert(child._attached == _attached);
if (child._depth <= _depth) {
child._depth = _depth + 1;
child.redepthChildren();
}
}
void redepthChildren() { // internal, do not call
// override this in subclasses with child nodes
// simply call redepthChild(child) for each child
}
/// Override this function in subclasses with child nodes to call
/// redepthChild(child) for each child. Do not call directly.
void redepthChildren() { }
bool _attached = false;
/// Whether this node is in a tree whose root is attached to something.
bool get attached => _attached;
/// Mark this node as attached.
///
/// Typically called only from overrides of [attachChildren] and to mark the
/// root of a tree attached.
void attach() {
// override this in subclasses with child nodes
// simply call attach() for each child then call your superclass
_attached = true;
attachChildren();
}
attachChildren() { } // workaround for lack of inter-class mixins in Dart
/// Override this function in subclasses with child to call attach() for each
/// child. Do not call directly.
attachChildren() { }
/// Mark this node as detached.
///
/// Typically called only from overrides for [detachChildren] and to mark the
/// root of a tree detached.
void detach() {
// override this in subclasses with child nodes
// simply call detach() for each child then call your superclass
_attached = false;
detachChildren();
}
detachChildren() { } // workaround for lack of inter-class mixins in Dart
/// Override this function in subclasses with child to call detach() for each
/// child. Do not call directly.
detachChildren() { }
// TODO(ianh): remove attachChildren()/detachChildren() workaround once mixins can use super.
AbstractNode _parent;
/// The parent of this node in the tree.
AbstractNode get parent => _parent;
void adoptChild(AbstractNode child) { // only for use by subclasses
/// Subclasses should call this function when they acquire a new child.
void adoptChild(AbstractNode child) {
assert(child != null);
assert(child._parent == null);
child._parent = this;
......@@ -48,7 +76,9 @@ class AbstractNode {
child.attach();
redepthChild(child);
}
void dropChild(AbstractNode child) { // only for use by subclasses
/// Subclasses should call this function when they lose a child.
void dropChild(AbstractNode child) {
assert(child != null);
assert(child._parent == this);
assert(child.attached == attached);
......
......@@ -4,31 +4,44 @@
import 'dart:sky' as sky;
typedef void _Route(sky.PointerEvent event);
/// A callback that receives a [sky.PointerEvent]
typedef void PointerRoute(sky.PointerEvent event);
/// A routing table for [sky.PointerEvent] events.
class PointerRouter {
final Map<int, List<_Route>> _routeMap = new Map<int, List<_Route>>();
final Map<int, List<PointerRoute>> _routeMap = new Map<int, List<PointerRoute>>();
void addRoute(int pointer, _Route route) {
List<_Route> routes = _routeMap.putIfAbsent(pointer, () => new List<_Route>());
/// Adds a route to the routing table
///
/// Whenever this object routes a [sky.PointerEvent] corresponding to
/// pointer, call route.
void addRoute(int pointer, PointerRoute route) {
List<PointerRoute> routes = _routeMap.putIfAbsent(pointer, () => new List<PointerRoute>());
assert(!routes.contains(route));
routes.add(route);
}
void removeRoute(int pointer, _Route route) {
/// Removes a route from the routing table
///
/// No longer call route when routing a [sky.PointerEvent] corresponding to
/// pointer. Requires that this route was previously added to the router.
void removeRoute(int pointer, PointerRoute route) {
assert(_routeMap.containsKey(pointer));
List<_Route> routes = _routeMap[pointer];
List<PointerRoute> routes = _routeMap[pointer];
assert(routes.contains(route));
routes.remove(route);
if (routes.isEmpty)
_routeMap.remove(pointer);
}
/// Call the routes registed for this pointer event.
///
/// Calls the routes in the order in which they were added to the route.
void route(sky.PointerEvent event) {
List<_Route> routes = _routeMap[event.pointer];
List<PointerRoute> routes = _routeMap[event.pointer];
if (routes == null)
return;
for (_Route route in new List<_Route>.from(routes))
for (PointerRoute route in new List<PointerRoute>.from(routes))
route(event);
}
}
......@@ -7,22 +7,33 @@ import 'dart:sky' as sky;
import 'package:sky/base/debug.dart';
typedef void Callback(double timeStamp);
/// A callback from the scheduler
///
/// The timeStamp is the number of milliseconds since the beginning of the
/// scheduler's epoch. Use timeStamp to determine how far to advance animation
/// timelines so that all the animations in the system are synchronized to a
/// common time base.
typedef void SchedulerCallback(double timeStamp);
bool _haveScheduledVisualUpdate = false;
int _nextCallbackId = 1;
final List<Callback> _persistentCallbacks = new List<Callback>();
Map<int, Callback> _transientCallbacks = new LinkedHashMap<int, Callback>();
final List<SchedulerCallback> _persistentCallbacks = new List<SchedulerCallback>();
Map<int, SchedulerCallback> _transientCallbacks = new LinkedHashMap<int, SchedulerCallback>();
final Set<int> _removedIds = new Set<int>();
/// Called by the engine to produce a new frame.
///
/// This function first calls all the callbacks registered by
/// [requestAnimationFrame] and then calls all the callbacks registered by
/// [addPersistentFrameCallback], which typically drive the rendering pipeline.
void beginFrame(double timeStamp) {
timeStamp /= timeDilation;
_haveScheduledVisualUpdate = false;
Map<int, Callback> callbacks = _transientCallbacks;
_transientCallbacks = new Map<int, Callback>();
Map<int, SchedulerCallback> callbacks = _transientCallbacks;
_transientCallbacks = new Map<int, SchedulerCallback>();
callbacks.forEach((id, callback) {
if (!_removedIds.contains(id))
......@@ -30,30 +41,45 @@ void beginFrame(double timeStamp) {
});
_removedIds.clear();
for (Callback callback in _persistentCallbacks)
for (SchedulerCallback callback in _persistentCallbacks)
callback(timeStamp);
}
/// Registers [beginFrame] callback with the engine.
void init() {
sky.view.setFrameCallback(beginFrame);
}
void addPersistentFrameCallback(Callback callback) {
/// Call callback every frame.
void addPersistentFrameCallback(SchedulerCallback callback) {
_persistentCallbacks.add(callback);
}
int requestAnimationFrame(Callback callback) {
/// Schedule a callback for the next frame.
///
/// The callback will be run prior to flushing the main rendering pipeline.
/// Typically, requestAnimationFrame is used to throttle writes into the
/// rendering pipeline until the system is ready to accept a new frame. For
/// example, if you wanted to tick through an animation, you should use
/// requestAnimation frame to determine when to tick the animation. The callback
/// is passed a timeStamp that you can use to determine how far along the
/// timeline to advance your animation.
///
/// Returns an id that can be used to unschedule this callback.
int requestAnimationFrame(SchedulerCallback callback) {
int id = _nextCallbackId++;
_transientCallbacks[id] = callback;
ensureVisualUpdate();
return id;
}
/// Cancel the callback identified by id.
void cancelAnimationFrame(int id) {
_transientCallbacks.remove(id);
_removedIds.add(id);
}
/// Ensure that a frame will be produced after this function is called.
void ensureVisualUpdate() {
if (_haveScheduledVisualUpdate)
return;
......
......@@ -4,21 +4,21 @@
/// Includes and re-exports all Sky rendering classes.
export 'rendering/auto_layout.dart';
export 'rendering/block.dart';
export 'rendering/box.dart';
export 'rendering/flex.dart';
export 'rendering/grid.dart';
export 'rendering/image.dart';
export 'rendering/layer.dart';
export 'rendering/object.dart';
export 'rendering/paragraph.dart';
export 'rendering/proxy_box.dart';
export 'rendering/shifted_box.dart';
export 'rendering/sky_binding.dart';
export 'rendering/stack.dart';
export 'rendering/toggleable.dart';
export 'rendering/view.dart';
export 'rendering/viewport.dart';
export 'package:sky/rendering/auto_layout.dart';
export 'package:sky/rendering/block.dart';
export 'package:sky/rendering/box.dart';
export 'package:sky/rendering/flex.dart';
export 'package:sky/rendering/grid.dart';
export 'package:sky/rendering/image.dart';
export 'package:sky/rendering/layer.dart';
export 'package:sky/rendering/object.dart';
export 'package:sky/rendering/paragraph.dart';
export 'package:sky/rendering/proxy_box.dart';
export 'package:sky/rendering/shifted_box.dart';
export 'package:sky/rendering/sky_binding.dart';
export 'package:sky/rendering/stack.dart';
export 'package:sky/rendering/toggleable.dart';
export 'package:sky/rendering/view.dart';
export 'package:sky/rendering/viewport.dart';
export 'package:vector_math/vector_math.dart' show Matrix4;
......@@ -4,49 +4,49 @@
/// Includes and re-exports all Sky widgets classes.
export 'widgets/animated_component.dart';
export 'widgets/animated_container.dart';
export 'widgets/basic.dart';
export 'widgets/button_base.dart';
export 'widgets/card.dart';
export 'widgets/checkbox.dart';
export 'widgets/date_picker.dart';
export 'widgets/default_text_style.dart';
export 'widgets/dialog.dart';
export 'widgets/dismissable.dart';
export 'widgets/drag_target.dart';
export 'widgets/drawer.dart';
export 'widgets/drawer_divider.dart';
export 'widgets/drawer_header.dart';
export 'widgets/drawer_item.dart';
export 'widgets/flat_button.dart';
export 'widgets/floating_action_button.dart';
export 'widgets/focus.dart';
export 'widgets/framework.dart';
export 'widgets/gesture_detector.dart';
export 'widgets/icon.dart';
export 'widgets/icon_button.dart';
export 'widgets/ink_well.dart';
export 'widgets/material.dart';
export 'widgets/material_button.dart';
export 'widgets/mimic.dart';
export 'widgets/mimic_overlay.dart';
export 'widgets/mixed_viewport.dart';
export 'widgets/modal_overlay.dart';
export 'widgets/navigator.dart';
export 'widgets/popup_menu.dart';
export 'widgets/popup_menu_item.dart';
export 'widgets/progress_indicator.dart';
export 'widgets/radio.dart';
export 'widgets/raised_button.dart';
export 'widgets/scaffold.dart';
export 'widgets/scrollable.dart';
export 'widgets/snack_bar.dart';
export 'widgets/switch.dart';
export 'widgets/tabs.dart';
export 'widgets/theme.dart';
export 'widgets/title.dart';
export 'widgets/tool_bar.dart';
export 'widgets/transitions.dart';
export 'package:sky/widgets/animated_component.dart';
export 'package:sky/widgets/animated_container.dart';
export 'package:sky/widgets/basic.dart';
export 'package:sky/widgets/button_base.dart';
export 'package:sky/widgets/card.dart';
export 'package:sky/widgets/checkbox.dart';
export 'package:sky/widgets/date_picker.dart';
export 'package:sky/widgets/default_text_style.dart';
export 'package:sky/widgets/dialog.dart';
export 'package:sky/widgets/dismissable.dart';
export 'package:sky/widgets/drag_target.dart';
export 'package:sky/widgets/drawer.dart';
export 'package:sky/widgets/drawer_divider.dart';
export 'package:sky/widgets/drawer_header.dart';
export 'package:sky/widgets/drawer_item.dart';
export 'package:sky/widgets/flat_button.dart';
export 'package:sky/widgets/floating_action_button.dart';
export 'package:sky/widgets/focus.dart';
export 'package:sky/widgets/framework.dart';
export 'package:sky/widgets/gesture_detector.dart';
export 'package:sky/widgets/icon.dart';
export 'package:sky/widgets/icon_button.dart';
export 'package:sky/widgets/ink_well.dart';
export 'package:sky/widgets/material.dart';
export 'package:sky/widgets/material_button.dart';
export 'package:sky/widgets/mimic.dart';
export 'package:sky/widgets/mimic_overlay.dart';
export 'package:sky/widgets/mixed_viewport.dart';
export 'package:sky/widgets/modal_overlay.dart';
export 'package:sky/widgets/navigator.dart';
export 'package:sky/widgets/popup_menu.dart';
export 'package:sky/widgets/popup_menu_item.dart';
export 'package:sky/widgets/progress_indicator.dart';
export 'package:sky/widgets/radio.dart';
export 'package:sky/widgets/raised_button.dart';
export 'package:sky/widgets/scaffold.dart';
export 'package:sky/widgets/scrollable.dart';
export 'package:sky/widgets/snack_bar.dart';
export 'package:sky/widgets/switch.dart';
export 'package:sky/widgets/tabs.dart';
export 'package:sky/widgets/theme.dart';
export 'package:sky/widgets/title.dart';
export 'package:sky/widgets/tool_bar.dart';
export 'package:sky/widgets/transitions.dart';
export 'package:vector_math/vector_math.dart' show Matrix4;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment