void SScrollBarTrack::OnArrangeChildren(const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren) const { const float Width = AllottedGeometry.Size.X; const float Height = AllottedGeometry.Size.Y; // We only need to show all three children when the thumb is visible, otherwise we only need to show the track if (IsNeeded()) { FTrackSizeInfo TrackSizeInfo = this->GetTrackSizeInfo(AllottedGeometry); // Arrange top half of the track FVector2D ChildSize = (Orientation == Orient_Horizontal) ? FVector2D(TrackSizeInfo.ThumbStart, Height) : FVector2D(Width, TrackSizeInfo.ThumbStart); FVector2D ChildPos(0, 0); ArrangedChildren.AddWidget( AllottedGeometry.MakeChild(Children[TOP_SLOT_INDEX].GetWidget(), ChildPos, ChildSize) ); // Arrange bottom half of the track ChildPos = (Orientation == Orient_Horizontal) ? FVector2D(TrackSizeInfo.GetThumbEnd(), 0) : FVector2D(0, TrackSizeInfo.GetThumbEnd()); ChildSize = (Orientation == Orient_Horizontal) ? FVector2D(AllottedGeometry.Size.X - TrackSizeInfo.GetThumbEnd(), Height) : FVector2D(Width, AllottedGeometry.Size.Y - TrackSizeInfo.GetThumbEnd()); ArrangedChildren.AddWidget( AllottedGeometry.MakeChild(Children[BOTTOM_SLOT_INDEX].GetWidget(), ChildPos, ChildSize) ); // Arrange the thumb ChildPos = (Orientation == Orient_Horizontal) ? FVector2D(TrackSizeInfo.ThumbStart, 0) : FVector2D(0, TrackSizeInfo.ThumbStart); ChildSize = (Orientation == Orient_Horizontal) ? FVector2D(TrackSizeInfo.ThumbSize, Height) : FVector2D(Width, TrackSizeInfo.ThumbSize); ArrangedChildren.AddWidget( AllottedGeometry.MakeChild(Children[THUMB_SLOT_INDEX].GetWidget(), ChildPos, ChildSize) ); } else { // No thumb is visible, so just show the top half of the track at the current width/height ArrangedChildren.AddWidget( AllottedGeometry.MakeChild(Children[TOP_SLOT_INDEX].GetWidget(), FVector2D(0, 0), FVector2D(Width, Height)) ); } }
FSelectedKey SSection::GetKeyUnderMouse( const FVector2D& MousePosition, const FGeometry& AllottedGeometry ) const { UMovieSceneSection& Section = *SectionInterface->GetSectionObject(); // Search every key area until we find the one under the mouse for( int32 KeyAreaIndex = 0; KeyAreaIndex < KeyAreas.Num(); ++KeyAreaIndex ) { const FKeyAreaElement& Element = KeyAreas[KeyAreaIndex]; TSharedRef<IKeyArea> KeyArea = Element.KeyAreaNode.GetKeyArea( SectionIndex ); // Compute the current key area geometry FGeometry KeyAreaGeometryPadded = GetKeyAreaGeometry( Element, AllottedGeometry ); // Is the key area under the mouse if( KeyAreaGeometryPadded.IsUnderLocation( MousePosition ) ) { FGeometry SectionGeometry = AllottedGeometry.MakeChild(FVector2D(SequencerSectionConstants::SectionGripSize, 0), AllottedGeometry.GetDrawSize() - FVector2D(SequencerSectionConstants::SectionGripSize*2, 0.0f)); FGeometry KeyAreaGeometry = GetKeyAreaGeometry( Element, SectionGeometry ); FVector2D LocalSpaceMousePosition = KeyAreaGeometry.AbsoluteToLocal( MousePosition ); FTimeToPixel TimeToPixelConverter = Section.IsInfinite() ? FTimeToPixel( ParentGeometry, GetSequencer().GetViewRange()) : FTimeToPixel( KeyAreaGeometry, TRange<float>( Section.GetStartTime(), Section.GetEndTime() ) ); // Check each key until we find one under the mouse (if any) TArray<FKeyHandle> KeyHandles = KeyArea->GetUnsortedKeyHandles(); for( int32 KeyIndex = 0; KeyIndex < KeyHandles.Num(); ++KeyIndex ) { FKeyHandle KeyHandle = KeyHandles[KeyIndex]; float KeyPosition = TimeToPixelConverter.TimeToPixel( KeyArea->GetKeyTime(KeyHandle) ); FGeometry KeyGeometry = KeyAreaGeometry.MakeChild( FVector2D( KeyPosition - FMath::TruncToFloat(SequencerSectionConstants::KeySize.X/2.0f), ((KeyAreaGeometry.Size.Y*.5f)-(SequencerSectionConstants::KeySize.Y*.5f)) ), SequencerSectionConstants::KeySize ); if( KeyGeometry.IsUnderLocation( MousePosition ) ) { // The current key is under the mouse return FSelectedKey( Section, KeyArea, KeyHandle ); } } // no key was selected in the current key area but the mouse is in the key area so it cannot possibly be in any other key area return FSelectedKey(); } } // No key was selected in any key area return FSelectedKey(); }
FGradientStopMark SColorGradientEditor::GetGradientStopAtPoint( const FVector2D& MousePos, const FGeometry& MyGeometry ) { FGeometry ColorMarkAreaGeometry = GetColorMarkAreaGeometry( MyGeometry ); FGeometry AlphaMarkAreaGeometry = GetAlphaMarkAreaGeometry( MyGeometry ); FTrackScaleInfo ScaleInfo(ViewMinInput.Get(), ViewMaxInput.Get(), 0.0f, 1.0f, MyGeometry.Size); if( ColorMarkAreaGeometry.IsUnderLocation( MousePos ) || AlphaMarkAreaGeometry.IsUnderLocation( MousePos ) ) { TArray<FGradientStopMark> ColorMarks; TArray<FGradientStopMark> AlphaMarks; GetGradientStopMarks( ColorMarks, AlphaMarks ); // See if any color stops are under the mouse for( int32 ColorIndex = 0; ColorIndex < ColorMarks.Num(); ++ColorIndex ) { const FGradientStopMark& Mark = ColorMarks[ColorIndex]; // Convert the time to a screen coordinate float XVal = ScaleInfo.InputToLocalX( Mark.Time ); if( XVal >= 0 ) { FGeometry MarkGeometry = ColorMarkAreaGeometry.MakeChild( FVector2D( XVal-HandleRect.Left, HandleRect.Top ), FVector2D( HandleRect.Right, HandleRect.Bottom ) ); if( MarkGeometry.IsUnderLocation( MousePos ) ) { return Mark; } } } // See if any color stops are under the mouse for( int32 ColorIndex = 0; ColorIndex < AlphaMarks.Num(); ++ColorIndex ) { const FGradientStopMark& Mark = AlphaMarks[ColorIndex]; float XVal = ScaleInfo.InputToLocalX( Mark.Time ); if( XVal >= 0 ) { FGeometry MarkGeometry = AlphaMarkAreaGeometry.MakeChild( FVector2D( XVal-HandleRect.Left, HandleRect.Top ), FVector2D( HandleRect.Right, HandleRect.Bottom ) ); if( MarkGeometry.IsUnderLocation( MousePos ) ) { return Mark; } } } } return FGradientStopMark(); }
/** * Gets the geometry of a section, optionally inflated by some margin * * @param AllottedGeometry The geometry of the area where sections are located * @param NodeHeight The height of the section area (and its children) * @param SectionInterface Interface to the section to get geometry for * @param TimeToPixelConverter Converts time to pixels and vice versa */ FGeometry GetSectionGeometry( const FGeometry& AllottedGeometry, int32 RowIndex, int32 MaxTracks, float NodeHeight, TSharedPtr<ISequencerSection> SectionInterface, const FTimeToPixel& TimeToPixelConverter ) { const UMovieSceneSection* Section = SectionInterface->GetSectionObject(); float StartX, EndX = 0; // If the section is infinite, occupy the entire width of the geometry where the section is located. if (Section->IsInfinite()) { StartX = AllottedGeometry.Position.X; EndX = AllottedGeometry.Position.X + AllottedGeometry.Size.X; } else { StartX = TimeToPixelConverter.TimeToPixel( Section->GetStartTime() ); EndX = TimeToPixelConverter.TimeToPixel( Section->GetEndTime() ); } // Actual section length without grips. float SectionLengthActual = EndX-StartX; float SectionLengthWithGrips = SectionLengthActual+SequencerSectionConstants::SectionGripSize*2; float ActualHeight = NodeHeight / MaxTracks; // Compute allotted geometry area that can be used to draw the section return AllottedGeometry.MakeChild( FVector2D( StartX-SequencerSectionConstants::SectionGripSize, ActualHeight * RowIndex ), FVector2D( SectionLengthWithGrips, ActualHeight ) ); }
virtual void OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const override { if (Children.Num() == 0) { return; } const float Alpha = 1.f - SlideCurve.GetLerp(); float PositionSoFar = AllottedGeometry.GetLocalSize().Y + StartSlideOffset*Alpha; for (int32 Index = 0; Index < NumSlots(); ++Index) { const SBoxPanel::FSlot& CurChild = Children[Index]; const EVisibility ChildVisibility = CurChild.GetWidget()->GetVisibility(); if (ChildVisibility != EVisibility::Collapsed) { const FVector2D ChildDesiredSize = CurChild.GetWidget()->GetDesiredSize(); const FMargin SlotPadding(CurChild.SlotPadding.Get()); const FVector2D SlotSize(AllottedGeometry.Size.X, ChildDesiredSize.Y + SlotPadding.GetTotalSpaceAlong<Orient_Vertical>()); const AlignmentArrangeResult XAlignmentResult = AlignChild<Orient_Horizontal>( SlotSize.X, CurChild, SlotPadding ); const AlignmentArrangeResult YAlignmentResult = AlignChild<Orient_Vertical>( SlotSize.Y, CurChild, SlotPadding ); ArrangedChildren.AddWidget( ChildVisibility, AllottedGeometry.MakeChild( CurChild.GetWidget(), FVector2D( XAlignmentResult.Offset, PositionSoFar - SlotSize.Y + YAlignmentResult.Offset ), FVector2D( XAlignmentResult.Size, YAlignmentResult.Size ) )); PositionSoFar -= SlotSize.Y; } } }
void SUniformGridPanel::OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const { if ( Children.Num() > 0 ) { const FVector2D CellSize(AllottedGeometry.Size.X / NumColumns, AllottedGeometry.Size.Y / NumRows); const FMargin& CurrentSlotPadding(SlotPadding.Get()); for ( int32 ChildIndex=0; ChildIndex < Children.Num(); ++ChildIndex ) { const FSlot& Child = Children[ChildIndex]; const EVisibility ChildVisibility = Child.GetWidget()->GetVisibility(); if ( ArrangedChildren.Accepts(ChildVisibility) ) { // Do the standard arrangement of elements within a slot // Takes care of alignment and padding. AlignmentArrangeResult XAxisResult = AlignChild<Orient_Horizontal>(CellSize.X, Child, CurrentSlotPadding); AlignmentArrangeResult YAxisResult = AlignChild<Orient_Vertical>(CellSize.Y, Child, CurrentSlotPadding); ArrangedChildren.AddWidget(ChildVisibility, AllottedGeometry.MakeChild(Child.GetWidget(), FVector2D(CellSize.X*Child.Column + XAxisResult.Offset, CellSize.Y*Child.Row + YAxisResult.Offset), FVector2D(XAxisResult.Size, YAxisResult.Size) )); } } } }
void SSequencerTrackArea::OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const { for (int32 ChildIndex = 0; ChildIndex < Children.Num(); ++ChildIndex) { const FTrackAreaSlot& CurChild = Children[ChildIndex]; const EVisibility ChildVisibility = CurChild.GetWidget()->GetVisibility(); if (!ArrangedChildren.Accepts(ChildVisibility)) { continue; } const FMargin Padding(0, CurChild.GetVerticalOffset(), 0, 0); AlignmentArrangeResult XResult = AlignChild<Orient_Horizontal>(AllottedGeometry.Size.X, CurChild, Padding, 1.0f, false); AlignmentArrangeResult YResult = AlignChild<Orient_Vertical>(AllottedGeometry.Size.Y, CurChild, Padding, 1.0f, false); ArrangedChildren.AddWidget(ChildVisibility, AllottedGeometry.MakeChild( CurChild.GetWidget(), FVector2D(XResult.Offset,YResult.Offset), FVector2D(XResult.Size, YResult.Size) ) ); } }
void SAnimationOutlinerView::OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const { const float Padding = SequencerLayoutConstants::NodePadding; const float IndentAmount = SequencerLayoutConstants::IndentAmount; float CurrentHeight = 0; for (int32 WidgetIndex = 0; WidgetIndex < Children.Num(); ++WidgetIndex) { const TSharedRef<SAnimationOutlinerTreeNode>& Widget = Children[WidgetIndex]; EVisibility Visibility = Widget->GetVisibility(); if( ArrangedChildren.Accepts( Visibility ) ) { const TSharedPtr<const FSequencerDisplayNode>& DisplayNode = Widget->GetDisplayNode(); // How large to make this node float HeightIncrement = DisplayNode->GetNodeHeight(); // How far to indent the widget float WidgetIndentOffset = IndentAmount*DisplayNode->GetTreeLevel(); // Place the widget at the current height, at the nodes desired size ArrangedChildren.AddWidget( Visibility, AllottedGeometry.MakeChild( Widget, FVector2D( WidgetIndentOffset, CurrentHeight ), FVector2D( AllottedGeometry.GetDrawSize().X-WidgetIndentOffset, HeightIncrement ) ) ); // Compute the start height for the next widget CurrentHeight += HeightIncrement+Padding; } } }
void SFlarePlanetaryBox::OnArrangeChildren(const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren) const { const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme(); for (int32 ChildIndex = 0; ChildIndex < Children.Num(); ++ChildIndex) { // Get all required data const SFlarePlanetaryBox::FSlot& CurChild = Children[ChildIndex]; const EVisibility ChildVisibility = CurChild.GetWidget()->GetVisibility(); FVector2D WidgetSize = CurChild.GetWidget()->GetDesiredSize(); FVector2D Offset = FVector2D::ZeroVector; // Child with index 0 is the main body, index 1 is probably the name but we don't care, others are sectors if (ChildIndex > 0) { float X, Y; float Angle = (360 / (Children.Num() - 1)) * (ChildIndex - 1) - 90; FMath::PolarToCartesian(Radius, FMath::DegreesToRadians(Angle), X, Y); Offset = FVector2D(X, Y); WidgetSize = FVector2D(CurChild.GetWidget()->GetDesiredSize().X, Theme.SectorButtonHeight); } // Arrange the child FVector2D Location = (AllottedGeometry.GetLocalSize() - WidgetSize) / 2 + Offset; ArrangedChildren.AddWidget(ChildVisibility, AllottedGeometry.MakeChild( CurChild.GetWidget(), Location, CurChild.GetWidget()->GetDesiredSize() )); } }
/** * This widget was created before render transforms existed for each widget, and it chose to apply the render transform AFTER the layout transform. * This means leveraging the render transform of FGeometry would be expensive, as we would need to use Concat(LayoutTransform, RenderTransform, Inverse(LayoutTransform). * Instead, we maintain the old way of doing it by modifying the AllottedGeometry only during rendering to append the widget's implied RenderTransform to the existing LayoutTransform. */ int32 SFxWidget::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { // Convert the 0..1 origin into local space extents. const FVector2D ScaleOrigin = RenderScaleOrigin.Get() * AllottedGeometry.Size; const FVector2D Offset = VisualOffset.Get() * AllottedGeometry.Size; // create the render transform as a scale around ScaleOrigin and offset it by Offset. const auto RenderTransform = Concatenate(Inverse(ScaleOrigin), RenderScale.Get(), ScaleOrigin, Offset); // This will append the render transform to the layout transform, and we only use it for rendering. FGeometry ModifiedGeometry = AllottedGeometry.MakeChild(AllottedGeometry.Size, RenderTransform); FArrangedChildren ArrangedChildren(EVisibility::Visible); this->ArrangeChildren(ModifiedGeometry, ArrangedChildren); // There may be zero elements in this array if our child collapsed/hidden if( ArrangedChildren.Num() > 0 ) { // We can only have one direct descendant. check( ArrangedChildren.Num() == 1 ); const FArrangedWidget& TheChild = ArrangedChildren[0]; // SFxWidgets are able to ignore parent clipping. const FSlateRect ChildClippingRect = (bIgnoreClipping.Get()) ? ModifiedGeometry.GetClippingRect() : MyClippingRect.IntersectionWith(ModifiedGeometry.GetClippingRect()); FWidgetStyle CompoundedWidgetStyle = FWidgetStyle(InWidgetStyle) .BlendColorAndOpacityTint(ColorAndOpacity.Get()) .SetForegroundColor( ForegroundColor ); return TheChild.Widget->Paint( Args.WithNewParent(this), TheChild.Geometry, ChildClippingRect, OutDrawElements, LayerId + 1, CompoundedWidgetStyle, ShouldBeEnabled( bParentEnabled ) ); } return LayerId; }
void SScaleBox::OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const { const EVisibility ChildVisibility = ChildSlot.GetWidget()->GetVisibility(); if ( ArrangedChildren.Accepts(ChildVisibility) ) { FVector2D DesiredSize = ChildSlot.GetWidget()->GetDesiredSize(); float FinalScale = 1; EStretch::Type CurrentStretch = Stretch.Get(); EStretchDirection::Type CurrentStretchDirection = StretchDirection.Get(); if ( DesiredSize.X != 0 && DesiredSize.Y != 0 ) { switch ( CurrentStretch ) { case EStretch::None: break; case EStretch::Fill: DesiredSize = AllottedGeometry.Size; break; case EStretch::ScaleToFit: FinalScale = FMath::Min(AllottedGeometry.Size.X / DesiredSize.X, AllottedGeometry.Size.Y / DesiredSize.Y); break; case EStretch::ScaleToFill: FinalScale = FMath::Max(AllottedGeometry.Size.X / DesiredSize.X, AllottedGeometry.Size.Y / DesiredSize.Y); break; } switch ( CurrentStretchDirection ) { case EStretchDirection::DownOnly: FinalScale = FMath::Min(FinalScale, 1.0f); break; case EStretchDirection::UpOnly: FinalScale = FMath::Max(FinalScale, 1.0f); break; } } FVector2D FinalOffset(0, 0); if ( CurrentStretch != EStretch::Fill ) { const FMargin SlotPadding(ChildSlot.SlotPadding.Get()); AlignmentArrangeResult XResult = AlignChild<Orient_Horizontal>(AllottedGeometry.Size.X, ChildSlot, SlotPadding, FinalScale, false); AlignmentArrangeResult YResult = AlignChild<Orient_Vertical>(AllottedGeometry.Size.Y, ChildSlot, SlotPadding, FinalScale, false); FinalOffset = FVector2D(XResult.Offset, YResult.Offset) * ( 1.0f / FinalScale ); } ArrangedChildren.AddWidget(ChildVisibility, AllottedGeometry.MakeChild( ChildSlot.GetWidget(), FinalOffset, DesiredSize, FinalScale ) ); } }
FGeometry SSection::GetKeyAreaGeometry( const struct FKeyAreaElement& KeyArea, const FGeometry& SectionGeometry ) const { // Get the height of the key area node. If the key area is top level then it is part of the section (and the same height ) and doesn't take up extra space float KeyAreaHeight = KeyArea.KeyAreaNode.IsTopLevel() ? SectionGeometry.GetDrawSize().Y : KeyArea.KeyAreaNode.GetNodeHeight(); // Compute the geometry for the key area return SectionGeometry.MakeChild( FVector2D( 0, KeyArea.HeightOffset ), FVector2D( SectionGeometry.Size.X, KeyAreaHeight ) ); }
void SSection::CheckForEdgeInteraction( const FPointerEvent& MouseEvent, const FGeometry& SectionGeometry ) { bLeftEdgeHovered = false; bRightEdgeHovered = false; bLeftEdgePressed = false; bRightEdgePressed = false; if (!SectionInterface->SectionIsResizable()) { return; } // Make areas to the left and right of the geometry. We will use these areas to determine if someone dragged the left or right edge of a section FGeometry SectionRectLeft = SectionGeometry.MakeChild( FVector2D::ZeroVector, FVector2D( SequencerSectionConstants::SectionGripSize, SectionGeometry.Size.Y ) ); FGeometry SectionRectRight = SectionGeometry.MakeChild( FVector2D( SectionGeometry.Size.X - SequencerSectionConstants::SectionGripSize, 0 ), SectionGeometry.Size ); if( SectionRectLeft.IsUnderLocation( MouseEvent.GetScreenSpacePosition() ) ) { if( MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton ) { bLeftEdgePressed = true; } else { bLeftEdgeHovered = true; } } else if( SectionRectRight.IsUnderLocation( MouseEvent.GetScreenSpacePosition() ) ) { if( MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton ) { bRightEdgePressed = true; } else { bRightEdgeHovered = true; } } }
void FSlateWidgetRun::ArrangeChildren( const TSharedRef< ILayoutBlock >& Block, const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const { // The block size and offset values are pre-scaled, so we need to account for that when converting the block offsets into paint geometry const float InverseScale = Inverse(AllottedGeometry.Scale); ArrangedChildren.AddWidget( AllottedGeometry.MakeChild(Info.Widget, TransformVector(InverseScale, Block->GetSize()), FSlateLayoutTransform(TransformPoint(InverseScale, Block->GetLocationOffset()))) ); }
void SDockingTabWell::OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const { // The specialized TabWell is dedicated to arranging tabs. // Tabs have uniform sizing (all tabs the same size). // TabWell also ignores widget visibilit, as it is not really // relevant. // The tab that is being dragged by the user, if any. TSharedPtr<SDockTab> TabBeingDragged = TabBeingDraggedPtr; const int32 NumChildren = Tabs.Num(); // Tabs have a uniform size. const FVector2D ChildSize = ComputeChildSize(AllottedGeometry); const float DraggedChildCenter = ChildBeingDraggedOffset + ChildSize.X / 2; // Arrange all the tabs left to right. float XOffset = 0; for( int32 TabIndex=0; TabIndex < NumChildren; ++TabIndex ) { const TSharedRef<SDockTab> CurTab = Tabs[TabIndex]; const float ChildWidthWithOverlap = ChildSize.X - CurTab->GetOverlapWidth(); // Is this spot reserved from the tab that is being dragged? if ( TabBeingDragged.IsValid() && XOffset <= DraggedChildCenter && DraggedChildCenter < (XOffset + ChildWidthWithOverlap) ) { // if so, leave some room to signify that this is where the dragged tab would end up XOffset += ChildWidthWithOverlap; } ArrangedChildren.AddWidget( AllottedGeometry.MakeChild(CurTab, FVector2D(XOffset, 0), ChildSize) ); XOffset += ChildWidthWithOverlap; } // Arrange the tab currently being dragged by the user, if any if ( TabBeingDragged.IsValid() ) { ArrangedChildren.AddWidget( AllottedGeometry.MakeChild( TabBeingDragged.ToSharedRef(), FVector2D(ChildBeingDraggedOffset,0), ChildSize) ); } }
void SMenuAnchor::OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const { ArrangeSingleChild( AllottedGeometry, ArrangedChildren, Children[0], FVector2D::UnitVector ); const TSharedPtr<SWindow> PresentingWindow = PopupWindowPtr.Pin(); if (IsOpenAndReusingWindow() && PresentingWindow.IsValid()) { const FPopupPlacement LocalPlacement(AllottedGeometry, Children[1].GetWidget()->GetDesiredSize(), Placement.Get()); ArrangedChildren.AddWidget(AllottedGeometry.MakeChild(Children[1].GetWidget(), LocalPlacement.LocalPopupSize, FSlateLayoutTransform(LocalPopupPosition))); } }
/** * Panels arrange their children in a space described by the AllottedGeometry parameter. The results of the arrangement * should be returned by appending a FArrangedWidget pair for every child widget. See StackPanel for an example */ void SSplitter::OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const { TArray<FLayoutGeometry> LayoutChildren = ArrangeChildrenForLayout(AllottedGeometry); // Arrange the children horizontally or vertically. for (int32 ChildIndex=0; ChildIndex < Children.Num(); ++ChildIndex) { ArrangedChildren.AddWidget( AllottedGeometry.MakeChild( Children[ChildIndex].GetWidget(), LayoutChildren[ChildIndex] ) ); } }
int32 FSlateHyperlinkRun::OnPaint( const FPaintArgs& Args, const FTextLayout::FLineView& Line, const TSharedRef< ILayoutBlock >& Block, const FTextBlockStyle& DefaultStyle, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { const TSharedRef< FWidgetLayoutBlock > WidgetBlock = StaticCastSharedRef< FWidgetLayoutBlock >( Block ); // The block size and offset values are pre-scaled, so we need to account for that when converting the block offsets into paint geometry const float InverseScale = Inverse(AllottedGeometry.Scale); const FGeometry WidgetGeometry = AllottedGeometry.MakeChild(TransformVector(InverseScale, Block->GetSize()), FSlateLayoutTransform(TransformPoint(InverseScale, Block->GetLocationOffset()))); return WidgetBlock->GetWidget()->Paint( Args, WidgetGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled ); }
void SSplitter2x2::OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const { TArray<FLayoutGeometry> LayoutChildren = ArrangeChildrenForLayout(AllottedGeometry); for (int32 ChildIndex=0; ChildIndex < Children.Num(); ++ChildIndex) { const FSlot& CurSlot = Children[ChildIndex]; // put them in their spot ArrangedChildren.AddWidget( AllottedGeometry.MakeChild( Children[ChildIndex].GetWidget(), LayoutChildren[ChildIndex] ) ); } }
void SFxWidget::OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const { const EVisibility MyVisibility = this->GetVisibility(); if ( ArrangedChildren.Accepts( MyVisibility ) ) { // Only layout scale affects the arranged geometry. const FSlateLayoutTransform LayoutTransform(LayoutScale.Get()); ArrangedChildren.AddWidget( AllottedGeometry.MakeChild( this->ChildSlot.GetWidget(), TransformVector(Inverse(LayoutTransform), AllottedGeometry.Size), LayoutTransform)); } }
void SGraphPanel::ArrangeChildrenForContextMenuSummon(const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren) const { // First pass nodes for (int32 ChildIndex = 0; ChildIndex < VisibleChildren.Num(); ++ChildIndex) { const TSharedRef<SNode>& SomeChild = VisibleChildren[ChildIndex]; if (!SomeChild->RequiresSecondPassLayout()) { ArrangedChildren.AddWidget( AllottedGeometry.MakeChild( SomeChild, SomeChild->GetPosition() - ViewOffset, SomeChild->GetDesiredSizeForMarquee(), GetZoomAmount() ) ); } } // Second pass nodes for (int32 ChildIndex = 0; ChildIndex < VisibleChildren.Num(); ++ChildIndex) { const TSharedRef<SNode>& SomeChild = VisibleChildren[ChildIndex]; if (SomeChild->RequiresSecondPassLayout()) { SomeChild->PerformSecondPassLayout(NodeToWidgetLookup); ArrangedChildren.AddWidget( AllottedGeometry.MakeChild( SomeChild, SomeChild->GetPosition() - ViewOffset, SomeChild->GetDesiredSizeForMarquee(), GetZoomAmount() ) ); } } }
void SWeakWidget::OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const { // We just want to show the child that we are presenting. Always stretch it to occupy all of the space. TSharedRef<SWidget> MyContent = WeakChild.GetWidget(); if( MyContent!=SNullWidget::NullWidget && ArrangedChildren.Accepts(MyContent->GetVisibility()) ) { ArrangedChildren.AddWidget( AllottedGeometry.MakeChild( MyContent, FVector2D(0,0), AllottedGeometry.Size ) ); } }
void SAutoFolding::OnArrangeChildren(const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren) const { //这里处理添加到content里面的逻辑,对齐方式,显示方式 areaSize = AllottedGeometry.GetLocalSize(); float startX = contentMargin.Left; float startY = contentMargin.Top; for (int32 ChildIndex = 0; ChildIndex < Children.Num(); ++ChildIndex) { const SBoxPanel::FSlot& CurChild = Children[ChildIndex]; const EVisibility ChildVisibility = CurChild.GetWidget()->GetVisibility(); FVector2D size = CurChild.GetWidget()->GetDesiredSize(); ArrangedChildren.AddWidget(ChildVisibility, AllottedGeometry.MakeChild(CurChild.GetWidget(), FVector2D(startX, startY), FVector2D(size.X, size.Y))); } }
virtual void OnArrangeChildren(const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren) const override { CachedSize = AllottedGeometry.GetLocalSize(); const TSharedRef<SWidget>& ChildWidget = ChildSlot.GetWidget(); if (ChildWidget->GetVisibility() != EVisibility::Collapsed) { const FVector2D& WidgetDesiredSize = ChildWidget->GetDesiredSize(); // Clamp the pan offset based on our current geometry SScrollableSnapshotImage* const NonConstThis = const_cast<SScrollableSnapshotImage*>(this); NonConstThis->ClampViewOffset(WidgetDesiredSize, CachedSize); ArrangedChildren.AddWidget(AllottedGeometry.MakeChild(ChildWidget, PhysicalOffset, WidgetDesiredSize)); } }
void SDPIScaler::OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const { const EVisibility MyVisibility = this->GetVisibility(); if ( ArrangedChildren.Accepts( MyVisibility ) ) { const float MyDPIScale = DPIScale.Get(); ArrangedChildren.AddWidget( AllottedGeometry.MakeChild( this->ChildSlot.GetWidget(), FVector2D::ZeroVector, AllottedGeometry.Size / MyDPIScale, MyDPIScale )); } }
FGeometry ComputeMenuPlacement(const FGeometry& AllottedGeometry, const FVector2D& PopupDesiredSize, EMenuPlacement PlacementMode) { // Compute the popup size, offset, and anchor rect in local space const FPopupPlacement Placement(AllottedGeometry, PopupDesiredSize, PlacementMode); // ask the application to compute the proper desktop offset for the anchor. This requires the offsets to be in desktop space. const FVector2D NewPositionDesktopSpace = FSlateApplication::Get().CalculatePopupWindowPosition( TransformRect(AllottedGeometry.GetAccumulatedLayoutTransform(), Placement.AnchorLocalSpace), TransformVector(AllottedGeometry.GetAccumulatedLayoutTransform(), Placement.LocalPopupSize), Placement.Orientation); // transform the desktop offset into local space and use that as the layout transform for the child content. return AllottedGeometry.MakeChild( Placement.LocalPopupSize, FSlateLayoutTransform(TransformPoint(Inverse(AllottedGeometry.GetAccumulatedLayoutTransform()), NewPositionDesktopSpace))); }
int32 SSection::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { int32 StartLayer = SCompoundWidget::OnPaint( Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled ); FGeometry SectionGeometry = AllottedGeometry.MakeChild( FVector2D( SequencerSectionConstants::SectionGripSize, 0 ), AllottedGeometry.GetDrawSize() - FVector2D( SequencerSectionConstants::SectionGripSize*2, 0.0f ) ); FSlateRect SectionClipRect = SectionGeometry.GetClippingRect().IntersectionWith( MyClippingRect ); // Ask the interface to draw the section int32 PostSectionLayer = SectionInterface->OnPaintSection( SectionGeometry, SectionClipRect, OutDrawElements, LayerId, bParentEnabled ); DrawSectionBorders(AllottedGeometry, MyClippingRect, OutDrawElements, PostSectionLayer ); PaintKeys( SectionGeometry, MyClippingRect, OutDrawElements, PostSectionLayer, InWidgetStyle ); // Section name with drop shadow FText SectionTitle = SectionInterface->GetSectionTitle(); if (!SectionTitle.IsEmpty()) { FSlateDrawElement::MakeText( OutDrawElements, PostSectionLayer+1, SectionGeometry.ToOffsetPaintGeometry(FVector2D(6, 6)), SectionTitle, FEditorStyle::GetFontStyle("NormalFont"), MyClippingRect, ESlateDrawEffect::None, FLinearColor::Black ); FSlateDrawElement::MakeText( OutDrawElements, PostSectionLayer+2, SectionGeometry.ToOffsetPaintGeometry(FVector2D(5, 5)), SectionTitle, FEditorStyle::GetFontStyle("NormalFont"), MyClippingRect, ESlateDrawEffect::None, FLinearColor::White ); } return LayerId; }
void SWrapBox::OnArrangeChildren(const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren) const { const float WidthToWrapAt = PreferredWidth.Get(); FChildArranger::Arrange(*this, [&](const FSlot& Slot, const FChildArranger::FArrangementData& ArrangementData) { // Calculate offset and size in slot using alignment. const AlignmentArrangeResult XResult = AlignChild<Orient_Horizontal>(ArrangementData.SlotSize.X, Slot, Slot.SlotPadding.Get()); const AlignmentArrangeResult YResult = AlignChild<Orient_Vertical>(ArrangementData.SlotSize.Y, Slot, Slot.SlotPadding.Get()); // Note: Alignment offset is relative to slot offset. const FVector2D PostAlignmentOffset = ArrangementData.SlotOffset + FVector2D(XResult.Offset, YResult.Offset); const FVector2D PostAlignmentSize = FVector2D(XResult.Size, YResult.Size); ArrangedChildren.AddWidget(AllottedGeometry.MakeChild(Slot.GetWidget(), PostAlignmentOffset, PostAlignmentSize)); }); }
void SZoomPan::OnArrangeChildren(const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren) const { const EVisibility ChildVisibility = ChildSlot.GetWidget()->GetVisibility(); if ( ArrangedChildren.Accepts(ChildVisibility) ) { const FMargin SlotPadding(ChildSlot.SlotPadding.Get()); AlignmentArrangeResult XResult = AlignChild<Orient_Horizontal>(AllottedGeometry.Size.X, ChildSlot, SlotPadding, 1); AlignmentArrangeResult YResult = AlignChild<Orient_Vertical>(AllottedGeometry.Size.Y, ChildSlot, SlotPadding, 1); ArrangedChildren.AddWidget( ChildVisibility, AllottedGeometry.MakeChild( ChildSlot.GetWidget(), FVector2D(XResult.Offset, YResult.Offset) - ViewOffset.Get(), ChildSlot.GetWidget()->GetDesiredSize(), ZoomAmount.Get() ) ); } }
/** * Gets the geometry of a section, optionally inflated by some margin * * @param AllottedGeometry The geometry of the area where sections are located * @param NodeHeight The height of the section area (and its children) * @param SectionInterface Interface to the section to get geometry for * @param TimeToPixelConverter Converts time to pixels and vice versa */ FGeometry GetSectionGeometry( const FGeometry& AllottedGeometry, int32 RowIndex, int32 MaxTracks, float NodeHeight, TSharedPtr<ISequencerSection> SectionInterface, const FTimeToPixel& TimeToPixelConverter ) { const UMovieSceneSection* Section = SectionInterface->GetSectionObject(); // Where to start drawing the section float StartX = TimeToPixelConverter.TimeToPixel( Section->GetStartTime() ); // Where to stop drawing the section float EndX = TimeToPixelConverter.TimeToPixel( Section->GetEndTime() ); // Actual section length without grips. float SectionLengthActual = EndX-StartX; float SectionLengthWithGrips = SectionLengthActual+SequencerSectionConstants::SectionGripSize*2; float ActualHeight = NodeHeight / MaxTracks; // Compute allotted geometry area that can be used to draw the section return AllottedGeometry.MakeChild( FVector2D( StartX-SequencerSectionConstants::SectionGripSize, ActualHeight * RowIndex ), FVector2D( SectionLengthWithGrips, ActualHeight ) ); }