504 lines
16 KiB
C++
504 lines
16 KiB
C++
// Copyright 2019-Present LexLiu. All Rights Reserved.
|
|
|
|
#include "Widgets/SCompoundWidget.h"
|
|
#include "DesktopPlatformModule.h"
|
|
#include "LGUIEditorStyle.h"
|
|
#pragma once
|
|
|
|
#define LOCTEXT_NAMESPACE "AnchorPreviewWidget"
|
|
|
|
namespace LGUIAnchorPreviewWidget
|
|
{
|
|
enum class UIAnchorHorizontalAlign :uint8
|
|
{
|
|
None, Left, Center, Right, Stretch
|
|
};
|
|
enum class UIAnchorVerticalAlign :uint8
|
|
{
|
|
None, Top, Middle, Bottom, Stretch
|
|
};
|
|
|
|
DECLARE_DELEGATE_TwoParams(FOnAnchorChange, UIAnchorHorizontalAlign, UIAnchorVerticalAlign);
|
|
|
|
//Anchor
|
|
class SAnchorPreviewWidget : public SCompoundWidget
|
|
{
|
|
public:
|
|
|
|
SLATE_BEGIN_ARGS(SAnchorPreviewWidget) {}
|
|
SLATE_ATTRIBUTE(float, BasePadding)
|
|
SLATE_ATTRIBUTE(bool, ButtonEnable)
|
|
SLATE_ATTRIBUTE(UIAnchorHorizontalAlign, SelectedHAlign)
|
|
SLATE_ATTRIBUTE(UIAnchorVerticalAlign, SelectedVAlign)
|
|
SLATE_ATTRIBUTE(UIAnchorHorizontalAlign, PersistentHAlign)
|
|
SLATE_ATTRIBUTE(UIAnchorVerticalAlign, PersistentVAlign)
|
|
SLATE_EVENT(FOnAnchorChange, OnAnchorChange)
|
|
SLATE_END_ARGS()
|
|
|
|
void Construct(const FArguments& InArgs,
|
|
FVector2D Size
|
|
)
|
|
{
|
|
auto anchorLineHorizontalWidth = Size.X;
|
|
auto anchorLineHorizontalHeight = 1;
|
|
auto anchorLineVerticalWidth = 1;
|
|
auto anchorLineVerticalHeight = Size.Y;
|
|
|
|
EHorizontalAlignment anchorDotLeftTopHAlign = EHorizontalAlignment::HAlign_Left;
|
|
EVerticalAlignment anchorDotLeftTopVAlign = EVerticalAlignment::VAlign_Top;
|
|
EHorizontalAlignment anchorDotRightTopHAlign = EHorizontalAlignment::HAlign_Right;
|
|
EVerticalAlignment anchorDotRightTopVAlign = EVerticalAlignment::VAlign_Top;
|
|
EHorizontalAlignment anchorDotLeftBottomHAlign = EHorizontalAlignment::HAlign_Left;
|
|
EVerticalAlignment anchorDotLeftBottomVAlign = EVerticalAlignment::VAlign_Bottom;
|
|
EHorizontalAlignment anchorDotRightBottomHAlign = EHorizontalAlignment::HAlign_Right;
|
|
EVerticalAlignment anchorDotRightBottomVAlign = EVerticalAlignment::VAlign_Bottom;
|
|
int anchorDotSize = 5;
|
|
//EHorizontalAlignment pivotDotHAlign = EHorizontalAlignment::HAlign_Left;
|
|
//EVerticalAlignment pivotDotVAlign = EVerticalAlignment::VAlign_Top;
|
|
int pivotDotSize = 5;
|
|
|
|
EHorizontalAlignment hAlign = EHorizontalAlignment::HAlign_Center;
|
|
switch (InArgs._PersistentHAlign.Get())
|
|
{
|
|
case UIAnchorHorizontalAlign::None:
|
|
{
|
|
anchorDotSize = 0;
|
|
anchorLineVerticalHeight = 0;
|
|
//pivotDotHAlign = EHorizontalAlignment::HAlign_Center;
|
|
}
|
|
break;
|
|
case UIAnchorHorizontalAlign::Left:
|
|
{
|
|
hAlign = EHorizontalAlignment::HAlign_Left;
|
|
anchorDotLeftTopHAlign = hAlign;
|
|
anchorDotLeftBottomHAlign = hAlign;
|
|
anchorDotRightTopHAlign = hAlign;
|
|
anchorDotRightBottomHAlign = hAlign;
|
|
//pivotDotHAlign = hAlign;
|
|
}break;
|
|
case UIAnchorHorizontalAlign::Center:
|
|
{
|
|
hAlign = EHorizontalAlignment::HAlign_Center;
|
|
anchorDotLeftTopHAlign = hAlign;
|
|
anchorDotLeftBottomHAlign = hAlign;
|
|
anchorDotRightTopHAlign = hAlign;
|
|
anchorDotRightBottomHAlign = hAlign;
|
|
//pivotDotHAlign = hAlign;
|
|
} break;
|
|
case UIAnchorHorizontalAlign::Right:
|
|
{
|
|
hAlign = EHorizontalAlignment::HAlign_Right;
|
|
anchorDotLeftTopHAlign = hAlign;
|
|
anchorDotLeftBottomHAlign = hAlign;
|
|
anchorDotRightTopHAlign = hAlign;
|
|
anchorDotRightBottomHAlign = hAlign;
|
|
//pivotDotHAlign = hAlign;
|
|
} break;
|
|
case UIAnchorHorizontalAlign::Stretch:
|
|
{
|
|
hAlign = EHorizontalAlignment::HAlign_Fill;
|
|
anchorLineVerticalHeight = 1;
|
|
//pivotDotHAlign = EHorizontalAlignment::HAlign_Center;
|
|
}
|
|
break;
|
|
}
|
|
EVerticalAlignment vAlign = EVerticalAlignment::VAlign_Center;
|
|
switch (InArgs._PersistentVAlign.Get())
|
|
{
|
|
case UIAnchorVerticalAlign::None:
|
|
{
|
|
anchorDotSize = 0;
|
|
anchorLineHorizontalWidth = 0;
|
|
//pivotDotVAlign = EVerticalAlignment::VAlign_Center;
|
|
}
|
|
break;
|
|
case UIAnchorVerticalAlign::Top:
|
|
{
|
|
vAlign = EVerticalAlignment::VAlign_Top;
|
|
anchorDotLeftTopVAlign = vAlign;
|
|
anchorDotLeftBottomVAlign = vAlign;
|
|
anchorDotRightTopVAlign = vAlign;
|
|
anchorDotRightBottomVAlign = vAlign;
|
|
//pivotDotVAlign = vAlign;
|
|
}
|
|
break;
|
|
case UIAnchorVerticalAlign::Middle:
|
|
{
|
|
vAlign = EVerticalAlignment::VAlign_Center;
|
|
anchorDotLeftTopVAlign = vAlign;
|
|
anchorDotLeftBottomVAlign = vAlign;
|
|
anchorDotRightTopVAlign = vAlign;
|
|
anchorDotRightBottomVAlign = vAlign;
|
|
//pivotDotVAlign = vAlign;
|
|
}
|
|
break;
|
|
case UIAnchorVerticalAlign::Bottom:
|
|
{
|
|
vAlign = EVerticalAlignment::VAlign_Bottom;
|
|
anchorDotLeftTopVAlign = vAlign;
|
|
anchorDotLeftBottomVAlign = vAlign;
|
|
anchorDotRightTopVAlign = vAlign;
|
|
anchorDotRightBottomVAlign = vAlign;
|
|
//pivotDotVAlign = vAlign;
|
|
}
|
|
break;
|
|
case UIAnchorVerticalAlign::Stretch:
|
|
{
|
|
vAlign = EVerticalAlignment::VAlign_Fill;
|
|
anchorLineHorizontalWidth = 1;
|
|
//pivotDotVAlign = EVerticalAlignment::VAlign_Center;
|
|
}
|
|
break;
|
|
}
|
|
|
|
auto anchorLineBrushHorizontal = FLGUIEditorStyle::Get().GetBrush("LGUIEditor.WhiteDot");
|
|
auto anchorLineBrushVertical = FLGUIEditorStyle::Get().GetBrush("LGUIEditor.WhiteDot");
|
|
if (InArgs._PersistentHAlign.Get() == UIAnchorHorizontalAlign::Stretch && InArgs._PersistentVAlign.Get() == UIAnchorVerticalAlign::Stretch)
|
|
{
|
|
anchorLineBrushHorizontal = FLGUIEditorStyle::Get().GetBrush("LGUIEditor.WhiteFrame");
|
|
anchorLineBrushVertical = FLGUIEditorStyle::Get().GetBrush("LGUIEditor.WhiteFrame");
|
|
}
|
|
else if (InArgs._PersistentHAlign.Get() == UIAnchorHorizontalAlign::None && InArgs._PersistentVAlign.Get() == UIAnchorVerticalAlign::Stretch)
|
|
{
|
|
anchorLineBrushHorizontal = FLGUIEditorStyle::Get().GetBrush("LGUIEditor.WhiteFrameHorizontal");
|
|
anchorLineHorizontalWidth = Size.X;
|
|
anchorLineHorizontalHeight = Size.Y;
|
|
anchorLineVerticalWidth = 0;
|
|
anchorLineVerticalHeight = 0;
|
|
}
|
|
else if (InArgs._PersistentHAlign.Get() == UIAnchorHorizontalAlign::Stretch && InArgs._PersistentVAlign.Get() == UIAnchorVerticalAlign::None)
|
|
{
|
|
anchorLineBrushVertical = FLGUIEditorStyle::Get().GetBrush("LGUIEditor.WhiteFrameVertical");
|
|
anchorLineVerticalWidth = Size.X;
|
|
anchorLineVerticalHeight = Size.Y;
|
|
anchorLineHorizontalWidth = 0;
|
|
anchorLineHorizontalHeight = 0;
|
|
}
|
|
|
|
ChildSlot
|
|
[
|
|
SNew(SOverlay)
|
|
//highlight selected
|
|
+ SOverlay::Slot()
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(Size.X)
|
|
.HeightOverride(Size.Y)
|
|
.HAlign(EHorizontalAlignment::HAlign_Center)
|
|
.VAlign(EVerticalAlignment::VAlign_Center)
|
|
[
|
|
InArgs._SelectedHAlign.Get() == InArgs._PersistentHAlign.Get() && InArgs._SelectedVAlign.Get() == InArgs._PersistentVAlign.Get() ?
|
|
(
|
|
SNew(SBox)
|
|
.WidthOverride(Size.X + 10)
|
|
.HeightOverride(Size.Y + 10)
|
|
[
|
|
SNew(SImage)
|
|
.Image(FLGUIEditorStyle::Get().GetBrush("LGUIEditor.WhiteFrame"))
|
|
.ColorAndOpacity(FLinearColor(FColor(255, 255, 255, 255)))
|
|
]
|
|
)
|
|
:
|
|
(SNew(SBox))
|
|
]
|
|
]
|
|
+ SOverlay::Slot()
|
|
[
|
|
SNew(SOverlay)
|
|
//outer rect
|
|
+ SOverlay::Slot()
|
|
[
|
|
SNew(SBox)
|
|
.HAlign(EHorizontalAlignment::HAlign_Center)
|
|
.VAlign(EVerticalAlignment::VAlign_Center)
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(Size.X)
|
|
.HeightOverride(Size.Y)
|
|
[
|
|
SNew(SImage)
|
|
.Image(FLGUIEditorStyle::Get().GetBrush("LGUIEditor.WhiteFrame"))
|
|
.ColorAndOpacity(FLinearColor(FColor(122, 122, 122, 122)))
|
|
]
|
|
]
|
|
]
|
|
+ SOverlay::Slot()
|
|
[
|
|
SNew(SBox)
|
|
.Padding(InArgs._BasePadding.Get())
|
|
[
|
|
SNew(SOverlay)
|
|
+ SOverlay::Slot()
|
|
[
|
|
InArgs._ButtonEnable.Get() ?
|
|
(
|
|
SNew(SBox)
|
|
[
|
|
SNew(SButton)
|
|
.ButtonStyle(FLGUIEditorStyle::Get(), "AnchorButton")
|
|
.ButtonColorAndOpacity(FLinearColor(FColor(100, 100, 100)))
|
|
.OnClicked_Lambda([=]() {
|
|
InArgs._OnAnchorChange.ExecuteIfBound(InArgs._PersistentHAlign.Get(), InArgs._PersistentVAlign.Get());
|
|
return FReply::Handled();
|
|
})
|
|
.ContentPadding(FMargin(0.0f, 0.0f))
|
|
]
|
|
)
|
|
:
|
|
(
|
|
SNew(SBox)
|
|
)
|
|
]
|
|
+ SOverlay::Slot()
|
|
[
|
|
SNew(SVerticalBox)
|
|
+ SVerticalBox::Slot()
|
|
.AutoHeight()
|
|
[
|
|
SNew(SBox)
|
|
[
|
|
SNew(SOverlay)
|
|
//half size rect in the middle
|
|
+ SOverlay::Slot()
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(Size.X)
|
|
.HeightOverride(Size.Y)
|
|
.Padding(this, &SAnchorPreviewWidget::GetInnerRectMargin, Size, InArgs._PersistentHAlign.Get(), InArgs._PersistentVAlign.Get(), InArgs._ButtonEnable.Get())
|
|
.HAlign(EHorizontalAlignment::HAlign_Center)
|
|
.VAlign(EVerticalAlignment::VAlign_Center)
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(this, &SAnchorPreviewWidget::GetInnerRectWidth, float(Size.X), InArgs._PersistentHAlign.Get(), InArgs._ButtonEnable.Get())
|
|
.HeightOverride(this, &SAnchorPreviewWidget::GetInnerRectHeight, float(Size.Y), InArgs._PersistentVAlign.Get(), InArgs._ButtonEnable.Get())
|
|
[
|
|
SNew(SImage)
|
|
.Image(FLGUIEditorStyle::Get().GetBrush("LGUIEditor.WhiteFrame"))
|
|
.ColorAndOpacity(FLinearColor(FColor(122, 122, 122, 255)))
|
|
.Visibility(EVisibility::HitTestInvisible)
|
|
]
|
|
]
|
|
]
|
|
//horizontal direction
|
|
+ SOverlay::Slot()
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(Size.X)
|
|
.HeightOverride(Size.Y)
|
|
.HAlign(hAlign)
|
|
.VAlign(vAlign)
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(anchorLineHorizontalWidth)
|
|
.HeightOverride(anchorLineHorizontalHeight)
|
|
[
|
|
SNew(SImage)
|
|
.Image(anchorLineBrushHorizontal)
|
|
.ColorAndOpacity(FLinearColor(FColor(170, 77, 77, 255)))
|
|
.Visibility(EVisibility::HitTestInvisible)
|
|
]
|
|
]
|
|
]
|
|
//vertical direction
|
|
+ SOverlay::Slot()
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(Size.X)
|
|
.HeightOverride(Size.Y)
|
|
.HAlign(hAlign)
|
|
.VAlign(vAlign)
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(anchorLineVerticalWidth)
|
|
.HeightOverride(anchorLineVerticalHeight)
|
|
[
|
|
SNew(SImage)
|
|
.Image(anchorLineBrushVertical)
|
|
.ColorAndOpacity(FLinearColor(FColor(170, 77, 77, 255)))
|
|
.Visibility(EVisibility::HitTestInvisible)
|
|
]
|
|
]
|
|
]
|
|
//pivot point//@todo: why commet? because not the desired behaviour i want
|
|
//+ SOverlay::Slot()
|
|
//[
|
|
// SNew(SBox)
|
|
// .WidthOverride(Size.X)
|
|
// .HeightOverride(Size.Y)
|
|
// .Padding(this, &SAnchorPreviewWidget::GetInnerRectMargin, Size, InArgs._PersistentHAlign.Get(), InArgs._PersistentVAlign.Get(), InArgs._ButtonEnable.Get())
|
|
// .Visibility(this, &SAnchorPreviewWidget::GetPivotDotVisibility, InArgs._PersistentHAlign.Get(), InArgs._PersistentVAlign.Get(), InArgs._ButtonEnable.Get())
|
|
// [
|
|
// SNew(SBox)
|
|
// .WidthOverride(Size.X * 0.5f)
|
|
// .HeightOverride(Size.Y * 0.5f)
|
|
// [
|
|
// SNew(SBox)
|
|
// .HAlign(pivotDotHAlign)
|
|
// .VAlign(pivotDotVAlign)
|
|
// [
|
|
// SNew(SBox)
|
|
// .WidthOverride(pivotDotSize)
|
|
// .HeightOverride(pivotDotSize)
|
|
// [
|
|
// SNew(SImage)
|
|
// .Image(FLGUIEditorStyle::Get().GetBrush("LGUIEditor.AnchorData_Dot"))
|
|
// .ColorAndOpacity(FLinearColor(FColor(50, 255, 200, 128)))
|
|
// .Visibility(EVisibility::HitTestInvisible)
|
|
// ]
|
|
// ]
|
|
// ]
|
|
// ]
|
|
//]
|
|
//left top anchor point
|
|
+ SOverlay::Slot()
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(Size.X)
|
|
.HeightOverride(Size.Y)
|
|
.HAlign(anchorDotLeftTopHAlign)
|
|
.VAlign(anchorDotLeftTopVAlign)
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(anchorDotSize)
|
|
.HeightOverride(anchorDotSize)
|
|
[
|
|
SNew(SImage)
|
|
.Image(FLGUIEditorStyle::Get().GetBrush("LGUIEditor.AnchorData_Dot"))
|
|
.ColorAndOpacity(FLinearColor(FColor(201, 146, 7, 255)))
|
|
.Visibility(EVisibility::HitTestInvisible)
|
|
]
|
|
]
|
|
]
|
|
//right top anchor point
|
|
+ SOverlay::Slot()
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(Size.X)
|
|
.HeightOverride(Size.Y)
|
|
.HAlign(anchorDotRightTopHAlign)
|
|
.VAlign(anchorDotRightTopVAlign)
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(anchorDotSize)
|
|
.HeightOverride(anchorDotSize)
|
|
[
|
|
SNew(SImage)
|
|
.Image(FLGUIEditorStyle::Get().GetBrush("LGUIEditor.AnchorData_Dot"))
|
|
.ColorAndOpacity(FLinearColor(FColor(201, 146, 7, 255)))
|
|
.Visibility(EVisibility::HitTestInvisible)
|
|
]
|
|
]
|
|
]
|
|
//left bottom anchor point
|
|
+ SOverlay::Slot()
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(Size.X)
|
|
.HeightOverride(Size.Y)
|
|
.HAlign(anchorDotLeftBottomHAlign)
|
|
.VAlign(anchorDotLeftBottomVAlign)
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(anchorDotSize)
|
|
.HeightOverride(anchorDotSize)
|
|
[
|
|
SNew(SImage)
|
|
.Image(FLGUIEditorStyle::Get().GetBrush("LGUIEditor.AnchorData_Dot"))
|
|
.ColorAndOpacity(FLinearColor(FColor(201, 146, 7, 255)))
|
|
.Visibility(EVisibility::HitTestInvisible)
|
|
]
|
|
]
|
|
]
|
|
//right bottom anchor point
|
|
+ SOverlay::Slot()
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(Size.X)
|
|
.HeightOverride(Size.Y)
|
|
.HAlign(anchorDotRightBottomHAlign)
|
|
.VAlign(anchorDotRightBottomVAlign)
|
|
[
|
|
SNew(SBox)
|
|
.WidthOverride(anchorDotSize)
|
|
.HeightOverride(anchorDotSize)
|
|
[
|
|
SNew(SImage)
|
|
.Image(FLGUIEditorStyle::Get().GetBrush("LGUIEditor.AnchorData_Dot"))
|
|
.ColorAndOpacity(FLinearColor(FColor(201, 146, 7, 255)))
|
|
.Visibility(EVisibility::HitTestInvisible)
|
|
]
|
|
]
|
|
]
|
|
]
|
|
]
|
|
]
|
|
]
|
|
]
|
|
]
|
|
];
|
|
}
|
|
|
|
private:
|
|
|
|
EVisibility GetPivotDotVisibility(UIAnchorHorizontalAlign PivotHAlign, UIAnchorVerticalAlign PivotVAlign, bool IsInteractable)const
|
|
{
|
|
return (
|
|
IsInteractable && FSlateApplication::Get().GetModifierKeys().IsShiftDown()
|
|
&& PivotHAlign != UIAnchorHorizontalAlign::None && PivotVAlign != UIAnchorVerticalAlign::None
|
|
) ? EVisibility::HitTestInvisible : EVisibility::Hidden;
|
|
}
|
|
FOptionalSize GetInnerRectWidth(float Size, UIAnchorHorizontalAlign hAlign, bool IsInteractable) const
|
|
{
|
|
bool snapAnchor = FSlateApplication::Get().GetModifierKeys().IsAltDown();
|
|
if (snapAnchor && IsInteractable)
|
|
{
|
|
if (hAlign == UIAnchorHorizontalAlign::Stretch)
|
|
{
|
|
return Size * 0.9f;
|
|
}
|
|
}
|
|
return Size * 0.5f;
|
|
}
|
|
FOptionalSize GetInnerRectHeight(float Size, UIAnchorVerticalAlign vAlign, bool IsInteractable) const
|
|
{
|
|
bool snapAnchor = FSlateApplication::Get().GetModifierKeys().IsAltDown();
|
|
if (snapAnchor && IsInteractable)
|
|
{
|
|
if (vAlign == UIAnchorVerticalAlign::Stretch)
|
|
{
|
|
return Size * 0.9f;
|
|
}
|
|
}
|
|
return Size * 0.5f;
|
|
}
|
|
FMargin GetInnerRectMargin(FVector2D Size, UIAnchorHorizontalAlign hAlign, UIAnchorVerticalAlign vAlign, bool IsInteractable)const
|
|
{
|
|
FMargin result(0, 0, 0, 0);
|
|
bool snapAnchor = FSlateApplication::Get().GetModifierKeys().IsAltDown();
|
|
if (snapAnchor && IsInteractable)
|
|
{
|
|
switch (hAlign)
|
|
{
|
|
case UIAnchorHorizontalAlign::Left:
|
|
result.Right = Size.X * 0.25f;
|
|
break;
|
|
case UIAnchorHorizontalAlign::Right:
|
|
result.Left = Size.X * 0.25f;
|
|
break;
|
|
}
|
|
switch (vAlign)
|
|
{
|
|
case UIAnchorVerticalAlign::Top:
|
|
result.Bottom = Size.X * 0.25f;
|
|
break;
|
|
case UIAnchorVerticalAlign::Bottom:
|
|
result.Top = Size.X * 0.25f;
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
};
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE |