UMG Spin Box 和 Text Box 限定输入为 Int

UE4 Limit Input Integer

在项目中需要用户输入一个整数,有两种方案来处理这种情况:

一. Widget Spin Box Limit Input Integer

利用 spin box 可以很好的限定用户输入的为数字,但是 UE4 自带的 spin box 默认的 Value 为 float :

public:
     /** Value stored in this spin box */
     UPROPERTY(EditAnywhere, Category=Content)
     float Value;

虽然可以很容易通过 truncate 或者 round 解决限定用户输入为整形,但是默认显示为浮点类型,但是可以通过继承 spin box 来生成自己的 int spin box 来解决这个问题。

MyIntegerSpinBox.h 文件:

//MyIntegerSpinBox.h

#include "Runtime/UMG/Public/UMG.h"
#include "Runtime/UMG/Public/Components/SpinBox.h"

#include "MyIntegerSpinBox.generated.h"

UCLASS(Blueprintable, BlueprintType)
class MYGAME_API UMyIntegerSpinBox : public USpinBox
{
 GENERATED_BODY()

protected:

     //within the spin box this is an optional value since we don't need it to restore
     //non-numeric input; if you choose you can just use the native float Value
     //and convert it to int when required
     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input Data")
     int32 IntegerValue;

     //this is an entirely optional value that your designers can use to
     //create alternative displays of the current, validated IntegerValue
     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input Data")
     FText DisplayValue;

public:

     UMyIntegerSpinBox();

     //~ Begin UWidget Interface
     virtual TSharedRef<SWidget> RebuildWidget() override;
     // End of UWidget

     UFUNCTION(BlueprintCallable, Category = "User Input")
     void MyHandleOnValueChanged(float InValue);

     UFUNCTION(BlueprintCallable, Category = "User Input")
     bool ValidateIntegerValue(float& InValue);

     UFUNCTION(BlueprintCallable, Category = "User Input")
     int32 GetIntFromFloat(const float& FloatValue);

     UFUNCTION(BlueprintCallable, Category = "User Input")
     void UpdateDisplayValue();

};

MyIntegerSpinBox.cpp 文件:

//MyIntegerSpinBox.cpp

#include "MyGame.h"

#include "MyIntegerSpinBox.h"

UMyIntegerSpinBox::UMyIntegerSpinBox():
    USpinBox(),
    IntegerValue(GetIntFromFloat(Value)),
    DisplayValue(FText::AsNumber(IntegerValue))
    {}

TSharedRef<SWidget> UMyIntegerSpinBox::RebuildWidget()
{
     MySpinBox = SNew(SSpinBox<float>)
         .Style(&WidgetStyle)
         .Font(Font)
         .ClearKeyboardFocusOnCommit(ClearKeyboardFocusOnCommit)
         .SelectAllTextOnCommit(SelectAllTextOnCommit)
         .OnValueChanged(BIND_UOBJECT_DELEGATE(FOnFloatValueChanged, MyHandleOnValueChanged))
         .OnValueCommitted(BIND_UOBJECT_DELEGATE(FOnFloatValueCommitted, HandleOnValueCommitted))
         .OnBeginSliderMovement(BIND_UOBJECT_DELEGATE(FSimpleDelegate, HandleOnBeginSliderMovement))
         .OnEndSliderMovement(BIND_UOBJECT_DELEGATE(FOnFloatValueChanged, HandleOnEndSliderMovement))
         ;
     return BuildDesignTimeWidget(MySpinBox.ToSharedRef());

}

void UMyIntegerSpinBox::MyHandleOnValueChanged(float InValue) {
     if (ValidateIntegerValue(InValue)) {
         HandleOnValueChanged(InValue);
     }
}

bool UMyIntegerSpinBox::ValidateIntegerValue(float& InValue) {
     //checking to make sure the value is different prevents an infinite loop via SetValue
     if (Value != InValue) {
         //round up or down, depending on where we're going
         InValue = Value < InValue ? FMath::CeilToFloat(InValue) : FMath::FloorToFloat(InValue);

         //then we have to set the value back to the spinner
         SetValue(InValue);

         //we can store the integer value if desired
         IntegerValue = GetIntFromFloat(InValue);
         //you can use CeilToFlot or Floor if you prefer
         //IntegerValue = FMath::CeilToFloat(InValue);
         //IntegerValue = FMath::Floor(InValue);

         //finally, update the optional FText display value
         UpdateDisplayValue();
         return true;

     }
     return false;

}

int32 UMyIntegerSpinBox::GetIntFromFloat(const float& FloatValue) {
     if (FloatValue >= 0.0f) {
         return (int)(FloatValue + 0.5f);

     }
     return (int)(FloatValue - 0.5f);

}

void UMyIntegerSpinBox::UpdateDisplayValue() {
     DisplayValue = FText::AsNumber(IntegerValue);

}

注意: 需要在 ProjectName.Build.cs 添加 Module 依赖项(通过手动添加或者是去除注释)如下图所示:


图一:项目设置

另一种解决方案就是复制源码,将数据存储类型换成 int 类型即可。

二. Widget Text Box Limit Input Integer

利用 Text Box 用户输入的随意性更大,需要更多限制,经过尝试,Text Box很好的解决了限定用户输入为整数问题。

图二:TextBox在用户动态输入文本时限定输入为整数

这里写图片描述图三:Set Display Amount 函数

[Reference]

1. https://github.com/BasicCoder/Intership_UE4

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值