diff --git a/CMakeLists.txt b/CMakeLists.txt index 21ec168..a60b9e8 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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/ProgressBar.cpp ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/Slider.cpp + ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/gui/widgets/ListView.cpp # render ${CMAKE_CURRENT_LIST_DIR}/src/ogfx/render/BasicRenderer.cpp diff --git a/src/ogfx/gui/WidgetManager.cpp b/src/ogfx/gui/WidgetManager.cpp index 8d794fd..a336be5 100644 --- a/src/ogfx/gui/WidgetManager.cpp +++ b/src/ogfx/gui/WidgetManager.cpp @@ -74,6 +74,7 @@ namespace ogfx std::ranges::sort(m_widgetList, {}, [](Widget* w) { return w->m_zIndex; }); + widget.refresh(); return true; } diff --git a/src/ogfx/gui/Widgets.hpp b/src/ogfx/gui/Widgets.hpp index e158420..181ce23 100644 --- a/src/ogfx/gui/Widgets.hpp +++ b/src/ogfx/gui/Widgets.hpp @@ -28,3 +28,4 @@ #include #include #include +#include diff --git a/src/ogfx/gui/widgets/ListView.cpp b/src/ogfx/gui/widgets/ListView.cpp new file mode 100644 index 0000000..e2a1abd --- /dev/null +++ b/src/ogfx/gui/widgets/ListView.cpp @@ -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 . +*/ + +#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); + } + } + } +} diff --git a/src/ogfx/gui/widgets/ListView.hpp b/src/ogfx/gui/widgets/ListView.hpp new file mode 100644 index 0000000..082b317 --- /dev/null +++ b/src/ogfx/gui/widgets/ListView.hpp @@ -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 . +*/ + +#pragma once + +#include +#include + +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 m_list; + }; + } + } +} diff --git a/src/ogfx/gui/widgets/Widget.hpp b/src/ogfx/gui/widgets/Widget.hpp index 0a5e5f7..ed8c4e8 100644 --- a/src/ogfx/gui/widgets/Widget.hpp +++ b/src/ogfx/gui/widgets/Widget.hpp @@ -283,6 +283,7 @@ namespace ogfx inline virtual void resetScroll(bool horizontal = true, bool vertical = true, bool propagate = true) { } inline virtual f32 getVScrollbarSize(void) const { return 0; } inline virtual f32 getHScrollbarSize(void) const { return 0; } + inline virtual void refresh(void) { } // ===================================================== inline virtual void onDraw(ogfx::BasicRenderer2D& gfx) { } diff --git a/src/ostd/math/Random.cpp b/src/ostd/math/Random.cpp index e3d648e..534c0f8 100755 --- a/src/ostd/math/Random.cpp +++ b/src/ostd/math/Random.cpp @@ -114,4 +114,12 @@ namespace ostd 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; + } } diff --git a/src/ostd/math/Random.hpp b/src/ostd/math/Random.hpp index 6db1d23..2405d87 100755 --- a/src/ostd/math/Random.hpp +++ b/src/ostd/math/Random.hpp @@ -1,21 +1,21 @@ /* - OmniaFramework - A collection of useful functionality - Copyright (C) 2025 OmniaX-Dev + OmniaFramework - A collection of useful functionality + 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 - 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 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. + 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 . + You should have received a copy of the GNU General Public License + along with OmniaFramework. If not, see . */ #pragma once @@ -52,6 +52,8 @@ namespace ostd Vec2 getVec2(Vec2 minmax_x = { 0.0f, 1.0f }, Vec2 minmax_y = { 0.0f, 1.0f }); f32 getOpenSimplex2D(f32 x, f32 y); + String getString(u32 length, const String& charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-!@#$%^&*()+=[]{}|/?.>,<;:'\"\\"); + inline FastNoiseLite& getNoiseGenerator(void) { return m_noiseGen; } template @@ -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 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 inline static T& getFromStdVec(stdvec& list) { return Random::s_gen.getFromStdVec(list); } diff --git a/src/test/GuiTest.cpp b/src/test/GuiTest.cpp index 2f9d16a..9e8d806 100644 --- a/src/test/GuiTest.cpp +++ b/src/test/GuiTest.cpp @@ -114,6 +114,8 @@ class Window : public ogfx::gui::Window }); m_slideLbl.setText(String("").add(m_slide.getValue(), 2)); + m_list.setSize(200, 300); + m_tabs.setSize(900, 700); auto& t1 = m_tabs.addTab("Tab1"); 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_slide, { 30, 250 }); t1.addWidget(m_slideLbl, { 340, 240 }); + t1.addWidget(m_list, { 30, 300 }); t2.addWidget(m_panel2, { 500, 100 }); m_panel3.addWidget(m_label4); @@ -200,6 +203,7 @@ class Window : public ogfx::gui::Window ProgressBar m_prog { *this, 0, 100 }; Slider m_slide { *this }; Label m_slideLbl { *this }; + ListView m_list { *this }; ostd::StepTimer m_timer; ostd::AsyncJob m_progressJob; @@ -209,6 +213,7 @@ class Window : public ogfx::gui::Window i32 main(i32 argc, char** argv) { + ostd::Random::autoSeed(); ostd::initialize(); Window window; window.initialize(1200, 800, "OmniaFramework - Test Window");