Started work on ListView widget

This commit is contained in:
OmniaX-Dev 2026-04-23 03:28:47 +02:00
parent 19f64f6af3
commit 69e7fb7f1d
9 changed files with 236 additions and 13 deletions

View file

@ -96,6 +96,7 @@ list(APPEND OGFX_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/RadioButton.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/RadioButton.cpp
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/ProgressBar.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/ProgressBar.cpp
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Slider.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Slider.cpp
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/ListView.cpp
# render # render
${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/BasicRenderer.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/BasicRenderer.cpp

View file

@ -74,6 +74,7 @@ namespace ogfx
std::ranges::sort(m_widgetList, {}, [](Widget* w) { std::ranges::sort(m_widgetList, {}, [](Widget* w) {
return w->m_zIndex; return w->m_zIndex;
}); });
widget.refresh();
return true; return true;
} }

View file

@ -28,3 +28,4 @@
#include <ogfx/gui/widgets/RadioButton.hpp> #include <ogfx/gui/widgets/RadioButton.hpp>
#include <ogfx/gui/widgets/ProgressBar.hpp> #include <ogfx/gui/widgets/ProgressBar.hpp>
#include <ogfx/gui/widgets/Slider.hpp> #include <ogfx/gui/widgets/Slider.hpp>
#include <ogfx/gui/widgets/ListView.hpp>

View file

@ -0,0 +1,125 @@
/*
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 "ListView.hpp"
#include "../../render/BasicRenderer.hpp"
#include "../Window.hpp"
#include "../../../ostd/math/Random.hpp"
namespace ogfx
{
namespace gui
{
namespace widgets
{
void ListView::Item::setText(const String& text)
{
if (m_text == text)
return;
m_text = text;
update_dimensions();
}
void ListView::Item::setFontSize(i32 fontSize)
{
if (m_fontSize == fontSize)
return;
m_fontSize = fontSize;
update_dimensions();
}
void ListView::Item::update_dimensions(void)
{
if (!isValid())
return;
m_dimensions = m_parent->getWindow().getGFX().getStringDimensions(m_text, m_fontSize);
m_dimensions += Vec2 { m_padding.x + m_padding.w, m_padding.y + m_padding.h };
}
ListView& ListView::create(void)
{
setPadding({ 0, 0, 0, 0 });
setTypeName("ogfx::gui::widgets::ListView");
enableStopEvents();
enableBackground();
enableBorder();
setBackgroundColor({ 160, 160, 160 });
setBorderColor({ 50, 50, 50 });
setStylesheetCategoryName("list");
validate();
for (i32 i = 0; i < 30; i++)
{
Item k { *this };
m_list.push_back(k);
}
return *this;
}
void ListView::applyTheme(const ostd::Stylesheet& theme)
{
}
void ListView::onDraw(ogfx::BasicRenderer2D& gfx)
{
f32 y = 0;
const auto& bounds = getGlobalBounds();
for (auto& item : m_list)
{
if (!item.isValid()) continue;
const auto& size = item.getDimensions();
gfx.drawString(item, bounds.getPosition() + Vec2 { 0, y } + getScrollOffset() + item.getPadding().getPosition(), item.getTextColor(), item.getFontSize());
y += size.y;
}
}
void ListView::afterDraw(ogfx::BasicRenderer2D& gfx)
{
drawScrollbars(gfx);
}
Rectangle ListView::getContentExtents(void) const
{
f32 maxX = 0, maxY = 0;
for (auto& item : m_list)
{
if (!item.isValid()) continue;
Vec2 size = item.getDimensions();
maxX = std::max(maxX, size.x);
maxY += size.y;
}
return { 0, 0, maxX, maxY };
}
void ListView::refresh(void)
{
for (auto& item : m_list)
{
item.setText(ostd::Random::getString(ostd::Random::getui8(0, 40)));
}
m_list[10].setFontSize(40);
m_list[16].setTextColor(Colors::Crimson);
}
}
}
}

View file

@ -0,0 +1,77 @@
/*
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 <ogfx/gui/widgets/Scrollbar.hpp>
namespace ogfx
{
namespace gui
{
namespace widgets
{
class ListView : public ScrollableWidget
{
public: class Item : public ostd::__i_stringeable
{
public:
inline Item(ListView& parent) { m_parent = &parent; }
void setText(const String& text);
void setFontSize(i32 fontSize);
inline String toString(void) const override { return m_text; }
inline bool isValid(void) const { return m_parent != nullptr && m_text.new_trim() != ""; }
inline Vec2 getDimensions(void) const { return m_dimensions; }
inline i32 getFontSize(void) const { return m_fontSize; }
inline String getText(void) const { return m_text; }
OSTD_PARAM_GETSET(Color, TextColor, m_textColor);
OSTD_PARAM_GETSET(Rectangle, Padding, m_padding);
private:
void update_dimensions(void);
private:
Vec2 m_dimensions { 0, 0 };
ListView* m_parent { nullptr };
String m_text { "" };
i32 m_fontSize { 16 };
Color m_textColor { 30, 30, 30 };
Rectangle m_padding { 5, 5, 20, 0 };
};
public:
inline ListView(WindowCore& window) : ScrollableWidget(window) { create(); }
ListView& create(void);
void applyTheme(const ostd::Stylesheet& theme) override;
void onDraw(ogfx::BasicRenderer2D& gfx) override;
void afterDraw(ogfx::BasicRenderer2D& gfx) override;
Rectangle getContentExtents(void) const override;
void refresh(void) override;
private:
stdvec<Item> m_list;
};
}
}
}

View file

@ -283,6 +283,7 @@ namespace ogfx
inline virtual void resetScroll(bool horizontal = true, bool vertical = true, bool propagate = true) { } inline virtual void resetScroll(bool horizontal = true, bool vertical = true, bool propagate = true) { }
inline virtual f32 getVScrollbarSize(void) const { return 0; } inline virtual f32 getVScrollbarSize(void) const { return 0; }
inline virtual f32 getHScrollbarSize(void) const { return 0; } inline virtual f32 getHScrollbarSize(void) const { return 0; }
inline virtual void refresh(void) { }
// ===================================================== // =====================================================
inline virtual void onDraw(ogfx::BasicRenderer2D& gfx) { } inline virtual void onDraw(ogfx::BasicRenderer2D& gfx) { }

View file

@ -114,4 +114,12 @@ namespace ostd
return m_noiseGen.GetNoise(x, y); return m_noiseGen.GetNoise(x, y);
} }
String RandomGenerator::getString(u32 length, const String& charset)
{
String rnd = "";
u32 len = charset.len();
for (i32 i = 0; i < length; i++)
rnd += charset[getui32(0, len - 1)];
return rnd;
}
} }

View file

@ -1,21 +1,21 @@
/* /*
OmniaFramework - A collection of useful functionality OmniaFramework - A collection of useful functionality
Copyright (C) 2025 OmniaX-Dev Copyright (C) 2025 OmniaX-Dev
This file is part of OmniaFramework. This file is part of OmniaFramework.
OmniaFramework is free software: you can redistribute it and/or modify OmniaFramework is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
OmniaFramework is distributed in the hope that it will be useful, OmniaFramework is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>. along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
@ -52,6 +52,8 @@ namespace ostd
Vec2 getVec2(Vec2 minmax_x = { 0.0f, 1.0f }, Vec2 minmax_y = { 0.0f, 1.0f }); Vec2 getVec2(Vec2 minmax_x = { 0.0f, 1.0f }, Vec2 minmax_y = { 0.0f, 1.0f });
f32 getOpenSimplex2D(f32 x, f32 y); f32 getOpenSimplex2D(f32 x, f32 y);
String getString(u32 length, const String& charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-!@#$%^&*()+=[]{}|/?.>,<;:'\"\\");
inline FastNoiseLite& getNoiseGenerator(void) { return m_noiseGen; } inline FastNoiseLite& getNoiseGenerator(void) { return m_noiseGen; }
template <typename T> template <typename T>
@ -99,6 +101,8 @@ namespace ostd
inline static Vec2 getVec2(Vec2 minmax_x = { 0.0f, 1.0f }, Vec2 minmax_y = { 0.0f, 1.0f }) { return Random::s_gen.getVec2(minmax_x, minmax_y); } inline static Vec2 getVec2(Vec2 minmax_x = { 0.0f, 1.0f }, Vec2 minmax_y = { 0.0f, 1.0f }) { return Random::s_gen.getVec2(minmax_x, minmax_y); }
inline static f32 getOpenSimplex2D(f32 x, f32 y) { return Random::s_gen.getOpenSimplex2D(x, y); } inline static f32 getOpenSimplex2D(f32 x, f32 y) { return Random::s_gen.getOpenSimplex2D(x, y); }
inline static String getString(u32 length, const String& charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-!@#$%^&*()+=[]{}|/?.>,<;:'\"\\") { return Random::s_gen.getString(length, charset); }
template <typename T> template <typename T>
inline static T& getFromStdVec(stdvec<T>& list) { return Random::s_gen.getFromStdVec<T>(list); } inline static T& getFromStdVec(stdvec<T>& list) { return Random::s_gen.getFromStdVec<T>(list); }

View file

@ -114,6 +114,8 @@ class Window : public ogfx::gui::Window
}); });
m_slideLbl.setText(String("").add(m_slide.getValue(), 2)); m_slideLbl.setText(String("").add(m_slide.getValue(), 2));
m_list.setSize(200, 300);
m_tabs.setSize(900, 700); m_tabs.setSize(900, 700);
auto& t1 = m_tabs.addTab("Tab1"); auto& t1 = m_tabs.addTab("Tab1");
auto& t2 = m_tabs.addTab("Tab2 Test"); auto& t2 = m_tabs.addTab("Tab2 Test");
@ -133,6 +135,7 @@ class Window : public ogfx::gui::Window
t1.addWidget(m_prog, { 30, 200 }); t1.addWidget(m_prog, { 30, 200 });
t1.addWidget(m_slide, { 30, 250 }); t1.addWidget(m_slide, { 30, 250 });
t1.addWidget(m_slideLbl, { 340, 240 }); t1.addWidget(m_slideLbl, { 340, 240 });
t1.addWidget(m_list, { 30, 300 });
t2.addWidget(m_panel2, { 500, 100 }); t2.addWidget(m_panel2, { 500, 100 });
m_panel3.addWidget(m_label4); m_panel3.addWidget(m_label4);
@ -200,6 +203,7 @@ class Window : public ogfx::gui::Window
ProgressBar m_prog { *this, 0, 100 }; ProgressBar m_prog { *this, 0, 100 };
Slider m_slide { *this }; Slider m_slide { *this };
Label m_slideLbl { *this }; Label m_slideLbl { *this };
ListView m_list { *this };
ostd::StepTimer m_timer; ostd::StepTimer m_timer;
ostd::AsyncJob<bool> m_progressJob; ostd::AsyncJob<bool> m_progressJob;
@ -209,6 +213,7 @@ class Window : public ogfx::gui::Window
i32 main(i32 argc, char** argv) i32 main(i32 argc, char** argv)
{ {
ostd::Random::autoSeed();
ostd::initialize(); ostd::initialize();
Window window; Window window;
window.initialize(1200, 800, "OmniaFramework - Test Window"); window.initialize(1200, 800, "OmniaFramework - Test Window");