Skip to content

Commit

Permalink
Window manager class for properly refreshing a stack of windows
Browse files Browse the repository at this point in the history
  • Loading branch information
Qrox committed Feb 11, 2020
1 parent 9aa7645 commit fa1024e
Show file tree
Hide file tree
Showing 10 changed files with 335 additions and 59 deletions.
7 changes: 4 additions & 3 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
#include "ret_val.h"
#include "tileray.h"
#include "ui.h"
#include "ui_manager.h"
#include "units.h"
#include "int_id.h"
#include "string_id.h"
Expand Down Expand Up @@ -1440,7 +1441,7 @@ bool game::do_turn()
}
sounds::process_sound_markers( &u );
if( !u.activity && !u.has_distant_destination() && uquit != QUIT_WATCH ) {
draw();
ui_manager::redraw();
}

if( handle_action() ) {
Expand Down Expand Up @@ -1537,7 +1538,7 @@ bool game::do_turn()
mon_info_update();
u.process_turn();
if( u.moves < 0 && get_option<bool>( "FORCE_REDRAW" ) ) {
draw();
ui_manager::redraw();
refresh_display();
}

Expand All @@ -1550,7 +1551,7 @@ bool game::do_turn()

if( player_is_sleeping ) {
if( calendar::once_every( 30_minutes ) || !player_was_sleeping ) {
draw();
ui_manager::redraw();
//Putting this in here to save on checking
if( calendar::once_every( 1_hours ) ) {
add_artifact_dreams( );
Expand Down
58 changes: 37 additions & 21 deletions src/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "string_formatter.h"
#include "string_input_popup.h"
#include "translations.h"
#include "ui_manager.h"
#include "color.h"
#include "point.h"

Expand Down Expand Up @@ -1014,13 +1015,32 @@ action_id input_context::display_menu( const bool permit_execute_action )

std::string hotkeys = ctxt.get_available_single_char_hotkeys( display_help_hotkeys );

int maxwidth = max( FULL_SCREEN_WIDTH, TERMX );
int width = min( 80, maxwidth );
int maxheight = max( FULL_SCREEN_HEIGHT, TERMY );
int height = min( maxheight, static_cast<int>( hotkeys.size() ) + LEGEND_HEIGHT + BORDER_SPACE );

catacurses::window w_help = catacurses::newwin( height - 2, width - 2,
point( maxwidth / 2 - width / 2, maxheight / 2 - height / 2 ) );
ui_adaptor ui;
int width = 0;
int height = 0;
catacurses::window w_help;
size_t display_height = 0;
size_t legwidth = 0;
string_input_popup spopup;
const auto recalc_size = [&]( ui_adaptor & ui ) {
int maxwidth = max( FULL_SCREEN_WIDTH, TERMX );
width = min( 80, maxwidth );
int maxheight = max( FULL_SCREEN_HEIGHT, TERMY );
height = min( maxheight, static_cast<int>( hotkeys.size() ) + LEGEND_HEIGHT + BORDER_SPACE );

w_help = catacurses::newwin( height - 2, width - 2,
point( maxwidth / 2 - width / 2, maxheight / 2 - height / 2 ) );
// height of the area usable for display of keybindings, excludes headers & borders
display_height = height - LEGEND_HEIGHT - BORDER_SPACE; // -2 for the border
// width of the legend
legwidth = width - 4 - BORDER_SPACE;
spopup.window( w_help, 4, 8, legwidth )
.max_length( legwidth )
.context( ctxt );
ui.position_from_window( w_help );
};
recalc_size( ui );
ui.on_screen_resize( recalc_size );

// has the user changed something?
bool changed = false;
Expand All @@ -1042,10 +1062,6 @@ action_id input_context::display_menu( const bool permit_execute_action )
static const nc_color unbound_key = c_light_red;
// (vertical) scroll offset
size_t scroll_offset = 0;
// height of the area usable for display of keybindings, excludes headers & borders
const size_t display_height = height - LEGEND_HEIGHT - BORDER_SPACE; // -2 for the border
// width of the legend
const size_t legwidth = width - 4 - BORDER_SPACE;
// keybindings help
std::string legend;
legend += colorize( _( "Unbound keys" ), unbound_key ) + "\n";
Expand All @@ -1060,14 +1076,8 @@ action_id input_context::display_menu( const bool permit_execute_action )
std::string filter_phrase;
std::string action;
int raw_input_char = 0;
string_input_popup spopup;
spopup.window( w_help, 4, 8, legwidth )
.max_length( legwidth )
.context( ctxt );

// do not switch IME mode now, but restore previous mode on return
ime_sentry sentry( ime_sentry::keep );
while( true ) {
const auto redraw = [&]( const ui_adaptor & ) {
werase( w_help );
draw_border( w_help, BORDER_COLOR, _( "Keybindings" ), c_light_red );
draw_scrollbar( w_help, scroll_offset, display_height,
Expand Down Expand Up @@ -1115,14 +1125,20 @@ action_id input_context::display_menu( const bool permit_execute_action )
}

// spopup.query_string() will call wrefresh( w_help )
catacurses::refresh();

spopup.text( filter_phrase );
spopup.query_string( false, true );
};
ui.on_redraw( redraw );

// do not switch IME mode now, but restore previous mode on return
ime_sentry sentry( ime_sentry::keep );
while( true ) {
ui_manager::redraw();

if( status == s_show ) {
filter_phrase = spopup.query_string( false );
action = ctxt.input_to_action( ctxt.get_raw_input() );
} else {
spopup.query_string( false, true );
action = ctxt.handle_input();
}
raw_input_char = ctxt.get_raw_input().get_first_input();
Expand Down
11 changes: 10 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "debug.h"
#include "filesystem.h"
#include "game.h"
#include "input.h"
#include "loading_ui.h"
#include "main_menu.h"
#include "mapsharing.h"
Expand All @@ -35,8 +36,8 @@
#include "path_info.h"
#include "rng.h"
#include "translations.h"
#include "input.h"
#include "type_id.h"
#include "ui_manager.h"

#if defined(TILES)
# if defined(_MSC_VER) && defined(USE_VCPKG)
Expand Down Expand Up @@ -685,6 +686,14 @@ int main( int argc, char *argv[] )
}
}

ui_adaptor main_ui;
main_ui.position_from_window( catacurses::stdscr );
main_ui.on_redraw( []( const ui_adaptor & ) {
g->draw();
} );
main_ui.on_screen_resize( []( ui_adaptor & ui ) {
ui.position_from_window( catacurses::stdscr );
} );
while( !g->do_turn() );
}

Expand Down
12 changes: 10 additions & 2 deletions src/popup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,23 @@
#include <array>
#include <memory>

#include "catacharset.h"
#include "ime.h"
#include "input.h"
#include "output.h"
#include "catacharset.h"

extern bool test_mode;

query_popup::query_popup()
: cur( 0 ), default_text_color( c_white ), anykey( false ), cancel( false ), ontop( false ),
fullscr( false )
{
adaptor.on_redraw( [this]( const ui_adaptor & ) {
show();
} );
adaptor.on_screen_resize( [this]( ui_adaptor & ) {
init();
} );
}

query_popup &query_popup::context( const std::string &cat )
Expand Down Expand Up @@ -208,6 +214,8 @@ void query_popup::init() const
const int win_x = ( TERMX - win_width ) / 2;
const int win_y = ontop ? 0 : ( TERMY - win_height ) / 2;
win = catacurses::newwin( win_height, win_width, point( win_x, win_y ) );

adaptor.position_from_window( win );
}

void query_popup::show() const
Expand Down Expand Up @@ -249,7 +257,7 @@ query_popup::result query_popup::query_once()
return { false, "ERROR", {} };
}

show();
ui_manager::redraw();

input_context ctxt( category );
if( cancel || !options.empty() ) {
Expand Down
4 changes: 3 additions & 1 deletion src/popup.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
#include <vector>
#include <utility>

#include "color.h"
#include "cursesdef.h"
#include "input.h"
#include "color.h"
#include "string_formatter.h"
#include "ui_manager.h"

/**
* UI class for displaying messages or querying player input with popups.
Expand Down Expand Up @@ -217,6 +218,7 @@ class query_popup
mutable catacurses::window win;
mutable std::vector<std::string> folded_msg;
mutable std::vector<button> buttons;
mutable ui_adaptor adaptor;

static std::vector<std::vector<std::string>> fold_query(
const std::string &category,
Expand Down
83 changes: 52 additions & 31 deletions src/sdltiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#include "json.h"
#include "optional.h"
#include "point.h"
#include "ui_manager.h"

#if defined(__linux__)
# include <cstdlib> // getenv()/setenv()
Expand Down Expand Up @@ -1773,7 +1774,7 @@ bool handle_resize( int w, int h )
TERMINAL_HEIGHT = WindowHeight / fontheight / scaling_factor;
SetupRenderTarget();
game_ui::init_ui();

ui_manager::screen_resized();
return true;
}
return false;
Expand Down Expand Up @@ -2891,6 +2892,11 @@ static void CheckMessages()
break;
}
break;
case SDL_RENDER_TARGETS_RESET:
// todo fix flicker when restoring window from sleep
// tood also redraw in wincurses port
ui_manager::redraw_all();
break;
case SDL_KEYDOWN: {
#if defined(__ANDROID__)
// Toggle virtual keyboard with Android back button. For some reason I get double inputs, so ignore everything once it's already down.
Expand Down Expand Up @@ -3697,45 +3703,60 @@ void rescale_tileset( int size )
game_ui::init_ui();
}

cata::optional<tripoint> input_context::get_coordinates( const catacurses::window &capture_win_ )
window_dimensions get_window_dimensions( const catacurses::window &win )
{
if( !coordinate_input_received ) {
return cata::nullopt;
}

cata_cursesport::WINDOW *const capture_win = ( capture_win_.get() ? capture_win_ :
g->w_terrain ).get<cata_cursesport::WINDOW>();
cata_cursesport::WINDOW *const pwin = win.get<cata_cursesport::WINDOW>();

// this contains the font dimensions of the capture_win,
// not necessarily the global standard font dimensions.
int fw = fontwidth;
int fh = fontheight;
// tiles might have different dimensions than standard font
if( use_tiles && capture_win == g->w_terrain ) {
fw = tilecontext->get_tile_width();
fh = tilecontext->get_tile_height();
// add_msg( m_info, "tile map fw %d fh %d", fw, fh);
} else if( map_font && capture_win == g->w_terrain ) {
window_dimensions dim;
if( use_tiles && win == g->w_terrain ) {
// tiles might have different dimensions than standard font
dim.scaled_font_size.x = tilecontext->get_tile_width();
dim.scaled_font_size.y = tilecontext->get_tile_height();
} else if( map_font && win == g->w_terrain ) {
// map font (if any) might differ from standard font
fw = map_font->fontwidth;
fh = map_font->fontheight;
} else if( overmap_font && capture_win == g->w_overmap ) {
fw = overmap_font->fontwidth;
fh = overmap_font->fontheight;
dim.scaled_font_size.x = map_font->fontwidth;
dim.scaled_font_size.y = map_font->fontheight;
} else if( overmap_font && win == g->w_overmap ) {
dim.scaled_font_size.x = overmap_font->fontwidth;
dim.scaled_font_size.y = overmap_font->fontheight;
} else {
dim.scaled_font_size.x = fontwidth;
dim.scaled_font_size.y = fontheight;
}

// multiplied by the user's specified scaling factor regardless of whether tiles are in use
fw = fw * get_scaling_factor();
fh = fh * get_scaling_factor();
dim.scaled_font_size *= get_scaling_factor();

dim.window_cell_pos = pwin->pos;
dim.window_cell_size.x = pwin->width;
dim.window_cell_size.y = pwin->height;

// Translate mouse coordinates to map coordinates based on tile size,
// the window position is *always* in standard font dimensions!
const point win_min( capture_win->pos.x * fontwidth, capture_win->pos.y * fontheight );
dim.window_pixel_pos = point( dim.window_cell_pos.x * fontwidth,
dim.window_cell_pos.y * fontheight );
// But the size of the window is in the font dimensions of the window.
const point win_size( capture_win->width * fw, capture_win->height * fh );
dim.window_pixel_size.x = dim.window_cell_size.x * dim.scaled_font_size.x;
dim.window_pixel_size.y = dim.window_cell_size.y * dim.scaled_font_size.y;

return dim;
}

cata::optional<tripoint> input_context::get_coordinates( const catacurses::window &capture_win_ )
{
if( !coordinate_input_received ) {
return cata::nullopt;
}

const catacurses::window &capture_win = capture_win_ ? capture_win_ : g->w_terrain;
const window_dimensions dim = get_window_dimensions( capture_win );

const int &fw = dim.scaled_font_size.x;
const int &fh = dim.scaled_font_size.y;
const point &win_min = dim.window_pixel_pos;
const point &win_size = dim.window_pixel_size;
const point win_max = win_min + win_size;
// add_msg( m_info, "win_ left %d top %d right %d bottom %d", win_left,win_top,win_right,win_bottom);
// add_msg( m_info, "coordinate_ x %d y %d", coordinate_x, coordinate_y);

// Translate mouse coordinates to map coordinates based on tile size
// Check if click is within bounds of the window we care about
const rectangle win_bounds( win_min, win_max );
if( !win_bounds.contains_inclusive( coordinate ) ) {
Expand All @@ -3758,7 +3779,7 @@ cata::optional<tripoint> input_context::get_coordinates( const catacurses::windo
p = view_offset + selected;
} else {
const point selected( screen_pos.x / fw, screen_pos.y / fh );
p = view_offset + selected - point( capture_win->width / 2, capture_win->height / 2 );
p = view_offset + selected - dim.window_cell_size / 2;
}

return tripoint( p, g->get_levz() );
Expand Down
15 changes: 15 additions & 0 deletions src/sdltiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@
#include <memory>

#include "color_loader.h"
#include "point.h"
#include "sdl_wrappers.h"

class cata_tiles;

namespace catacurses
{
class window;
} // namespace catacurses

extern SDL_Texture_Ptr alt_rect_tex;
extern bool alt_rect_tex_enabled;
extern std::unique_ptr<cata_tiles> tilecontext;
Expand All @@ -25,6 +31,15 @@ void rescale_tileset( int size );
bool save_screenshot( const std::string &file_path );
void toggle_fullscreen_window();

struct window_dimensions {
point scaled_font_size;
point window_cell_pos;
point window_cell_size;
point window_pixel_pos;
point window_pixel_size;
};
window_dimensions get_window_dimensions( const catacurses::window &win );

#endif // TILES

#endif // CATA_SDLTILES_H
Loading

0 comments on commit fa1024e

Please sign in to comment.