Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate uilist to ImGui #73045

Closed
wants to merge 36 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9a9eb72
wip make uilist use imgui
db48x Dec 11, 2023
0781a9d
moving to modern p_impl approach
katemonster33 Apr 12, 2024
d5abe30
Taking a different approach with imgui uilist, going to try to make t…
katemonster33 Apr 12, 2024
91f87f3
progress woo
katemonster33 Apr 12, 2024
2fedf29
fixed compile errors
katemonster33 Apr 15, 2024
2b6d797
re-implemented the header text, fixed some draw size issues.
katemonster33 Apr 15, 2024
6b2bf55
working on excising the curses-based objects from the uilist.
katemonster33 Apr 15, 2024
5c8c964
clean up some minor errors
db48x Apr 21, 2024
22b97aa
factor out color conversion to ImVec4
db48x Apr 23, 2024
4a8eff3
add left and right columns to uilist for use in callback->refresh
db48x Apr 23, 2024
7487b55
rewrite query_destination_callback (advanced inventory) to use ImGui
db48x Apr 23, 2024
55e71af
move draw_colored_text to the cataimgui namespace
db48x Apr 24, 2024
53033b1
make foldstring wrap each line separately
db48x Apr 24, 2024
6df2bed
rewrite pocket_favorite_callback (advanced inventory) to use ImGui
db48x Apr 24, 2024
ab939f1
make astyle
db48x Apr 24, 2024
bf8f720
remove mention of ui_adaptor from users of uilist
db48x Apr 24, 2024
41c0d2a
rewrite spellbook_callback to use ImGui
db48x Apr 25, 2024
ef0cf55
remove app_uilist_handler
db48x Apr 25, 2024
582c7d8
rewrite teleporter_callback to use ImGui
db48x Apr 26, 2024
d03ef9d
appease astyle
db48x Apr 26, 2024
c8dd700
rewrite the example monmenu_cb in ui.h to use ImGui
db48x Apr 26, 2024
d75d0b1
uilist should allow the choices to scroll, not the whole window
db48x Apr 27, 2024
b351e9e
rewrite wish_mutate_callback to use ImGui
db48x Apr 27, 2024
15ae4e3
rewrite wish_monster_callback to use ImGui
db48x Apr 27, 2024
c885ab4
Rewrite the wish_item_callback to use ImGui, but imperfectly
db48x Apr 28, 2024
cfe4df4
make sure that the uilist leaves room to show access keys/invlets
db48x Apr 30, 2024
60631ff
rewrite spellcasting_callback to use ImGui
db48x Apr 30, 2024
ab41c11
remove color stack and wrap width from cataimgui::draw_colored_text
db48x May 1, 2024
d9a01bd
uilist should scroll the selected item into view if the list is long
db48x May 1, 2024
6735c49
finally remove all mention of catacurses from the uilist
db48x May 1, 2024
57536be
uilist uses Selectable correctly to handle mouse events
db48x May 1, 2024
5c192b5
oops, keep new_centered_win around since there are other callers
db48x May 1, 2024
2340525
fix a missing include
db48x May 1, 2024
5c308e7
appease astyle yet again
db48x May 1, 2024
e4aa53f
mouse input actually works correctly in uilists
db48x May 1, 2024
a0b0e23
appease astyle yet again
db48x May 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 19 additions & 6 deletions src/advanced_inv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "cached_options.h"
#include "calendar.h"
#include "cata_assert.h"
#include "cata_imgui.h"
#include "cata_scope_helpers.h"
#include "catacharset.h"
#include "character.h"
Expand All @@ -27,6 +28,7 @@
#include "enums.h"
#include "game.h"
#include "game_constants.h"
#include "imgui/imgui.h"
#include "input.h"
#include "input_context.h"
#include "inventory.h"
Expand Down Expand Up @@ -2024,8 +2026,11 @@ class query_destination_callback : public uilist_callback

void query_destination_callback::draw_squares( const uilist *menu )
{
ImGui::TableSetColumnIndex( 0 );
ImGui::NewLine();
ImGui::NewLine();
ImGui::NewLine();
cata_assert( menu->entries.size() >= 9 );
int ofs = -25 - 4;
int sel = 0;
if( menu->selected >= 0 && static_cast<size_t>( menu->selected ) < menu->entries.size() ) {
sel = _adv_inv.screen_relative_location(
Expand All @@ -2041,12 +2046,20 @@ void query_destination_callback::draw_squares( const uilist *menu )
bool canputitems = menu->entries[i - 1].enabled && square.canputitems();
nc_color bcolor = canputitems ? sel == loc ? h_white : c_light_gray : c_red;
nc_color kcolor = canputitems ? sel == loc ? h_white : c_dark_gray : c_red;
const point p( square.hscreen + point( ofs, 5 ) );
mvwprintz( menu->window, p, bcolor, "%c", bracket[0] );
wprintz( menu->window, kcolor, "%s", key );
wprintz( menu->window, bcolor, "%c", bracket[1] );
// TODO(db48x): maybe make these clickable buttons or something
ImGui::PushID( i );
ImGui::BeginGroup();
ImGui::TextColored( cataimgui::imvec4_from_color( bcolor ), "%c", bracket[0] );
ImGui::SameLine( 0.0, 0.0 );
ImGui::TextColored( cataimgui::imvec4_from_color( kcolor ), "%s", key.c_str() );
ImGui::SameLine( 0.0, 0.0 );
ImGui::TextColored( cataimgui::imvec4_from_color( bcolor ), "%c", bracket[1] );
ImGui::EndGroup();
ImGui::PopID();
if( i % 3 != 0 ) {
ImGui::SameLine();
}
}
wnoutrefresh( menu->window );
}

bool advanced_inventory::query_destination( aim_location &def )
Expand Down
76 changes: 38 additions & 38 deletions src/cata_imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,22 @@ struct pairs {
std::array<RGBTuple, color_loader<RGBTuple>::COLOR_NAMES_COUNT> rgbPalette;
std::array<pairs, 100> colorpairs; //storage for pair'ed colored

ImVec4 cataimgui::imvec4_from_color( nc_color color )
{
int pair_id = color.get_index();
pairs &pair = colorpairs[pair_id];

int palette_index = pair.FG != 0 ? pair.FG : pair.BG;
if( color.is_bold() ) {
palette_index += color_loader<RGBTuple>::COLOR_NAMES_COUNT / 2;
}
RGBTuple &rgbCol = rgbPalette[palette_index];
return { static_cast<float>( rgbCol.Red / 255. ),
static_cast<float>( rgbCol.Green / 255. ),
static_cast<float>( rgbCol.Blue / 255. ),
static_cast<float>( 255. ) };
}

ImTui::TScreen *imtui_screen = nullptr;
std::vector<std::pair<int, ImTui::mouse_event>> imtui_events;

Expand Down Expand Up @@ -168,6 +184,15 @@ RGBTuple color_loader<RGBTuple>::from_rgb( const int r, const int g, const int b
#include <imgui/imgui_impl_sdl2.h>
#include <imgui/imgui_impl_sdlrenderer2.h>

ImVec4 cataimgui::imvec4_from_color( nc_color &color )
{
SDL_Color c = curses_color_to_SDL( color );
return { static_cast<float>( c.r / 255. ),
static_cast<float>( c.g / 255. ),
static_cast<float>( c.b / 255. ),
static_cast<float>( c.a / 255. ) };
}

struct CataImFont : public ImFont {
std::unordered_map<ImU32, unsigned char> sdlColorsToCata;
const cataimgui::client &imclient;
Expand Down Expand Up @@ -348,29 +373,21 @@ void cataimgui::imvec2_to_point( ImVec2 *src, point *dest )
}
}

void cataimgui::window::draw_colored_text( std::string const &text, const nc_color &color,
float wrap_width, bool *is_selected, bool *is_focused, bool *is_hovered )
void cataimgui::draw_colored_text( std::string const &text,
__attribute__( ( unused ) ) const nc_color &color, bool *is_selected, bool *is_focused,
bool *is_hovered )
{
nc_color color_cpy = color;
draw_colored_text( text, color_cpy, wrap_width, is_selected, is_focused, is_hovered );
draw_colored_text( text, color_cpy, is_selected, is_focused, is_hovered );
}

void cataimgui::window::draw_colored_text( std::string const &text, nc_color &color,
float wrap_width, bool *is_selected, bool *is_focused, bool *is_hovered )
void cataimgui::draw_colored_text( std::string const &text,
__attribute__( ( unused ) ) nc_color &color, bool *is_selected, bool *is_focused, bool *is_hovered )
{
ImGui::PushID( text.c_str() );
ImGui::PushTextWrapPos( 0 );
ImGuiID itemId = GImGui->CurrentWindow->IDStack.back();
std::stack<nc_color> color_stack;
color_stack.push( color );
size_t chars_per_line = size_t( wrap_width );
if( chars_per_line == 0 ) {
chars_per_line = SIZE_MAX;
}
#if defined(WIN32) || defined(TILES)
size_t char_width = size_t( ImGui::CalcTextSize( " " ).x );
chars_per_line /= char_width;
#endif
std::vector<std::string> folded_msg = foldstring( text, chars_per_line );
std::vector<std::string> folded_msg = foldstring( text, -1 );

for( const std::string &line : folded_msg ) {

Expand All @@ -387,45 +404,27 @@ void cataimgui::window::draw_colored_text( std::string const &text, nc_color &co

if( seg[0] == '<' ) {
const color_tag_parse_result::tag_type type =
update_color_stack( color_stack, seg, report_color_error::yes );
update_imgui_color_stack( seg, report_color_error::yes );
if( type != color_tag_parse_result::non_color_tag ) {
seg = rm_prefix( seg );
}
}

color = color_stack.empty() ? color : color_stack.top();
if( i++ != 0 ) {
ImGui::SameLine( 0, 0 );
}
#if !(defined(TILES) || defined(WIN32))
int pair_id = color.get_index();
pairs &pair = colorpairs[pair_id];

int palette_index = pair.FG != 0 ? pair.FG : pair.BG;
if( color.is_bold() ) {
palette_index += color_loader<RGBTuple>::COLOR_NAMES_COUNT / 2;
}
RGBTuple &rgbCol = rgbPalette[palette_index];
ImGui::TextColored( { static_cast<float>( rgbCol.Red / 255. ), static_cast<float>( rgbCol.Green / 255. ),
static_cast<float>( rgbCol.Blue / 255. ), static_cast<float>( 255. ) },
"%s", seg.c_str() );
#else
SDL_Color c = curses_color_to_SDL( color );
ImGui::TextColored( { static_cast<float>( c.r / 255. ), static_cast<float>( c.g / 255. ),
static_cast<float>( c.b / 255. ), static_cast<float>( c.a / 255. ) },
"%s", seg.c_str() );
#endif
ImGui::TextUnformatted( seg.c_str() );
GImGui->LastItemData.ID = itemId;
if( is_focused && !*is_focused ) {
*is_focused = ImGui::IsItemFocused();
}
if( is_hovered && !*is_hovered ) {
*is_hovered = GImGui->HoveredId == itemId;
}

}
}

ImGui::PopTextWrapPos();
ImGui::PopID();
}

Expand Down Expand Up @@ -476,7 +475,8 @@ cataimgui::window::window( int window_flags )

this->window_flags = window_flags | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNavFocus |
ImGuiWindowFlags_NoBringToFrontOnFocus;
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoScrollbar |
ImGuiWindowFlags_NoScrollWithMouse;
}

cataimgui::window::window( const std::string &id_, int window_flags ) : window( window_flags )
Expand Down
14 changes: 8 additions & 6 deletions src/cata_imgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ struct item_info_data;

struct point;
class ImVec2;
class ImVec4;
class Font;
class input_context;

namespace cataimgui
{
ImVec4 imvec4_from_color( nc_color &color );

struct bounds {
float x;
float y;
Expand Down Expand Up @@ -76,6 +79,11 @@ class client
void point_to_imvec2( point *src, ImVec2 *dest );
void imvec2_to_point( ImVec2 *src, point *dest );

void draw_colored_text( std::string const &text, const nc_color &color, bool *is_selected = nullptr,
bool *is_focused = nullptr, bool *is_hovered = nullptr );
void draw_colored_text( std::string const &text, nc_color &color, bool *is_selected = nullptr,
bool *is_focused = nullptr, bool *is_hovered = nullptr );

class window
{
std::unique_ptr<class window_impl> p_impl;
Expand All @@ -86,12 +94,6 @@ class window
public:
explicit window( const std::string &id_, int window_flags = 0 );
virtual ~window();
void draw_colored_text( std::string const &text, const nc_color &color,
float wrap_width = 0.0F, bool *is_selected = nullptr,
bool *is_focused = nullptr, bool *is_hovered = nullptr );
void draw_colored_text( std::string const &text, nc_color &color,
float wrap_width = 0.0F, bool *is_selected = nullptr,
bool *is_focused = nullptr, bool *is_hovered = nullptr );
bool action_button( const std::string &action, const std::string &text );
bool has_button_action();
std::string get_button_action();
Expand Down
16 changes: 8 additions & 8 deletions src/editmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1282,7 +1282,7 @@ void editmap::edit_fld()
const field_type &ftype = idx.obj();
int fsel_intensity = field_intensity;
if( fmenu.ret > 0 ) {
shared_ptr_fast<ui_adaptor> fmenu_ui = fmenu.create_or_get_ui_adaptor();
shared_ptr_fast<uilist_impl> fmenu_ui = fmenu.create_or_get_ui();

uilist femenu;
femenu.w_width_setup = width;
Expand Down Expand Up @@ -1421,7 +1421,7 @@ void editmap::edit_itm()
restore_on_out_of_scope<std::string> info_txt_prev( info_txt_curr );
restore_on_out_of_scope<std::string> info_title_prev( info_title_curr );

shared_ptr_fast<ui_adaptor> ilmenu_ui = ilmenu.create_or_get_ui_adaptor();
shared_ptr_fast<uilist_impl> ilmenu_ui = ilmenu.create_or_get_ui();

do {
info_txt_curr.clear();
Expand Down Expand Up @@ -1463,7 +1463,7 @@ void editmap::edit_itm()
};
imenu.allow_additional = true;

shared_ptr_fast<ui_adaptor> imenu_ui = imenu.create_or_get_ui_adaptor();
shared_ptr_fast<uilist_impl> imenu_ui = imenu.create_or_get_ui();

do {
imenu.query();
Expand Down Expand Up @@ -1848,7 +1848,7 @@ void editmap::mapgen_preview( const real_coords &tc, uilist &gmenu )

gmenu.border_color = c_light_gray;
gmenu.hilight_color = c_black_white;
gmenu.create_or_get_ui_adaptor()->invalidate_ui();
//gmenu.create_or_get_ui_adaptor()->invalidate_ui();

uilist gpmenu;
gpmenu.w_width_setup = width;
Expand Down Expand Up @@ -1976,10 +1976,10 @@ void editmap::mapgen_preview( const real_coords &tc, uilist &gmenu )
} else if( gpmenu.ret == UILIST_ADDITIONAL ) {
if( gpmenu.ret_act == "LEFT" ) {
gmenu.scrollby( -1 );
gmenu.create_or_get_ui_adaptor()->invalidate_ui();
//gmenu.create_or_get_ui_adaptor()->invalidate_ui();
} else if( gpmenu.ret_act == "RIGHT" ) {
gmenu.scrollby( 1 );
gmenu.create_or_get_ui_adaptor()->invalidate_ui();
//gmenu.create_or_get_ui_adaptor()->invalidate_ui();
}
}
showpreview = gpmenu.ret == UILIST_TIMEOUT ? !showpreview : true;
Expand All @@ -1991,7 +1991,7 @@ void editmap::mapgen_preview( const real_coords &tc, uilist &gmenu )
}
gmenu.border_color = c_magenta;
gmenu.hilight_color = h_white;
gmenu.create_or_get_ui_adaptor()->invalidate_ui();
//gmenu.create_or_get_ui_adaptor()->invalidate_ui();
hilights["mapgentgt"].points.clear();
cleartmpmap( tmpmap );
}
Expand Down Expand Up @@ -2191,7 +2191,7 @@ void editmap::edit_mapgen()

if( gmenu.ret >= 0 ) {
blink = false;
shared_ptr_fast<ui_adaptor> gmenu_ui = gmenu.create_or_get_ui_adaptor();
shared_ptr_fast<uilist_impl> gmenu_ui = gmenu.create_or_get_ui();
mapgen_preview( tc, gmenu );
blink = true;
} else if( gmenu.ret == UILIST_ADDITIONAL ) {
Expand Down
9 changes: 5 additions & 4 deletions src/input_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ void keybindings_ui::draw_controls()
scroll_offset = SIZE_MAX;
size_t legend_idx = 0;
for( ; legend_idx < 4; legend_idx++ ) {
draw_colored_text( legend[legend_idx], c_white );
cataimgui::draw_colored_text( legend[legend_idx], c_white );
ImGui::SameLine();
std::string button_text_no_color = remove_color_tags( buttons[legend_idx].second );
ImGui::SetCursorPosX( str_width_to_pixels( width ) - ( get_text_width(
Expand All @@ -693,7 +693,7 @@ void keybindings_ui::draw_controls()
ImGui::EndDisabled();
}
for( ; legend_idx < legend.size(); legend_idx++ ) {
draw_colored_text( legend[legend_idx], c_white );
cataimgui::draw_colored_text( legend[legend_idx], c_white );
}
draw_filter( *ctxt, status == kb_menu_status::filter );
if( last_status != status && status == kb_menu_status::filter ) {
Expand Down Expand Up @@ -769,8 +769,9 @@ void keybindings_ui::draw_controls()
key_text += string_format( "%s:", ctxt->get_action_name( action_id ) );
bool is_selected = false;
bool is_hovered = false;
draw_colored_text( key_text, col, 0.0f, status == kb_menu_status::show ? nullptr : &is_selected,
nullptr, &is_hovered );
cataimgui::draw_colored_text( key_text, col,
status == kb_menu_status::show ? nullptr : &is_selected,
nullptr, &is_hovered );
if( ( is_selected || is_hovered ) && invlet != ' ' ) {
highlight_row_index = i;
}
Expand Down