RenderCore/Geometry/RCDimension.h (59 lines of code) (raw):

/* * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import <RenderCore/CKDefines.h> #if CK_NOT_SWIFT #import <UIKit/UIKit.h> #import <RenderCore/RCAssert.h> #import <RenderCore/CKSizeRange.h> /** A dimension relative to constraints to be provided in the future. A RelativeDimension can be one of three types: "Auto" - This indicated "I have no opinion" and may be resolved in whatever way makes most sense given the circumstances. This is the default type. "Points" - Just a number. It will always resolve to exactly this amount. "Percent" - Multiplied to a provided parent amount to resolve a final amount. If the parent amount is undefined (NaN) or infinite, it acts as if Auto size was specified instead. A number of convenience constructors have been provided to make using RelativeDimension straight-forward. RCRelativeDimension x; // Auto (default case) RCRelativeDimension z = 10; // 10 Points RCRelativeDimension y = RCRelativeDimension::Auto(); // Auto RCRelativeDimension u = RCRelativeDimension::Percent(0.5); // 50% */ class RCRelativeDimension; namespace std { template <> struct hash<RCRelativeDimension> { size_t operator ()(const RCRelativeDimension &) noexcept; }; } class RCRelativeDimension { public: // Make sizeof(Type) == sizeof(CGFloat) so that the default // constructor takes fewer instructions (because of SLP // vectorization). enum class Type : NSInteger { AUTO, POINTS, PERCENT, }; /** Default constructor is equivalent to "Auto". */ constexpr RCRelativeDimension() noexcept : _type(Type::AUTO), _value(0) {} RCRelativeDimension(CGFloat points) noexcept : RCRelativeDimension(Type::POINTS, points) {} constexpr static RCRelativeDimension Auto() noexcept { return RCRelativeDimension(); } static RCRelativeDimension Points(CGFloat p) noexcept { return RCRelativeDimension(p); } static RCRelativeDimension Percent(CGFloat p) noexcept { return {RCRelativeDimension::Type::PERCENT, p}; } RCRelativeDimension(const RCRelativeDimension &) = default; RCRelativeDimension &operator=(const RCRelativeDimension &) = default; bool operator==(const RCRelativeDimension &) const noexcept; NSString *description() const noexcept; CGFloat resolve(CGFloat autoSize, CGFloat parent) const noexcept; Type type() const noexcept; CGFloat value() const noexcept; private: RCRelativeDimension(Type type, CGFloat value) : _type(type), _value(value) {} Type _type; CGFloat _value; friend std::hash<RCRelativeDimension>; }; /** Expresses a size with relative dimensions. */ struct RCRelativeSize { RCRelativeDimension width; RCRelativeDimension height; RCRelativeSize(const RCRelativeDimension &width, const RCRelativeDimension &height) noexcept; /** Convenience constructor to provide size in Points. */ RCRelativeSize(const CGSize &size) noexcept; /** Convenience constructor for {Auto, Auto} */ constexpr RCRelativeSize() = default; /** Resolve this size relative to a parent size and an auto size. */ CGSize resolveSize(const CGSize &parentSize, const CGSize &autoSize) const noexcept; bool operator==(const RCRelativeSize &other) const noexcept; NSString *description() const noexcept; }; /** Expresses an inclusive range of relative sizes. Used to provide additional constraint to component layout. */ struct RCRelativeSizeRange { RCRelativeSize min; RCRelativeSize max; RCRelativeSizeRange(const RCRelativeSize &min, const RCRelativeSize &max); /** Convenience constructors to provide an exact size (min == max). RCRelativeSizeRange r = {80, 60} // width: [80, 80], height: [60, 60]. */ RCRelativeSizeRange(const RCRelativeSize &exact) noexcept; RCRelativeSizeRange(const CGSize &exact) noexcept; RCRelativeSizeRange(const RCRelativeDimension &exactWidth, const RCRelativeDimension &exactHeight) noexcept; /** Convenience constructor for {{Auto, Auto}, {Auto, Auto}}. */ constexpr RCRelativeSizeRange() = default; /** Provided a parent size and values to use in place of Auto, compute final dimensions for this RelativeSizeRange to arrive at a SizeRange. As an example: CGSize parent = {200, 120}; RelativeSizeRange rel = {Percent(0.5), Percent(2/3)} rel.resolveSizeRange(parent); // {{100, 60}, {100, 60}} The default for Auto() is *everything*, meaning min = {0,0}; max = {INFINITY, INFINITY}; */ CKSizeRange resolveSizeRange(const CGSize &parentSize, const CKSizeRange &autoSizeRange = {{0,0}, {INFINITY, INFINITY}}) const noexcept; }; #endif