bool IScrollMathModel::IsRectVisible(const Rect2F& rect) const { //in container Point2F totalMovement = Offset(); if (mDirection.IsVertical()) { float bottom = rect.Bottom() + totalMovement.Y; float top = rect.Top() + totalMovement.Y; return (mContainer.Bottom() <= bottom&& mContainer.Top() >= bottom) || (mContainer.Bottom() <= top && mContainer.Top() >= top); } else if (mDirection.IsHorizontal()) { float left = rect.Left() + totalMovement.X; float right = rect.Right() + totalMovement.X; return (mContainer.Left() <= left&& mContainer.Right() >= left) || (mContainer.Left() <= right && mContainer.Right() >= right); } else { Rect2F copy = rect; copy.Origin += totalMovement; return mContainer.IsIntersect(rect); } }
Point2F Geometry::ApplyMargin(const Rect2F& selfRect, const Rect2F& parentRect, MarginEdges marginEdges, const ThicknessF& margin) { Point2F pos = selfRect.Origin; if (MEDUSA_FLAG_HAS(marginEdges, MarginEdges::Horizontal)) { //当前节点到父节点对应两条边的距离之比总是不变的 float aspect = Math::Abs(margin.Left) / (Math::Abs(margin.Right) + Math::Abs(margin.Left)); float length = parentRect.Width() - selfRect.Width(); float leftWidth = Math::LinearInterpolate(0.f, length, aspect); pos.X = parentRect.Left() + leftWidth; } else { if (MEDUSA_FLAG_HAS(marginEdges, MarginEdges::Left)) { pos.X = Math::Max(pos.X, margin.Left + parentRect.Left()); } if (MEDUSA_FLAG_HAS(marginEdges, MarginEdges::Right)) { pos.X = Math::Min(pos.X, parentRect.Right() - margin.Right); } } if (MEDUSA_FLAG_HAS(marginEdges, MarginEdges::Vertical)) { //当前节点到父节点对应两条边的距离之比总是不变的 float aspect = Math::Abs(margin.Bottom) / (Math::Abs(margin.Bottom) + Math::Abs(margin.Top)); float length = parentRect.Height() - selfRect.Height(); float bottomWidth = Math::LinearInterpolate(0.f, length, aspect); pos.Y = parentRect.Bottom() + bottomWidth; } else { if (MEDUSA_FLAG_HAS(marginEdges, MarginEdges::Bottom)) { pos.Y = Math::Max(pos.Y, margin.Bottom + parentRect.Bottom()); } if (MEDUSA_FLAG_HAS(marginEdges, MarginEdges::Top)) { pos.Y = Math::Min(pos.Y, parentRect.Top() - margin.Top); } } return pos; }
Point2F Geometry::DockToRect(const Rect2F& rect, DockPoint dock, const Point2F& relativePosition /*= Point2F::Zero*/) { Point2F pos; switch (dock) { case DockPoint::None: pos = Point2F::Zero; break; case DockPoint::LeftBottom: pos = rect.LeftBottom(); pos += relativePosition; break; case DockPoint::LeftCenter: pos = rect.LeftCenter(); pos += relativePosition; break; case DockPoint::LeftTop: pos = rect.LeftTop(); pos += relativePosition; break; case DockPoint::MiddleBottom: pos = rect.MiddleBottom(); pos += relativePosition; break; case DockPoint::MiddleCenter: pos = rect.MiddleCenter(); pos += relativePosition; break; case DockPoint::MiddleTop: pos = rect.MiddleTop(); pos += relativePosition; break; case DockPoint::RightBottom: pos = rect.RightBottom(); pos += relativePosition; break; case DockPoint::RightCenter: pos = rect.RightCenter(); pos += relativePosition; break; case DockPoint::RightTop: pos = rect.RightTop(); pos += relativePosition; break; case DockPoint::Percent: pos.X = relativePosition.X*rect.Size.Width; pos.Y = relativePosition.Y*rect.Size.Height; break; default: break; } return pos; }
void ScrollPanel::OnInitializeTargetBoundingBox() { Rect2F targetBoundingBox = Rect2F::Zero; if (mNodes.Count() > mManagedNodes.Count()) { //try to optimize this for (auto child : mNodes) { CONTINUE_IF(mManagedNodes.Contains(child)); Rect2F boundingBox = child->GetBoundingBox().To2D(); targetBoundingBox.Union(boundingBox); } } mScrollModel->Initialize(mSize.To2D(), targetBoundingBox); }
bool WrapPanel::ArrangeChildren(const Rect2F& limitRect/*=Rect2F::Zero*/, NodeLayoutArrangeFlags arrangeFlags/*=NodeLayoutArrangeFlags::None*/) { Rect2F leftRect = limitRect; leftRect.Origin.X += mPadding.Left; leftRect.Size.Width -= mPadding.Left + mPadding.Right; leftRect.Origin.Y += mPadding.Down; leftRect.Size.Height -= mPadding.Down + mPadding.Up; Point2F origin = Point2F::Zero; Rect2F itemRect = Rect2F::Zero; bool hasFixedSize = mItemFixedSize != Size2F::Zero; if (mDirection == Direction::Horizontal) { origin.X = leftRect.Left(); origin.Y = leftRect.Top(); for(auto child: mNodes) { itemRect.Size = hasFixedSize ? mItemFixedSize : child->MeasuredSize(); origin.Y = Math::Min(origin.Y, leftRect.Top() - itemRect.Size.Height); itemRect.Origin = origin; child->ArrangeRecursively(itemRect, arrangeFlags); origin.X += itemRect.Size.Width; if (origin.X > leftRect.Size.Width) { //change line leftRect.Size.Height = origin.Y - mItemOffset.Y; origin.X = 0; } else { origin.X += mItemOffset.X; } } } else { origin.X = leftRect.Left(); origin.Y = leftRect.Top(); for (auto child : mNodes) { itemRect.Size = hasFixedSize ? mItemFixedSize : child->MeasuredSize(); origin.Y -= itemRect.Size.Height; itemRect.Origin.Y = origin.Y; origin.X = Math::Max(origin.X, leftRect.Right() - itemRect.Size.Width); child->ArrangeRecursively(itemRect, arrangeFlags); if (origin.Y < 0.f) { //change line origin.X += mItemOffset.X; leftRect.Size.Width -= (origin.X - leftRect.Origin.X); leftRect.Origin.X = origin.X; origin.Y = leftRect.Top(); itemRect.Origin.X = origin.X; } else { origin.Y -= mItemOffset.Y; } } } return true; }