From 0fcfd513d2197e7f77909f35176a87c1f322a99d Mon Sep 17 00:00:00 2001 From: mrsrina Date: Sat, 7 Jun 2025 19:25:20 -0300 Subject: [PATCH 1/5] [update] actions --- include/ekg/core/context.hpp | 1 + include/ekg/io/event.hpp | 45 +++++++++++++++++++++++++++++--- include/ekg/ui/button/button.hpp | 7 ++++- src/io/event.cpp | 10 +++++++ src/ui/button/widget.cpp | 32 +++++++++++++++++++++-- 5 files changed, 89 insertions(+), 6 deletions(-) diff --git a/include/ekg/core/context.hpp b/include/ekg/core/context.hpp index 76eb00cf..2eb953d1 100644 --- a/include/ekg/core/context.hpp +++ b/include/ekg/core/context.hpp @@ -66,6 +66,7 @@ namespace ekg { ekg::at_t pressed_at {ekg::at_t::not_found}; ekg::type released_type {}; ekg::at_t released_at {ekg::at_t::not_found}; + int64_t frequency {500}; float dt {}; bool redraw {}; }; diff --git a/include/ekg/io/event.hpp b/include/ekg/io/event.hpp index 701bd3f4..2304e23f 100644 --- a/include/ekg/io/event.hpp +++ b/include/ekg/io/event.hpp @@ -25,11 +25,48 @@ #define EKG_IO_EVENT_HPP #include "ekg/handler/input.hpp" +#include "ekg/handler/callback.hpp" + +#include namespace ekg { enum behavior : ekg::flags_t { no_auto_set_viewport_when_resize = 2 << 1 }; + + constexpr size_t enum_layer_size {8}; + enum class layer { + bg, + outline, + highlight_bg, + highlight_fg, + active_bg, + active_outline, + text_fg, + text_outline + }; + + constexpr size_t enum_action_size {8}; + enum class action { + hover, + active, + press, + release + }; + + template + struct at_array_t { + protected: + std::array ats {}; + public: + ekg::at_t &operator[](t item) { + return this->ats[static_cast(item)]; + } + + ekg::at_t &operator[](size_t index) { + return this->ats[index]; + } + }; } namespace ekg::io { @@ -46,6 +83,10 @@ namespace ekg::io { ekg::at_t &property_at = ekg::at_t::not_found ); + void dispatch( + ekg::at_t &callback_at + ); + enum class stage { pre, process, @@ -91,8 +132,6 @@ namespace ekg::io { }; } -namespace ekg::io { - -} +#define ekg_action(actions, action, state) if (state) ekg::io::dispatch(actions[action]); #endif diff --git a/include/ekg/ui/button/button.hpp b/include/ekg/ui/button/button.hpp index 895ecef9..caf1fb02 100644 --- a/include/ekg/ui/button/button.hpp +++ b/include/ekg/ui/button/button.hpp @@ -27,6 +27,7 @@ #include "ekg/io/descriptor.hpp" #include "ekg/io/font.hpp" #include "ekg/math/geometry.hpp" +#include "ekg/io/event.hpp" namespace ekg { struct button_color_scheme_t { @@ -55,9 +56,11 @@ namespace ekg { public: ekg::value text {}; ekg::font font_size {ekg::font::medium}; - bool is_check_box {}; + ekg::flags_t box {ekg::dock::none}; ekg::flags_t dock {}; ekg::button_t::check_t::widget_t widget {}; + ekg::at_array_t layers {}; + ekg::at_array_t actions {}; }; static ekg::button_t not_found; @@ -68,6 +71,8 @@ namespace ekg { std::string tag {}; ekg::flags_t dock {}; ekg::rect_t rect {}; + ekg::at_array_t layers {}; + ekg::at_array_t actions {}; std::vector checks {}; ekg::button_color_scheme_t color_scheme {}; public: diff --git a/src/io/event.cpp b/src/io/event.cpp index 98b49a50..77be392b 100644 --- a/src/io/event.cpp +++ b/src/io/event.cpp @@ -83,3 +83,13 @@ void ekg::io::dispatch( break; } } + +void ekg::io::dispatch( + ekg::at_t &callback_at +) { + if (callback_at == ekg::at_t::not_found) { + return; + } + + ekg::p_core->handler_callback.dispatch(callback_at); +} diff --git a/src/ui/button/widget.cpp b/src/ui/button/widget.cpp index 3f5050f3..393dbcb4 100644 --- a/src/ui/button/widget.cpp +++ b/src/ui/button/widget.cpp @@ -54,6 +54,12 @@ void ekg::ui::reload( ekg::axis::horizontal }; + if (button.checks.empty()) { + button.checks.push_back( + {} + ); + } + ekg::aligned_t aligned_dimension {}; for (ekg::button_t::check_t &check : button.checks) { ekg::draw::font &draw_font { @@ -90,14 +96,14 @@ void ekg::ui::reload( ekg::draw::get_font_renderer(check.font_size) }; - if (check.is_check_box) { + if (check.box != ekg::dock::none) { check.widget.rect_box.w = check.widget.rect_text.h; check.widget.rect_box.h = check.widget.rect_text.h; mask.insert( { .p_rect = &check.widget.rect_box, - .dock = check.dock + .dock = check.box } ); } @@ -123,7 +129,29 @@ void ekg::ui::event( ekg::button_t &button, const ekg::io::stage &stage ) { + switch (stage) { + case ekg::io::stage::process: { + ekg::rect_t &abs {ekg::ui::get_abs_rect(property, button.rect)}; + ekg::input_info_t &input {ekg::p_core->handler_input.info}; + + if (property.widget.is_hovering && input.has_motion) { + ekg_action( + button.actions, + ekg::action::hover, + ekg::timing_t::second > ekg::gui.ui.frequency + ); + } + if (!property.widget.is_active && property.widget.is_hovering && input.was_pressed) { + } + + break; + } + case ekg::io::stage::pre: + break; + case ekg::io::stage::post: + break; + } } void ekg::ui::high_frequency( From 7c230eddfa7465351a9b459b433ab19cad994185 Mon Sep 17 00:00:00 2001 From: mrsrina Date: Sun, 8 Jun 2025 17:35:15 -0300 Subject: [PATCH 2/5] [ref][fix][update] 'sampler_at' to 'at_t' in RHI; callback handler not repeating; button widget runtime --- .hdoc.toml | 2 +- CMakeLists.txt | 5 + cmake/properties.cmake | 2 +- include/ekg/core/context.hpp | 6 +- include/ekg/core/pools.hpp | 6 +- include/ekg/draw/allocator.hpp | 2 +- include/ekg/draw/shape/shape.hpp | 4 +- include/ekg/gpu/api.hpp | 2 +- include/ekg/gpu/opengl/gl.hpp | 2 +- include/ekg/io/event.hpp | 2 +- include/ekg/io/memory.hpp | 12 +- include/ekg/ui/button/button.hpp | 8 +- include/ekg/ui/property.hpp | 4 +- src/core/pools.cpp | 5 + src/core/runtime.cpp | 2 + src/draw/allocator.cpp | 8 +- src/draw/shape/shape.cpp | 8 +- src/draw/typography/font.cpp | 2 +- src/ekg.cpp | 2 +- src/gpu/opengl/gl.cpp | 12 +- src/handler/callback/handler.cpp | 1 + src/handler/theme/handler.cpp | 11 ++ src/ui/button/widget.cpp | 273 ++++++++++++++++++++++++++++++- src/ui/frame/widget.cpp | 15 +- 24 files changed, 348 insertions(+), 48 deletions(-) diff --git a/.hdoc.toml b/.hdoc.toml index 87fe7173..43462e61 100644 --- a/.hdoc.toml +++ b/.hdoc.toml @@ -1,6 +1,6 @@ [project] name = "ekg" -version = "1.0.0" +version = "2.0.0" git_repo_url = "https://github.com/vokegpu/ekg-ui-library/" git_default_branch = "version-core" diff --git a/CMakeLists.txt b/CMakeLists.txt index e2a37277..5e730ddd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,6 +63,11 @@ target_compile_options( #-g ) +target_compile_definitions( + ekg PRIVATE + EKG_VERSION="${EKG_VERSION}" +) + set_target_properties( ekg PROPERTIES CXX_STANDARD 17 diff --git a/cmake/properties.cmake b/cmake/properties.cmake index 54a49719..03de6607 100644 --- a/cmake/properties.cmake +++ b/cmake/properties.cmake @@ -1,4 +1,4 @@ -set(EKG_VERSION 2.0.0) +set(EKG_VERSION 2.1.0) set(EKG_INCLUDE_DIRS "${CMAKE_INSTALL_PREFIX}/include") if(CMAKE_TOOLCHAIN_FILE) diff --git a/include/ekg/core/context.hpp b/include/ekg/core/context.hpp index 2eb953d1..321d7a02 100644 --- a/include/ekg/core/context.hpp +++ b/include/ekg/core/context.hpp @@ -36,11 +36,11 @@ namespace ekg { extern struct dpi_t { public: ekg::rect_t viewport {}; - ekg::rect_t scale {0.0f, 0.0f, 1080.0f, 1920.0f}; - bool auto_scale {}; + ekg::rect_t scale {0.0f, 0.0f, 1920.0f, 1080.0f}; + bool auto_scale {true}; float scale_interval {25.0f}; float factor_scale {}; - float font_scale {}; + float font_scale {18.0f}; float min_sizes {10.0f}; ekg::vec2_t font_offset {4, 6}; } dpi; diff --git a/include/ekg/core/pools.hpp b/include/ekg/core/pools.hpp index e47c24e1..6b57d754 100644 --- a/include/ekg/core/pools.hpp +++ b/include/ekg/core/pools.hpp @@ -92,13 +92,15 @@ namespace ekg::core { } \ \ ekg::property_t &parent {ekg::query(ekg::gui.bind.parent_at)}; \ - if (parent != ekg::property_t::not_found && is_container) { \ - if (widget.dock != ekg::dock::none) { \ + if (is_container) { \ + if (parent != ekg::property_t::not_found && widget.dock != ekg::dock::none) { \ parent.children.push_back(widget.at); \ + property.parent_at = ekg::gui.bind.parent_at; \ } else { \ ekg::gui.bind.parent_at = widget.at; \ } \ } else if (parent != ekg::property_t::not_found) { \ + property.parent_at = ekg::gui.bind.parent_at; \ parent.children.push_back(widget.at); \ } \ \ diff --git a/include/ekg/draw/allocator.hpp b/include/ekg/draw/allocator.hpp index 40643ad1..1d8104b1 100644 --- a/include/ekg/draw/allocator.hpp +++ b/include/ekg/draw/allocator.hpp @@ -65,7 +65,7 @@ namespace ekg::draw { void revoke(); void to_gpu(); - void bind_texture(ekg::sampler_t &sampler); + void bind_texture(ekg::at_t &sampler_at); ekg::gpu::data_t &bind_current_data(); size_t get_current_data_id(); ekg::gpu::data_t &get_data_by_index(size_t index); diff --git a/include/ekg/draw/shape/shape.hpp b/include/ekg/draw/shape/shape.hpp index 2e5d53a0..9a1aad6d 100644 --- a/include/ekg/draw/shape/shape.hpp +++ b/include/ekg/draw/shape/shape.hpp @@ -37,14 +37,14 @@ namespace ekg::draw { const ekg::rect_t &rect, const ekg::rgba_t &color, ekg::pixel_thickness_t line_thicnkess, - ekg::sampler_t &sampler + ekg::at_t &sampler_at ); void rect( float x, float y, float w, float h, const ekg::rgba_t &color, ekg::pixel_thickness_t line_thicnkess, - ekg::sampler_t &sampler + ekg::at_t &sampler_at ); void scissor( diff --git a/include/ekg/gpu/api.hpp b/include/ekg/gpu/api.hpp index 35b46f23..3bed856d 100644 --- a/include/ekg/gpu/api.hpp +++ b/include/ekg/gpu/api.hpp @@ -93,7 +93,7 @@ namespace ekg::gpu { ) { return ekg::result::failed_not_implemented; }; virtual ekg::at_t &bind_sampler( - ekg::sampler_t &sampler + ekg::at_t &sampler_at ) { return ekg::at_t::not_found; }; }; } diff --git a/include/ekg/gpu/opengl/gl.hpp b/include/ekg/gpu/opengl/gl.hpp index 400ba5ce..672abe8e 100644 --- a/include/ekg/gpu/opengl/gl.hpp +++ b/include/ekg/gpu/opengl/gl.hpp @@ -106,7 +106,7 @@ namespace ekg { ) override; ekg::at_t &bind_sampler( - ekg::sampler_t &sampler + ekg::at_t &sampler_at ) override; }; } diff --git a/include/ekg/io/event.hpp b/include/ekg/io/event.hpp index 2304e23f..00136822 100644 --- a/include/ekg/io/event.hpp +++ b/include/ekg/io/event.hpp @@ -60,7 +60,7 @@ namespace ekg { std::array ats {}; public: ekg::at_t &operator[](t item) { - return this->ats[static_cast(item)]; + return this->ats[static_cast(item)]; } ekg::at_t &operator[](size_t index) { diff --git a/include/ekg/io/memory.hpp b/include/ekg/io/memory.hpp index 21802749..2b558044 100644 --- a/include/ekg/io/memory.hpp +++ b/include/ekg/io/memory.hpp @@ -37,7 +37,7 @@ /** * A low-level assert used in risks cases where virtual-address should be warned. **/ -#define ekg_assert_low_level(state, alarm, end) if (state) alarm; end; +#define ekg_assert_low_level(state, alarm, end) if (state) { alarm; end; } /** * A dev-purpose log level untracked for EKG. @@ -189,9 +189,10 @@ namespace ekg { this->changed = true; } - void set(const t &val) { + bool set(const t &val) { this->get() = p; this->changed = true; + return true; } t &get() { @@ -220,6 +221,13 @@ namespace ekg { return false; } + public: + template + ekg::value &operator = (const s &val) { + this->get() = val; + this->changed = true; + return *this; + } }; struct mapped_address_sign_info_t { diff --git a/include/ekg/ui/button/button.hpp b/include/ekg/ui/button/button.hpp index caf1fb02..8ccf1653 100644 --- a/include/ekg/ui/button/button.hpp +++ b/include/ekg/ui/button/button.hpp @@ -37,6 +37,7 @@ namespace ekg { ekg::rgba_t background {}; ekg::rgba_t outline {}; ekg::rgba_t highlight {}; + ekg::rgba_t active {}; ekg::rgba_t box_background {}; ekg::rgba_t box_outline {}; @@ -50,14 +51,17 @@ namespace ekg { public: struct widget_t { public: + bool is_highlight {}; + bool is_active {}; ekg::rect_t rect_text {}; ekg::rect_t rect_box {}; }; public: ekg::value text {}; + ekg::value value {}; ekg::font font_size {ekg::font::medium}; ekg::flags_t box {ekg::dock::none}; - ekg::flags_t dock {}; + ekg::flags_t dock {ekg::dock::left}; ekg::button_t::check_t::widget_t widget {}; ekg::at_array_t layers {}; ekg::at_array_t actions {}; @@ -72,7 +76,7 @@ namespace ekg { ekg::flags_t dock {}; ekg::rect_t rect {}; ekg::at_array_t layers {}; - ekg::at_array_t actions {}; + ekg::at_array_t actions {}; std::vector checks {}; ekg::button_color_scheme_t color_scheme {}; public: diff --git a/include/ekg/ui/property.hpp b/include/ekg/ui/property.hpp index 28f02667..3e4f5064 100644 --- a/include/ekg/ui/property.hpp +++ b/include/ekg/ui/property.hpp @@ -62,8 +62,8 @@ namespace ekg { bool is_focused {}; bool is_warning {}; bool is_high_frequency {}; - bool should_refresh_size {}; - bool should_buffering {}; + bool should_refresh_size {true}; + bool should_buffering {true}; }; public: static ekg::property_t not_found; diff --git a/src/core/pools.cpp b/src/core/pools.cpp index 93e57195..2d7a7aad 100644 --- a/src/core/pools.cpp +++ b/src/core/pools.cpp @@ -31,4 +31,9 @@ void ekg::core::registry(ekg::property_t &property) { ekg::io::operation::swap, property.at ); + + ekg::io::dispatch( + ekg::io::operation::reload, + property.at + ); } diff --git a/src/core/runtime.cpp b/src/core/runtime.cpp index 1a46dd4a..b413daf6 100644 --- a/src/core/runtime.cpp +++ b/src/core/runtime.cpp @@ -181,6 +181,8 @@ void ekg::core::scalenize(ekg::info_t &info) { ) }; + ekg::log() << "Scalenize font size to " << ekg::dpi.font_scale; + if (ekg::p_core->draw_font_medium.font_size != font_size) { ekg::p_core->draw_font_small.set_size( ekg::clamp_min( diff --git a/src/draw/allocator.cpp b/src/draw/allocator.cpp index 332184ad..1b4c844e 100644 --- a/src/draw/allocator.cpp +++ b/src/draw/allocator.cpp @@ -62,13 +62,9 @@ void ekg::draw::allocator::invoke() { this->stride_instance.y = 0; } -void ekg::draw::allocator::bind_texture(ekg::sampler_t &sampler) { - if (sampler == ekg::sampler_t::not_found) { - return; - } - +void ekg::draw::allocator::bind_texture(ekg::at_t &sampler_at) { ekg::gpu::data_t &data {this->gpu_data_buffer.at(this->data_instance)}; - data.sampler_at = ekg::p_core->p_gpu_api->bind_sampler(sampler); + data.sampler_at = ekg::p_core->p_gpu_api->bind_sampler(sampler_at); } void ekg::draw::allocator::dispatch() { diff --git a/src/draw/shape/shape.cpp b/src/draw/shape/shape.cpp index e00839e6..41b1fa1e 100644 --- a/src/draw/shape/shape.cpp +++ b/src/draw/shape/shape.cpp @@ -29,13 +29,13 @@ void ekg::draw::rect( const ekg::rect_t &rect, const ekg::rgba_t &color, ekg::pixel_thickness_t line_thickness, - ekg::sampler_t &sampler + ekg::at_t &sampler_at ) { ekg::draw::rect( rect.x, rect.y, rect.w, rect.h, color, line_thickness, - sampler + sampler_at ); } @@ -43,7 +43,7 @@ void ekg::draw::rect( float x, float y, float w, float h, const ekg::rgba_t &color, ekg::pixel_thickness_t line_thickness, - ekg::sampler_t &sampler + ekg::at_t &sampler_at ) { if (color.w < 10) { return; @@ -66,7 +66,7 @@ void ekg::draw::rect( data.hash = 1; ekg::draw::allocator::is_simple_shape = true; - ekg::p_core->draw_allocator.bind_texture(sampler); + ekg::p_core->draw_allocator.bind_texture(sampler_at); ekg::p_core->draw_allocator.dispatch(); } diff --git a/src/draw/typography/font.cpp b/src/draw/typography/font.cpp index 0b2348f0..806ac689 100644 --- a/src/draw/typography/font.cpp +++ b/src/draw/typography/font.cpp @@ -581,7 +581,7 @@ void ekg::draw::font::blit( this->flush(); ekg::draw::allocator::is_simple_shape = false; - ekg::p_core->draw_allocator.bind_texture(ekg::query(this->atlas_texture_sampler_at)); + ekg::p_core->draw_allocator.bind_texture(this->atlas_texture_sampler_at); ekg::p_core->draw_allocator.dispatch(); } diff --git a/src/ekg.cpp b/src/ekg.cpp index a30e5210..1324ce47 100644 --- a/src/ekg.cpp +++ b/src/ekg.cpp @@ -46,7 +46,7 @@ ekg::flags_t ekg::init( return ekg::result::failed; } - ekg::log() << "Initializing..."; + ekg::log() << "Initializing EKG version " << EKG_VERSION; ekg::p_core = p_runtime; diff --git a/src/gpu/opengl/gl.cpp b/src/gpu/opengl/gl.cpp index 5df0a750..d29b64df 100644 --- a/src/gpu/opengl/gl.cpp +++ b/src/gpu/opengl/gl.cpp @@ -561,7 +561,15 @@ ekg::flags_t ekg::opengl::gen_font_atlas_and_map_glyph( return ekg::result::success; } -ekg::at_t &ekg::opengl::bind_sampler(ekg::sampler_t &sampler) { +ekg::at_t &ekg::opengl::bind_sampler(ekg::at_t &sampler_at) { + ekg::sampler_t &sampler { + ekg::query(sampler_at) + }; + + if (sampler == ekg::sampler_t::not_found) { + return ekg::at_t::not_found; + } + uint64_t size {this->bound_sampler_list.size()}; for (uint64_t it {}; it < this->bound_sampler_list.size(); it++) { ekg::at_t &at {this->bound_sampler_list.at(it)}; @@ -576,7 +584,7 @@ ekg::at_t &ekg::opengl::bind_sampler(ekg::sampler_t &sampler) { sampler.gl_protected_active_index = this->protected_texture_active_index++; } - this->bound_sampler_list.emplace_back() = sampler; + this->bound_sampler_list.emplace_back() = sampler.at; return sampler.at; } diff --git a/src/handler/callback/handler.cpp b/src/handler/callback/handler.cpp index 8ac12fc0..9a1ed3ba 100644 --- a/src/handler/callback/handler.cpp +++ b/src/handler/callback/handler.cpp @@ -81,6 +81,7 @@ void ekg::handler::callback::dispatch(uint64_t index) { void ekg::handler::callback::update() { while (!this->queue.empty()) { ekg::callback_t &callback {ekg::query(this->queue.front())}; + callback.at.flags = 0; this->queue.pop(); if (callback == ekg::callback_t::not_found) { diff --git a/src/handler/theme/handler.cpp b/src/handler/theme/handler.cpp index c3a34b8b..76c915ad 100644 --- a/src/handler/theme/handler.cpp +++ b/src/handler/theme/handler.cpp @@ -42,6 +42,17 @@ void ekg::handler::theme::init() { light_pinky_theme.frame_color_scheme.warning_outline = {242, 242, 0, 100}; light_pinky_theme.frame_color_scheme.actions_margin_pixel_thickness = 18; + light_pinky_theme.button_color_scheme.text_foreground = {141, 141, 141, 255}; + light_pinky_theme.button_color_scheme.background = {204, 204, 204, 50}; + light_pinky_theme.button_color_scheme.active = {245, 169, 184, 100}; + light_pinky_theme.button_color_scheme.outline = {202, 207, 222, 0}; + light_pinky_theme.button_color_scheme.highlight = {245, 169, 184, 50}; + light_pinky_theme.button_color_scheme.text_foreground = {141, 141, 141, 255}; + light_pinky_theme.button_color_scheme.box_outline = light_pinky_theme.button_color_scheme.outline; + light_pinky_theme.button_color_scheme.box_active = {202, 207, 222, 50}; + light_pinky_theme.button_color_scheme.box_highlight = light_pinky_theme.button_color_scheme.highlight; + light_pinky_theme.button_color_scheme.box_background = light_pinky_theme.button_color_scheme.background; + this->registry(light_pinky_theme.tag) = light_pinky_theme; this->set_current_theme(light_pinky_theme.tag); } diff --git a/src/ui/button/widget.cpp b/src/ui/button/widget.cpp index 393dbcb4..647dcad5 100644 --- a/src/ui/button/widget.cpp +++ b/src/ui/button/widget.cpp @@ -28,6 +28,8 @@ #include "ekg/draw/shape/shape.hpp" #include "ekg/draw/typography/font.hpp" #include "ekg/core/context.hpp" +#include "ekg/core/runtime.hpp" +#include "ekg/core/pools.hpp" void ekg::ui::reload( ekg::property_t &property, @@ -78,6 +80,7 @@ void ekg::ui::reload( ); } + button.rect.scaled_height = ekg::max(1, button.rect.scaled_height); button.rect.h = aligned_dimension.h * button.rect.scaled_height; ekg::layout::mask mask {}; @@ -131,25 +134,146 @@ void ekg::ui::event( ) { switch (stage) { case ekg::io::stage::process: { + ekg::input_info_t &input {ekg::p_core->handler_input.input}; + if (!input.has_motion || !input.was_pressed || !input.was_released) { + return; + } + + ekg::vec2_t interact {static_cast>(input.interact)}; ekg::rect_t &abs {ekg::ui::get_abs_rect(property, button.rect)}; - ekg::input_info_t &input {ekg::p_core->handler_input.info}; + ekg::rect_t rect {}; + + bool was_pressed_any {}; + bool was_released_any {}; + bool is_hovering_any {}; + bool is_active_any {}; + bool is_checks_size_equals_to_one {button.checks.size() == 1}; + bool is_checkbox {}; + + for (ekg::button_t::check_t &check : button.checks) { + rect = ( + is_checks_size_equals_to_one + ? + property.widget.rect + : + property.widget.rect + check.widget.rect_text + ); + + is_checkbox = check.box != ekg::dock::none; + if (is_checkbox) { + rect = property.widget.rect + check.widget.rect_box; + } - if (property.widget.is_hovering && input.has_motion) { ekg_action( - button.actions, + check.actions, ekg::action::hover, + ( + check.widget.is_highlight = property.widget.is_hovering && ekg::rect_collide_vec2(rect, interact) + ) + && + (is_hovering_any = true) // make sure it is hovering any + && ekg::timing_t::second > ekg::gui.ui.frequency ); - } - if (!property.widget.is_active && property.widget.is_hovering && input.was_pressed) { + if ( + input.was_pressed + && + check.widget.is_highlight + && + ekg::fire("button-active") + ) { + ekg_action( + check.actions, + ekg::action::press, + ( + check.widget.is_active = true + ) + && + (was_pressed_any = true) + ); + + if (!is_checkbox) { + check.value.set(true); + } + } + + if ( + input.was_released + && + check.widget.is_active + ) { + check.widget.is_active = false; + + ekg_action( + check.actions, + ekg::action::active, + ( + check.widget.is_highlight + ) + && + (is_checkbox ? (check.value.set(!check.value.get())) : (check.value.set(false))) + && + (is_active_any = true) + ); + + ekg_action( + check.actions, + ekg::action::release, + ( + true + ) + && + (was_released_any = true) + ); + } } + ekg_action( + button.actions, + ekg::action::hover, + ( + is_hovering_any && ekg::timing_t::second > ekg::gui.ui.frequency + ) + ); + + ekg_action( + button.actions, + ekg::action::active, + ( + is_active_any + ) + ); + + ekg_action( + button.actions, + ekg::action::press, + ( + was_pressed_any + ) + ); + + ekg_action( + button.actions, + ekg::action::release, + ( + was_released_any + ) + ); + break; } case ekg::io::stage::pre: + ekg::ui::pre_event( + property, + button.rect, + false + ); break; case ekg::io::stage::post: + ekg::ui::post_event( + property + ); break; } } @@ -165,18 +289,151 @@ void ekg::ui::pass( ekg::property_t &property, ekg::button_t &button ) { - + property.widget.should_buffering = true; + for (ekg::button_t::check_t &check : button.checks) { + if (check.value.was_changed()) { + property.widget.should_buffering = true; + return; + } + } } void ekg::ui::buffering( ekg::property_t &property, ekg::button_t &button ) { - + ekg::rect_t &rect_abs { + ekg::ui::get_abs_rect(property, button.rect) + }; + + ekg_assert_scissor( + property.widget.rect_scissor, + rect_abs, + ekg::query(property.parent_at).widget.rect, + true + ); + + ekg::draw::rect( + rect_abs, + button.color_scheme.background, + ekg::draw::mode::fill, + button.layers[ekg::layer::bg] + ); + + ekg::rect_t rect {}; + + bool is_checks_size_equals_to_one {button.checks.size() == 1}; + bool is_checkbox {}; + + for (ekg::button_t::check_t &check : button.checks) { + rect = ( + is_checks_size_equals_to_one + ? + property.widget.rect + : + property.widget.rect + check.widget.rect_text + ); + + is_checkbox = check.box != ekg::dock::none; + if (is_checkbox) { + rect = property.widget.rect + check.widget.rect_box; + ekg::draw::rect( + rect, + button.color_scheme.box_background, + ekg::draw::mode::fill, + check.layers[ekg::layer::bg] + ); + + if (check.widget.is_active) { + ekg::draw::rect( + rect, + button.color_scheme.box_active, + ekg::draw::mode::fill, + check.layers[ekg::layer::active_bg] + ); + } + + if (check.widget.is_highlight) { + ekg::draw::rect( + rect, + button.color_scheme.box_background, + ekg::draw::mode::fill, + check.layers[ekg::layer::highlight_bg] + ); + } + + ekg::draw::rect( + rect, + button.color_scheme.box_outline, + ekg::draw::mode::outline, + check.layers[ekg::layer::outline] + ); + + if (check.widget.is_active) { + ekg::draw::rect( + rect, + button.color_scheme.box_active, + ekg::draw::mode::fill, + check.layers[ekg::layer::active_bg] + ); + } + + ekg::draw::get_font_renderer(check.font_size) + .blit( + check.text.get(), + rect_abs.x + check.widget.rect_text.x, rect_abs.y + check.widget.rect_text.y, + button.color_scheme.text_foreground + ); + } else { + if (!is_checks_size_equals_to_one) { + ekg::draw::rect( + rect, + button.color_scheme.background, + ekg::draw::mode::fill, + check.layers[ekg::layer::bg] + ); + } + + if (check.widget.is_active) { + ekg::draw::rect( + rect, + button.color_scheme.active, + ekg::draw::mode::fill, + check.layers[ekg::layer::active_bg] + ); + } + + if (check.widget.is_highlight) { + ekg::draw::rect( + rect, + button.color_scheme.highlight, + ekg::draw::mode::fill, + check.layers[ekg::layer::highlight_bg] + ); + } + + ekg::draw::get_font_renderer(check.font_size) + .blit( + check.text.get(), + rect_abs.x + check.widget.rect_text.x, rect_abs.y + check.widget.rect_text.y, + button.color_scheme.text_foreground + ); + } + } + + ekg::draw::rect( + rect_abs, + button.color_scheme.outline, + ekg::draw::mode::outline, + button.layers[ekg::layer::bg] + ); } void ekg::ui::unmap( ekg::button_t &button ) { - + for (ekg::button_t::check_t &check : button.checks) { + check.text.ownership(nullptr); + check.value.ownership(nullptr); + } } diff --git a/src/ui/frame/widget.cpp b/src/ui/frame/widget.cpp index 0d03a32d..2f51963f 100644 --- a/src/ui/frame/widget.cpp +++ b/src/ui/frame/widget.cpp @@ -36,12 +36,13 @@ void ekg::ui::reload( ekg::property_t &property, ekg::frame_t &frame ) { - if (property.widget.should_refresh_size) { + if (property.widget.should_refresh_size && static_cast(frame.rect.h) == 0) { frame.rect.h = ekg::layout::get_widget_height_by_children( property ); - property.widget.should_refresh_size = false; } + + property.widget.should_refresh_size = false; } void ekg::ui::event( @@ -310,7 +311,7 @@ void ekg::ui::buffering( rect, property.widget.is_focused ? frame.color_scheme.focused_background : frame.color_scheme.background, ekg::draw::mode::fill, - ekg::sampler_t::not_found + ekg::at_t::not_found ); if (property.widget.is_active) { @@ -318,7 +319,7 @@ void ekg::ui::buffering( rect, frame.color_scheme.highlight, ekg::draw::mode::fill, - ekg::sampler_t::not_found + ekg::at_t::not_found ); } @@ -327,7 +328,7 @@ void ekg::ui::buffering( rect, frame.color_scheme.highlight, ekg::draw::mode::fill, - ekg::sampler_t::not_found + ekg::at_t::not_found ); } @@ -335,7 +336,7 @@ void ekg::ui::buffering( rect, property.widget.is_focused ? frame.color_scheme.focused_outline : frame.color_scheme.outline, ekg::draw::mode::outline, - ekg::sampler_t::not_found + ekg::at_t::not_found ); if (property.widget.is_warning) { @@ -343,7 +344,7 @@ void ekg::ui::buffering( rect, frame.color_scheme.warning_outline, ekg::draw::mode::outline, - ekg::sampler_t::not_found + ekg::at_t::not_found ); } } From ba3465742e7e35803b8fc312d4c333310d052381 Mon Sep 17 00:00:00 2001 From: mrsrina Date: Sun, 8 Jun 2025 22:24:48 -0300 Subject: [PATCH 3/5] [feature] smart-caching for allocator; button impl ok --- include/ekg/draw/allocator.hpp | 24 ++++- include/ekg/gpu/data.hpp | 6 +- include/ekg/gpu/sampler.hpp | 4 +- include/ekg/io/event.hpp | 2 + include/ekg/ui/property.hpp | 3 + src/core/runtime.cpp | 4 +- src/draw/allocator.cpp | 173 +++++++++++++++------------------ src/draw/typography/font.cpp | 3 +- src/ekg.cpp | 3 - src/gpu/opengl/gl.cpp | 6 +- src/gpu/opengl/shaders.cpp | 4 +- src/handler/theme/handler.cpp | 1 + src/ui/button/widget.cpp | 33 +++++-- src/ui/frame/widget.cpp | 12 ++- 14 files changed, 162 insertions(+), 116 deletions(-) diff --git a/include/ekg/draw/allocator.hpp b/include/ekg/draw/allocator.hpp index 1d8104b1..7cc20239 100644 --- a/include/ekg/draw/allocator.hpp +++ b/include/ekg/draw/allocator.hpp @@ -34,15 +34,23 @@ * This macro prevent from dispatching any GPU-data under a render section * if the content is not visible to the parent rect_scissor. **/ -#define ekg_assert_scissor(rect_scissor, rect_child, rect_parent, is_parented) \ +#define ekg_draw_allocator_assert_scissor(rect_scissor, rect_child, rect_parent, is_parented) \ if (!ekg::p_core->draw_allocator.sync_scissor(rect_scissor, rect_child, rect_parent, is_parented)) return; +#define ekg_draw_allocator_bind_local(p_geometry_buffer, p_gpu_data_buffer) \ + ekg::p_core->draw_allocator.bind_local(p_geometry_buffer, p_gpu_data_buffer); + +#define ekg_draw_allocator_pass() \ + ekg::p_core->draw_allocator.pass(); \ + return; + namespace ekg::draw { class allocator { public: static bool enable_high_priority; static bool is_simple_shape; protected: + size_t global_data_instance {}; size_t data_instance {}; ekg::vec2_t stride_instance {}; size_t simple_shape_instance {}; @@ -53,7 +61,12 @@ namespace ekg::draw { std::vector gpu_data_buffer {}; std::vector high_priority_gpu_data_buffer {}; std::vector geometry_buffer {}; + + std::vector *p_local_geometry_buffer {}; + std::vector *p_local_gpu_data_buffer {}; + size_t last_geometry_buffer_size {}; + size_t memory_block_offset_counter {}; bool was_hash_changed {}; int32_t previous_hash {}; @@ -66,11 +79,14 @@ namespace ekg::draw { void to_gpu(); void bind_texture(ekg::at_t &sampler_at); + void bind_local( + std::vector *p_geometry_buffer, + std::vector *p_gpu_data_buffer + ); + ekg::gpu::data_t &bind_current_data(); - size_t get_current_data_id(); - ekg::gpu::data_t &get_data_by_index(size_t index); - void clear_current_data(); void dispatch(); + void pass(); bool sync_scissor( ekg::rect_t &rect_scissor, diff --git a/include/ekg/gpu/data.hpp b/include/ekg/gpu/data.hpp index 65ee15e9..e2150510 100644 --- a/include/ekg/gpu/data.hpp +++ b/include/ekg/gpu/data.hpp @@ -32,11 +32,15 @@ namespace ekg::gpu { public: static ekg::gpu::data_t not_found; public: - float buffer[12] {}; ekg::at_t sampler_at {ekg::at_t::not_found}; + public: + float buffer[12] {}; int8_t line_thickness {}; int32_t begin_stride {}; int32_t end_stride {}; + int32_t prev_mem_block_size {}; + int32_t mem_block_offset {}; + bool is_new {}; ekg::hash_t hash {}; int32_t scissor_id {-1}; public: diff --git a/include/ekg/gpu/sampler.hpp b/include/ekg/gpu/sampler.hpp index 1aef96f8..3f755d6c 100644 --- a/include/ekg/gpu/sampler.hpp +++ b/include/ekg/gpu/sampler.hpp @@ -34,7 +34,7 @@ namespace ekg { static constexpr ekg::type type {ekg::type::sampler}; static ekg::sampler_t not_found; public: - const char *p_tag {}; + std::string tag {}; uint32_t w {}; uint32_t h {}; uint32_t channel {}; @@ -47,7 +47,7 @@ namespace ekg { struct sampler_info_t { public: - const char *p_tag {}; + std::string tag {}; int32_t offset[2] {}; int32_t w {}; int32_t h {}; diff --git a/include/ekg/io/event.hpp b/include/ekg/io/event.hpp index 00136822..d16bbf12 100644 --- a/include/ekg/io/event.hpp +++ b/include/ekg/io/event.hpp @@ -132,6 +132,8 @@ namespace ekg::io { }; } + #define ekg_action(actions, action, state) if (state) ekg::io::dispatch(actions[action]); +#define ekg_set(should_rebuffering, state, new_state) ((state != new_state) && (should_rebuffering = true) && ((state = new_state) || true)) #endif diff --git a/include/ekg/ui/property.hpp b/include/ekg/ui/property.hpp index 3e4f5064..cb50f0cb 100644 --- a/include/ekg/ui/property.hpp +++ b/include/ekg/ui/property.hpp @@ -26,6 +26,7 @@ #include "ekg/io/descriptor.hpp" #include "ekg/math/geometry.hpp" +#include "ekg/gpu/data.hpp" namespace ekg { struct property_t { @@ -47,6 +48,8 @@ namespace ekg { struct widget_t { public: + std::vector geometry_buffer {}; + std::vector gpu_data_buffer {}; ekg::rect_t rect_scissor {}; ekg::vec2_t min_size {}; ekg::rect_t rect {}; diff --git a/src/core/runtime.cpp b/src/core/runtime.cpp index b413daf6..734896dd 100644 --- a/src/core/runtime.cpp +++ b/src/core/runtime.cpp @@ -181,9 +181,9 @@ void ekg::core::scalenize(ekg::info_t &info) { ) }; - ekg::log() << "Scalenize font size to " << ekg::dpi.font_scale; - if (ekg::p_core->draw_font_medium.font_size != font_size) { + ekg::log() << "Scalenize font size updated from-to: " << ekg::p_core->draw_font_medium.font_size << ' ' << font_size; + ekg::p_core->draw_font_small.set_size( ekg::clamp_min( font_size - ekg::dpi.font_offset.x, diff --git a/src/draw/allocator.cpp b/src/draw/allocator.cpp index 1b4c844e..e2434b01 100644 --- a/src/draw/allocator.cpp +++ b/src/draw/allocator.cpp @@ -44,52 +44,85 @@ void ekg::draw::allocator::invoke() { this->stride_instance.y = 0; this->simple_shape_instance = 0; this->geometry_instance = 0; + this->global_data_instance = 0; + this->gpu_data_buffer.clear(); + this->geometry_buffer.clear(); /** * inserting a simple triangle mesh, * is necessary to make work the simple-shape rendering. **/ + this->p_local_geometry_buffer = &this->geometry_buffer; this->push_back_geometry(0.0f, 0.0f, 0.0f, 0.0f); this->push_back_geometry(0.0f, 1.0f, 0.0f, 1.0f); this->push_back_geometry(1.0f, 0.0f, 1.0f, 0.0f); this->push_back_geometry(1.0f, 1.0f, 1.0f, 1.0f); - - if (this->data_instance >= this->gpu_data_buffer.size()) { - this->gpu_data_buffer.emplace_back(); - } + this->p_local_geometry_buffer = nullptr; this->stride_instance.x += this->stride_instance.y; this->stride_instance.y = 0; } void ekg::draw::allocator::bind_texture(ekg::at_t &sampler_at) { - ekg::gpu::data_t &data {this->gpu_data_buffer.at(this->data_instance)}; + ekg::gpu::data_t &data {this->p_local_gpu_data_buffer->at(this->data_instance)}; data.sampler_at = ekg::p_core->p_gpu_api->bind_sampler(sampler_at); } -void ekg::draw::allocator::dispatch() { - ekg::gpu::data_t *p_data {/* stupid */}; +void ekg::draw::allocator::revoke() { + if ( + this->last_geometry_buffer_size != this->geometry_instance + || + this->was_hash_changed + ) { + ekg::p_core->p_gpu_api->pass_geometry_buffer_to_gpu( + this->geometry_buffer.data(), + this->geometry_buffer.size() + ); + } - if (ekg::draw::allocator::enable_high_priority) { - this->high_priority_gpu_data_buffer.push_back(this->gpu_data_buffer.at(this->data_instance)); + this->last_geometry_buffer_size = this->geometry_instance; + this->was_hash_changed = false; + ekg::metrics.gpu_data_count = this->data_instance; +} - p_data = ( - &this->high_priority_gpu_data_buffer.at(this->high_priority_data_instance) - ); +void ekg::draw::allocator::to_gpu() { + ekg::p_core->p_gpu_api->pass_gpu_data_buffer_to_gpu( + this->gpu_data_buffer + ); +} - this->data_instance -= this->data_instance > 0; - this->high_priority_data_instance++; - } else { - p_data = &this->gpu_data_buffer.at(this->data_instance); +void ekg::draw::allocator::bind_local( + std::vector *p_geometry_buffer, + std::vector *p_gpu_data_buffer +) { + this->p_local_geometry_buffer = p_geometry_buffer; + this->p_local_gpu_data_buffer = p_gpu_data_buffer; + this->p_local_geometry_buffer->clear(); + this->data_instance = 0; +} + +ekg::gpu::data_t &ekg::draw::allocator::bind_current_data() { + if (this->data_instance >= this->p_local_gpu_data_buffer->size()) { + this->p_local_gpu_data_buffer->emplace_back().is_new = true; } + ekg::gpu::data_t &data {this->p_local_gpu_data_buffer->at(this->data_instance)}; + data.line_thickness = 0; + data.sampler_at = ekg::sampler_t::not_found; + this->previous_hash = data.hash; + return data; +} + +void ekg::draw::allocator::dispatch() { + ekg::gpu::data_t &data {this->p_local_gpu_data_buffer->at(this->data_instance)}; + /** * Scissor must be externally synchned. **/ - p_data->buffer[8] = this->scissor_instance.x; - p_data->buffer[9] = this->scissor_instance.y; - p_data->buffer[10] = this->scissor_instance.w; - p_data->buffer[11] = this->scissor_instance.h; + data.buffer[8] = this->scissor_instance.x; + data.buffer[9] = this->scissor_instance.y; + data.buffer[10] = this->scissor_instance.w; + data.buffer[11] = this->scissor_instance.h; /** * the point of re-using a simple shape stride makes performance a little better, @@ -102,22 +135,22 @@ void ekg::draw::allocator::dispatch() { /** * Simple shade contains only 4 vertices because it is indexed-rendered. **/ - p_data->begin_stride = this->simple_shape_instance; - p_data->end_stride = 4; + data.begin_stride = this->simple_shape_instance; + data.end_stride = 4; } else { /** * Peek `ekg/gpu/gl/shaders.cpp`. * Any value less than -1.0 is considered a concave by the vertex shader. **/ - p_data->buffer[3] = -1.1f; + data.buffer[3] = -1.1f; - p_data->begin_stride = this->stride_instance.x; - p_data->end_stride = this->stride_instance.y; + data.begin_stride = this->stride_instance.x; + data.end_stride = this->stride_instance.y; } if (!this->was_hash_changed) { this->was_hash_changed = ( - this->previous_hash != p_data->hash + this->previous_hash != data.hash ); } @@ -126,75 +159,31 @@ void ekg::draw::allocator::dispatch() { this->data_instance++; } -void ekg::draw::allocator::revoke() { - this->data_instance -= this->data_instance > 0; +void ekg::draw::allocator::pass() { + if (!this->p_local_gpu_data_buffer->empty()) { + ekg::gpu::data_t &data {this->p_local_gpu_data_buffer->at(0)}; + if ( + !data.is_new + ) { + data.mem_block_offset = this->p_local_geometry_buffer->size() - data.prev_mem_block_size; + } - if (!this->high_priority_gpu_data_buffer.empty()) { - uint64_t high_priority_gpu_data_buffer_size { - this->high_priority_gpu_data_buffer.size() - }; + data.prev_mem_block_size = this->p_local_geometry_buffer->size(); this->gpu_data_buffer.insert( - this->gpu_data_buffer.begin() + this->data_instance + 1, - this->high_priority_gpu_data_buffer.begin(), - this->high_priority_gpu_data_buffer.end() + this->gpu_data_buffer.end(), + this->p_local_gpu_data_buffer->begin(), + this->p_local_gpu_data_buffer->end() ); - - this->data_instance += high_priority_gpu_data_buffer_size; - this->high_priority_gpu_data_buffer.clear(); - this->high_priority_data_instance = 0; - } - - if ( - this->last_geometry_buffer_size != this->geometry_instance - || - this->was_hash_changed - ) { - ekg::p_core->p_gpu_api->pass_geometry_buffer_to_gpu( - this->geometry_buffer.data(), - this->geometry_buffer.size() + + this->geometry_buffer.insert( + this->geometry_buffer.end(), + this->p_local_geometry_buffer->begin(), + this->p_local_geometry_buffer->end() ); - } - - this->last_geometry_buffer_size = this->geometry_instance; - this->was_hash_changed = false; - ekg::metrics.gpu_data_count = this->data_instance; -} - -void ekg::draw::allocator::to_gpu() { - ekg::p_core->p_gpu_api->pass_gpu_data_buffer_to_gpu( - this->gpu_data_buffer - ); -} - -void ekg::draw::allocator::clear_current_data() { - if (!ekg::draw::allocator::enable_high_priority && this->data_instance >= this->gpu_data_buffer.size()) { - this->gpu_data_buffer.emplace_back(); - } - - /* allocator handle automatically the size of data */ - ekg::gpu::data_t &data {this->gpu_data_buffer.at(this->data_instance)}; - data.line_thickness = 0; - data.sampler_at = ekg::sampler_t::not_found; - - this->previous_hash = data.hash; -} -ekg::gpu::data_t &ekg::draw::allocator::bind_current_data() { - this->clear_current_data(); - return this->gpu_data_buffer.at(this->data_instance); -} - -size_t ekg::draw::allocator::get_current_data_id() { - return this->data_instance; -} - -ekg::gpu::data_t &ekg::draw::allocator::get_data_by_index(size_t index) { - if (index >= this->gpu_data_buffer.size()) { - return ekg::gpu::data_t::not_found; + this->global_data_instance += this->gpu_data_buffer.size(); } - - return this->gpu_data_buffer[index]; } bool ekg::draw::allocator::sync_scissor( @@ -268,9 +257,9 @@ void ekg::draw::allocator::push_back_geometry( float u, float v ) { this->stride_instance.y++; - this->geometry_buffer.push_back(x); - this->geometry_buffer.push_back(y); - this->geometry_buffer.push_back(u); - this->geometry_buffer.push_back(v); + this->p_local_geometry_buffer->push_back(x); + this->p_local_geometry_buffer->push_back(y); + this->p_local_geometry_buffer->push_back(u); + this->p_local_geometry_buffer->push_back(v); this->geometry_instance += 4; } diff --git a/src/draw/typography/font.cpp b/src/draw/typography/font.cpp index 806ac689..90e79120 100644 --- a/src/draw/typography/font.cpp +++ b/src/draw/typography/font.cpp @@ -263,7 +263,6 @@ void ekg::draw::font::set_font(const std::string_view &path) { font_face.path = path; font_face.was_face_changed = true; font_face.was_size_changed = true; - this->reload(); } } @@ -306,6 +305,8 @@ void ekg::draw::font::reload() { if (this->atlas_texture_sampler_at == ekg::at_t::not_found) { ekg::sampler_t &sampler {ekg::make({})}; this->atlas_texture_sampler_at = sampler.at; + sampler.tag = "font-renderer"; + sampler.gl_protected_active_index = true; } size_t functional_fonts {}; diff --git a/src/ekg.cpp b/src/ekg.cpp index 1324ce47..7a2e2c54 100644 --- a/src/ekg.cpp +++ b/src/ekg.cpp @@ -67,17 +67,14 @@ ekg::flags_t ekg::init( ekg::p_core->draw_font_small.init(); ekg::p_core->draw_font_small.set_font(runtime_properties_info.default_font_path_text); ekg::p_core->draw_font_small.set_font_emoji(runtime_properties_info.default_font_path_emoji); - ekg::p_core->draw_font_small.get_atlas_texture_sampler().gl_protected_active_index = true;; ekg::p_core->draw_font_medium.init(); ekg::p_core->draw_font_medium.set_font(runtime_properties_info.default_font_path_text); ekg::p_core->draw_font_medium.set_font_emoji(runtime_properties_info.default_font_path_emoji); - ekg::p_core->draw_font_medium.get_atlas_texture_sampler().gl_protected_active_index = true;; ekg::p_core->draw_font_big.init(); ekg::p_core->draw_font_big.set_font(runtime_properties_info.default_font_path_text); ekg::p_core->draw_font_big.set_font_emoji(runtime_properties_info.default_font_path_emoji); - ekg::p_core->draw_font_big.get_atlas_texture_sampler().gl_protected_active_index = true; ekg::info_t info {}; ekg::core::scalenize(info); diff --git a/src/gpu/opengl/gl.cpp b/src/gpu/opengl/gl.cpp index d29b64df..cc702890 100644 --- a/src/gpu/opengl/gl.cpp +++ b/src/gpu/opengl/gl.cpp @@ -345,7 +345,7 @@ ekg::flags_t ekg::opengl::allocate_sampler( glBindTexture(GL_TEXTURE_2D, 0); - sampler.p_tag = sampler_allocate_info.p_tag; + sampler.tag = sampler_allocate_info.tag; return ekg::result::success; } @@ -584,6 +584,8 @@ ekg::at_t &ekg::opengl::bind_sampler(ekg::at_t &sampler_at) { sampler.gl_protected_active_index = this->protected_texture_active_index++; } + ekg::log() << sampler.tag; + this->bound_sampler_list.emplace_back() = sampler.at; return sampler.at; } @@ -617,7 +619,7 @@ void ekg::opengl::pass_gpu_data_buffer_to_gpu( glActiveTexture(GL_TEXTURE0 + this->protected_texture_active_index); - ekg::at_t previous_sampler_bound {.unique_id = ekg::not_found}; + ekg::at_t previous_sampler_bound {.index = UINT64_MAX}; bool sampler_going_on {}; for (ekg::gpu::data_t &data : gpu_data_buffer) { diff --git a/src/gpu/opengl/shaders.cpp b/src/gpu/opengl/shaders.cpp index 2d668508..842c6ee6 100644 --- a/src/gpu/opengl/shaders.cpp +++ b/src/gpu/opengl/shaders.cpp @@ -175,7 +175,7 @@ void ekg::gpu::glsl_opengl_pipeline_fsh( textureColor.a - (1.0f - aFragColor.a) ); - //aFragColor = vec4(aFragColor.a, 0.0f, 0.0f, 1.0f); + //aFragColor = vec4(0.0f, 1.0f, 0.0f, 1.0f); break; case 2: textureColor = texture(uTextureSampler, vPos); @@ -184,6 +184,8 @@ void ekg::gpu::glsl_opengl_pipeline_fsh( textureColor.rgb, textureColor.a - (1.0f - aFragColor.a) ); + + //aFragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f); break; } } diff --git a/src/handler/theme/handler.cpp b/src/handler/theme/handler.cpp index 76c915ad..0bfe5f0b 100644 --- a/src/handler/theme/handler.cpp +++ b/src/handler/theme/handler.cpp @@ -33,6 +33,7 @@ void ekg::handler::theme::init() { .description = "Pasted light-theme... moow", }; + light_pinky_theme.layout_offset = 2.0f; light_pinky_theme.frame_color_scheme.background = {242, 242, 242, 255}; light_pinky_theme.frame_color_scheme.highlight = {242, 242, 242, 0}; light_pinky_theme.frame_color_scheme.outline = {190, 190, 190, 0}; diff --git a/src/ui/button/widget.cpp b/src/ui/button/widget.cpp index 647dcad5..70509f08 100644 --- a/src/ui/button/widget.cpp +++ b/src/ui/button/widget.cpp @@ -168,10 +168,14 @@ void ekg::ui::event( check.actions, ekg::action::hover, ( - check.widget.is_highlight = property.widget.is_hovering && ekg::rect_collide_vec2(rect, interact) + ekg_set( + property.widget.should_buffering, + check.widget.is_highlight, + property.widget.is_hovering && ekg::rect_collide_vec2(rect, interact) + ) ) && - (is_hovering_any = true) // make sure it is hovering any + (is_hovering_any = true) && ekg::timing_t::second > ekg::gui.ui.frequency ); @@ -187,7 +191,11 @@ void ekg::ui::event( check.actions, ekg::action::press, ( - check.widget.is_active = true + ekg_set( + property.widget.should_buffering, + check.widget.is_active, + true + ) ) && (was_pressed_any = true) @@ -203,7 +211,11 @@ void ekg::ui::event( && check.widget.is_active ) { - check.widget.is_active = false; + ekg_set( + property.widget.should_buffering, + check.widget.is_active, + false + ); ekg_action( check.actions, @@ -289,13 +301,20 @@ void ekg::ui::pass( ekg::property_t &property, ekg::button_t &button ) { - property.widget.should_buffering = true; + ekg_draw_allocator_bind_local(&property.widget.geometry_buffer, &property.widget.gpu_data_buffer); + + if (property.widget.should_buffering) { + return; + } + for (ekg::button_t::check_t &check : button.checks) { if (check.value.was_changed()) { property.widget.should_buffering = true; return; } } + + ekg_draw_allocator_pass(); } void ekg::ui::buffering( @@ -306,7 +325,7 @@ void ekg::ui::buffering( ekg::ui::get_abs_rect(property, button.rect) }; - ekg_assert_scissor( + ekg_draw_allocator_assert_scissor( property.widget.rect_scissor, rect_abs, ekg::query(property.parent_at).widget.rect, @@ -427,6 +446,8 @@ void ekg::ui::buffering( ekg::draw::mode::outline, button.layers[ekg::layer::bg] ); + + ekg_draw_allocator_pass(); } void ekg::ui::unmap( diff --git a/src/ui/frame/widget.cpp b/src/ui/frame/widget.cpp index 2f51963f..d2164035 100644 --- a/src/ui/frame/widget.cpp +++ b/src/ui/frame/widget.cpp @@ -291,7 +291,13 @@ void ekg::ui::pass( ekg::property_t &property, ekg::frame_t &frame ) { - property.widget.should_buffering = true; + ekg_draw_allocator_bind_local(&property.widget.geometry_buffer, &property.widget.gpu_data_buffer); + + if (property.widget.should_buffering) { + return; + } + + ekg_draw_allocator_pass(); } void ekg::ui::buffering( @@ -300,7 +306,7 @@ void ekg::ui::buffering( ) { ekg::rect_t &rect {ekg::ui::get_abs_rect(property, frame.rect)}; - ekg_assert_scissor( + ekg_draw_allocator_assert_scissor( property.widget.rect_scissor, rect, ekg::query(property.parent_at).widget.rect, @@ -347,6 +353,8 @@ void ekg::ui::buffering( ekg::at_t::not_found ); } + + ekg_draw_allocator_pass(); } void ekg::ui::unmap( From 64dd5b9a17e08e3d2ee32af457a5d24ddd3cf25b Mon Sep 17 00:00:00 2001 From: mrsrina Date: Sun, 8 Jun 2025 22:40:13 -0300 Subject: [PATCH 4/5] [fix] docknize --- include/ekg/core/pools.hpp | 5 ++++- include/ekg/handler/theme.hpp | 2 +- include/ekg/io/event.hpp | 3 ++- include/ekg/io/memory.hpp | 2 +- include/ekg/ui/button/button.hpp | 4 ++-- include/ekg/ui/property.hpp | 4 ++-- src/core/pools.cpp | 5 +++++ src/core/runtime.cpp | 10 ++++++---- src/draw/allocator.cpp | 3 ++- src/gpu/opengl/gl.cpp | 2 ++ src/handler/theme/handler.cpp | 1 + src/layout/docknize.cpp | 10 +++++++++- src/layout/extentnize.cpp | 8 +++++--- src/ui/abstract.cpp | 2 +- src/ui/button/widget.cpp | 14 ++++++++------ src/ui/frame/widget.cpp | 2 ++ 16 files changed, 53 insertions(+), 24 deletions(-) diff --git a/include/ekg/core/pools.hpp b/include/ekg/core/pools.hpp index 6b57d754..19c73f62 100644 --- a/include/ekg/core/pools.hpp +++ b/include/ekg/core/pools.hpp @@ -96,11 +96,14 @@ namespace ekg::core { if (parent != ekg::property_t::not_found && widget.dock != ekg::dock::none) { \ parent.children.push_back(widget.at); \ property.parent_at = ekg::gui.bind.parent_at; \ + property.abs_parent_at = parent.abs_parent_at; \ } else { \ - ekg::gui.bind.parent_at = widget.at; \ + ekg::gui.bind.parent_at = property.at; \ + property.abs_parent_at = property.at; \ } \ } else if (parent != ekg::property_t::not_found) { \ property.parent_at = ekg::gui.bind.parent_at; \ + property.abs_parent_at = parent.abs_parent_at; \ parent.children.push_back(widget.at); \ } \ \ diff --git a/include/ekg/handler/theme.hpp b/include/ekg/handler/theme.hpp index af8e7ce9..10fa4b72 100644 --- a/include/ekg/handler/theme.hpp +++ b/include/ekg/handler/theme.hpp @@ -35,7 +35,7 @@ namespace ekg { std::string description {}; public: float layout_offset {}; - ekg::pixel_t layout_margin_thickness {}; + ekg::pixel_t layout_margin_thickness {2}; ekg::button_color_scheme_t button_color_scheme {}; ekg::frame_color_scheme_t frame_color_scheme {}; }; diff --git a/include/ekg/io/event.hpp b/include/ekg/io/event.hpp index d16bbf12..c2ff5b44 100644 --- a/include/ekg/io/event.hpp +++ b/include/ekg/io/event.hpp @@ -26,6 +26,7 @@ #include "ekg/handler/input.hpp" #include "ekg/handler/callback.hpp" +#include "ekg/core/context.hpp" #include @@ -134,6 +135,6 @@ namespace ekg::io { #define ekg_action(actions, action, state) if (state) ekg::io::dispatch(actions[action]); -#define ekg_set(should_rebuffering, state, new_state) ((state != new_state) && (should_rebuffering = true) && ((state = new_state) || true)) +#define ekg_set(should_rebuffering, state, new_state) ((state != new_state) && (ekg::gui.ui.redraw = true) && (should_rebuffering = true) && ((state = new_state) || true)) #endif diff --git a/include/ekg/io/memory.hpp b/include/ekg/io/memory.hpp index 2b558044..da50c365 100644 --- a/include/ekg/io/memory.hpp +++ b/include/ekg/io/memory.hpp @@ -58,7 +58,7 @@ namespace ekg { template constexpr bool has(ekg::flags_t bits, t bit) { - return (bits & bit) == bit; + return (bits & bit) >= bit; } template diff --git a/include/ekg/ui/button/button.hpp b/include/ekg/ui/button/button.hpp index 8ccf1653..4e546d61 100644 --- a/include/ekg/ui/button/button.hpp +++ b/include/ekg/ui/button/button.hpp @@ -63,7 +63,7 @@ namespace ekg { ekg::flags_t box {ekg::dock::none}; ekg::flags_t dock {ekg::dock::left}; ekg::button_t::check_t::widget_t widget {}; - ekg::at_array_t layers {}; + ekg::at_array_t layers {}; ekg::at_array_t actions {}; }; @@ -73,7 +73,7 @@ namespace ekg { ekg::at_t property_at {}; public: std::string tag {}; - ekg::flags_t dock {}; + ekg::flags_t dock {ekg::dock::left | ekg::dock::fill}; ekg::rect_t rect {}; ekg::at_array_t layers {}; ekg::at_array_t actions {}; diff --git a/include/ekg/ui/property.hpp b/include/ekg/ui/property.hpp index cb50f0cb..95d7d920 100644 --- a/include/ekg/ui/property.hpp +++ b/include/ekg/ui/property.hpp @@ -59,8 +59,8 @@ namespace ekg { bool is_absolute {}; bool is_active {}; bool is_hovering {}; - bool is_visible {}; - bool is_enabled {}; + bool is_visible {true}; + bool is_enabled {true}; bool is_highlight {}; bool is_focused {}; bool is_warning {}; diff --git a/src/core/pools.cpp b/src/core/pools.cpp index 2d7a7aad..52147054 100644 --- a/src/core/pools.cpp +++ b/src/core/pools.cpp @@ -36,4 +36,9 @@ void ekg::core::registry(ekg::property_t &property) { ekg::io::operation::reload, property.at ); + + ekg::io::dispatch( + ekg::io::operation::docknize, + property.abs_parent_at + ); } diff --git a/src/core/runtime.cpp b/src/core/runtime.cpp index 734896dd..57e5da3d 100644 --- a/src/core/runtime.cpp +++ b/src/core/runtime.cpp @@ -69,9 +69,9 @@ void ekg::core::swap(ekg::info_t &info) { return; } - bool was_found {}; - ekg::p_core->top_level_stack.clear(); + ekg::p_core->stack.clear(); + bool was_found {}; for (ekg::at_t &at : ekg::p_core->registry) { ekg::property_t &property {ekg::query(at)}; @@ -84,6 +84,7 @@ void ekg::core::swap(ekg::info_t &info) { } // recurse + was_found = false; ekg::p_core->collector.clear(); ekg::core::swap_collector(was_found, at); @@ -108,6 +109,7 @@ void ekg::core::swap(ekg::info_t &info) { ekg::p_core->top_level_stack.end() ); + ekg::p_core->top_level_stack.clear(); ekg::p_core->collector.clear(); ekg::gui.bind.swap_at = ekg::at_t::not_found; } @@ -140,9 +142,9 @@ void ekg::core::docknize(ekg::info_t &info) { return; } - for (ekg::at_t &at : ekg::p_core->reload) { + for (ekg::at_t &at : ekg::p_core->docknize) { ekg::property_t &property {ekg::query(at)}; - if (property == ekg::property_t::not_found) { + if (property == ekg::property_t::not_found || !property.operation.should_docknize) { continue; } diff --git a/src/draw/allocator.cpp b/src/draw/allocator.cpp index e2434b01..a27c03c5 100644 --- a/src/draw/allocator.cpp +++ b/src/draw/allocator.cpp @@ -45,6 +45,7 @@ void ekg::draw::allocator::invoke() { this->simple_shape_instance = 0; this->geometry_instance = 0; this->global_data_instance = 0; + this->gpu_data_buffer.clear(); this->geometry_buffer.clear(); @@ -173,7 +174,7 @@ void ekg::draw::allocator::pass() { this->gpu_data_buffer.insert( this->gpu_data_buffer.end(), this->p_local_gpu_data_buffer->begin(), - this->p_local_gpu_data_buffer->end() + this->p_local_gpu_data_buffer->begin() + this->data_instance ); this->geometry_buffer.insert( diff --git a/src/gpu/opengl/gl.cpp b/src/gpu/opengl/gl.cpp index cc702890..8a0deff1 100644 --- a/src/gpu/opengl/gl.cpp +++ b/src/gpu/opengl/gl.cpp @@ -625,6 +625,8 @@ void ekg::opengl::pass_gpu_data_buffer_to_gpu( for (ekg::gpu::data_t &data : gpu_data_buffer) { sampler_going_on = data.sampler_at != ekg::at_t::not_found; + //ekg_log_low_level(" meow " << data.mem_block_offset); + if ( sampler_going_on && diff --git a/src/handler/theme/handler.cpp b/src/handler/theme/handler.cpp index 0bfe5f0b..4c90f0fe 100644 --- a/src/handler/theme/handler.cpp +++ b/src/handler/theme/handler.cpp @@ -34,6 +34,7 @@ void ekg::handler::theme::init() { }; light_pinky_theme.layout_offset = 2.0f; + light_pinky_theme.layout_margin_thickness = 2; light_pinky_theme.frame_color_scheme.background = {242, 242, 242, 255}; light_pinky_theme.frame_color_scheme.highlight = {242, 242, 242, 0}; light_pinky_theme.frame_color_scheme.outline = {190, 190, 190, 0}; diff --git a/src/layout/docknize.cpp b/src/layout/docknize.cpp index f5cc29b4..a63d9fec 100644 --- a/src/layout/docknize.cpp +++ b/src/layout/docknize.cpp @@ -274,6 +274,14 @@ void ekg::layout::docknize_widget( return; } + if (parent_property.widget.should_refresh_size) { + ekg_abstract_todo( + parent_property.descriptor_at.flags, + parent_property.descriptor_at, + ekg::ui::reload(parent_property, descriptor); + ); + } + if (parent_property.widget.rect.w == 0.0f || parent_property.widget.rect.h == 0.0f) { return; } @@ -403,7 +411,7 @@ void ekg::layout::docknize_widget( ekg::layout::extentnize_widget( parent_property, ekg::dock::fill, - ekg::dock::next | (is_top ? ekg::dock::bottom : ekg::dock::top), + (is_top ? ekg::dock::bottom : ekg::dock::bottom), ekg::axis::horizontal, extent, count diff --git a/src/layout/extentnize.cpp b/src/layout/extentnize.cpp index 062f461a..8b44a2ab 100644 --- a/src/layout/extentnize.cpp +++ b/src/layout/extentnize.cpp @@ -64,6 +64,7 @@ void ekg::layout::extentnize_mask( bool is_last_index {}; bool is_ok_flag {}; + bool is_stop_flag {}; extent += offset.x; @@ -74,15 +75,16 @@ void ekg::layout::extentnize_mask( } is_last_index = it == latest_index; + is_stop_flag = ekg::has(component.dock, ekg::dock::next) || ekg::has(component.dock, flag_stop); if ( - (ekg::has(component.dock, flag_stop) && it != in_out_count) + (is_stop_flag && it != in_out_count) || is_last_index ) { extent -= offset.x; flag_ok_count += ( - (is_ok_flag = (!ekg::has(component.dock, flag_stop) && (ekg::has(component.dock, flag_ok)) && is_last_index)) + (is_ok_flag = (!is_stop_flag && (ekg::has(component.dock, flag_ok)) && is_last_index)) ); /** @@ -190,7 +192,7 @@ void ekg::layout::extentnize_widget( ); is_ok = ekg::has(dock, flag_ok); - is_stop = ekg::has(dock, flag_stop); + is_stop = ekg::has(dock, ekg::dock::next) || ekg::has(dock, flag_stop); if ( (is_stop && it != in_out_count) diff --git a/src/ui/abstract.cpp b/src/ui/abstract.cpp index 0f6188db..1e5ee9a7 100644 --- a/src/ui/abstract.cpp +++ b/src/ui/abstract.cpp @@ -62,7 +62,7 @@ void ekg::ui::pre_event( || property.parent_at == ekg::at_t::not_found || - ekg::rect_collide_vec2(property.widget.rect_scissor, interact) + ekg::rect_collide_vec2(property.widget.rect_scissor, interact) ) ); } diff --git a/src/ui/button/widget.cpp b/src/ui/button/widget.cpp index 70509f08..daf509dc 100644 --- a/src/ui/button/widget.cpp +++ b/src/ui/button/widget.cpp @@ -135,7 +135,7 @@ void ekg::ui::event( switch (stage) { case ekg::io::stage::process: { ekg::input_info_t &input {ekg::p_core->handler_input.input}; - if (!input.has_motion || !input.was_pressed || !input.was_released) { + if (!input.has_motion && !input.was_pressed && !input.was_released) { return; } @@ -164,15 +164,17 @@ void ekg::ui::event( rect = property.widget.rect + check.widget.rect_box; } + ekg_set( + property.widget.should_buffering, + check.widget.is_highlight, + (property.widget.is_hovering && ekg::rect_collide_vec2(rect, interact)) + ); + ekg_action( check.actions, ekg::action::hover, ( - ekg_set( - property.widget.should_buffering, - check.widget.is_highlight, - property.widget.is_hovering && ekg::rect_collide_vec2(rect, interact) - ) + check.widget.is_highlight ) && (is_hovering_any = true) diff --git a/src/ui/frame/widget.cpp b/src/ui/frame/widget.cpp index d2164035..ee8a5a3a 100644 --- a/src/ui/frame/widget.cpp +++ b/src/ui/frame/widget.cpp @@ -36,6 +36,8 @@ void ekg::ui::reload( ekg::property_t &property, ekg::frame_t &frame ) { + ekg::ui::get_abs_rect(property, frame.rect); + if (property.widget.should_refresh_size && static_cast(frame.rect.h) == 0) { frame.rect.h = ekg::layout::get_widget_height_by_children( property From aaec025284470196a964532e25bbe5f2a43c4d72 Mon Sep 17 00:00:00 2001 From: mrsrina Date: Mon, 9 Jun 2025 01:02:26 -0300 Subject: [PATCH 5/5] [fix] allocator; button --- include/ekg/gpu/data.hpp | 4 ++-- include/ekg/io/memory.hpp | 4 ++-- src/draw/allocator.cpp | 28 ++++++++++++------------ src/gpu/opengl/gl.cpp | 2 -- src/handler/theme/handler.cpp | 6 +++--- src/ui/button/widget.cpp | 40 +++++++++++++++-------------------- 6 files changed, 38 insertions(+), 46 deletions(-) diff --git a/include/ekg/gpu/data.hpp b/include/ekg/gpu/data.hpp index e2150510..71f224a7 100644 --- a/include/ekg/gpu/data.hpp +++ b/include/ekg/gpu/data.hpp @@ -38,8 +38,8 @@ namespace ekg::gpu { int8_t line_thickness {}; int32_t begin_stride {}; int32_t end_stride {}; - int32_t prev_mem_block_size {}; - int32_t mem_block_offset {}; + // int32_t prev_mem_block_size {}; + // int32_t mem_block_offset {}; bool is_new {}; ekg::hash_t hash {}; int32_t scissor_id {-1}; diff --git a/include/ekg/io/memory.hpp b/include/ekg/io/memory.hpp index da50c365..ff0b80ee 100644 --- a/include/ekg/io/memory.hpp +++ b/include/ekg/io/memory.hpp @@ -166,7 +166,7 @@ namespace ekg { class value { protected: t val {}; - t *p {}; + t *p {nullptr}; t previous {}; bool changed {}; public: @@ -190,7 +190,7 @@ namespace ekg { } bool set(const t &val) { - this->get() = p; + this->get() = val; this->changed = true; return true; } diff --git a/src/draw/allocator.cpp b/src/draw/allocator.cpp index a27c03c5..0d3a78bb 100644 --- a/src/draw/allocator.cpp +++ b/src/draw/allocator.cpp @@ -161,7 +161,7 @@ void ekg::draw::allocator::dispatch() { } void ekg::draw::allocator::pass() { - if (!this->p_local_gpu_data_buffer->empty()) { + /*if (!this->p_local_gpu_data_buffer->empty()) { ekg::gpu::data_t &data {this->p_local_gpu_data_buffer->at(0)}; if ( !data.is_new @@ -170,21 +170,21 @@ void ekg::draw::allocator::pass() { } data.prev_mem_block_size = this->p_local_geometry_buffer->size(); + }*/ - this->gpu_data_buffer.insert( - this->gpu_data_buffer.end(), - this->p_local_gpu_data_buffer->begin(), - this->p_local_gpu_data_buffer->begin() + this->data_instance - ); - - this->geometry_buffer.insert( - this->geometry_buffer.end(), - this->p_local_geometry_buffer->begin(), - this->p_local_geometry_buffer->end() - ); + this->gpu_data_buffer.insert( + this->gpu_data_buffer.end(), + this->p_local_gpu_data_buffer->begin(), + this->p_local_gpu_data_buffer->begin() + this->data_instance + ); - this->global_data_instance += this->gpu_data_buffer.size(); - } + this->geometry_buffer.insert( + this->geometry_buffer.end(), + this->p_local_geometry_buffer->begin(), + this->p_local_geometry_buffer->end() + ); + + this->global_data_instance += this->gpu_data_buffer.size(); } bool ekg::draw::allocator::sync_scissor( diff --git a/src/gpu/opengl/gl.cpp b/src/gpu/opengl/gl.cpp index 8a0deff1..cc702890 100644 --- a/src/gpu/opengl/gl.cpp +++ b/src/gpu/opengl/gl.cpp @@ -625,8 +625,6 @@ void ekg::opengl::pass_gpu_data_buffer_to_gpu( for (ekg::gpu::data_t &data : gpu_data_buffer) { sampler_going_on = data.sampler_at != ekg::at_t::not_found; - //ekg_log_low_level(" meow " << data.mem_block_offset); - if ( sampler_going_on && diff --git a/src/handler/theme/handler.cpp b/src/handler/theme/handler.cpp index 4c90f0fe..037a3c1d 100644 --- a/src/handler/theme/handler.cpp +++ b/src/handler/theme/handler.cpp @@ -51,9 +51,9 @@ void ekg::handler::theme::init() { light_pinky_theme.button_color_scheme.highlight = {245, 169, 184, 50}; light_pinky_theme.button_color_scheme.text_foreground = {141, 141, 141, 255}; light_pinky_theme.button_color_scheme.box_outline = light_pinky_theme.button_color_scheme.outline; - light_pinky_theme.button_color_scheme.box_active = {202, 207, 222, 50}; - light_pinky_theme.button_color_scheme.box_highlight = light_pinky_theme.button_color_scheme.highlight; - light_pinky_theme.button_color_scheme.box_background = light_pinky_theme.button_color_scheme.background; + light_pinky_theme.button_color_scheme.box_active = {245, 169, 184, 200}; + light_pinky_theme.button_color_scheme.box_highlight = {245, 169, 184, 50}; + light_pinky_theme.button_color_scheme.box_background = {202, 207, 222, 100}; this->registry(light_pinky_theme.tag) = light_pinky_theme; this->set_current_theme(light_pinky_theme.tag); diff --git a/src/ui/button/widget.cpp b/src/ui/button/widget.cpp index daf509dc..dbe984ba 100644 --- a/src/ui/button/widget.cpp +++ b/src/ui/button/widget.cpp @@ -62,7 +62,10 @@ void ekg::ui::reload( ); } + ekg::theme_t &global_theme {ekg::p_core->handler_theme.get_current_theme()}; ekg::aligned_t aligned_dimension {}; + + float width {}; for (ekg::button_t::check_t &check : button.checks) { ekg::draw::font &draw_font { ekg::draw::get_font_renderer(check.font_size) @@ -78,6 +81,14 @@ void ekg::ui::reload( ekg::dpi.min_sizes, aligned_dimension ); + + check.widget.rect_box = check.widget.rect_text; + check.widget.rect_box.w += global_theme.layout_offset * 2.0f; + + if (check.box == ekg::dock::none) { + check.widget.rect_text.x = (check.widget.rect_text.w / 2) - (check.widget.rect_box.w / 2); + check.widget.rect_box.h = aligned_dimension.h; + } } button.rect.scaled_height = ekg::max(1, button.rect.scaled_height); @@ -156,13 +167,10 @@ void ekg::ui::event( ? property.widget.rect : - property.widget.rect + check.widget.rect_text + check.widget.rect_box + property.widget.rect ); is_checkbox = check.box != ekg::dock::none; - if (is_checkbox) { - rect = property.widget.rect + check.widget.rect_box; - } ekg_set( property.widget.should_buffering, @@ -222,10 +230,6 @@ void ekg::ui::event( ekg_action( check.actions, ekg::action::active, - ( - check.widget.is_highlight - ) - && (is_checkbox ? (check.value.set(!check.value.get())) : (check.value.set(false))) && (is_active_any = true) @@ -347,17 +351,16 @@ void ekg::ui::buffering( bool is_checkbox {}; for (ekg::button_t::check_t &check : button.checks) { + is_checkbox = check.box != ekg::dock::none; rect = ( is_checks_size_equals_to_one ? property.widget.rect : - property.widget.rect + check.widget.rect_text + check.widget.rect_box + property.widget.rect ); - is_checkbox = check.box != ekg::dock::none; if (is_checkbox) { - rect = property.widget.rect + check.widget.rect_box; ekg::draw::rect( rect, button.color_scheme.box_background, @@ -365,7 +368,7 @@ void ekg::ui::buffering( check.layers[ekg::layer::bg] ); - if (check.widget.is_active) { + if (check.value.get()) { ekg::draw::rect( rect, button.color_scheme.box_active, @@ -377,7 +380,7 @@ void ekg::ui::buffering( if (check.widget.is_highlight) { ekg::draw::rect( rect, - button.color_scheme.box_background, + button.color_scheme.box_highlight, ekg::draw::mode::fill, check.layers[ekg::layer::highlight_bg] ); @@ -390,15 +393,6 @@ void ekg::ui::buffering( check.layers[ekg::layer::outline] ); - if (check.widget.is_active) { - ekg::draw::rect( - rect, - button.color_scheme.box_active, - ekg::draw::mode::fill, - check.layers[ekg::layer::active_bg] - ); - } - ekg::draw::get_font_renderer(check.font_size) .blit( check.text.get(), @@ -415,7 +409,7 @@ void ekg::ui::buffering( ); } - if (check.widget.is_active) { + if (check.value.get()) { ekg::draw::rect( rect, button.color_scheme.active,