703 lines
20 KiB
C++
703 lines
20 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "Widgets/Input/SEditableText.h"
|
|
#include "Framework/Text/TextEditHelper.h"
|
|
#include "Framework/Text/PlainTextLayoutMarshaller.h"
|
|
#include "Widgets/Text/SlateEditableTextLayout.h"
|
|
#include "Types/ReflectionMetadata.h"
|
|
#include "Types/TrackedMetaData.h"
|
|
|
|
#if WITH_ACCESSIBILITY
|
|
#include "Widgets/Accessibility/SlateAccessibleWidgets.h"
|
|
#endif
|
|
|
|
SEditableText::SEditableText()
|
|
{
|
|
#if WITH_ACCESSIBILITY
|
|
AccessibleBehavior = EAccessibleBehavior::Auto;
|
|
bCanChildrenBeAccessible = false;
|
|
#endif
|
|
}
|
|
|
|
SEditableText::~SEditableText()
|
|
{
|
|
// Needed to avoid "deletion of pointer to incomplete type 'FSlateEditableTextLayout'; no destructor called" error when using TUniquePtr
|
|
}
|
|
|
|
void SEditableText::Construct( const FArguments& InArgs )
|
|
{
|
|
bIsReadOnly = InArgs._IsReadOnly;
|
|
bIsPassword = InArgs._IsPassword;
|
|
|
|
bIsCaretMovedWhenGainFocus = InArgs._IsCaretMovedWhenGainFocus;
|
|
bSelectAllTextWhenFocused = InArgs._SelectAllTextWhenFocused;
|
|
bRevertTextOnEscape = InArgs._RevertTextOnEscape;
|
|
bClearKeyboardFocusOnCommit = InArgs._ClearKeyboardFocusOnCommit;
|
|
bAllowContextMenu = InArgs._AllowContextMenu;
|
|
OnContextMenuOpening = InArgs._OnContextMenuOpening;
|
|
OnIsTypedCharValid = InArgs._OnIsTypedCharValid;
|
|
OnTextChangedCallback = InArgs._OnTextChanged;
|
|
OnTextCommittedCallback = InArgs._OnTextCommitted;
|
|
MinDesiredWidth = InArgs._MinDesiredWidth;
|
|
bSelectAllTextOnCommit = InArgs._SelectAllTextOnCommit;
|
|
bSelectWordOnMouseDoubleClick = InArgs._SelectWordOnMouseDoubleClick;
|
|
VirtualKeyboardType = InArgs._VirtualKeyboardType;
|
|
VirtualKeyboardOptions = InArgs._VirtualKeyboardOptions;
|
|
VirtualKeyboardTrigger = InArgs._VirtualKeyboardTrigger;
|
|
VirtualKeyboardDismissAction = InArgs._VirtualKeyboardDismissAction;
|
|
OnKeyCharHandler = InArgs._OnKeyCharHandler;
|
|
OnKeyDownHandler = InArgs._OnKeyDownHandler;
|
|
bEnableIntegratedKeyboard = InArgs._EnableIntegratedKeyboard;
|
|
|
|
Font = InArgs._Font;
|
|
ColorAndOpacity = InArgs._ColorAndOpacity;
|
|
BackgroundImageSelected = InArgs._BackgroundImageSelected;
|
|
|
|
// We use the given style when creating the text layout as it may not be safe to call the override delegates until we've finished being constructed
|
|
// The first call to SynchronizeTextStyle will apply the correct overrides, and that will happen before the first paint
|
|
check(InArgs._Style);
|
|
FTextBlockStyle TextStyle = FCoreStyle::Get().GetWidgetStyle<FTextBlockStyle>("NormalText");
|
|
TextStyle.Font = InArgs._Style->Font;
|
|
TextStyle.ColorAndOpacity = InArgs._Style->ColorAndOpacity;
|
|
TextStyle.HighlightShape = InArgs._Style->BackgroundImageSelected;
|
|
|
|
PlainTextMarshaller = FPlainTextLayoutMarshaller::Create();
|
|
PlainTextMarshaller->SetIsPassword(bIsPassword);
|
|
|
|
// We use a separate marshaller for the hint text, as that should never be displayed as a password
|
|
TSharedRef<FPlainTextLayoutMarshaller> HintTextMarshaller = FPlainTextLayoutMarshaller::Create();
|
|
|
|
EditableTextLayout = MakeUnique<FSlateEditableTextLayout>(*this, InArgs._Text, TextStyle, InArgs._TextShapingMethod, InArgs._TextFlowDirection, FCreateSlateTextLayout(), PlainTextMarshaller.ToSharedRef(), HintTextMarshaller);
|
|
EditableTextLayout->SetHintText(InArgs._HintText);
|
|
EditableTextLayout->SetSearchText(InArgs._SearchText);
|
|
EditableTextLayout->SetCursorBrush(InArgs._CaretImage.IsSet() ? InArgs._CaretImage : &InArgs._Style->CaretImage);
|
|
EditableTextLayout->SetCompositionBrush(InArgs._BackgroundImageComposing.IsSet() ? InArgs._BackgroundImageComposing : &InArgs._Style->BackgroundImageComposing);
|
|
EditableTextLayout->SetDebugSourceInfo(TAttribute<FString>::Create(TAttribute<FString>::FGetter::CreateLambda([this]{ return FReflectionMetaData::GetWidgetDebugInfo(this); })));
|
|
EditableTextLayout->SetJustification(InArgs._Justification);
|
|
EditableTextLayout->SetOverflowPolicy(InArgs._OverflowPolicy);
|
|
|
|
// build context menu extender
|
|
MenuExtender = MakeShareable(new FExtender());
|
|
MenuExtender->AddMenuExtension("EditText", EExtensionHook::Before, TSharedPtr<FUICommandList>(), InArgs._ContextMenuExtender);
|
|
|
|
AddMetadata(MakeShared<FTrackedMetaData>(this, FName(TEXT("EditableText"))));
|
|
}
|
|
|
|
void SEditableText::SetText( const TAttribute< FText >& InNewText )
|
|
{
|
|
EditableTextLayout->SetText(InNewText);
|
|
}
|
|
|
|
FText SEditableText::GetText() const
|
|
{
|
|
return EditableTextLayout->GetText();
|
|
}
|
|
|
|
bool SEditableText::SetEditableText(const FText& InNewText)
|
|
{
|
|
return EditableTextLayout->SetEditableText(InNewText);
|
|
}
|
|
|
|
void SEditableText::SetFont( const TAttribute< FSlateFontInfo >& InNewFont )
|
|
{
|
|
Font = InNewFont;
|
|
|
|
Invalidate(EInvalidateWidgetReason::Layout);
|
|
}
|
|
|
|
FSlateFontInfo SEditableText::GetFont() const
|
|
{
|
|
return Font.Get();
|
|
}
|
|
|
|
void SEditableText::SetTextStyle( const FEditableTextStyle& InNewTextStyle )
|
|
{
|
|
Font = InNewTextStyle.Font;
|
|
ColorAndOpacity = InNewTextStyle.ColorAndOpacity;
|
|
BackgroundImageSelected = &InNewTextStyle.BackgroundImageSelected;
|
|
|
|
Invalidate(EInvalidateWidgetReason::Layout);
|
|
}
|
|
|
|
void SEditableText::SetTextBlockStyle(const FTextBlockStyle* InTextStyle)
|
|
{
|
|
if (InTextStyle)
|
|
{
|
|
EditableTextLayout->SetTextStyle(*InTextStyle);
|
|
Invalidate(EInvalidateWidgetReason::Layout); //Using Layout as changing text block size can affect the size.
|
|
}
|
|
}
|
|
|
|
void SEditableText::Tick( const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime )
|
|
{
|
|
EditableTextLayout->Tick(AllottedGeometry, InCurrentTime, InDeltaTime);
|
|
}
|
|
|
|
int32 SEditableText::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const
|
|
{
|
|
const FTextBlockStyle& EditableTextStyle = EditableTextLayout->GetTextStyle();
|
|
const FLinearColor ForegroundColor = EditableTextStyle.ColorAndOpacity.GetColor(InWidgetStyle);
|
|
|
|
FWidgetStyle TextWidgetStyle = FWidgetStyle(InWidgetStyle)
|
|
.SetForegroundColor(ForegroundColor);
|
|
|
|
LayerId = EditableTextLayout->OnPaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, TextWidgetStyle, ShouldBeEnabled(bParentEnabled));
|
|
|
|
return LayerId;
|
|
}
|
|
|
|
void SEditableText::CacheDesiredSize(float LayoutScaleMultiplier)
|
|
{
|
|
SynchronizeTextStyle();
|
|
EditableTextLayout->CacheDesiredSize(LayoutScaleMultiplier);
|
|
SWidget::CacheDesiredSize(LayoutScaleMultiplier);
|
|
}
|
|
|
|
FVector2D SEditableText::ComputeDesiredSize(float LayoutScaleMultiplier) const
|
|
{
|
|
FVector2D TextLayoutSize = EditableTextLayout->ComputeDesiredSize(LayoutScaleMultiplier);
|
|
TextLayoutSize.X = FMath::Max(TextLayoutSize.X, MinDesiredWidth.Get());
|
|
return TextLayoutSize;
|
|
}
|
|
|
|
FChildren* SEditableText::GetChildren()
|
|
{
|
|
return EditableTextLayout->GetChildren();
|
|
}
|
|
|
|
void SEditableText::OnArrangeChildren(const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren) const
|
|
{
|
|
EditableTextLayout->OnArrangeChildren(AllottedGeometry, ArrangedChildren);
|
|
}
|
|
|
|
FReply SEditableText::OnDragOver( const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent )
|
|
{
|
|
TSharedPtr<FExternalDragOperation> DragDropOp = DragDropEvent.GetOperationAs<FExternalDragOperation>();
|
|
if ( DragDropOp.IsValid() )
|
|
{
|
|
if ( DragDropOp->HasText() )
|
|
{
|
|
return FReply::Handled();
|
|
}
|
|
}
|
|
|
|
return FReply::Unhandled();
|
|
}
|
|
|
|
FReply SEditableText::OnDrop( const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent )
|
|
{
|
|
TSharedPtr<FExternalDragOperation> DragDropOp = DragDropEvent.GetOperationAs<FExternalDragOperation>();
|
|
if ( DragDropOp.IsValid() )
|
|
{
|
|
if ( DragDropOp->HasText() )
|
|
{
|
|
EditableTextLayout->SetText(FText::FromString(DragDropOp->GetText()));
|
|
return FReply::Handled();
|
|
}
|
|
}
|
|
|
|
return FReply::Unhandled();
|
|
}
|
|
|
|
bool SEditableText::SupportsKeyboardFocus() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
FReply SEditableText::OnFocusReceived( const FGeometry& MyGeometry, const FFocusEvent& InFocusEvent )
|
|
{
|
|
EditableTextLayout->HandleFocusReceived(InFocusEvent);
|
|
return FReply::Handled();
|
|
}
|
|
|
|
void SEditableText::OnFocusLost( const FFocusEvent& InFocusEvent )
|
|
{
|
|
EditableTextLayout->HandleFocusLost(InFocusEvent);
|
|
}
|
|
|
|
FReply SEditableText::OnKeyChar( const FGeometry& MyGeometry, const FCharacterEvent& InCharacterEvent )
|
|
{
|
|
FReply Reply = FReply::Unhandled();
|
|
|
|
// First call the user defined key handler, there might be overrides to normal functionality
|
|
if (OnKeyCharHandler.IsBound())
|
|
{
|
|
Reply = OnKeyCharHandler.Execute(MyGeometry, InCharacterEvent);
|
|
}
|
|
|
|
if (!Reply.IsEventHandled())
|
|
{
|
|
Reply = EditableTextLayout->HandleKeyChar(InCharacterEvent);
|
|
}
|
|
|
|
return Reply;
|
|
}
|
|
|
|
FReply SEditableText::OnKeyDown( const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent )
|
|
{
|
|
FReply Reply = FReply::Unhandled();
|
|
|
|
// First call the user defined key handler, there might be overrides to normal functionality
|
|
if (OnKeyDownHandler.IsBound())
|
|
{
|
|
Reply = OnKeyDownHandler.Execute(MyGeometry, InKeyEvent);
|
|
}
|
|
|
|
if (!Reply.IsEventHandled())
|
|
{
|
|
Reply = EditableTextLayout->HandleKeyDown(InKeyEvent);
|
|
|
|
if (!Reply.IsEventHandled())
|
|
{
|
|
Reply = SWidget::OnKeyDown(MyGeometry, InKeyEvent);
|
|
}
|
|
}
|
|
|
|
return Reply;
|
|
}
|
|
|
|
FReply SEditableText::OnKeyUp( const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent )
|
|
{
|
|
return EditableTextLayout->HandleKeyUp(InKeyEvent);
|
|
}
|
|
|
|
FReply SEditableText::OnMouseButtonDown( const FGeometry& InMyGeometry, const FPointerEvent& InMouseEvent )
|
|
{
|
|
return EditableTextLayout->HandleMouseButtonDown(InMyGeometry, InMouseEvent);
|
|
}
|
|
|
|
FReply SEditableText::OnMouseButtonUp( const FGeometry& InMyGeometry, const FPointerEvent& InMouseEvent )
|
|
{
|
|
return EditableTextLayout->HandleMouseButtonUp(InMyGeometry, InMouseEvent);
|
|
}
|
|
|
|
FReply SEditableText::OnMouseMove( const FGeometry& InMyGeometry, const FPointerEvent& InMouseEvent )
|
|
{
|
|
return EditableTextLayout->HandleMouseMove(InMyGeometry, InMouseEvent);
|
|
}
|
|
|
|
FReply SEditableText::OnMouseButtonDoubleClick( const FGeometry& InMyGeometry, const FPointerEvent& InMouseEvent )
|
|
{
|
|
return EditableTextLayout->HandleMouseButtonDoubleClick(InMyGeometry, InMouseEvent);
|
|
}
|
|
|
|
FCursorReply SEditableText::OnCursorQuery( const FGeometry& MyGeometry, const FPointerEvent& CursorEvent ) const
|
|
{
|
|
return FCursorReply::Cursor( EMouseCursor::TextEditBeam );
|
|
}
|
|
|
|
const FSlateBrush* SEditableText::GetFocusBrush() const
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
bool SEditableText::IsInteractable() const
|
|
{
|
|
return IsEnabled();
|
|
}
|
|
|
|
bool SEditableText::ComputeVolatility() const
|
|
{
|
|
return SWidget::ComputeVolatility()
|
|
|| HasKeyboardFocus()
|
|
|| EditableTextLayout->ComputeVolatility()
|
|
|| Font.IsBound()
|
|
|| ColorAndOpacity.IsBound()
|
|
|| BackgroundImageSelected.IsBound()
|
|
|| bIsReadOnly.IsBound()
|
|
|| bIsPassword.IsBound()
|
|
|| MinDesiredWidth.IsBound();
|
|
}
|
|
|
|
void SEditableText::SetHintText( const TAttribute< FText >& InHintText )
|
|
{
|
|
EditableTextLayout->SetHintText(InHintText);
|
|
}
|
|
|
|
FText SEditableText::GetHintText() const
|
|
{
|
|
return EditableTextLayout->GetHintText();
|
|
}
|
|
|
|
void SEditableText::SetSearchText(const TAttribute<FText>& InSearchText)
|
|
{
|
|
EditableTextLayout->SetSearchText(InSearchText);
|
|
}
|
|
|
|
FText SEditableText::GetSearchText() const
|
|
{
|
|
return EditableTextLayout->GetSearchText();
|
|
}
|
|
|
|
void SEditableText::SetIsReadOnly( TAttribute< bool > InIsReadOnly )
|
|
{
|
|
bIsReadOnly = InIsReadOnly;
|
|
}
|
|
|
|
void SEditableText::SetIsPassword( TAttribute< bool > InIsPassword )
|
|
{
|
|
bIsPassword = InIsPassword;
|
|
PlainTextMarshaller->SetIsPassword(bIsPassword);
|
|
}
|
|
|
|
void SEditableText::SetColorAndOpacity(TAttribute<FSlateColor> Color)
|
|
{
|
|
ColorAndOpacity = Color;
|
|
}
|
|
|
|
void SEditableText::SetMinDesiredWidth(const TAttribute<float>& InMinDesiredWidth)
|
|
{
|
|
MinDesiredWidth = InMinDesiredWidth;
|
|
}
|
|
|
|
void SEditableText::SetIsCaretMovedWhenGainFocus(const TAttribute<bool>& InIsCaretMovedWhenGainFocus)
|
|
{
|
|
bIsCaretMovedWhenGainFocus = InIsCaretMovedWhenGainFocus;
|
|
}
|
|
|
|
void SEditableText::SetSelectAllTextWhenFocused(const TAttribute<bool>& InSelectAllTextWhenFocused)
|
|
{
|
|
bSelectAllTextWhenFocused = InSelectAllTextWhenFocused;
|
|
}
|
|
|
|
void SEditableText::SetRevertTextOnEscape(const TAttribute<bool>& InRevertTextOnEscape)
|
|
{
|
|
bRevertTextOnEscape = InRevertTextOnEscape;
|
|
}
|
|
|
|
void SEditableText::SetClearKeyboardFocusOnCommit(const TAttribute<bool>& InClearKeyboardFocusOnCommit)
|
|
{
|
|
bClearKeyboardFocusOnCommit = InClearKeyboardFocusOnCommit;
|
|
}
|
|
|
|
void SEditableText::SetSelectAllTextOnCommit(const TAttribute<bool>& InSelectAllTextOnCommit)
|
|
{
|
|
bSelectAllTextOnCommit = InSelectAllTextOnCommit;
|
|
}
|
|
|
|
void SEditableText::SetSelectWordOnMouseDoubleClick(const TAttribute<bool>& InSelectWordOnMouseDoubleClick)
|
|
{
|
|
bSelectWordOnMouseDoubleClick = InSelectWordOnMouseDoubleClick;
|
|
}
|
|
|
|
void SEditableText::SetJustification(const TAttribute<ETextJustify::Type>& InJustification)
|
|
{
|
|
EditableTextLayout->SetJustification(InJustification);
|
|
}
|
|
|
|
void SEditableText::SetAllowContextMenu(const TAttribute< bool >& InAllowContextMenu)
|
|
{
|
|
bAllowContextMenu = InAllowContextMenu;
|
|
}
|
|
|
|
void SEditableText::SetEnableIntegratedKeyboard(const TAttribute<bool>& InEnableIntegratedKeyboard)
|
|
{
|
|
bEnableIntegratedKeyboard = InEnableIntegratedKeyboard;
|
|
}
|
|
|
|
void SEditableText::SetVirtualKeyboardDismissAction(TAttribute< EVirtualKeyboardDismissAction > InVirtualKeyboardDismissAction)
|
|
{
|
|
VirtualKeyboardDismissAction = InVirtualKeyboardDismissAction;
|
|
}
|
|
|
|
void SEditableText::SetTextShapingMethod(const TOptional<ETextShapingMethod>& InTextShapingMethod)
|
|
{
|
|
EditableTextLayout->SetTextShapingMethod(InTextShapingMethod);
|
|
}
|
|
|
|
void SEditableText::SetTextFlowDirection(const TOptional<ETextFlowDirection>& InTextFlowDirection)
|
|
{
|
|
EditableTextLayout->SetTextFlowDirection(InTextFlowDirection);
|
|
}
|
|
|
|
void SEditableText::SetOverflowPolicy(TOptional<ETextOverflowPolicy> InOverflowPolicy)
|
|
{
|
|
EditableTextLayout->SetOverflowPolicy(InOverflowPolicy);
|
|
}
|
|
|
|
bool SEditableText::AnyTextSelected() const
|
|
{
|
|
return EditableTextLayout->AnyTextSelected();
|
|
}
|
|
|
|
void SEditableText::SelectAllText()
|
|
{
|
|
EditableTextLayout->SelectAllText();
|
|
}
|
|
|
|
void SEditableText::ClearSelection()
|
|
{
|
|
EditableTextLayout->ClearSelection();
|
|
}
|
|
|
|
FText SEditableText::GetSelectedText() const
|
|
{
|
|
return EditableTextLayout->GetSelectedText();
|
|
}
|
|
|
|
void SEditableText::GoTo(const FTextLocation& NewLocation)
|
|
{
|
|
EditableTextLayout->GoTo(NewLocation);
|
|
}
|
|
|
|
void SEditableText::GoTo(const ETextLocation NewLocation)
|
|
{
|
|
EditableTextLayout->GoTo(NewLocation);
|
|
}
|
|
|
|
void SEditableText::ScrollTo(const FTextLocation& NewLocation)
|
|
{
|
|
EditableTextLayout->ScrollTo(NewLocation);
|
|
}
|
|
|
|
void SEditableText::ScrollTo(const ETextLocation NewLocation)
|
|
{
|
|
EditableTextLayout->ScrollTo(NewLocation);
|
|
}
|
|
|
|
void SEditableText::BeginSearch(const FText& InSearchText, const ESearchCase::Type InSearchCase, const bool InReverse)
|
|
{
|
|
EditableTextLayout->BeginSearch(InSearchText, InSearchCase, InReverse);
|
|
}
|
|
|
|
void SEditableText::AdvanceSearch(const bool InReverse)
|
|
{
|
|
EditableTextLayout->AdvanceSearch(InReverse);
|
|
}
|
|
|
|
void SEditableText::EnableTextInputMethodContext()
|
|
{
|
|
EditableTextLayout->EnableTextInputMethodContext();
|
|
}
|
|
|
|
FTextSelection SEditableText::GetSelection() const
|
|
{
|
|
return EditableTextLayout->GetSelection();
|
|
}
|
|
|
|
void SEditableText::SelectText(const FTextLocation& InSelectionStart, const FTextLocation& InCursorLocation)
|
|
{
|
|
EditableTextLayout->SelectText(InSelectionStart, InCursorLocation);
|
|
}
|
|
|
|
void SEditableText::SynchronizeTextStyle()
|
|
{
|
|
// Has the style used for this editable text changed?
|
|
bool bTextStyleChanged = false;
|
|
FTextBlockStyle NewTextStyle = EditableTextLayout->GetTextStyle();
|
|
|
|
// Sync from the font override
|
|
if (Font.IsSet())
|
|
{
|
|
const FSlateFontInfo& NewFontInfo = Font.Get();
|
|
if (!NewTextStyle.Font.IsIdenticalTo(NewFontInfo))
|
|
{
|
|
NewTextStyle.Font = NewFontInfo;
|
|
bTextStyleChanged = true;
|
|
}
|
|
}
|
|
|
|
// Sync from the color override
|
|
if (ColorAndOpacity.IsSet())
|
|
{
|
|
const FSlateColor& NewColorAndOpacity = ColorAndOpacity.Get();
|
|
if (NewTextStyle.ColorAndOpacity != NewColorAndOpacity)
|
|
{
|
|
NewTextStyle.ColorAndOpacity = NewColorAndOpacity;
|
|
bTextStyleChanged = true;
|
|
}
|
|
}
|
|
|
|
// Sync from the highlight shape override
|
|
if (BackgroundImageSelected.IsSet())
|
|
{
|
|
const FSlateBrush* NewSelectionBrush = BackgroundImageSelected.Get();
|
|
if (NewSelectionBrush && NewTextStyle.HighlightShape != *NewSelectionBrush)
|
|
{
|
|
NewTextStyle.HighlightShape = *NewSelectionBrush;
|
|
bTextStyleChanged = true;
|
|
}
|
|
}
|
|
|
|
if (bTextStyleChanged)
|
|
{
|
|
EditableTextLayout->SetTextStyle(NewTextStyle);
|
|
EditableTextLayout->ForceRefreshTextLayout(EditableTextLayout->GetEditableText());
|
|
}
|
|
}
|
|
|
|
bool SEditableText::IsTextReadOnly() const
|
|
{
|
|
return bIsReadOnly.Get(false);
|
|
}
|
|
|
|
bool SEditableText::IsTextPassword() const
|
|
{
|
|
return bIsPassword.Get(false);
|
|
}
|
|
|
|
bool SEditableText::IsMultiLineTextEdit() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool SEditableText::IsIntegratedKeyboardEnabled() const
|
|
{
|
|
return bEnableIntegratedKeyboard.Get(false);
|
|
}
|
|
|
|
bool SEditableText::ShouldJumpCursorToEndWhenFocused() const
|
|
{
|
|
return bIsCaretMovedWhenGainFocus.Get(false);
|
|
}
|
|
|
|
bool SEditableText::ShouldSelectAllTextWhenFocused() const
|
|
{
|
|
return bSelectAllTextWhenFocused.Get(false);
|
|
}
|
|
|
|
bool SEditableText::ShouldClearTextSelectionOnFocusLoss() const
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool SEditableText::ShouldRevertTextOnEscape() const
|
|
{
|
|
return bRevertTextOnEscape.Get(false);
|
|
}
|
|
|
|
bool SEditableText::ShouldClearKeyboardFocusOnCommit() const
|
|
{
|
|
return bClearKeyboardFocusOnCommit.Get(false);
|
|
}
|
|
|
|
bool SEditableText::ShouldSelectAllTextOnCommit() const
|
|
{
|
|
return bSelectAllTextOnCommit.Get(false);
|
|
}
|
|
|
|
bool SEditableText::ShouldSelectWordOnMouseDoubleClick() const
|
|
{
|
|
return bSelectWordOnMouseDoubleClick.Get(true);
|
|
}
|
|
|
|
bool SEditableText::CanInsertCarriageReturn() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool SEditableText::CanTypeCharacter(const TCHAR InChar) const
|
|
{
|
|
if (OnIsTypedCharValid.IsBound())
|
|
{
|
|
return OnIsTypedCharValid.Execute(InChar);
|
|
}
|
|
|
|
return InChar != TEXT('\t');
|
|
}
|
|
|
|
void SEditableText::EnsureActiveTick()
|
|
{
|
|
TSharedPtr<FActiveTimerHandle> ActiveTickTimerPin = ActiveTickTimer.Pin();
|
|
if (ActiveTickTimerPin.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
auto DoActiveTick = [this](double InCurrentTime, float InDeltaTime) -> EActiveTimerReturnType
|
|
{
|
|
// Continue if we still have focus, otherwise treat as a fire-and-forget Tick() request
|
|
const bool bShouldAppearFocused = HasKeyboardFocus() || EditableTextLayout->HasActiveContextMenu();
|
|
return (bShouldAppearFocused) ? EActiveTimerReturnType::Continue : EActiveTimerReturnType::Stop;
|
|
};
|
|
|
|
const float TickPeriod = EditableTextDefs::BlinksPerSecond * 0.5f;
|
|
ActiveTickTimer = RegisterActiveTimer(TickPeriod, FWidgetActiveTimerDelegate::CreateLambda(DoActiveTick));
|
|
}
|
|
|
|
EKeyboardType SEditableText::GetVirtualKeyboardType() const
|
|
{
|
|
return VirtualKeyboardType.Get();
|
|
}
|
|
|
|
FVirtualKeyboardOptions SEditableText::GetVirtualKeyboardOptions() const
|
|
{
|
|
return VirtualKeyboardOptions;
|
|
}
|
|
|
|
EVirtualKeyboardTrigger SEditableText::GetVirtualKeyboardTrigger() const
|
|
{
|
|
return VirtualKeyboardTrigger.Get();
|
|
}
|
|
|
|
EVirtualKeyboardDismissAction SEditableText::GetVirtualKeyboardDismissAction() const
|
|
{
|
|
return VirtualKeyboardDismissAction.Get();
|
|
}
|
|
|
|
TSharedRef<SWidget> SEditableText::GetSlateWidget()
|
|
{
|
|
return AsShared();
|
|
}
|
|
|
|
TSharedPtr<SWidget> SEditableText::GetSlateWidgetPtr()
|
|
{
|
|
if (DoesSharedInstanceExist())
|
|
{
|
|
return AsShared();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
TSharedPtr<SWidget> SEditableText::BuildContextMenuContent() const
|
|
{
|
|
if (!bAllowContextMenu.Get())
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
if (OnContextMenuOpening.IsBound())
|
|
{
|
|
return OnContextMenuOpening.Execute();
|
|
}
|
|
|
|
return EditableTextLayout->BuildDefaultContextMenu(MenuExtender);
|
|
}
|
|
|
|
void SEditableText::OnTextChanged(const FText& InText)
|
|
{
|
|
OnTextChangedCallback.ExecuteIfBound(InText);
|
|
}
|
|
|
|
void SEditableText::OnTextCommitted(const FText& InText, const ETextCommit::Type InTextAction)
|
|
{
|
|
OnTextCommittedCallback.ExecuteIfBound(InText, InTextAction);
|
|
}
|
|
|
|
void SEditableText::OnCursorMoved(const FTextLocation& InLocation)
|
|
{
|
|
Invalidate(EInvalidateWidgetReason::Layout);
|
|
}
|
|
|
|
float SEditableText::UpdateAndClampHorizontalScrollBar(const float InViewOffset, const float InViewFraction, const EVisibility InVisiblityOverride)
|
|
{
|
|
return EditableTextLayout->GetScrollOffset().X;
|
|
}
|
|
|
|
float SEditableText::UpdateAndClampVerticalScrollBar(const float InViewOffset, const float InViewFraction, const EVisibility InVisiblityOverride)
|
|
{
|
|
return 0.0f;
|
|
}
|
|
|
|
#if WITH_ACCESSIBILITY
|
|
TSharedRef<FSlateAccessibleWidget> SEditableText::CreateAccessibleWidget()
|
|
{
|
|
return MakeShareable<FSlateAccessibleWidget>(new FSlateAccessibleEditableText(SharedThis(this)));
|
|
}
|
|
|
|
TOptional<FText> SEditableText::GetDefaultAccessibleText(EAccessibleType AccessibleType) const
|
|
{
|
|
return GetHintText();
|
|
}
|
|
#endif
|