October3d55/M/LGUI/Source/LGUIEditor/Public/Widget/AnchorPreviewWidget.h

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