Sync push

This commit is contained in:
OmniaX-Dev 2026-04-18 07:27:46 +02:00
parent e2287c06f0
commit d618de0981
7 changed files with 108 additions and 42 deletions

View file

@ -30,7 +30,7 @@ window.backgroundColor = rgba(160, 160, 160, 255)
titlebarHeight = 18 titlebarHeight = 18
titlebarFontSize = 18 titlebarFontSize = 18
titlebarTextAlign = text_left titlebarTextAlign = text_left
scrollSpeed = vec2(0.8, 0.8) scrollSpeed = 15.0
padding = rect(15, 15, 15, 15) padding = rect(15, 15, 15, 15)
margin = rect(0, 0, 0, 0) margin = rect(0, 0, 0, 0)
} }

View file

@ -21,6 +21,7 @@
#pragma once #pragma once
#include <ostd/data/BaseObject.hpp> #include <ostd/data/BaseObject.hpp>
#include <ostd/math/Geometry.hpp>
namespace ogfx namespace ogfx
{ {
@ -48,7 +49,7 @@ namespace ogfx
class MouseEventData : public ostd::BaseObject class MouseEventData : public ostd::BaseObject
{ {
public: enum class eButton { None = 0, Left, Middle, Right }; public: enum class eButton { None = 0, Left, Middle, Right };
public: enum class eScrollDirection { None = 0, Up, Down }; public: enum class eScrollDirection { None = 0, Up, Down, Left, Right };
public: public:
inline MouseEventData(WindowCore& parent, f32 mousex, f32 mousey, eButton btn) : parentWindow(parent), position_x(mousex), position_y(mousey), button(btn) inline MouseEventData(WindowCore& parent, f32 mousex, f32 mousey, eButton btn) : parentWindow(parent), position_x(mousex), position_y(mousey), button(btn)
{ {
@ -61,7 +62,7 @@ namespace ogfx
f32 position_y; f32 position_y;
eButton button; eButton button;
eScrollDirection scroll { eScrollDirection::None }; eScrollDirection scroll { eScrollDirection::None };
f32 scrollAmount { 0 }; Vec2 scrollAmount { 0 };
gui::Widget* mousePressedOnWidget { nullptr }; gui::Widget* mousePressedOnWidget { nullptr };
WindowCore& parentWindow; WindowCore& parentWindow;
}; };

View file

@ -462,16 +462,36 @@ namespace ogfx
else if (event.type == SDL_EVENT_MOUSE_WHEEL) else if (event.type == SDL_EVENT_MOUSE_WHEEL)
{ {
MouseEventData mmd = get_mouse_state(event); MouseEventData mmd = get_mouse_state(event);
f32 delta = event.wheel.y; f32 deltaY = event.wheel.y;
f32 deltaX = event.wheel.x;
if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED)
delta = -delta; deltaY = -deltaY;
if (delta < 0) if (deltaY < 0)
{
mmd.scroll = MouseEventData::eScrollDirection::Down; mmd.scroll = MouseEventData::eScrollDirection::Down;
else if (delta > 0) mmd.scrollAmount = { 0.0f, deltaY };
}
else if (deltaY > 0)
{
mmd.scroll = MouseEventData::eScrollDirection::Up; mmd.scroll = MouseEventData::eScrollDirection::Up;
mmd.scrollAmount = { 0.0f, deltaY };
}
else if (deltaX < 0)
{
mmd.scroll = MouseEventData::eScrollDirection::Right;
mmd.scrollAmount = { deltaX, 0.0f };
}
else if (deltaX > 0)
{
mmd.scroll = MouseEventData::eScrollDirection::Left;
mmd.scrollAmount = { deltaX, 0.0f };
}
else else
{
mmd.scroll = MouseEventData::eScrollDirection::None; mmd.scroll = MouseEventData::eScrollDirection::None;
mmd.scrollAmount = delta; mmd.scrollAmount = { 0.0f, 0.0f };
}
ostd::SignalHandler::emitSignal(ostd::BuiltinSignals::MouseScrolled, ostd::Signal::Priority::RealTime, mmd); ostd::SignalHandler::emitSignal(ostd::BuiltinSignals::MouseScrolled, ostd::Signal::Priority::RealTime, mmd);
} }
else if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN) else if (event.type == SDL_EVENT_MOUSE_BUTTON_DOWN)

View file

@ -39,6 +39,15 @@ namespace ogfx
m_scrollbar.setMargin({ 0, getTitlebarHeight(), 0, 0 }); m_scrollbar.setMargin({ 0, getTitlebarHeight(), 0, 0 });
m_scrollbar.enableManualDraw(true); m_scrollbar.enableManualDraw(true);
addWidget(m_scrollbar); addWidget(m_scrollbar);
m_smoothScrollTimer.create(30.0f, [&](f64 dt) -> void {
f32 scrollStep = m_scrollTarget / 60.0f;
m_currentScroll += scrollStep;
addScrollOffset({ 0, scrollStep });
if (m_currentScroll > m_scrollTarget)
m_currentScroll = m_scrollTarget;
}, [&](void) -> bool {
return m_currentScroll == m_scrollTarget;
}, true);
validate(); validate();
return *this; return *this;
} }
@ -53,7 +62,7 @@ namespace ogfx
setBorderColor(getThemeValue<Color>(theme, "panel.borderColor", Colors::Black)); setBorderColor(getThemeValue<Color>(theme, "panel.borderColor", Colors::Black));
setPadding(getThemeValue<Rectangle>(theme, "panel.padding", { 15, 15, 15, 15 })); setPadding(getThemeValue<Rectangle>(theme, "panel.padding", { 15, 15, 15, 15 }));
setMargin(getThemeValue<Rectangle>(theme, "panel.margin", { 0, 0, 0, 0 })); setMargin(getThemeValue<Rectangle>(theme, "panel.margin", { 0, 0, 0, 0 }));
m_scrollSpeed = getThemeValue<Vec2>(theme, "panel.scrollSpeed", { 0.0f, 0.8f }); m_scrollSpeed = getThemeValue<f32>(theme, "panel.scrollSpeed", 0.8f);
m_basePadding = getPadding(); m_basePadding = getPadding();
m_titleColor = getThemeValue<Color>(theme, "panel.titleColor", Colors::Black); m_titleColor = getThemeValue<Color>(theme, "panel.titleColor", Colors::Black);
m_titlebarColor = getThemeValue<Color>(theme, "panel.titlebarColor", Colors::Transparent); m_titlebarColor = getThemeValue<Color>(theme, "panel.titlebarColor", Colors::Transparent);
@ -71,6 +80,11 @@ namespace ogfx
// gfx.fillRect(getContentExtents() + Rectangle { getGlobalPosition(), 0, 0 }, { 80, 0, 0, 30 }); // gfx.fillRect(getContentExtents() + Rectangle { getGlobalPosition(), 0, 0 }, { 80, 0, 0, 30 });
} }
void Panel::onUpdate(void)
{
m_smoothScrollTimer.update();
}
void Panel::afterDraw(ogfx::BasicRenderer2D& gfx) void Panel::afterDraw(ogfx::BasicRenderer2D& gfx)
{ {
draw_titlebar(gfx); draw_titlebar(gfx);
@ -81,12 +95,19 @@ namespace ogfx
{ {
if (!isScrollAllowed()) if (!isScrollAllowed())
return; return;
if (m_smoothScrollTimer.isStopped())
m_smoothScrollTimer.restart();
f32 offset_y = 0; f32 offset_y = 0;
if (event.mouse->scroll == MouseEventData::eScrollDirection::Down) if (event.mouse->scroll == MouseEventData::eScrollDirection::Down)
offset_y = (m_scrollSpeed.y * event.mouse->scrollAmount * 15.0f); {
m_scrollTarget += (m_scrollSpeed * event.mouse->scrollAmount.y);
}
else if (event.mouse->scroll == MouseEventData::eScrollDirection::Up) else if (event.mouse->scroll == MouseEventData::eScrollDirection::Up)
offset_y = (m_scrollSpeed.y * event.mouse->scrollAmount * 15.0f); {
addScrollOffset({ 0, offset_y });
m_scrollTarget += (m_scrollSpeed * event.mouse->scrollAmount.y);
}
event.handle(); event.handle();
} }

View file

@ -22,6 +22,7 @@
#include <ogfx/gui/widgets/Widget.hpp> #include <ogfx/gui/widgets/Widget.hpp>
#include <ogfx/gui/widgets/Scrollbar.hpp> #include <ogfx/gui/widgets/Scrollbar.hpp>
#include <ostd/utils/Time.hpp>
namespace ogfx namespace ogfx
{ {
@ -46,6 +47,7 @@ namespace ogfx
Panel& create(void); Panel& create(void);
void applyTheme(const ostd::Stylesheet& theme) override; void applyTheme(const ostd::Stylesheet& theme) override;
void onDraw(ogfx::BasicRenderer2D& gfx) override; void onDraw(ogfx::BasicRenderer2D& gfx) override;
void onUpdate(void) override;
void afterDraw(ogfx::BasicRenderer2D& gfx) override; void afterDraw(ogfx::BasicRenderer2D& gfx) override;
void onMouseScrolled(const Event& event) override; void onMouseScrolled(const Event& event) override;
void setTitlebarType(const String& type); void setTitlebarType(const String& type);
@ -68,6 +70,7 @@ namespace ogfx
String m_title { "Panel" }; String m_title { "Panel" };
Vec2 m_scrollOffset { 0, 0 }; Vec2 m_scrollOffset { 0, 0 };
VerticalScrollBar m_scrollbar { getWindow() }; VerticalScrollBar m_scrollbar { getWindow() };
ostd::StepTimer m_smoothScrollTimer;
Color m_titleColor { Colors::Black }; Color m_titleColor { Colors::Black };
i32 m_titlebarType = TitleBarTypes::NoneValue; i32 m_titlebarType = TitleBarTypes::NoneValue;
@ -78,7 +81,10 @@ namespace ogfx
Color m_titlebarBorderColor { Colors::Black }; Color m_titlebarBorderColor { Colors::Black };
Rectangle m_basePadding { 0, 0, 0, 0 }; Rectangle m_basePadding { 0, 0, 0, 0 };
i32 m_titleTextAlign { 0 }; i32 m_titleTextAlign { 0 };
Vec2 m_scrollSpeed { 0.8f, 0.8f }; f32 m_scrollSpeed { 0.8f };
f32 m_scrollTarget { 0.0f };
f32 m_currentScroll { 0.0f };
}; };
} }
} }

View file

@ -597,19 +597,26 @@ namespace ostd
StepTimer& StepTimer::create(f64 updatesPerSecond, StepTimer::Callback callback) StepTimer& StepTimer::create(f64 updatesPerSecond, StepTimer::Callback callback, StopConditionCallback stopCondition, bool stopped)
{ {
m_targetDt = 1.0 / updatesPerSecond; m_targetDt = 1.0 / updatesPerSecond;
m_callback = std::move(callback); m_callback = std::move(callback);
m_stopCondition = std::move(stopCondition);
m_prevTime = Clock::now(); m_prevTime = Clock::now();
m_accumulator = 0.0; m_accumulator = 0.0;
m_stopped = stopped;
m_valid = true; m_valid = true;
return *this; return *this;
} }
void StepTimer::update(void) void StepTimer::update(void)
{ {
if (!m_valid) return; if (!m_valid || m_stopped || !m_callback) return;
if (m_stopCondition && m_stopCondition())
{
m_stopped = true;
return;
}
TimePoint currentTime = Clock::now(); TimePoint currentTime = Clock::now();
Duration frameDuration = currentTime - m_prevTime; Duration frameDuration = currentTime - m_prevTime;
@ -638,6 +645,7 @@ namespace ostd
{ {
m_accumulator = 0.0; m_accumulator = 0.0;
m_prevTime = Clock::now(); m_prevTime = Clock::now();
m_stopped = false;
} }
} }

View file

@ -119,26 +119,36 @@ namespace ostd
{ {
public: public:
using Callback = std::function<void(f64 dt)>; using Callback = std::function<void(f64 dt)>;
using StopConditionCallback = std::function<bool(void)>;
using StopCallback = std::function<void(void)>;
using Clock = std::chrono::high_resolution_clock; using Clock = std::chrono::high_resolution_clock;
using TimePoint = Clock::time_point; using TimePoint = Clock::time_point;
using Duration = Clock::duration; using Duration = Clock::duration;
public: public:
StepTimer() = default; StepTimer() = default;
inline StepTimer(f64 updatesPerSecond, Callback callback) { create(updatesPerSecond, callback); } inline StepTimer(f64 updatesPerSecond, Callback callback, bool stopped = false) { create(updatesPerSecond, callback, stopped); }
StepTimer& create(f64 updatesPerSecond, Callback callback); StepTimer& create(f64 updatesPerSecond, Callback callback, bool stopped = false);
void update(void); void update(void);
void reset(void); void reset(void);
inline void setStopCondition(StopConditionCallback stopCondition) { m_stopCondition = stopCondition; }
inline void setStopCallback(StopCallback callback) { m_stopCallback = callback; }
inline void restart(void) { reset(); }
inline void stop(void) { m_stopped = true; }
inline f64 getInterpolationAlpha(void) const { return m_valid && m_targetDt > 0.0 ? m_accumulator / m_targetDt : 0.0; } inline f64 getInterpolationAlpha(void) const { return m_valid && m_targetDt > 0.0 ? m_accumulator / m_targetDt : 0.0; }
inline void invalidate(void) { m_valid = false; } inline void invalidate(void) { m_valid = false; }
inline bool isValid(void) const { return m_valid; } inline bool isValid(void) const { return m_valid; }
inline bool isStopped(void) const { return m_stopped; }
private: private:
TimePoint m_prevTime; TimePoint m_prevTime;
f64 m_targetDt { 0.0 }; f64 m_targetDt { 0.0 };
Callback m_callback { nullptr }; Callback m_callback { nullptr };
StopConditionCallback m_stopCondition { nullptr };
StopCallback m_stopCallback { nullptr };
f64 m_accumulator { 0.0 }; f64 m_accumulator { 0.0 };
bool m_valid { false }; bool m_valid { false };
bool m_stopped { false };
}; };
struct GameClock struct GameClock