Redesigned slider to support customizing the size of the Scrubber.

This commit is contained in:
2025-06-24 01:57:14 -05:00
parent 72e21451a6
commit d5d6703ee9
2 changed files with 81 additions and 60 deletions

View File

@@ -18,56 +18,53 @@
namespace JUI
{
template<typename T>
T roundMultiple( T value, T multiple )
{
if (multiple == 0) return value;
return static_cast<T>(std::round(static_cast<double>(value)/static_cast<double>(multiple))*static_cast<double>(multiple));
}
struct Scrubber {
public:
Color4 color;
UDim2 size;
protected:
private:
};
/// A slider is a widget with a handle which can be pulled back and forth to change the value.
class Slider : public Rect, public Clickable, public Hoverable
{
public:
/// Invoked when the value of the slider is changed, usually by the user interacting with it.
Event<float> ValueChanged;
/// The default constructor initializes member variables to reasonable defaults.
Slider();
/// Constructs a slider by specifying it's parent widget.
explicit Slider(JUI::Widget* parent);
/// @return The minimum value allowed by the slider.
[[nodiscard]] float Minimum() const;
/// @return The maximum value allowed by the slider.
[[nodiscard]] float Maximum() const;
/// @return The increments the slider moves in.
[[nodiscard]] float Interval() const;
[[nodiscard]] float CurrentValue() const;
[[nodiscard]] Color4 ScrubberColor() const;
[[nodiscard]] float ScrubberWidth() const;
/// @note Deprecated in favor of Slider::ScrubberSize().
[[deprecated]] [[nodiscard]] float ScrubberWidth() const;
[[nodiscard]] UDim2 ScrubberSize() const;
[[nodiscard]] float ScrubberRounding() const;
/// Returns whether the slider is currently being dragged by the user.
[[nodiscard]] bool Dragging() const;
[[nodiscard]] float Range() const;
/// Sets the minimum value allowed by the slider.
void Minimum(float min);
void Maximum(float max);
void Interval(float inter);
void CurrentValue(float value);
/// @return The percentage of the slider, in the range [0, 1].
float Percentage() const;
/// Sets the percentage of the slider, in the range [0, 1]. The percentage is the underlying representation used interally.
void Percentage(float value);
void ScrubberColor(const Color4& color);
void ScrubberWidth(float width);
/// @note Deprecated in favor of Slider::ScrubberSize().
[[deprecated]] void ScrubberWidth(float width);
void ScrubberSize(const UDim2& size);
void ScrubberRounding(float rounding);
void SetDragging(bool value);
void OnClick(const J3ML::LinearAlgebra::Vector2 &MousePos, const JUI::MouseButton &MouseButton) override;
@@ -75,7 +72,13 @@ namespace JUI
void OnHover(const J3ML::LinearAlgebra::Vector2 &MousePos) override;
void OnExit(const J3ML::LinearAlgebra::Vector2 &MousePos) override;
void Update(float delta) override;
Vector2 GetScrubberAbsolutePosition() const;
Vector2 GetScrubberAbsoluteSize() const;
void Draw() override;
void InnerDraw() override;
protected:
@@ -85,8 +88,9 @@ namespace JUI
float current;
float percentage = 0.f;
bool dragging = false;
float scrubber_width = 20;
UDim2 scrubber_size {20_px, 100_percent};
Color4 scrubber_color = Colors::White;
float scrubber_rounding = 0.f;
private:
};

View File

@@ -20,6 +20,13 @@ namespace JUI
return map(value, in.min, in.max, out.min, out.max);
}
template<typename T>
T roundMultiple( T value, T multiple )
{
if (multiple == 0) return value;
return static_cast<T>(std::round(static_cast<double>(value)/static_cast<double>(multiple))*static_cast<double>(multiple));
}
Slider::Slider(JUI::Widget *parent) : Slider()
{
this->Parent(parent);
@@ -65,6 +72,8 @@ namespace JUI
{
Vector2 mouse = last_known_mouse_pos;
float scrubber_width = GetScrubberAbsoluteSize().x;
float slider_abs_left = this->GetAbsolutePosition().x;
float slider_abs_right = (this->GetAbsolutePosition().x + this->GetAbsoluteSize().x) - scrubber_width;
float slider_total_width = this->GetAbsoluteSize().x - scrubber_width;
@@ -93,52 +102,46 @@ namespace JUI
Rect::Update(delta);
}
void Slider::InnerDraw() {
Rect::InnerDraw();
Vector2 pos = {
percentage * (GetAbsoluteSize().x - scrubber_width) + GetAbsolutePosition().x
,GetAbsolutePosition().y
};
/// @note Calls GetScrubberAbsoluteSize() to compute box's offset.
Vector2 Slider::GetScrubberAbsolutePosition() const {
/*
Vector2 child_size_scale = this->Size().GetScale();
Vector2 child_size_px = this->Size().GetPixels();
// TODO: Integrate padding.
Vector2 parent_abs_size = this->GetParent()->GetAbsoluteSize();
float x_offset = percentage * (GetAbsoluteSize().x - GetScrubberAbsoluteSize().x);
Vector2 pad_size_reduction = GetAbsolutePaddingBottomRight();
float rect_half_height = (GetAbsoluteSize().y / 2.f);
Vector2 abs_size = child_size_px + (parent_abs_size * child_size_scale) - pad_size_reduction;
*/
float y_offset = rect_half_height - (GetScrubberAbsoluteSize().y / 2.f);
UDim scrub_width = UDim(scrubber_width, 0.f);
float padding = 2;
Vector2 scrub_rel_pos = {x_offset, y_offset};
float scrubber_abs_width = scrub_width.Pixels + (GetAbsoluteSize().x * scrub_width.Scale) - padding;
J2D::FillRoundedRect(scrubber_color, pos, {scrubber_abs_width, GetAbsoluteSize().y});
return GetAbsolutePosition() + scrub_rel_pos;
}
Vector2 Slider::GetScrubberAbsoluteSize() const {
Vector2 abs_size = GetAbsoluteSize();
Vector2 scrub_size_px = scrubber_size.GetPixels();
Vector2 scrub_size_scale = scrubber_size.GetScale();
// TODO: Implement Slider::ScrubberPadding();
Vector2 padding = GetAbsolutePaddingBottomRight();
return scrub_size_px + (abs_size * scrub_size_scale) - padding;
}
void Slider::InnerDraw() {
Rect::InnerDraw();
Vector2 pos = GetScrubberAbsolutePosition();
Vector2 size = GetScrubberAbsoluteSize();
RectBase::Draw(scrubber_color, border_color, pos, size, scrubber_rounding, border_width, border_mode, corner_mode);
}
void Slider::Draw() {
//scrubber->Draw();
Rect::Draw();
Vector2 pos = {
percentage * (GetAbsoluteSize().x - scrubber_width) + GetAbsolutePosition().x
,GetAbsolutePosition().y
};
float abs_vertical_center_of_rect = GetAbsolutePosition().y + (GetAbsoluteSize().y / 2.f);
enum RectType { NORMAL, ROUNDED, CHAMFERED };
/// TODO: Implement internal padding on scrubber element?
//J2D::Begin();
//JGL::J2D::FillRect(scrubber_color, pos, {scrubber_width, GetAbsoluteSize().y});
//J2D::End();
}
float Slider::Minimum() const { return minimum; }
@@ -153,7 +156,15 @@ namespace JUI
Color4 Slider::ScrubberColor() const { return scrubber_color; }
float Slider::ScrubberWidth() const { return scrubber_width; }
float Slider::ScrubberWidth() const { return scrubber_size.X.Pixels; }
UDim2 Slider::ScrubberSize() const {
return scrubber_size;
}
float Slider::ScrubberRounding() const {
return scrubber_rounding;
}
float Slider::Range() const { return maximum - minimum; }
@@ -172,7 +183,13 @@ namespace JUI
void Slider::ScrubberColor(const Color4 &color) { scrubber_color = color;}
void Slider::ScrubberWidth(float width) { scrubber_width = width;}
void Slider::ScrubberWidth(float width) { scrubber_size.X.Pixels = width;}
void Slider::ScrubberSize(const UDim2 &size) {
scrubber_size = size;
}
void Slider::ScrubberRounding(float rounding) { scrubber_rounding = rounding;}
Slider::Slider() {
Name("Slider");