6#include "Components/CanvasPanel.h"
7#include "Components/CanvasPanelSlot.h"
8#include "TimerManager.h"
12 Super::NativeConstruct();
15 if (UCanvasPanelSlot* RootSlot = Cast<UCanvasPanelSlot>(Slot))
35 Super::NativeDestruct();
43 if (!InMouseEvent.IsMouseButtonDown(EKeys::LeftMouseButton))
44 return FReply::Unhandled();
53 dragStartTime = GetWorld() ? GetWorld()->GetTimeSeconds() : 0.0f;
57 TSharedPtr<SWidget> CachedWidget = GetCachedWidget();
58 if (CachedWidget.IsValid())
60 return FReply::Handled().CaptureMouse(CachedWidget.ToSharedRef());
63 return FReply::Handled();
69 return FReply::Unhandled();
75 float dragDistance = dragDelta.Size();
78 if (dragDistance <= 10.0f)
80 return FReply::Handled().ReleaseMouseCapture();
84 float dragTime = GetWorld() ? (GetWorld()->GetTimeSeconds() -
dragStartTime) : 0.01f;
85 float velocity = dragDistance / FMath::Max(dragTime, 0.01f);
93 return FReply::Handled().ReleaseMouseCapture();
99 return FReply::Unhandled();
106 return FReply::Handled();
142 UCanvasPanelSlot* containerSlot = Cast<UCanvasPanelSlot>(
PageContainer->Slot);
158 GetWorld()->GetTimerManager().SetTimer(
178 for (int32 i = 0; i < ItemCount; ++i)
188 UCanvasPanelSlot* slot =
PageContainer->AddChildToCanvas(newItem);
193 FVector2D itemPosition;
195 itemPosition = FVector2D(stride * i, 0.0f);
197 itemPosition = FVector2D(0.0f, stride * i);
199 slot->SetAnchors(FAnchors(0.0f, 0.0f, 0.0f, 0.0f));
200 slot->SetAlignment(FVector2D(0.0f, 0.0f));
201 slot->SetPosition(itemPosition);
214 PageDotIndicator->SetVisibility(ItemCount > 1 ? ESlateVisibility::Visible : ESlateVisibility::Collapsed);
255 int32 dragPages = FMath::RoundToInt(dragRatio);
260 return FMath::Clamp(targetPage, 0,
pageItemList.Num() - 1);
266 UCanvasPanelSlot* containerSlot = Cast<UCanvasPanelSlot>(
PageContainer->Slot);
278 float easedAlpha = FMath::InterpEaseOut(0.0f, 1.0f, Alpha, 2.0f);
282 containerSlot->SetPosition(currentPosition);
319 float offset = -stride * PageIndex;
321 return ScrollDirection == EPageScrollDirection::Horizontal ? FVector2D(offset, 0.0f) : FVector2D(0.0f, offset);
326 if (UCanvasPanelSlot* containerSlot = Cast<UCanvasPanelSlot>(
PageContainer->Slot))
328 containerSlot->SetPosition(Position);
345 UCanvasPanelSlot* containerSlot = Cast<UCanvasPanelSlot>(
PageContainer->Slot);
349 FVector2D containerPos = containerSlot->GetPosition();
351 float viewportCenter = (
ScrollDirection == EPageScrollDirection::Horizontal)
365 pagePos = FVector2D(stride * i, 0.0f);
367 pagePos = FVector2D(0.0f, stride * i);
369 float pageCenter = (
ScrollDirection == EPageScrollDirection::Horizontal)
370 ? (containerPos.X + pagePos.X +
PageSize.X * 0.5f)
371 : (containerPos.Y + pagePos.Y +
PageSize.Y * 0.5f);
373 float distance = FMath::Abs(pageCenter - viewportCenter);
375 float normalizedDistance = FMath::Clamp(distance / maxDistance, 0.0f, 1.0f);
380 item->SetRenderScale(FVector2D(scale, scale));
390 UCanvasPanelSlot* containerSlot = Cast<UCanvasPanelSlot>(
PageContainer->Slot);
399 FVector2D newPosition = basePosition;
402 newPosition.X += dragDelta.X;
404 newPosition.Y += dragDelta.Y;
406 containerSlot->SetPosition(newPosition);
페이지 스크롤 뷰의 개별 페이지 아이템 UPageScrollView에 의해 동적으로 생성되며, 개별 페이지의 콘텐츠를 담는 컨테이너입니다.
void UpdateFocusState(bool bInFocused, float InScale)
포커스 상태를 업데이트합니다.
virtual void InitData(int32 InIndex, class UPageScrollView *InOwner)
페이지 아이템을 초기화합니다.
void MovePage(int32 PageIndex, bool bAnimate=true)
특정 페이지로 이동합니다.
void UpdateItemScales()
페이지 아이템들의 스케일을 거리 기반으로 업데이트합니다.
FVector2D PageSize
각 페이지의 크기 (Width × Height)
FVector2D animTargetPosition
void SetContainerPosition(FVector2D Position)
컨테이너 위치를 설정합니다.
void StopAnimation()
스냅 애니메이션을 중지합니다.
TObjectPtr< class UPageScrollDot > PageDotIndicator
페이지 인디케이터 (선택적)
virtual void NativeDestruct() override
int32 PrevPageIndex
이전 페이지 인덱스 (스냅 계산용)
float SideScale
중앙에서 벗어난 페이지의 스케일 값
int32 CurPageIndex
현재 선택된 페이지 인덱스
FVector2D dragCurrentPosition
float FocusScale
중앙에 있는 페이지의 스케일 값
FORCEINLINE float GetPageStride() const
페이지 간 거리를 계산합니다.
bool bIsDragging
드래그 상태 추적
void TickSnapAnimation()
스냅 애니메이션을 Tick합니다.
void UpdatePageDotIndicator()
페이지 인디케이터를 업데이트합니다.
void SetNumberOfPages(int32 ItemCount)
페이지 개수를 설정하고 동적으로 생성합니다.
FVector2D animStartPosition
TObjectPtr< class UCanvasPanel > PageContainer
페이지 아이템들을 담을 컨테이너 (드래그로 위치 이동)
virtual FReply NativeOnMouseMove(const FGeometry &InGeometry, const FPointerEvent &InMouseEvent) override
마우스 이동 이벤트
TSubclassOf< class UPageScrollItem > PageItemClass
페이지 아이템으로 생성할 위젯 블루프린트 클래스
FVector2D GetPagePosition(int32 PageIndex) const
페이지 인덱스에 해당하는 목표 위치를 계산합니다.
EPageScrollDirection ScrollDirection
스크롤 방향 (수평/수직)
void PrevPage()
이전 페이지로 이동합니다.
FOnPageChanged OnPageChanged
페이지 변경 이벤트
FVector2D dragStartPosition
void NextPage()
다음 페이지로 이동합니다.
FVector2D ViewportSize
뷰포트 크기 (SizeBox에서 계산)
FTimerHandle snapAnimTimerHandle
애니메이션 상태
virtual void NativeConstruct() override
virtual FReply NativeOnMouseButtonDown(const FGeometry &InGeometry, const FPointerEvent &InMouseEvent) override
마우스 버튼 다운 이벤트
void UpdateContainerPositionDuringDrag()
드래그 중 컨테이너 위치를 업데이트합니다.
float FastSwipeThreshold
빠른 스와이프 인식 임계값 (픽셀/초)
virtual FReply NativeOnMouseButtonUp(const FGeometry &InGeometry, const FPointerEvent &InMouseEvent) override
마우스 버튼 업 이벤트
float SnapAnimationSpeed
스냅 애니메이션 속도 (초 단위)
bool bEnableScaleEffect
중앙 스케일 효과 활성화 여부
int32 CalculateTargetPage(FVector2D DragDelta, float Velocity) const
드래그 종료 시 목표 페이지를 계산합니다.
int32 DefaultPageIndex
기본으로 선택될 페이지 인덱스
TArray< TObjectPtr< class UPageScrollItem > > pageItemList
생성된 페이지 아이템 목록