mirror of
https://github.com/sinbad/StevesUEHelpers.git
synced 2025-02-23 09:35:25 +00:00
Added smooth changing progress bar
This commit is contained in:
parent
88b5a5dcaf
commit
e7c9c373c3
@ -0,0 +1,62 @@
|
||||
#include "StevesUI/SmoothChangingProgressBar.h"
|
||||
|
||||
void USmoothChangingProgressBar::SetPercentSmoothly(float InPercent)
|
||||
{
|
||||
UnregisterTimer();
|
||||
|
||||
TargetPercent = InPercent;
|
||||
const float Curr = GetPercent();
|
||||
if (!FMath::IsNearlyEqual(Curr, TargetPercent))
|
||||
{
|
||||
if (FMath::IsNearlyZero(PercentChangeSpeed) || !MyProgressBar.IsValid())
|
||||
{
|
||||
SetPercent(InPercent);
|
||||
}
|
||||
else
|
||||
{
|
||||
SmoothChangeHandle = MyProgressBar->RegisterActiveTimer(
|
||||
PercentChangeFrequency,
|
||||
FWidgetActiveTimerDelegate::CreateUObject(this, &USmoothChangingProgressBar::TickPercent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USmoothChangingProgressBar::StopSmoothPercentChange()
|
||||
{
|
||||
UnregisterTimer();
|
||||
}
|
||||
|
||||
void USmoothChangingProgressBar::BeginDestroy()
|
||||
{
|
||||
Super::BeginDestroy();
|
||||
|
||||
UnregisterTimer();
|
||||
}
|
||||
|
||||
void USmoothChangingProgressBar::UnregisterTimer()
|
||||
{
|
||||
if (SmoothChangeHandle.IsValid() && MyProgressBar.IsValid())
|
||||
{
|
||||
MyProgressBar->UnRegisterActiveTimer(SmoothChangeHandle.Pin().ToSharedRef());
|
||||
SmoothChangeHandle.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
EActiveTimerReturnType USmoothChangingProgressBar::TickPercent(double CurrTime, float DeltaTime)
|
||||
{
|
||||
const float CurrPercent = GetPercent();
|
||||
const float Direction = FMath::Sign(TargetPercent - CurrPercent);
|
||||
const float Change = DeltaTime * Direction * PercentChangeSpeed;
|
||||
|
||||
const float NewPercent = Direction > 0
|
||||
? FMath::Min(CurrPercent + Change, TargetPercent)
|
||||
: FMath::Max(CurrPercent + Change, TargetPercent);
|
||||
SetPercent(NewPercent);
|
||||
|
||||
// Stop this if reached target (will unregister itself)
|
||||
if (FMath::IsNearlyEqual(TargetPercent, GetPercent()))
|
||||
{
|
||||
return EActiveTimerReturnType::Stop;
|
||||
}
|
||||
return EActiveTimerReturnType::Continue;
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Components/ProgressBar.h"
|
||||
#include "SmoothChangingProgressBar.generated.h"
|
||||
|
||||
/**
|
||||
* A specialised progress bar that can be told to change its percent smoothly instead of all at once.
|
||||
* Note: Because SetPercent isn't virtual on UProgressBar, you need to use the alternate SetPercentSmoothly
|
||||
* function instead, and call StopSmoothPercentChange to interrupt it if you need to manually set it using
|
||||
* SetPercent.
|
||||
*/
|
||||
UCLASS()
|
||||
class STEVESUEHELPERS_API USmoothChangingProgressBar : public UProgressBar
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
protected:
|
||||
TWeakPtr<FActiveTimerHandle> SmoothChangeHandle;
|
||||
|
||||
float TargetPercent;
|
||||
|
||||
void UnregisterTimer();
|
||||
EActiveTimerReturnType TickPercent(double CurrTime, float DeltaTime);
|
||||
public:
|
||||
/// The speed at which the progress bar changes. This value means the max percentage changes
|
||||
/// in one second. Set this to 0 to make changes instant. Changes to this value only affect
|
||||
/// the next call to SetPercentSmoothly.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Progress")
|
||||
float PercentChangeSpeed = 1.0f;
|
||||
|
||||
/// The frequency at which we should update the bar. Set this to 0 to update every frame,
|
||||
/// or > 0 to update every X seconds (useful to save tick time for slow updates).
|
||||
/// Changes to this value only affect the next call to SetPercentSmoothly.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Progress")
|
||||
float PercentChangeFrequency = 0.0f;
|
||||
|
||||
/// Changes the bar percentage smoothly from its current value.
|
||||
/// Automatically interrupts any existing smooth change.
|
||||
UFUNCTION(BlueprintCallable, Category="Progress")
|
||||
void SetPercentSmoothly(float InPercent);
|
||||
|
||||
/// Stop any pending smooth changes to percent
|
||||
/// Call this if you need to interrupt any current smooth change and
|
||||
UFUNCTION(BlueprintCallable, Category="Progress")
|
||||
void StopSmoothPercentChange();
|
||||
|
||||
virtual void BeginDestroy() override;
|
||||
|
||||
|
||||
|
||||
};
|
@ -107,4 +107,5 @@ Alternatives are:
|
||||
|
||||
## See Also
|
||||
|
||||
* [Input Image](InputImage.md)
|
||||
* [Input Image](InputImage.md)
|
||||
* [Widgets](Widgets.md)
|
19
doc/SmoothChangingProgress.md
Normal file
19
doc/SmoothChangingProgress.md
Normal file
@ -0,0 +1,19 @@
|
||||
# Smooth Changing Progress Bar
|
||||
|
||||
This is a fairly simple extension to Progress Bar to allow it to change smoothly
|
||||
rather than jumping.
|
||||
|
||||
You configure this as follows:
|
||||
|
||||
* Set `PercentChangeSpeed` to the amount of percent change per second
|
||||
* Optionally set `PercentChangeFrequency`; at 0, it updates every frame, otherwise
|
||||
it can update less frequently by setting this to a number of seconds
|
||||
* Call `SetPercentSmoothly` instead of `SetPercent`
|
||||
* (`SetPercent` is not virtual in `UProgressBar` so we cannot override that. This
|
||||
also means that if you want to interrupt the smooth change, you need to call
|
||||
`StopSmoothPercentChange`)
|
||||
|
||||
|
||||
## See Also
|
||||
|
||||
* [Widgets](Widgets.md)
|
@ -66,3 +66,7 @@ Several custom widgets are supplied to assist with some common challenges:
|
||||
and also remembers the last focus widget if you switch away & back
|
||||
without destroying it.
|
||||
|
||||
* [Smooth Changing Progress Bar](SmoothChangingProgress.md)
|
||||
|
||||
A ProgressBar subclass which adds the ability to smoothly change rather than
|
||||
jumping straight to the target value.
|
Loading…
x
Reference in New Issue
Block a user