Skip to content

Commit

Permalink
migrate compare item menu to imgui
Browse files Browse the repository at this point in the history
  • Loading branch information
mqrause committed Dec 14, 2024
1 parent 7b67e86 commit 2272d2a
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 93 deletions.
3 changes: 2 additions & 1 deletion src/crafting_gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2290,7 +2290,8 @@ static void compare_recipe_with_item( const item &recipe_item, Character &crafte
if( !to_compare ) {
break;
}
game_menus::inv::compare_items( recipe_item, *to_compare );
game_menus::inv::compare_item_menu menu( recipe_item, *to_compare );
menu.show();
} while( true );
}

Expand Down
181 changes: 91 additions & 90 deletions src/game_inventory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
#include "messages.h"
#include "npctrade.h"
#include "options.h"
#include "output.h"
#include "pimpl.h"
#include "point.h"
#include "recipe.h"
Expand Down Expand Up @@ -2296,106 +2295,107 @@ drop_locations game_menus::inv::smoke_food( Character &you, units::volume total_
return smoke_s.execute();
}

bool game_menus::inv::compare_items( const item &first, const item &second,
const std::string &confirm_message )
{
std::string action;
input_context ctxt;
ui_adaptor ui;
item_info_data item_info_first;
item_info_data item_info_second;
int page_size = 0;
int scroll_pos_first = 0;
int scroll_pos_second = 0;
bool first_execution = true;
static int lang_version = detail::get_current_language_version();
do {
//lang check here is needed to redraw the menu when using "Toggle language to English" option
if( first_execution || lang_version != detail::get_current_language_version() ) {
std::vector<iteminfo> v_item_first;
std::vector<iteminfo> v_item_second;

first.info( true, v_item_first );
second.info( true, v_item_second );

item_info_first = item_info_data( first.tname(), first.type_name(),
v_item_first, v_item_second, scroll_pos_first );

item_info_second = item_info_data( second.tname(), second.type_name(),
v_item_second, v_item_first, scroll_pos_second );

item_info_first.without_getch = true;
item_info_second.without_getch = true;

ctxt.register_action( "HELP_KEYBINDINGS" );
if( !confirm_message.empty() ) {
ctxt.register_action( "CONFIRM" );
}
ctxt.register_action( "QUIT" );
ctxt.register_action( "UP" );
ctxt.register_action( "DOWN" );
ctxt.register_action( "PAGE_UP" );
ctxt.register_action( "PAGE_DOWN" );

catacurses::window wnd_first;
catacurses::window wnd_second;
catacurses::window wnd_message;

ui.reset();
ui.on_screen_resize( [&]( ui_adaptor & ui ) {
const int half_width = TERMX / 2;
const int height = TERMY;
const int offset_y = confirm_message.empty() ? 0 : 3;
page_size = TERMY - offset_y - 2;
wnd_first = catacurses::newwin( height - offset_y, half_width, point::zero );
wnd_second = catacurses::newwin( height - offset_y, half_width, point( half_width, 0 ) );

if( !confirm_message.empty() ) {
wnd_message = catacurses::newwin( offset_y, TERMX, point( 0, height - offset_y ) );
}

ui.position( point::zero, point( half_width * 2, height ) );
} );
ui.mark_resize();
ui.on_redraw( [&]( const ui_adaptor & ) {
if( !confirm_message.empty() ) {
draw_border( wnd_message );
nc_color col = c_white;
print_colored_text(
wnd_message, point( 3, 1 ), col, col,
confirm_message + " " +
ctxt.describe_key_and_name( "CONFIRM" ) + " " +
ctxt.describe_key_and_name( "QUIT" ) );
wnoutrefresh( wnd_message );
}
game_menus::inv::compare_item_menu::compare_item_menu( const item &first, const item &second,
const std::string &confirm_message ) :
cataimgui::window( "compare", ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoNavInputs ),
first( first ),
second( second ),
confirm_message( confirm_message )
{
ctxt.register_action( "HELP_KEYBINDINGS" );
if( !confirm_message.empty() ) {
ctxt.register_action( "CONFIRM" );
}
ctxt.register_action( "QUIT" );
ctxt.register_action( "UP" );
ctxt.register_action( "DOWN" );
ctxt.register_action( "PAGE_UP" );
ctxt.register_action( "PAGE_DOWN" );
ctxt.set_timeout( 10 );

// todo: regen info when toggling language?
first.info( true, first_info );
second.info( true, second_info );
}

draw_item_info( wnd_first, item_info_first );
draw_item_info( wnd_second, item_info_second );
} );
lang_version = detail::get_current_language_version();
first_execution = false;
static void draw_column( const std::string &label, const ImVec2 &size, const item &it,
std::vector<iteminfo> &first, std::vector<iteminfo> &second, cataimgui::scroll &s )
{
if( ImGui::BeginChild( label.c_str(), size ) ) {
cataimgui::TextColoredParagraph( c_light_gray, it.tname() );
ImGui::NewLine();
if( it.tname().find( it.type_name() ) == std::string::npos ) {
cataimgui::TextColoredParagraph( c_light_gray, it.type_name() );
ImGui::NewLine();
}
ImGui::NewLine();
cataimgui::set_scroll( s );
display_item_info( first, second );
}
ImGui::EndChild();
}

void game_menus::inv::compare_item_menu::draw_controls()
{
float half_width = ImGui::GetContentRegionAvail().x / 2;
float height = ImGui::GetContentRegionAvail().y;
ImGuiStyle &style = ImGui::GetStyle();
float spacing_x = style.ItemSpacing.x;
float top_y = ImGui::GetCursorPosY();
float confirm_height = confirm_message.empty() ? 0.f : ImGui::GetFrameHeightWithSpacing();

// cataimgui::set_scroll resets scroll, so we need a copy for parallel scrolling
// not ideal, but this is such a special use case it's probably not worth changing
// todo: also synchronize scrolling when using mouse wheel/dragging scroll bar?
cataimgui::scroll s_copy = s;

draw_column( "compare_left", ImVec2( half_width - spacing_x, height - confirm_height ), first,
first_info, second_info, s );
ImGui::SetCursorPos( { half_width + spacing_x, top_y } );
draw_column( "compare_right", ImVec2( half_width - spacing_x, height - confirm_height ), second,
second_info, first_info, s_copy );

if( !confirm_message.empty() ) {
ImGui::AlignTextToFramePadding();
cataimgui::TextColoredParagraph( c_white, confirm_message );
// todo: spacing should be part of paragraph so it behaves the same as other elements
ImGui::Spacing();
ImGui::SameLine();
action_button( "CONFIRM", ctxt.get_button_text( "CONFIRM" ) );
ImGui::SameLine();
action_button( "QUIT", ctxt.get_button_text( "QUIT" ) );
}
}

cataimgui::bounds game_menus::inv::compare_item_menu::get_bounds()
{
return { 0.f, 0.f, ImGui::GetMainViewport()->Size.x, ImGui::GetMainViewport()->Size.y };
}

bool game_menus::inv::compare_item_menu::show()
{
while( true ) {
ui_manager::redraw();

action = ctxt.handle_input();
std::string action = has_button_action() ? get_button_action() : ctxt.handle_input();

if( action == "UP" ) {
scroll_pos_first--;
scroll_pos_second--;
s = cataimgui::scroll::line_up;
} else if( action == "DOWN" ) {
scroll_pos_first++;
scroll_pos_second++;
s = cataimgui::scroll::line_down;
} else if( action == "PAGE_UP" ) {
scroll_pos_first -= page_size;
scroll_pos_second -= page_size;
s = cataimgui::scroll::page_up;
} else if( action == "PAGE_DOWN" ) {
scroll_pos_first += page_size;
scroll_pos_second += page_size;
s = cataimgui::scroll::page_down;
} else if( action == "CONFIRM" ) {
return true;
} else if( action == "QUIT" ) {
return false;
}
} while( action != "QUIT" && action != "CONFIRM" );
}

return action == "CONFIRM";
return false;
}

void game_menus::inv::compare( const std::optional<tripoint> &offset )
Expand Down Expand Up @@ -2428,7 +2428,8 @@ void game_menus::inv::compare( const std::optional<tripoint> &offset )
break;
}

compare_items( *to_compare.first, *to_compare.second );
compare_item_menu menu( *to_compare.first, *to_compare.second );
menu.show();
} while( true );
}

Expand Down
20 changes: 20 additions & 0 deletions src/game_inventory.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <list>
#include <utility>

#include "cata_imgui.h"
#include "inventory_ui.h"
#include "item.h"
#include "item_location.h"
Expand Down Expand Up @@ -71,6 +72,25 @@ void swap_letters();
* pressed, false for "quit" input.
* @return False if confirm_message is empty or QUIT input was pressed.
*/
class compare_item_menu : public cataimgui::window
{
public:
compare_item_menu( const item &first, const item &second, const std::string &confirm_message = "" );
bool show();

protected:
void draw_controls() override;
cataimgui::bounds get_bounds() override;

private:
item first;
item second;
const std::string confirm_message;
input_context ctxt;
std::vector<iteminfo> first_info;
std::vector<iteminfo> second_info;
cataimgui::scroll s = cataimgui::scroll::none;
};
bool compare_items( const item &first, const item &second,
const std::string &confirm_message = "" );

Expand Down
2 changes: 1 addition & 1 deletion src/iuse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5327,7 +5327,7 @@ std::optional<int> iuse::gunmod_attach( Character *p, item *it, const tripoint_b

modded_gun.put_in( mod_copy, pocket_type::MOD );

if( !game_menus::inv::compare_items( *loc, modded_gun, _( "Attach modification?" ) ) ) {
if( !game_menus::inv::compare_item_menu( *loc, modded_gun, _( "Attach modification?" ) ).show() ) {
continue;
}

Expand Down
2 changes: 1 addition & 1 deletion src/iuse_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4408,7 +4408,7 @@ std::optional<int> detach_gunmods_actor::use( Character *p, item &it,
if( p->meets_requirements( *mods[mod_index], gun_copy ) ||
query_yn( _( "Are you sure? You may be lacking the skills needed to reattach this modification." ) ) ) {

if( game_menus::inv::compare_items( it, gun_copy, _( "Remove modification?" ) ) ) {
if( game_menus::inv::compare_item_menu( it, gun_copy, _( "Remove modification?" ) ).show() ) {
p->gunmod_remove( it, *mods[mod_index] );
return 0;
}
Expand Down

0 comments on commit 2272d2a

Please sign in to comment.