// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'events.dart'; /// An object that can hit-test pointers. abstract class HitTestable { // ignore: one_member_abstracts // This class is intended to be used as an interface with the implements // keyword, and should not be extended directly. factory HitTestable._() => null; /// Check whether the given position hits this object. /// /// If this given position hits this object, consider adding a [HitTestEntry] /// to the given hit test result. void hitTest(HitTestResult result, Offset position); } /// An object that can dispatch events. abstract class HitTestDispatcher { // ignore: one_member_abstracts // This class is intended to be used as an interface with the implements // keyword, and should not be extended directly. factory HitTestDispatcher._() => null; /// Override this method to dispatch events. void dispatchEvent(PointerEvent event, HitTestResult result); } /// An object that can handle events. abstract class HitTestTarget { // ignore: one_member_abstracts // This class is intended to be used as an interface with the implements // keyword, and should not be extended directly. factory HitTestTarget._() => null; /// Override this method to receive events. void handleEvent(PointerEvent 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 { /// Creates a hit test entry. const HitTestEntry(this.target); /// The [HitTestTarget] encountered during the hit test. final HitTestTarget target; @override String toString() => '$target'; } /// The result of performing a hit test. class HitTestResult { /// Creates a hit test result. /// /// If the [path] argument is null, the [path] field will be initialized with /// and empty list. HitTestResult({ List<HitTestEntry> path }) : _path = path ?? <HitTestEntry>[]; /// An unmodifiable list of [HitTestEntry] objects recorded during the hit test. /// /// The first entry in the path is the most specific, typically the one at /// the leaf of tree being hit tested. Event propagation starts with the most /// specific (i.e., first) entry and proceeds in order through the path. List<HitTestEntry> get path => new List<HitTestEntry>.unmodifiable(_path); final List<HitTestEntry> _path; /// 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 most specific to least specific, typically during an /// upward walk of the tree being hit tested. void add(HitTestEntry entry) { _path.add(entry); } @override String toString() => 'HitTestResult(${_path.isEmpty ? "<empty path>" : _path.join(", ")})'; }