void CalculateArrangeRectVertically(RPNode node, out double y, out double height) { Rect measureRect = node.m_measureRect; double desiredHeight = Math.Min(measureRect.Height, node.GetDesiredHeight()); MUX_ASSERT(node.IsMeasured() && (measureRect.Height != double.PositiveInfinity)); // The initial values correspond to the top corner, using the // desired size of element. If no attached properties were set, // this means that the element will default to the top corner of // the panel. y = measureRect.Y; height = desiredHeight; if (node.IsTopAnchored()) { if (node.IsBottomAnchored()) { y = measureRect.Y; height = measureRect.Height; } else { y = measureRect.Y; height = desiredHeight; } } else if (node.IsBottomAnchored()) { y = measureRect.Y + measureRect.Height - desiredHeight; height = desiredHeight; } else if (node.IsVerticalCenterAnchored()) { y = measureRect.Y + (measureRect.Height / 2.0f) - (desiredHeight / 2.0f); height = desiredHeight; } }
void CalculateArrangeRectHorizontally(RPNode node, out double x, out double width) { Rect measureRect = node.m_measureRect; double desiredWidth = Math.Min(measureRect.Width, node.GetDesiredWidth()); MUX_ASSERT(node.IsMeasured() && (measureRect.Width != double.PositiveInfinity)); // The initial values correspond to the left corner, using the // desired size of element. If no attached properties were set, // this means that the element will default to the left corner of // the panel. x = measureRect.X; width = desiredWidth; if (node.IsLeftAnchored()) { if (node.IsRightAnchored()) { x = measureRect.X; width = measureRect.Width; } else { x = measureRect.X; width = desiredWidth; } } else if (node.IsRightAnchored()) { x = measureRect.X + measureRect.Width - desiredWidth; width = desiredWidth; } else if (node.IsHorizontalCenterAnchored()) { x = measureRect.X + (measureRect.Width / 2.0f) - (desiredWidth / 2.0f); width = desiredWidth; } }
void AccumulateNegativeDesiredHeight(RPNode node, double y) { double initialY = y; bool isVerticallyCenteredFromTop = false; bool isVerticallyCenteredFromBottom = false; MUX_ASSERT(node.IsMeasured()); // If we are going in the negative direction, move the cursor // down by the desired height of the node with which we are // currently working and refresh the minimum negative value. y -= node.GetDesiredHeight(); m_minY = Math.Min(m_minY, y); if (node.IsAlignBottomWithPanel()) { if (!m_isMinCapped) { m_minY = y; m_isMinCapped = true; } } else if (node.IsAlignBottomWith()) { // If the AlignBottomWithNode and AlignTopWithNode are the // same element, we can skip the former, since we will move // through the latter later. if (node.m_alignBottomWithNode != node.m_alignTopWithNode) { AccumulatePositiveDesiredHeight(node.m_alignBottomWithNode, y); } } else if (node.IsAlignVerticalCenterWith()) { isVerticallyCenteredFromBottom = true; } else if (node.IsAbove()) { AccumulateNegativeDesiredHeight(node.m_aboveNode, y); } if (node.IsAlignTopWithPanel()) { if (m_isMaxCapped) { m_maxY = Math.Max(m_maxY, initialY); } else { m_maxY = initialY; m_isMaxCapped = true; } } else if (node.IsAlignTopWith()) { // If this element's top is aligned to some other element's // top, now we will be going in the negative direction to // that other element in order to continue the traversal of // the dependency chain. But first, since we arrived to the // node where we currently are by going in the negative // direction, that means that we have already moved the // cursor down to calculate the minimum negative value, // so we will use the initial value of Y. AccumulateNegativeDesiredHeight(node.m_alignTopWithNode, initialY); } else if (node.IsAlignVerticalCenterWith()) { isVerticallyCenteredFromTop = true; } else if (node.IsBelow()) { // If this element is below some other element, now we'll // be going in the positive direction to that other element // in order to continue the traversal of the dependency // chain. But first, since we arrived to the node where we // currently are by going in the negative direction, that // means that we have already moved the cursor down to // calculate the minimum negative value, so we will use // the initial value of Y. AccumulatePositiveDesiredHeight(node.m_belowNode, initialY); } if (isVerticallyCenteredFromTop && isVerticallyCenteredFromBottom) { double centerY = y + (node.GetDesiredHeight() / 2.0f); double edgeY = centerY + (node.m_alignVerticalCenterWithNode.GetDesiredHeight() / 2.0f); m_maxY = Math.Max(m_maxY, edgeY); AccumulateNegativeDesiredHeight(node.m_alignVerticalCenterWithNode, edgeY); } else if (node.IsVerticalCenterAnchored()) { // If this node is vertically anchored to the center, then it // means that it is the root of this dependency chain based on // the current definition of precedence for raints: // e.g. AlignTopWithPanel // > AlignTopWith // > Below // > AlignVerticalCenterWithPanel // Thus, we can report its height as twice the height of // either the difference from center to top or the difference // from center to bottom, whichever is the greatest. double centerY = y + (node.GetDesiredHeight() / 2.0f); double upper = m_maxY - centerY; double lower = centerY - m_minY; m_maxY = Math.Max(upper, lower) * 2.0f; m_minY = 0.0f; } }
private void AccumulateNegativeDesiredWidth(RPNode node, double x) { double initialX = x; bool isHorizontallyCenteredFromLeft = false; bool isHorizontallyCenteredFromRight = false; MUX_ASSERT(node.IsMeasured()); // If we are going in the negative direction, move the cursor // left by the desired width of the node with which we are // currently working and refresh the minimum negative value. x -= node.GetDesiredWidth(); m_minX = Math.Min(m_minX, x); if (node.IsAlignRightWithPanel()) { if (!m_isMinCapped) { m_minX = x; m_isMinCapped = true; } } else if (node.IsAlignRightWith()) { // If the AlignRightWithNode and AlignLeftWithNode are the // same element, we can skip the former, since we will move // through the latter later. if (node.m_alignRightWithNode != node.m_alignLeftWithNode) { AccumulatePositiveDesiredWidth(node.m_alignRightWithNode, x); } } else if (node.IsAlignHorizontalCenterWith()) { isHorizontallyCenteredFromRight = true; } else if (node.IsLeftOf()) { AccumulateNegativeDesiredWidth(node.m_leftOfNode, x); } if (node.IsAlignLeftWithPanel()) { if (m_isMaxCapped) { m_maxX = Math.Max(m_maxX, initialX); } else { m_maxX = initialX; m_isMaxCapped = true; } } else if (node.IsAlignLeftWith()) { // If this element's left is aligned to some other element's // left, now we will be going in the negative direction to // that other element in order to continue the traversal of // the dependency chain. But first, since we arrived to the // node where we currently are by going in the negative // direction, that means that we have already moved the // cursor left to calculate the minimum negative value, // so we will use the initial value of X. AccumulateNegativeDesiredWidth(node.m_alignLeftWithNode, initialX); } else if (node.IsAlignHorizontalCenterWith()) { isHorizontallyCenteredFromLeft = true; } else if (node.IsRightOf()) { // If this element is to the right of some other element, // now we will be going in the positive direction to that // other element in order to continue the traversal of the // dependency chain. But first, since we arrived to the // node where we currently are by going in the negative // direction, that means that we have already moved the // cursor left to calculate the minimum negative value, so // we will use the initial value of X. AccumulatePositiveDesiredWidth(node.m_rightOfNode, initialX); } if (isHorizontallyCenteredFromLeft && isHorizontallyCenteredFromRight) { double centerX = x + (node.GetDesiredWidth() / 2.0f); double edgeX = centerX + (node.m_alignHorizontalCenterWithNode.GetDesiredWidth() / 2.0f); m_maxX = Math.Max(m_maxX, edgeX); AccumulateNegativeDesiredWidth(node.m_alignHorizontalCenterWithNode, edgeX); } else if (node.IsHorizontalCenterAnchored()) { // If this node is horizontally anchored to the center, then it // means that it is the root of this dependency chain based on // the current definition of precedence for raints: // e.g. AlignLeftWithPanel // > AlignLeftWith // > RightOf // > AlignHorizontalCenterWithPanel // Thus, we can report its width as twice the width of // either the difference from center to left or the difference // from center to right, whichever is the greatest. double centerX = x + (node.GetDesiredWidth() / 2.0f); double upper = m_maxX - centerX; double lower = centerX - m_minX; m_maxX = Math.Max(upper, lower) * 2.0f; m_minX = 0.0f; } }