/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include #include #include #include #include #include #include #include #include #include namespace facebook { namespace react { struct LayoutConstraints; struct LayoutContext; /* * Describes all sufficient layout API (in approach-agnostic way) * which makes a concurrent layout possible. */ class LayoutableShadowNode : public virtual Sealable { public: using UnsharedList = better:: small_vector; virtual ~LayoutableShadowNode() noexcept = default; /* * Measures the node (and node content, propbably recursivly) with * given constrains and relying on possible layout. * Default implementation returns zero size. */ virtual Size measure(LayoutConstraints layoutConstraints) const; /* * Computes layout recusively. * Additional environmental constraints might be provided via `layoutContext` * argument. * Default implementation basically calls `layoutChildren()` and then * `layout()` (recursively), and provides some obvious performance * optimization. */ virtual void layout(LayoutContext layoutContext); /* * Returns layout metrics computed during previous layout pass. */ virtual LayoutMetrics getLayoutMetrics() const; /* * Returns `true` if the node represents only information necessary for * layout computation and can be safely removed from view hierarchy. * Default implementation returns `false`. */ virtual bool isLayoutOnly() const; /* * Returns a transform object that represents transformations that will/should * be applied on top of regular layout metrics by mounting layer. * The `transform` value modifies a coordinate space of a layout system. * Default implementation returns `Identity` transform. */ virtual Transform getTransform() const; /* * Returns layout metrics relatively to the given ancestor node. */ LayoutMetrics getRelativeLayoutMetrics( const LayoutableShadowNode &ancestorLayoutableShadowNode) const; protected: /* * Clean or Dirty layout state: * Indicates whether all nodes (and possibly their subtrees) along the path * to the root node should be re-layouted. */ virtual void cleanLayout() = 0; virtual void dirtyLayout() = 0; virtual bool getIsLayoutClean() const = 0; /* * Indicates does the shadow node (or any descendand node of the node) * get a new layout metrics during a previous layout pass. */ virtual void setHasNewLayout(bool hasNewLayout) = 0; virtual bool getHasNewLayout() const = 0; /* * Applies layout for all children; * does not call anything in recusive manner *by desing*. */ virtual void layoutChildren(LayoutContext layoutContext); /* * Unifed methods to access text layout metrics. */ virtual Float firstBaseline(Size size) const; virtual Float lastBaseline(Size size) const; /* * Returns layoutable children to interate on. */ virtual LayoutableShadowNode::UnsharedList getLayoutableChildNodes() const = 0; /* * In case layout algorithm needs to mutate this (probably sealed) node, * it has to clone and replace it in the hierarchy before to do so. */ virtual LayoutableShadowNode *cloneAndReplaceChild( LayoutableShadowNode *child, int suggestedIndex = -1) = 0; /* * Sets layout metrics for the shadow node. * Returns true if the metrics are different from previous ones. */ virtual bool setLayoutMetrics(LayoutMetrics layoutMetrics); #pragma mark - DebugStringConvertible #if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList getDebugProps() const; #endif private: LayoutMetrics layoutMetrics_{}; }; } // namespace react } // namespace facebook