From d010cafacb0f82a2bbd9805dd1eea25e02f7a07a Mon Sep 17 00:00:00 2001 From: Zyntex Date: Sat, 18 Nov 2023 01:24:04 +0100 Subject: [PATCH] add slider and wip combobox menu component --- example-mod/src/mod.cpp | 12 +++- src/core/menu/framework.cpp | 129 ++++++++++++++++++++++++++++++++++-- src/core/menu/framework.h | 6 ++ src/core/shared/menu.cpp | 18 ++++- src/wormhole-sdk | 2 +- 5 files changed, 155 insertions(+), 12 deletions(-) diff --git a/example-mod/src/mod.cpp b/example-mod/src/mod.cpp index 49a1251..558b8d8 100644 --- a/example-mod/src/mod.cpp +++ b/example-mod/src/mod.cpp @@ -64,6 +64,14 @@ wh_api::wh_mod_info_t *c_wormhole_mod::get_info( ) { } void c_wormhole_mod::paint_menu( ) { - static bool example_value; - wh->menu->checkbox( example_value, "example checkbox" ); + static bool example_checkbox_val; + wh->menu->checkbox( example_checkbox_val, "example checkbox" ); + static int example_slider_val; + wh->menu->slider( example_slider_val, 0, 100, "example slider" ); + static float example_sliderf_val; + wh->menu->sliderf( example_sliderf_val, 0.f, 10.f, "example sliderf" ); + static int example_combo_val; + static bool example_combo_open; + const char *items[] = { "value 1", "value 2", "value 3" }; + wh->menu->combo( example_combo_val, example_combo_open, items, 3, "example combo" ); } diff --git a/src/core/menu/framework.cpp b/src/core/menu/framework.cpp index 1b9edb0..eb4b542 100644 --- a/src/core/menu/framework.cpp +++ b/src/core/menu/framework.cpp @@ -2,6 +2,8 @@ #include "core/mods/mods.h" +#include + void gui::framework::begin( sdk::vec2_t pos, sdk::vec2_t size ) { cur_menu = menu_t( ); @@ -18,6 +20,34 @@ void gui::framework::begin( sdk::vec2_t pos, sdk::vec2_t size ) { } void gui::framework::end( ) { + if ( cur_menu.cur_combo_items.size( ) ) { + auto cur_pos = cur_menu.pos + cur_menu.cur_combo_pos; + + const auto size = sdk::vec2_t( 140, 26 ); + + for ( const auto &item : cur_menu.cur_combo_items ) { + wh->render->draw_text( cur_pos.x + 8, cur_pos.y + 2, fonts::normal, colors::white, false, item ); + + wh->render->draw_outlined_rect( cur_pos.x, cur_pos.y, size.x, size.y, colors::dark ); + + cur_pos.y += 25; + } + + // bool hover = wh->input->is_cursor_in_area( cur_pos.x + 3, cur_pos.y + text_size.y + 3, cur_pos.x + size.x - 3, cur_pos.y + text_size.y + size.y - 3 ); + // bool clicking = hover && wh->input->get_key_press( sdk::mouse_left ); + + // if ( clicking ) { + // } + + // wh->render->draw_text( cur_pos.x, cur_pos.y, fonts::normal, colors::white, false, label ); + + // cur_pos.y += text_size.y; + + // wh->render->draw_text( cur_pos.x + 8, cur_pos.y + 2, fonts::normal, colors::white, false, items[ val ] ); + + // cur_menu.cursor.y += size.y + text_size.y + 4; + } + wh->portal2->surface->set_clip_rect( 0, 0, wh->render->get_screen_size( ).x, wh->render->get_screen_size( ).y ); wh->portal2->surface->enable_clipping = false; } @@ -128,14 +158,101 @@ bool gui::framework::button( sdk::vec2_t size, std::string label ) { void gui::framework::checkbox( bool &val, std::string label ) { const auto cur_pos = cur_menu.pos + cur_menu.cursor; - bool hover = wh->input->is_cursor_in_area( cur_pos.x, cur_pos.y, cur_pos.x + 20, cur_pos.y + 20 ); - bool clicking = hover && wh->input->get_key_held( sdk::mouse_left ); - - wh->render->draw_outlined_rect( cur_pos.x, cur_pos.y, 20, 20, val ? colors::white : colors::dark ); - wh->render->draw_filled_rect( cur_pos.x + 3, cur_pos.y + 3, 14, 14, val ? colors::white : sdk::color_t( 0, 0, 0, 0 ) ); + const auto size = sdk::vec2_t( 20, 20 ); - wh->render->draw_text( cur_pos.x + 24, cur_pos.y - 2, fonts::normal, colors::white, false, label ); + bool hover = wh->input->is_cursor_in_area( cur_pos.x, cur_pos.y, cur_pos.x + size.x, cur_pos.y + size.y ); + bool clicking = hover && wh->input->get_key_held( sdk::mouse_left ); if ( hover && wh->input->get_key_press( sdk::mouse_left ) ) val = !val; + + wh->render->draw_outlined_rect( cur_pos.x, cur_pos.y, size.x, size.y, val ? colors::white : colors::dark ); + wh->render->draw_filled_rect( cur_pos.x + 3, cur_pos.y + 3, size.x - 6, size.y - 6, val ? colors::white : sdk::color_t( 0, 0, 0, 0 ) ); + + wh->render->draw_text( cur_pos.x + size.x + 4, cur_pos.y - 2, fonts::normal, colors::white, false, label ); + + cur_menu.cursor.y += size.y + 4; +} + +void gui::framework::slider( int &val, int min, int max, std::string label ) { + auto cur_pos = cur_menu.pos + cur_menu.cursor; + + const auto size = sdk::vec2_t( 140, 20 ); + const auto text_size = wh->render->get_text_size( fonts::normal, label ); + + bool hover = wh->input->is_cursor_in_area( cur_pos.x + 3, cur_pos.y + text_size.y + 3, cur_pos.x + size.x - 3, cur_pos.y + text_size.y + size.y - 3 ); + bool clicking = hover && wh->input->get_key_held( sdk::mouse_left ); + + float value = ( float ) val / ( max - min ); + + if ( clicking ) { + value = ( wh->input->get_cursor_position( ).x - ( cur_pos.x + 3 ) ) / ( size.x - 6 ); + val = value * ( max - min ); + } + + wh->render->draw_text( cur_pos.x, cur_pos.y, fonts::normal, colors::white, false, label ); + + cur_pos.y += text_size.y; + + wh->render->draw_outlined_rect( cur_pos.x, cur_pos.y, size.x, size.y, clicking ? colors::white : colors::dark ); + wh->render->draw_filled_rect( cur_pos.x + 3, cur_pos.y + 3, value * ( size.x - 6 ), size.y - 6, colors::white ); + + wh->render->draw_text( cur_pos.x + size.x + 4, cur_pos.y - 2, fonts::normal, colors::white, false, utils::string::ssprintf( "%d", val ) ); + + cur_menu.cursor.y += size.y + text_size.y + 4; +} + +void gui::framework::sliderf( float &val, float min, float max, std::string label ) { + auto cur_pos = cur_menu.pos + cur_menu.cursor; + + const auto size = sdk::vec2_t( 140, 20 ); + const auto text_size = wh->render->get_text_size( fonts::normal, label ); + + bool hover = wh->input->is_cursor_in_area( cur_pos.x + 3, cur_pos.y + text_size.y + 3, cur_pos.x + size.x - 3, cur_pos.y + text_size.y + size.y - 3 ); + bool clicking = hover && wh->input->get_key_held( sdk::mouse_left ); + + float value = val / ( max - min ); + + if ( clicking ) { + value = ( wh->input->get_cursor_position( ).x - ( cur_pos.x + 3 ) ) / ( size.x - 6 ); + val = value * ( max - min ); + } + + wh->render->draw_text( cur_pos.x, cur_pos.y, fonts::normal, colors::white, false, label ); + + cur_pos.y += text_size.y; + + wh->render->draw_outlined_rect( cur_pos.x, cur_pos.y, size.x, size.y, clicking ? colors::white : colors::dark ); + wh->render->draw_filled_rect( cur_pos.x + 3, cur_pos.y + 3, value * ( size.x - 6 ), size.y - 6, colors::white ); + + wh->render->draw_text( cur_pos.x + size.x + 4, cur_pos.y - 2, fonts::normal, colors::white, false, utils::string::ssprintf( "%.1f", val ) ); + + cur_menu.cursor.y += size.y + text_size.y + 4; +} + +void gui::framework::combo( int &val, bool &open, std::vector items, std::string label ) { + auto cur_pos = cur_menu.pos + cur_menu.cursor; + + const auto size = sdk::vec2_t( 140, 26 ); + const auto text_size = wh->render->get_text_size( fonts::normal, label ); + + bool hover = wh->input->is_cursor_in_area( cur_pos.x + 3, cur_pos.y + text_size.y + 3, cur_pos.x + size.x - 3, cur_pos.y + text_size.y + size.y - 3 ); + bool clicking = hover && wh->input->get_key_press( sdk::mouse_left ); + + if ( clicking ) + open = !open; + + if ( open ) { + cur_menu.cur_combo_pos = sdk::vec2_t( cur_menu.cursor.x, cur_menu.cursor.y + size.y + text_size.y ); + cur_menu.cur_combo_items = items; + } + + wh->render->draw_text( cur_pos.x, cur_pos.y, fonts::normal, colors::white, false, label ); + + cur_pos.y += text_size.y; + + wh->render->draw_outlined_rect( cur_pos.x, cur_pos.y, size.x, size.y, open ? colors::white : colors::dark ); + wh->render->draw_text( cur_pos.x + 8, cur_pos.y + 2, fonts::normal, colors::white, false, items[ val ] ); + + cur_menu.cursor.y += size.y + text_size.y + 4; } diff --git a/src/core/menu/framework.h b/src/core/menu/framework.h index f98cb77..4d71617 100644 --- a/src/core/menu/framework.h +++ b/src/core/menu/framework.h @@ -27,6 +27,9 @@ namespace gui { int tab_count; int mod_count; + + sdk::vec2_t cur_combo_pos; + std::vector cur_combo_items; }; inline menu_t cur_menu; @@ -38,5 +41,8 @@ namespace gui { bool button( sdk::vec2_t size, std::string label ); void checkbox( bool &val, std::string label ); + void slider( int &val, int min, int max, std::string label ); + void sliderf( float &val, float min, float max, std::string label ); + void combo( int &val, bool &open, std::vector items, std::string label ); } // namespace framework } // namespace gui diff --git a/src/core/shared/menu.cpp b/src/core/shared/menu.cpp index 084208d..0b945b6 100644 --- a/src/core/shared/menu.cpp +++ b/src/core/shared/menu.cpp @@ -2,6 +2,10 @@ #include "core/menu/framework.h" +#include +#include +#include + bool c_menu::button( sdk::vec2_t size, const char *label ) { return gui::framework::button( size, label ); } @@ -9,12 +13,20 @@ void c_menu::checkbox( bool &val, const char *label ) { return gui::framework::checkbox( val, label ); } void c_menu::slider( int &val, int min, int max, const char *label ) { + return gui::framework::slider( val, min, max, label ); } void c_menu::sliderf( float &val, float min, float max, const char *label ) { + return gui::framework::sliderf( val, min, max, label ); } -void c_menu::colorpicker( sdk::color_t &val, const char *label ) { +void c_menu::colorpicker( sdk::color_t &val, bool &open, const char *label ) { } -void c_menu::combo( int &val, const char **items, const char *label ) { +void c_menu::combo( int &val, bool &open, const char *items[], int items_count, const char *label ) { + std::vector items_vector; + for ( std::size_t i = 0; i < items_count; ++i ) { + items_vector.push_back( items[ i ] ); + } + + return gui::framework::combo( val, open, items_vector, label ); } -void c_menu::multicombo( int &val, const char **items, const char *label ) { +void c_menu::multicombo( int &val, bool &open, const char *items[], int items_count, const char *label ) { } diff --git a/src/wormhole-sdk b/src/wormhole-sdk index 508fed5..f008a30 160000 --- a/src/wormhole-sdk +++ b/src/wormhole-sdk @@ -1 +1 @@ -Subproject commit 508fed5804cc7ca9783c002f30b6ed3f21ccb13e +Subproject commit f008a3024ba9b195d339f5c965e655ecdea6ac8d