static FEndOfListResult ComputeOffsetForEndOfList( const FGeometry& ListPanelGeometry, const FChildren& ListPanelChildren ) { float OffsetFromEndOfList = 0.0f; float AvailableSpace = ListPanelGeometry.Size.Y; float ItemsAboveView = 0.0f; for ( int ChildIndex=ListPanelChildren.Num()-1; ChildIndex >= 0; --ChildIndex ) { const float CurChildHeight = ListPanelChildren.GetChildAt(ChildIndex)->GetDesiredSize().Y; if (AvailableSpace == 0) { ItemsAboveView ++; } if ( CurChildHeight < AvailableSpace ) { // This whole child fits OffsetFromEndOfList += 1; AvailableSpace -= CurChildHeight; } else { OffsetFromEndOfList += AvailableSpace / CurChildHeight; ItemsAboveView += (CurChildHeight - AvailableSpace)/CurChildHeight; AvailableSpace = 0; } } return FEndOfListResult( OffsetFromEndOfList, ItemsAboveView ); }
void SWidget::SlatePrepass(float LayoutScaleMultiplier) { //SLATE_CYCLE_COUNTER_SCOPE_CUSTOM_DETAILED(SLATE_STATS_DETAIL_LEVEL_MED, GSlatePrepass, GetType()); // TODO Figure out a better way than to just reset the pointer. This causes problems when we prepass // volatile widgets, who still need to know about their invalidation panel incase they vanish themselves. // Reset the layout cache object each pre-pass to ensure we never access a stale layout cache object // as this widget could have been moved in and out of a panel that was invalidated between frames. //LayoutCache = nullptr; if ( bCanHaveChildren ) { // Cache child desired sizes first. This widget's desired size is // a function of its children's sizes. FChildren* MyChildren = this->GetChildren(); int32 NumChildren = MyChildren->Num(); for ( int32 ChildIndex=0; ChildIndex < NumChildren; ++ChildIndex ) { const TSharedRef<SWidget>& Child = MyChildren->GetChildAt(ChildIndex); if ( Child->Visibility.Get() != EVisibility::Collapsed ) { const float ChildLayoutScaleMultiplier = GetRelativeLayoutScale(MyChildren->GetSlotAt(ChildIndex)); // Recur: Descend down the widget tree. Child->SlatePrepass(LayoutScaleMultiplier*ChildLayoutScaleMultiplier); } } } // Cache this widget's desired size. CacheDesiredSize(LayoutScaleMultiplier); }
static PyObject *py_ue_swidget_get_children(ue_PySWidget *self, PyObject * args) { FChildren *children = self->Widget->GetChildren(); PyObject *py_list = PyList_New(0); for (int32 i = 0; i < children->Num(); i++) { TSharedRef<SWidget> widget = children->GetChildAt(i); PyObject *item = (PyObject *)ue_py_get_swidget(widget); PyList_Append(py_list, item); Py_DECREF(item); } return py_list; }
void SWidget::CachePrepass(ILayoutCache* InLayoutCache) { if ( bCanHaveChildren ) { FChildren* MyChildren = this->GetChildren(); int32 NumChildren = MyChildren->Num(); for ( int32 ChildIndex=0; ChildIndex < NumChildren; ++ChildIndex ) { const TSharedRef<SWidget>& Child = MyChildren->GetChildAt(ChildIndex); if ( Child->GetVisibility().IsVisible() == false ) { Child->LayoutCache = InLayoutCache; } else { Child->CachePrepass(InLayoutCache); } } } }
TSharedPtr<class SWidget> GetFirstKeyboardFocusableWidget( TSharedPtr<class SWidget> FocusCandidate ) { if ( FocusCandidate->SupportsKeyboardFocus() ) { return FocusCandidate; } FChildren * Children = FocusCandidate->GetChildren(); if ( Children != NULL ) { for ( int32 i = 0; i < Children->Num(); i++ ) { FocusCandidate = GetFirstKeyboardFocusableWidget( Children->GetChildAt( i ) ); if ( FocusCandidate.IsValid() ) { return FocusCandidate; } } } return NULL; }