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; } }
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; } }