Added ProgressBar widget
This commit is contained in:
parent
1c9d0b5ab9
commit
327582c463
11 changed files with 215 additions and 5 deletions
|
|
@ -94,6 +94,7 @@ list(APPEND OGFX_SOURCE_FILES
|
|||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Scrollbar.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Button.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/RadioButton.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/ProgressBar.cpp
|
||||
|
||||
# render
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/BasicRenderer.cpp
|
||||
|
|
@ -152,7 +153,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|||
target_compile_definitions(${OMNIA_STD_LIB} PUBLIC OX_DEBUG_BUILD)
|
||||
target_compile_definitions(${OMNIA_GFX_LIB} PUBLIC OX_DEBUG_BUILD)
|
||||
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
add_compile_options(-MMD -MP -Wall)
|
||||
add_compile_options(-MMD -MP -Wall -latomic)
|
||||
target_compile_definitions(${OMNIA_STD_LIB} PUBLIC OX_RELEASE_BUILD)
|
||||
target_compile_definitions(${OMNIA_GFX_LIB} PUBLIC OX_RELEASE_BUILD)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -219,3 +219,19 @@ const $accentColorDark = #6B0A1DFF
|
|||
(image) {
|
||||
}
|
||||
% ===================
|
||||
|
||||
|
||||
|
||||
% ====== Image ======
|
||||
(progressbar) {
|
||||
backgroundColor = #400000FF
|
||||
progressColor = #AA0000FF
|
||||
borderColor = $accentColor
|
||||
showDecimal = false
|
||||
showText = true
|
||||
useBackgroundGradient = true
|
||||
backgroundGradient = gradientV(#400A1DFF - $accentColorDark)
|
||||
useProgressGradient = true
|
||||
progressGradient = gradientV(#C21135FF - #820B23FF)
|
||||
}
|
||||
% ===================
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ Add theme caching
|
|||
Implement cursors in Stylesheet
|
||||
FIX: Window getting exponentially bigger when Desktop scale changes
|
||||
FIX: Refreshing scroll when content extent changes
|
||||
Add Dark Mode Default theme
|
||||
Add Dark Mode Default theme, and see if I can query OS theme mode to saelect the right theme
|
||||
FIX: Float values in stylesheet needing to have decimal point to be read as float
|
||||
Make parsing of vec2 and rect in stylesheet, consistent with other value functions like gradients and animations
|
||||
Add buttons to scroll tabs in TabPanel
|
||||
|
|
@ -46,7 +46,7 @@ Implement following widgets:
|
|||
***Tooltips
|
||||
***Radio Button
|
||||
***Grouping
|
||||
Progressbar
|
||||
***Progressbar
|
||||
Horizontal Slider
|
||||
Vertical Slider
|
||||
ListBox
|
||||
|
|
|
|||
|
|
@ -26,3 +26,4 @@
|
|||
#include <ogfx/gui/widgets/Scrollbar.hpp>
|
||||
#include <ogfx/gui/widgets/Button.hpp>
|
||||
#include <ogfx/gui/widgets/RadioButton.hpp>
|
||||
#include <ogfx/gui/widgets/ProgressBar.hpp>
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ namespace ogfx
|
|||
inline Color getCheckBoxColor(void) const { return m_checkBoxColor; }
|
||||
inline void setCheckBoxColor(const Color& color) { m_checkBoxColor = color; }
|
||||
inline bool isChecked(void) const { return m_checked; }
|
||||
inline void setStateChangedCallback(std::function<void(CheckBox&, bool)> callback) { callback_onStateChanged = callback; }
|
||||
inline void setStateChangedCallback(std::function<void(CheckBox&, bool)> callback) { callback_onStateChanged = std::move(callback); }
|
||||
|
||||
private:
|
||||
void __update_size(ogfx::BasicRenderer2D& gfx);
|
||||
|
|
|
|||
98
src/ogfx/gui/widgets/ProgressBar.cpp
Normal file
98
src/ogfx/gui/widgets/ProgressBar.cpp
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
OmniaFramework - A collection of useful functionality
|
||||
Copyright (C) 2025 OmniaX-Dev
|
||||
|
||||
This file is part of OmniaFramework.
|
||||
|
||||
OmniaFramework is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OmniaFramework is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ProgressBar.hpp"
|
||||
#include "../../render/BasicRenderer.hpp"
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
namespace widgets
|
||||
{
|
||||
ProgressBar& ProgressBar::create(void)
|
||||
{
|
||||
setPadding({ 0, 0, 0, 0 });
|
||||
setTypeName("ogfx::gui::widgets::ProgressBar");
|
||||
disableChildren();
|
||||
enableBackground();
|
||||
enableBorder();
|
||||
setStylesheetCategoryName("progressbar");
|
||||
validate();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ProgressBar::applyTheme(const ostd::Stylesheet& theme)
|
||||
{
|
||||
setProgressColor(getThemeValue<Color>(theme, "progressColor", getProgressColor()));
|
||||
enableShowDecimal(getThemeValue<bool>(theme, "showDecimal", isShowDecimalEnabled()));
|
||||
enableShowText(getThemeValue<bool>(theme, "showText", isShowTextEnabled()));
|
||||
enableProgressGradient(getThemeValue<bool>(theme, "useProgressGradient", isProgressGradientEnabled()));
|
||||
setProgressGradient(getThemeValue<ColorGradient>(theme, "progressGradient", getProgressGradient()));
|
||||
}
|
||||
|
||||
void ProgressBar::onDraw(ogfx::BasicRenderer2D& gfx)
|
||||
{
|
||||
f32 prog = getProgressNormalized();
|
||||
f32 progressw = (prog * getw());
|
||||
if (isProgressGradientEnabled())
|
||||
gfx.fillGradientRect({ getGlobalPosition(), { progressw, geth() } }, m_progressGradient);
|
||||
else
|
||||
gfx.fillRect({ getGlobalPosition(), { progressw, geth() } }, getProgressColor());
|
||||
if (isShowTextEnabled())
|
||||
{
|
||||
String text = "";
|
||||
if (isShowDecimalEnabled())
|
||||
text.add(prog * 100, 2).add("%");
|
||||
else
|
||||
text.add(cast<i32>(std::round(prog * 100))).add("%");
|
||||
gfx.drawCenteredString(text, getGlobalBounds(), getTextColor(), getFontSize());
|
||||
}
|
||||
}
|
||||
|
||||
void ProgressBar::setProgressNormalized(f32 normalized_value)
|
||||
{
|
||||
f32 current = m_progress.load(std::memory_order_relaxed);
|
||||
f32 next = current;
|
||||
next = current + std::clamp(normalized_value, 0.0f, 1.0f) * (m_max - m_min);
|
||||
m_progress.store(next, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void ProgressBar::setProgress(f32 value)
|
||||
{
|
||||
f32 current = m_progress.load(std::memory_order_relaxed);
|
||||
f32 next = current;
|
||||
next = std::clamp(value, m_min, m_max);
|
||||
m_progress.store(next, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
f32 ProgressBar::getProgress(void) const
|
||||
{
|
||||
return m_progress.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
f32 ProgressBar::getProgressNormalized(void) const
|
||||
{
|
||||
f32 s = m_progress.load(std::memory_order_relaxed);
|
||||
return (s - m_min) / (m_max - m_min);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
64
src/ogfx/gui/widgets/ProgressBar.hpp
Normal file
64
src/ogfx/gui/widgets/ProgressBar.hpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
OmniaFramework - A collection of useful functionality
|
||||
Copyright (C) 2025 OmniaX-Dev
|
||||
|
||||
This file is part of OmniaFramework.
|
||||
|
||||
OmniaFramework is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OmniaFramework is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ogfx/gui/widgets/Widget.hpp>
|
||||
#include <atomic>
|
||||
|
||||
namespace ogfx
|
||||
{
|
||||
namespace gui
|
||||
{
|
||||
namespace widgets
|
||||
{
|
||||
class ProgressBar : public Widget
|
||||
{
|
||||
public:
|
||||
inline ProgressBar(WindowCore& window, f32 min = 0.0f, f32 max = 1.0f, f32 start = 0.0f) : Widget({ 0, 0, 0, 0 }, window), m_progress(std::clamp(start, min, max)), m_min(min), m_max(max) { create(); }
|
||||
ProgressBar& create(void);
|
||||
void applyTheme(const ostd::Stylesheet& theme) override;
|
||||
void onDraw(ogfx::BasicRenderer2D& gfx) override;
|
||||
void setProgressNormalized(f32 normalized_value);
|
||||
void setProgress(f32 value);
|
||||
f32 getProgress(void) const;
|
||||
f32 getProgressNormalized(void) const;
|
||||
OSTD_PARAM_GETSET(Color, ProgressColor, m_progressColor);
|
||||
OSTD_BOOL_PARAM_GETSET_E(ShowDecimal, m_showDecimal);
|
||||
OSTD_BOOL_PARAM_GETSET_E(ShowText, m_showText);
|
||||
OSTD_BOOL_PARAM_GETSET_E(ProgressGradient, m_useProgressGradient);
|
||||
OSTD_PARAM_GETSET(ColorGradient, ProgressGradient, m_progressGradient);
|
||||
|
||||
private:
|
||||
Color m_progressColor { 255, 255, 255 };
|
||||
f32 m_min { 0.0f };
|
||||
f32 m_max { 1.0f };
|
||||
std::atomic<f32> m_progress;
|
||||
bool m_showDecimal { false };
|
||||
bool m_showText { true };
|
||||
bool m_useProgressGradient { true };
|
||||
ColorGradient m_progressGradient {
|
||||
{ Colors::Crimson.darkened(0.1f), Colors::Crimson.darkened(0.35f) },
|
||||
{ 1.0f }
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -117,9 +117,14 @@ namespace ogfx
|
|||
{
|
||||
if (is_button_present(sender))
|
||||
{
|
||||
if (m_selected != nullptr && m_selected == &sender)
|
||||
return;
|
||||
unselect_all();
|
||||
auto previous = m_selected;
|
||||
m_selected = &sender;
|
||||
m_selected->__set_selected(true);
|
||||
if (previous != nullptr && callback_onSelectionChanged != nullptr)
|
||||
callback_onSelectionChanged(*previous, sender);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ namespace ogfx
|
|||
public:
|
||||
RadioButtonGroup(void);
|
||||
RadioButton& addButton(Widget& parent, const String& text, const Vec2& position = { 0, 0 });
|
||||
inline void setSelectionChangedCallback(std::function<void(RadioButton& previous, RadioButton& sender)> callback) { callback_onSelectionChanged = std::move(callback); }
|
||||
|
||||
private:
|
||||
void set_selected(RadioButton& sender);
|
||||
|
|
@ -75,6 +76,7 @@ namespace ogfx
|
|||
private:
|
||||
stdvec<std::unique_ptr<RadioButton>> m_buttons;
|
||||
RadioButton* m_selected { nullptr };
|
||||
std::function<void(RadioButton& previous, RadioButton& sender)> callback_onSelectionChanged { nullptr };
|
||||
|
||||
friend class RadioButton;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ namespace ogfx
|
|||
Rectangle m_padding { 0, 0, 0, 0 };
|
||||
Rectangle m_margin { 0, 0, 0, 0 };
|
||||
Vec2 m_contentOffset { 0, 0 };
|
||||
i32 m_borderRadius { 10 };
|
||||
i32 m_borderRadius { 0 };
|
||||
i32 m_borderWidth { 2 };
|
||||
Color m_borderColor { 255, 255, 255 };
|
||||
bool m_showBorder { false };
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include <SDL3/SDL_rect.h>
|
||||
#include <ogfx/utils/Keycodes.hpp>
|
||||
#include <ogfx/ogfx.hpp>
|
||||
#include <ostd/utils/Async.hpp>
|
||||
|
||||
ogfx::WindowCore::FileDialogFilterList filters = {
|
||||
{ "Image files", { "png", "jpg", "jpeg", "bmp" } },
|
||||
|
|
@ -103,6 +104,8 @@ class Window : public ogfx::gui::Window
|
|||
m_panel2.enableTooltip();
|
||||
m_panel2.setTooltipText("PANEL tooltip");
|
||||
|
||||
m_prog.setSize(300, 30);
|
||||
|
||||
m_tabs.setSize(900, 700);
|
||||
auto& t1 = m_tabs.addTab("Tab1");
|
||||
auto& t2 = m_tabs.addTab("Tab2 Test");
|
||||
|
|
@ -115,6 +118,11 @@ class Window : public ogfx::gui::Window
|
|||
m_radioGroup.addButton(t1, "Radio this out!", { 30, 80 });
|
||||
m_radioGroup.addButton(t1, "Radio Opt. 2", { 30, 110 });
|
||||
m_radioGroup.addButton(t1, "Radio 3", { 30, 140 });
|
||||
m_radioGroup.setSelectionChangedCallback([&](RadioButton& previous, RadioButton& sender) -> void {
|
||||
std::cout << previous.getText() << "\n";
|
||||
std::cout << sender.getText() << "\n\n";
|
||||
});
|
||||
t1.addWidget(m_prog, { 30, 200 });
|
||||
t2.addWidget(m_panel2, { 500, 100 });
|
||||
|
||||
m_panel3.addWidget(m_label4);
|
||||
|
|
@ -133,6 +141,17 @@ class Window : public ogfx::gui::Window
|
|||
|
||||
m_theme.loadFromFile("./DefaultTheme.oss", true, getDefaultStylesheetVariableList());
|
||||
setTheme(m_theme);
|
||||
|
||||
m_progressJob.start([this] {
|
||||
f32 prog = 0.0f;
|
||||
while (prog < 100)
|
||||
{
|
||||
prog += 0.6f;
|
||||
ostd::Time::sleep(ostd::Random::getui32(10, 200));
|
||||
this->m_prog.setProgress(prog);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
inline void onSignal(ostd::Signal& signal) override
|
||||
|
|
@ -168,6 +187,10 @@ class Window : public ogfx::gui::Window
|
|||
ImageLabel m_img { *this };
|
||||
TabPanel m_tabs { *this };
|
||||
RadioButtonGroup m_radioGroup;
|
||||
ProgressBar m_prog { *this, 0, 100 };
|
||||
|
||||
ostd::StepTimer m_timer;
|
||||
ostd::AsyncJob<bool> m_progressJob;
|
||||
|
||||
ostd::Stylesheet m_theme;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue