mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-06 12:43:58 +00:00
216 lines
9.1 KiB
Plaintext
216 lines
9.1 KiB
Plaintext
//
|
|
// ASEnvironmentInternal.mm
|
|
// AsyncDisplayKit
|
|
//
|
|
// 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 "ASEnvironmentInternal.h"
|
|
|
|
#import <queue>
|
|
|
|
//#define LOG(...) NSLog(__VA_ARGS__)
|
|
#define LOG(...)
|
|
|
|
#define AS_SUPPORT_PROPAGATION YES
|
|
#define AS_DOES_NOT_SUPPORT_PROPAGATION NO
|
|
|
|
BOOL ASEnvironmentStatePropagationEnabled()
|
|
{
|
|
return AS_DOES_NOT_SUPPORT_PROPAGATION;
|
|
}
|
|
|
|
BOOL ASEnvironmentStateTraitCollectionPropagationEnabled()
|
|
{
|
|
return AS_SUPPORT_PROPAGATION;
|
|
}
|
|
|
|
#pragma mark - Traversing an ASEnvironment Tree
|
|
|
|
void ASEnvironmentPerformBlockOnObjectAndChildren(id<ASEnvironment> object, void(^block)(id<ASEnvironment> node))
|
|
{
|
|
if (!object) {
|
|
return;
|
|
}
|
|
|
|
std::queue<id<ASEnvironment>> queue;
|
|
queue.push(object);
|
|
|
|
while (!queue.empty()) {
|
|
id<ASEnvironment> object = queue.front(); queue.pop();
|
|
|
|
block(object);
|
|
|
|
for (id<ASEnvironment> child in [object children]) {
|
|
queue.push(child);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ASEnvironmentPerformBlockOnObjectAndParents(id<ASEnvironment> object, void(^block)(id<ASEnvironment> node))
|
|
{
|
|
while (object) {
|
|
block(object);
|
|
object = [object parent];
|
|
}
|
|
}
|
|
|
|
|
|
#pragma mark - Set and get extensible values from state structs
|
|
|
|
void _ASEnvironmentLayoutOptionsExtensionSetBoolAtIndex(id<ASEnvironment> object, int idx, BOOL value)
|
|
{
|
|
NSCAssert(idx < kMaxEnvironmentStateBoolExtensions, @"Setting index outside of max bool extensions space");
|
|
|
|
ASEnvironmentState state = object.environmentState;
|
|
state.layoutOptionsState._extensions.boolExtensions[idx] = value;
|
|
object.environmentState = state;
|
|
}
|
|
|
|
BOOL _ASEnvironmentLayoutOptionsExtensionGetBoolAtIndex(id<ASEnvironment> object, int idx)
|
|
{
|
|
NSCAssert(idx < kMaxEnvironmentStateBoolExtensions, @"Accessing index outside of max bool extensions space");
|
|
return object.environmentState.layoutOptionsState._extensions.boolExtensions[idx];
|
|
}
|
|
|
|
void _ASEnvironmentLayoutOptionsExtensionSetIntegerAtIndex(id<ASEnvironment> object, int idx, NSInteger value)
|
|
{
|
|
NSCAssert(idx < kMaxEnvironmentStateIntegerExtensions, @"Setting index outside of max integer extensions space");
|
|
|
|
ASEnvironmentState state = object.environmentState;
|
|
state.layoutOptionsState._extensions.integerExtensions[idx] = value;
|
|
object.environmentState = state;
|
|
}
|
|
|
|
NSInteger _ASEnvironmentLayoutOptionsExtensionGetIntegerAtIndex(id<ASEnvironment> object, int idx)
|
|
{
|
|
NSCAssert(idx < kMaxEnvironmentStateIntegerExtensions, @"Accessing index outside of max integer extensions space");
|
|
return object.environmentState.layoutOptionsState._extensions.integerExtensions[idx];
|
|
}
|
|
|
|
void _ASEnvironmentLayoutOptionsExtensionSetEdgeInsetsAtIndex(id<ASEnvironment> object, int idx, UIEdgeInsets value)
|
|
{
|
|
NSCAssert(idx < kMaxEnvironmentStateEdgeInsetExtensions, @"Setting index outside of max edge insets extensions space");
|
|
|
|
ASEnvironmentState state = object.environmentState;
|
|
state.layoutOptionsState._extensions.edgeInsetsExtensions[idx] = value;
|
|
object.environmentState = state;
|
|
}
|
|
|
|
UIEdgeInsets _ASEnvironmentLayoutOptionsExtensionGetEdgeInsetsAtIndex(id<ASEnvironment> object, int idx)
|
|
{
|
|
NSCAssert(idx < kMaxEnvironmentStateEdgeInsetExtensions, @"Accessing index outside of max edge insets extensions space");
|
|
return object.environmentState.layoutOptionsState._extensions.edgeInsetsExtensions[idx];
|
|
}
|
|
|
|
|
|
#pragma mark - Merging functions for states
|
|
|
|
ASEnvironmentState ASEnvironmentMergeObjectAndState(ASEnvironmentState environmentState, ASEnvironmentHierarchyState hierarchyState, ASEnvironmentStatePropagation propagation) {
|
|
// Merge object and hierarchy state
|
|
LOG(@"Merge object and state: %@ - ASEnvironmentHierarchyState", hierarchyState);
|
|
return environmentState;
|
|
}
|
|
|
|
ASEnvironmentState ASEnvironmentMergeObjectAndState(ASEnvironmentState environmentState, ASEnvironmentLayoutOptionsState layoutOptionsState, ASEnvironmentStatePropagation propagation) {
|
|
// Merge object and layout options state
|
|
LOG(@"Merge object and state: %@ - ASEnvironmentLayoutOptionsState", layoutOptionsState);
|
|
|
|
if (!ASEnvironmentStatePropagationEnabled() && propagation == ASEnvironmentStatePropagation::UP) {
|
|
return environmentState;
|
|
}
|
|
|
|
// Support propagate up
|
|
if (propagation == ASEnvironmentStatePropagation::UP) {
|
|
|
|
// Object is the parent and the state is the state of the child
|
|
const ASEnvironmentLayoutOptionsState defaultState = ASEnvironmentDefaultLayoutOptionsState;
|
|
ASEnvironmentLayoutOptionsState parentLayoutOptionsState = environmentState.layoutOptionsState;
|
|
|
|
// For every field check if the parent value is equal to the default and if so propegate up the value of the passed
|
|
// in layout options state
|
|
if (parentLayoutOptionsState.spacingBefore == defaultState.spacingBefore) {
|
|
parentLayoutOptionsState.spacingBefore = layoutOptionsState.spacingBefore;
|
|
}
|
|
if (parentLayoutOptionsState.spacingAfter == defaultState.spacingAfter) {
|
|
parentLayoutOptionsState.spacingAfter = layoutOptionsState.spacingAfter;
|
|
}
|
|
if (parentLayoutOptionsState.alignSelf == defaultState.alignSelf) {
|
|
parentLayoutOptionsState.alignSelf = layoutOptionsState.alignSelf;
|
|
}
|
|
if (parentLayoutOptionsState.flexGrow == defaultState.flexGrow) {
|
|
parentLayoutOptionsState.flexGrow = layoutOptionsState.flexGrow;
|
|
}
|
|
if (ASRelativeDimensionEqualToRelativeDimension(parentLayoutOptionsState.flexBasis, defaultState.flexBasis)) {
|
|
parentLayoutOptionsState.flexBasis = layoutOptionsState.flexBasis;
|
|
}
|
|
if (parentLayoutOptionsState.alignSelf == defaultState.alignSelf) {
|
|
parentLayoutOptionsState.alignSelf = layoutOptionsState.alignSelf;
|
|
}
|
|
if (parentLayoutOptionsState.ascender == defaultState.ascender) {
|
|
parentLayoutOptionsState.ascender = layoutOptionsState.ascender;
|
|
}
|
|
|
|
if (ASRelativeSizeRangeEqualToRelativeSizeRange(parentLayoutOptionsState.sizeRange, defaultState.sizeRange)) {
|
|
// For now it is unclear if we should be up-propagating sizeRange or layoutPosition.
|
|
// parentLayoutOptionsState.sizeRange = layoutOptionsState.sizeRange;
|
|
}
|
|
if (CGPointEqualToPoint(parentLayoutOptionsState.layoutPosition, defaultState.layoutPosition)) {
|
|
// For now it is unclear if we should be up-propagating sizeRange or layoutPosition.
|
|
// parentLayoutOptionsState.layoutPosition = layoutOptionsState.layoutPosition;
|
|
}
|
|
|
|
// Merge extended values if necessary
|
|
const ASEnvironmentStateExtensions defaultExtensions = ASEnvironmentDefaultStateExtensions;
|
|
const ASEnvironmentStateExtensions layoutOptionsStateExtensions = layoutOptionsState._extensions;
|
|
ASEnvironmentStateExtensions parentLayoutOptionsExtensions = parentLayoutOptionsState._extensions;
|
|
|
|
for (int i = 0; i < kMaxEnvironmentStateBoolExtensions; i++) {
|
|
if (parentLayoutOptionsExtensions.boolExtensions[i] == defaultExtensions.boolExtensions[i]) {
|
|
parentLayoutOptionsExtensions.boolExtensions[i] = layoutOptionsStateExtensions.boolExtensions[i];
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < kMaxEnvironmentStateIntegerExtensions; i++) {
|
|
if (parentLayoutOptionsExtensions.integerExtensions[i] == defaultExtensions.integerExtensions[i]) {
|
|
parentLayoutOptionsExtensions.integerExtensions[i] = layoutOptionsStateExtensions.integerExtensions[i];
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < kMaxEnvironmentStateEdgeInsetExtensions; i++) {
|
|
if (UIEdgeInsetsEqualToEdgeInsets(parentLayoutOptionsExtensions.edgeInsetsExtensions[i], defaultExtensions.edgeInsetsExtensions[i])) {
|
|
parentLayoutOptionsExtensions.edgeInsetsExtensions[i] = layoutOptionsStateExtensions.edgeInsetsExtensions[i];
|
|
}
|
|
}
|
|
parentLayoutOptionsState._extensions = parentLayoutOptionsExtensions;
|
|
|
|
// Update layout options state
|
|
environmentState.layoutOptionsState = parentLayoutOptionsState;
|
|
}
|
|
|
|
return environmentState;
|
|
}
|
|
|
|
ASEnvironmentState ASEnvironmentMergeObjectAndState(ASEnvironmentState childEnvironmentState, ASEnvironmentTraitCollection parentTraitCollection, ASEnvironmentStatePropagation propagation) {
|
|
if (propagation == ASEnvironmentStatePropagation::DOWN && !ASEnvironmentStateTraitCollectionPropagationEnabled()) {
|
|
return childEnvironmentState;
|
|
}
|
|
|
|
// Support propagate down
|
|
if (propagation == ASEnvironmentStatePropagation::DOWN) {
|
|
ASEnvironmentTraitCollection childTraitCollection = childEnvironmentState.environmentTraitCollection;
|
|
childTraitCollection.horizontalSizeClass = parentTraitCollection.horizontalSizeClass;
|
|
childTraitCollection.verticalSizeClass = parentTraitCollection.verticalSizeClass;
|
|
childTraitCollection.userInterfaceIdiom = parentTraitCollection.userInterfaceIdiom;
|
|
childTraitCollection.forceTouchCapability = parentTraitCollection.forceTouchCapability;
|
|
childTraitCollection.displayScale = parentTraitCollection.displayScale;
|
|
childTraitCollection.containerSize = parentTraitCollection.containerSize;
|
|
childEnvironmentState.environmentTraitCollection = childTraitCollection;
|
|
|
|
}
|
|
return childEnvironmentState;
|
|
}
|