Skip to content

Commit

Permalink
add colorpicker and a bunch of other shit
Browse files Browse the repository at this point in the history
  • Loading branch information
hero622 committed Aug 23, 2024
1 parent 8fbe453 commit 6b8b161
Show file tree
Hide file tree
Showing 10 changed files with 306 additions and 27 deletions.
153 changes: 143 additions & 10 deletions src/core/menu/framework.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@ void gui::framework::set_theme( bool dark ) {
colors::bg = color_t( 255, 255, 255, 255 );
colors::fg = color_t( 200, 200, 200, 255 );
colors::text = color_t( 0, 0, 0, 200 );
colors::accent = color_t( 66, 128, 244, 255 );
colors::disabled = color_t( 0, 0, 0, 64 );
} else {
colors::bg = color_t( 21, 21, 21, 255 );
colors::fg = color_t( 59, 59, 59, 255 );
colors::text = color_t( 255, 255, 255, 64 );
colors::accent = color_t( 66, 128, 244, 255 );
colors::disabled = color_t( 255, 255, 255, 2 );
}
}
Expand All @@ -30,8 +28,8 @@ void gui::framework::begin( vec2_t pos, vec2_t size ) {

cur_menu.cursor = vec2_t( 8, 8 );

// block input to other controls when a dropdown is open
cur_menu.block_input = !cur_dropdown.id.empty( );
// block input to other controls when a dropdown or colorpicker is open
cur_menu.block_input = !cur_dropdown.id.empty( ) || !cur_colorpicker.id.empty( );

photon->render->draw_rounded_rect( cur_menu.pos.x, cur_menu.pos.y, cur_menu.size.x, cur_menu.size.y, colors::bg, 8 );

Expand Down Expand Up @@ -75,6 +73,9 @@ void gui::framework::end( ) {
} else
scroll_offset = 0; // reset scroll offset if content can fit in page

interfaces::surface->set_clip_rect( 0, 0, photon->render->get_screen_size( ).x, photon->render->get_screen_size( ).y );
interfaces::surface->enable_clipping = false;

// draw dropdowns
if ( !cur_dropdown.id.empty( ) ) {
auto cur_pos = cur_dropdown.pos;
Expand Down Expand Up @@ -110,8 +111,102 @@ void gui::framework::end( ) {
}
}

interfaces::surface->set_clip_rect( 0, 0, photon->render->get_screen_size( ).x, photon->render->get_screen_size( ).y );
interfaces::surface->enable_clipping = false;
// draw colorpickers
if ( !cur_colorpicker.id.empty( ) ) {
auto cur_pos = cur_colorpicker.pos;

auto size = vec2_t( 220, 200 );

cur_pos.x += 20;

photon->render->draw_rounded_rect( cur_pos.x, cur_pos.y, size.x, size.y, colors::fg, 8 );
photon->render->draw_rounded_rect( cur_pos.x + 1, cur_pos.y + 1, size.x - 2, size.y - 2, colors::bg, 8 );

cur_pos += vec2_t( 8, 8 );
size -= vec2_t( 16, 16 );

const auto width = size.x - 24;
const auto height = size.y - 20;

/* logic */
bool hover_sv = photon->input->is_cursor_in_area( cur_pos.x, cur_pos.y, cur_pos.x + width - 2, cur_pos.y + height - 2 );
bool hover_h = photon->input->is_cursor_in_area( cur_pos.x + size.x - 18, cur_pos.y, cur_pos.x + size.x - 18 + 20, cur_pos.y + height - 2 );
bool hover_a = photon->input->is_cursor_in_area( cur_pos.x, cur_pos.y + size.y - 14, cur_pos.x + width - 2, cur_pos.y + size.y - 14 + 14 );
bool holding = photon->input->get_key_held( mouse_left );
bool clicking = photon->input->get_key_press( mouse_left );

float& h = cur_colorpicker.h;
float& s = cur_colorpicker.s;
float& v = cur_colorpicker.v;
float& a = cur_colorpicker.a;

// clicking out
// HACK: check if not first frame by checking if alpha is initialized
if ( a != -1 && clicking && !hover_sv && !hover_h && !hover_a ) {
cur_colorpicker = colorpicker_t( );
return;
}

a = cur_colorpicker.value.a / 255.f;

#define SV_ID "photon colorpicker sv"
#define H_ID "photon colorpicker h"
#define A_ID "photon colorpicker a"

if ( holding && cur_slider.empty( ) ) {
if ( hover_sv )
cur_slider = SV_ID;
else if ( hover_h )
cur_slider = H_ID;
else if ( hover_a )
cur_slider = A_ID;
} else if ( !holding && !cur_slider.empty( ) )
cur_slider.clear( );

if ( cur_slider == SV_ID ) {
s = std::clamp( ( photon->input->get_cursor_position( ).x - cur_pos.x ) / ( width - 2 ), 0.f, 1.f );
v = 1.f - std::clamp( ( photon->input->get_cursor_position( ).y - cur_pos.y ) / ( height - 2 ), 0.f, 1.f );
} else if ( cur_slider == H_ID )
h = std::clamp( ( photon->input->get_cursor_position( ).y - cur_pos.y ) / ( height - 2 ), 0.f, 1.f );
else if ( cur_slider == A_ID )
a = std::clamp( ( photon->input->get_cursor_position( ).x - cur_pos.x ) / ( width - 2 ), 0.f, 1.f );

#undef SV_ID
#undef H_ID
#undef A_ID

color_t col = color_t::from_hsv( h, s, v );
col.a = a * 255;

cur_colorpicker.value = col;

/* drawing */
// saturation, value
photon->render->draw_outlined_rect( cur_pos.x - 1, cur_pos.y - 1, width + 2, height + 2, colors::fg );
photon->render->draw_gradient( cur_pos.x, cur_pos.y, width, height, { 255, 255, 255 }, color_t::from_hsv( h, 1.f, 1.f ), true );
photon->render->draw_gradient( cur_pos.x, cur_pos.y, width, height, { 0, 0, 0, 0 }, { 0, 0, 0 }, false );

// hue
photon->render->draw_outlined_rect( cur_pos.x + size.x - 18 - 1, cur_pos.y - 1, 20, height + 2, colors::fg );
photon->render->draw_texture( cur_pos.x + size.x - 18, cur_pos.y, 18, height, "photon_hue_gradient" );

// alpha
photon->render->draw_outlined_rect( cur_pos.x - 1, cur_pos.y + size.y - 14 - 1, width + 2, 16, colors::fg );
photon->render->draw_filled_rect( cur_pos.x, cur_pos.y + size.y - 14, width, 14, col );

/* draw cursors */
// saturation, value
photon->render->draw_outlined_rect( cur_pos.x + s * ( width - 2 ) - 1, cur_pos.y + ( 1.f - v ) * ( height - 2 ) - 1, 4, 4, colors::gray );
photon->render->draw_filled_rect( cur_pos.x + s * ( width - 2 ), cur_pos.y + ( 1.f - v ) * ( height - 2 ), 2, 2, { 255, 255, 255, 64 } );

// hue
photon->render->draw_outlined_rect( cur_pos.x + size.x - 18 - 1, cur_pos.y + h * ( height - 2 ) - 1, 20, 3, colors::gray );
photon->render->draw_filled_rect( cur_pos.x + size.x - 18, cur_pos.y + h * ( height - 2 ), 18, 1, { 255, 255, 255, 64 } );

// alpha
photon->render->draw_outlined_rect( cur_pos.x + a * ( width - 2 ) - 1, cur_pos.y + size.y - 14 - 1, 3, 16, colors::gray );
photon->render->draw_filled_rect( cur_pos.x + a * ( width - 2 ), cur_pos.y + size.y - 14, 1, 14, { 255, 255, 255, 64 } );
}
}

bool gui::framework::tab( int& selected, vec2_t pos, vec2_t size, const std::string& label, bool texture ) {
Expand Down Expand Up @@ -302,14 +397,15 @@ void gui::framework::slider( int& val, int min, int max, const std::string& labe
photon->render->draw_rounded_rect( cur_pos2.x, cur_pos2.y + 1, size.x, size.y - 13, colors::fg, 4 );
photon->render->draw_rounded_rect( cur_pos2.x, cur_pos2.y + 1, value * size.x, size.y - 13, colors::accent, 4 );

const auto text_size = photon->render->get_text_size( fonts::smaller, util::ssprintf( "%d", val ).c_str( ) );
photon->render->draw_text( cur_pos2.x - text_size.x / 2 - 8, cur_pos2.y - 3, fonts::smaller, colors::text, true, util::ssprintf( "%d", val ).c_str( ) );

cur_pos2 += vec2_t( radius_half, radius_half );
cur_pos2.x += value * ( size.x - radius );

photon->render->draw_circle( cur_pos2.x, cur_pos2.y, radius, colors::accent );
photon->render->draw_circle( cur_pos2.x, cur_pos2.y, radius - 4, colors::white );

photon->render->draw_text( cur_pos2.x, cur_pos2.y - 26, fonts::smaller, colors::text, true, util::ssprintf( "%d", val ).c_str( ) );

cur_menu.cursor.y += size.y + 16;
}

Expand Down Expand Up @@ -346,18 +442,55 @@ void gui::framework::sliderf( float& val, float min, float max, const std::strin
photon->render->draw_rounded_rect( cur_pos2.x, cur_pos2.y + 1, size.x, size.y - 13, colors::fg, 4 );
photon->render->draw_rounded_rect( cur_pos2.x, cur_pos2.y + 1, value * size.x, size.y - 13, colors::accent, 4 );

const auto text_size = photon->render->get_text_size( fonts::smaller, util::ssprintf( "%.1f", val ).c_str( ) );
photon->render->draw_text( cur_pos2.x - text_size.x / 2 - 8, cur_pos2.y - 3, fonts::smaller, colors::text, true, util::ssprintf( "%.1f", val ).c_str( ) );

cur_pos2 += vec2_t( radius_half, radius_half );
cur_pos2.x += value * ( size.x - radius );

photon->render->draw_circle( cur_pos2.x, cur_pos2.y, radius, colors::accent );
photon->render->draw_circle( cur_pos2.x, cur_pos2.y, radius - 4, colors::white );

photon->render->draw_text( cur_pos2.x, cur_pos2.y - 26, fonts::smaller, colors::text, true, util::ssprintf( "%.1f", val ).c_str( ) );

cur_menu.cursor.y += size.y + 16;
}

void gui::framework::colorpicker( color_t& val, const std::string& label ) {
auto cur_pos = cur_menu.pos + cur_menu.cursor;
cur_pos.y -= scroll_offset;

const auto size = vec2_t( 20, 20 );

auto cur_pos2 = align_right( cur_pos, size );

bool open = cur_colorpicker.id == label;

bool hover = ( !cur_menu.block_input || open ) && photon->input->is_cursor_in_area( cur_pos2.x, cur_pos2.y, cur_pos2.x + size.x, cur_pos2.y + size.y );
bool clicking = hover && photon->input->get_key_press( mouse_left );

if ( clicking ) {
if ( open )
cur_colorpicker = colorpicker_t( );
else {
cur_colorpicker.id = label;
cur_colorpicker.pos = cur_pos2;
cur_colorpicker.value = val;
val.to_hsv( cur_colorpicker.h, cur_colorpicker.s, cur_colorpicker.v );
}

open = !open;
}

if ( open )
val = cur_colorpicker.value;

photon->render->draw_text( cur_pos.x, cur_pos.y, fonts::normal, colors::text, false, util::to_upper( label ).c_str( ) );

photon->render->draw_rounded_rect( cur_pos2.x, cur_pos2.y, size.x, size.y, colors::gray, 8 );

photon->render->draw_rounded_rect( cur_pos2.x + 1, cur_pos2.y + 1, size.x - 2, size.y - 2, colors::bg, 8 );
photon->render->draw_rounded_rect( cur_pos2.x + 1, cur_pos2.y + 1, size.x - 2, size.y - 2, val, 8 );

cur_menu.cursor.y += size.y + 16;
}

void gui::framework::combo( std::size_t& val, const std::vector< std::string >& items, const std::string& label ) {
Expand Down
12 changes: 8 additions & 4 deletions src/core/menu/framework.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ namespace gui {
inline color_t red = color_t( 168, 43, 43 );

// theme colors
inline color_t accent = color_t( 66, 128, 244, 255 );
inline color_t bg;
inline color_t fg;
inline color_t text;
inline color_t accent;
inline color_t disabled;
} // namespace colors

Expand Down Expand Up @@ -56,12 +56,16 @@ namespace gui {
inline dropdown_t cur_dropdown;

struct colorpicker_t {

std::string id;
vec2_t pos;
color_t value;
float h, s, v;
float a{ -1 };
};
inline colorpicker_t cur_colorpicker;

inline std::string cur_slider; // FIXME: make this somehow be only for current menu but still persist
inline int scroll_offset; // ditto
inline std::string cur_slider;
inline int scroll_offset; // FIXME: make this somehow be only for current menu but still persist

void set_theme( bool dark = false );

Expand Down
33 changes: 28 additions & 5 deletions src/core/menu/gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ SIGNAL_CALLBACK( void, __rescall, update_button_state, const int*, event ) {
original( ecx, event );
}

static color_t* hue_tex;

bool gui::initialize( ) {
framework::set_theme( false );

Expand All @@ -90,11 +92,22 @@ bool gui::initialize( ) {
photon->render->create_font( framework::fonts::title, "D-DIN EXP", 24, true, fontflag_antialias );
photon->render->create_font( framework::fonts::bigtitle, "D-DIN EXP", 32, true, fontflag_antialias );

photon->render->load_texture( "photon_icon", resource::icons::photon, 50, 50, sizeof( resource::icons::photon ) );
photon->render->load_texture( "photon_list", resource::icons::list, 32, 32, sizeof( resource::icons::list ) );
photon->render->load_texture( "photon_gear", resource::icons::gear, 32, 32, sizeof( resource::icons::gear ) );
photon->render->load_texture( "photon_left_arrow", resource::icons::left_arrow, 32, 32, sizeof( resource::icons::left_arrow ) );
photon->render->load_texture( "photon_arrows", resource::icons::arrows, 32, 32, sizeof( resource::icons::arrows ) );
photon->render->load_texture_png( "photon_icon", resource::icons::photon, 50, 50, sizeof( resource::icons::photon ) );
photon->render->load_texture_png( "photon_list", resource::icons::list, 32, 32, sizeof( resource::icons::list ) );
photon->render->load_texture_png( "photon_gear", resource::icons::gear, 32, 32, sizeof( resource::icons::gear ) );
photon->render->load_texture_png( "photon_left_arrow", resource::icons::left_arrow, 32, 32, sizeof( resource::icons::left_arrow ) );
photon->render->load_texture_png( "photon_arrows", resource::icons::arrows, 32, 32, sizeof( resource::icons::arrows ) );

// initialize hue gradient texture (this should probably be in framework)
constexpr int tex_height = 180;

hue_tex = new color_t[ 1 * tex_height ];
for ( int i = 0; i < tex_height; ++i ) {
float hue = i * ( 1.f / tex_height );

hue_tex[ i ] = color_t::from_hsv( hue, 1.f, 1.f );
}
photon->render->load_texture_raw( "photon_hue_gradient", ( uint8_t* ) hue_tex, 1, tex_height );

photon->signal->get( "lock_cursor" )->add_callback( &lock_cursor_cbk );
photon->signal->get( "paint" )->add_callback( &paint_cbk );
Expand All @@ -109,6 +122,8 @@ bool gui::initialize( ) {
void gui::uninitialize( ) {
dx9::uninitialize( );

DELETE_PTR( hue_tex );

photon->render->destruct_font( framework::fonts::bigtitle );
photon->render->destruct_font( framework::fonts::title );
photon->render->destruct_font( framework::fonts::normal );
Expand Down Expand Up @@ -161,14 +176,22 @@ void gui::paint( ) {
}
}
if ( framework::tab( tab, { screen_half.x + 100 + 8, screen_half.y - tab_height / 2 }, { tab_height, tab_height }, "photon_gear", true ) ) {
framework::separator( "menu settings" );

framework::colorpicker( framework::colors::accent, "accent color" );

static bool dark_mode = false;
if ( framework::toggle( dark_mode, "dark mode" ) )
framework::set_theme( dark_mode );

framework::separator( "game settings" );

static bool fast_loads = true;
if ( framework::toggle( fast_loads, "fast loads" ) )
convars::set_fast_loads( fast_loads );

framework::separator( "hud settings" );

framework::slider( huds::safezone_x, 0, 32, "hud safezone x" );
framework::slider( huds::safezone_y, 0, 32, "hud safezone y" );
}
Expand Down
33 changes: 33 additions & 0 deletions src/core/shared/hud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,31 @@ void c_hud::draw_line( int x, int y, int w, int h, color_t color ) {

photon->render->draw_line( x, y, w, h, color );
}
void c_hud::draw_polygon( int n, vertex_t* vertices, color_t color ) {
// FIXME: do some calculation here to figure out bounds
// if ( !cur_hud )
// return;

// setup_context( x, y, w, h );

// photon->render->draw_polygon( n, vertices, color );
}
void c_hud::draw_rounded_rect( int x, int y, int w, int h, color_t color, int rounding ) {
if ( !cur_hud )
return;

setup_context( x, y, w, h );

photon->render->draw_rounded_rect( x, y, w, h, color, rounding );
}
void c_hud::draw_circle( int x, int y, int radius, color_t color ) {
if ( !cur_hud )
return;

setup_context( x, y, radius * 2, radius * 2 ); // XXX: maybe wrong ? too lazy to test rn

photon->render->draw_circle( x, y, radius, color );
}
void c_hud::draw_text( int x, int y, h_font font, color_t color, bool center, const char* text ) {
if ( !cur_hud )
return;
Expand All @@ -90,3 +115,11 @@ void c_hud::draw_texture( int x, int y, int w, int h, const char* texture, color

photon->render->draw_texture( x, y, w, h, texture, color );
}
void c_hud::draw_gradient( int x, int y, int w, int h, color_t color1, color_t color2, bool horizontal ) {
if ( !cur_hud )
return;

setup_context( x, y, w, h );

photon->render->draw_gradient( x, y, w, h, color1, color2, horizontal );
}
1 change: 1 addition & 0 deletions src/core/shared/menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ 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( color_t& val, const char* label ) {
return gui::framework::colorpicker( val, label );
}
void c_menu::combo( std::size_t& val, const char* items[], std::size_t items_count, const char* label ) {
std::vector< std::string > items_vector;
Expand Down
Loading

0 comments on commit 6b8b161

Please sign in to comment.