mirror of
https://github.com/sinbad/StevesUEHelpers.git
synced 2025-02-23 17:45:23 +00:00
Dynamic changing of input image embedded in Rich Text now working
This commit is contained in:
parent
016e3977cf
commit
d33ed25bad
@ -9,8 +9,8 @@
|
|||||||
#include "Widgets/Images/SImage.h"
|
#include "Widgets/Images/SImage.h"
|
||||||
|
|
||||||
|
|
||||||
// Slat SNew only supports 5 custom arguments so we need to batch things up
|
// Slate SNew only supports 5 custom arguments so we need to batch things up
|
||||||
struct FInputImageParams
|
struct FRichTextInputImageParams
|
||||||
{
|
{
|
||||||
/// What type of an input binding this image should look up
|
/// What type of an input binding this image should look up
|
||||||
EInputBindingType BindingType;
|
EInputBindingType BindingType;
|
||||||
@ -41,6 +41,7 @@ protected:
|
|||||||
URichTextBlockInputImageDecorator* Decorator = nullptr;
|
URichTextBlockInputImageDecorator* Decorator = nullptr;
|
||||||
|
|
||||||
FSlateBrush Brush;
|
FSlateBrush Brush;
|
||||||
|
float TimeUntilNextSpriteCheck = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SLATE_BEGIN_ARGS(SRichInlineInputImage)
|
SLATE_BEGIN_ARGS(SRichInlineInputImage)
|
||||||
@ -49,7 +50,7 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void Construct(const FArguments& InArgs, FInputImageParams InParams,
|
void Construct(const FArguments& InArgs, FRichTextInputImageParams InParams,
|
||||||
const FTextBlockStyle& TextStyle, TOptional<int32> Width, TOptional<int32> Height, EStretch::Type Stretch)
|
const FTextBlockStyle& TextStyle, TOptional<int32> Width, TOptional<int32> Height, EStretch::Type Stretch)
|
||||||
{
|
{
|
||||||
BindingType = InParams.BindingType;
|
BindingType = InParams.BindingType;
|
||||||
@ -60,12 +61,13 @@ public:
|
|||||||
|
|
||||||
// Sadly, we cannot hook into the events needed to update based on input changes here
|
// Sadly, we cannot hook into the events needed to update based on input changes here
|
||||||
// All attempts to use GetStevesGameSubsystem() fail because the world pointer
|
// All attempts to use GetStevesGameSubsystem() fail because the world pointer
|
||||||
// doesn't work, I think perhaps because this Slate Construct call is in another thread.
|
// doesn't work, I think perhaps because this Slate Construct call is in another thread which pre-dates it.
|
||||||
// We will need to do the work to update the brush from the main thread later
|
// We will need to do the work to update the brush from the main thread later
|
||||||
|
|
||||||
// We can use static methods though
|
// We can use static methods though
|
||||||
if (InParams.InitialSprite)
|
if (InParams.InitialSprite)
|
||||||
UStevesGameSubsystem::SetBrushFromAtlas(&Brush, InParams.InitialSprite, true);
|
UStevesGameSubsystem::SetBrushFromAtlas(&Brush, InParams.InitialSprite, true);
|
||||||
|
TimeUntilNextSpriteCheck = 0.25f;
|
||||||
|
|
||||||
const TSharedRef<FSlateFontMeasure> FontMeasure = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
|
const TSharedRef<FSlateFontMeasure> FontMeasure = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
|
||||||
float IconHeight = FMath::Min((float)FontMeasure->GetMaxCharacterHeight(TextStyle.Font, 1.0f), Brush.ImageSize.Y);
|
float IconHeight = FMath::Min((float)FontMeasure->GetMaxCharacterHeight(TextStyle.Font, 1.0f), Brush.ImageSize.Y);
|
||||||
@ -99,6 +101,30 @@ public:
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override
|
||||||
|
{
|
||||||
|
SCompoundWidget::Tick(AllottedGeometry, InCurrentTime, InDeltaTime);
|
||||||
|
|
||||||
|
// I would prefer to hook into the events here but there is NO safe teardown in these RichText decorators
|
||||||
|
// with which to unsub from events, so we're down to brute forcing this in Tick() le sigh
|
||||||
|
// At least limit the frequency and only change as needed
|
||||||
|
TimeUntilNextSpriteCheck -= InDeltaTime;
|
||||||
|
if (TimeUntilNextSpriteCheck <= 0)
|
||||||
|
{
|
||||||
|
auto GS = GetStevesGameSubsystem(Decorator->GetWorld());
|
||||||
|
if (GS)
|
||||||
|
{
|
||||||
|
// Can only support default theme, no way to edit theme in decorator config
|
||||||
|
auto Sprite = GS->GetInputImageSprite(BindingType, ActionOrAxisName, Key, PlayerIndex);
|
||||||
|
if (Sprite && Brush.GetResourceObject() != Sprite)
|
||||||
|
UStevesGameSubsystem::SetBrushFromAtlas(&Brush, Sprite, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
TimeUntilNextSpriteCheck = 0.25f;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Again, wish I could just subclass FRichInlineImage here, le sigh
|
// Again, wish I could just subclass FRichInlineImage here, le sigh
|
||||||
@ -127,7 +153,7 @@ protected:
|
|||||||
|
|
||||||
virtual TSharedPtr<SWidget> CreateDecoratorWidget(const FTextRunInfo& RunInfo, const FTextBlockStyle& TextStyle) const override
|
virtual TSharedPtr<SWidget> CreateDecoratorWidget(const FTextRunInfo& RunInfo, const FTextBlockStyle& TextStyle) const override
|
||||||
{
|
{
|
||||||
FInputImageParams Params;
|
FRichTextInputImageParams Params;
|
||||||
Params.PlayerIndex = 0;
|
Params.PlayerIndex = 0;
|
||||||
Params.BindingType = EInputBindingType::Key;
|
Params.BindingType = EInputBindingType::Key;
|
||||||
Params.Key = EKeys::AnyKey;
|
Params.Key = EKeys::AnyKey;
|
||||||
@ -157,6 +183,7 @@ protected:
|
|||||||
|
|
||||||
// Look up the initial sprite here
|
// Look up the initial sprite here
|
||||||
// The Slate widget can't do it in Construct because World pointer doesn't work (thread issues?)
|
// The Slate widget can't do it in Construct because World pointer doesn't work (thread issues?)
|
||||||
|
// Also annoying: can't keep Brush on this class because this method is const. UGH
|
||||||
auto GS = GetStevesGameSubsystem(Decorator->GetWorld());
|
auto GS = GetStevesGameSubsystem(Decorator->GetWorld());
|
||||||
if (GS)
|
if (GS)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user