Mega draw manager implementation
This has been megasquashed because it was a month-long mess of fixes and reworks. In summary: * objects no-longer draw by hooking a DRAW event. In stead they inherit from gui2::top_level_drawable, and implement its interface. * the game display now renders to an offscreen buffer. This is used to implement hardware scrolling, and to redraw after halos, floating labels etc. move. * halos, floating labels, tooltips, and a few more things are now drawn on top of the game display, rather than as part of it. This allows them to be updated independently without reading pixels from the screen. * surface restorers have been removed. Reading pixels from the screen should now be unnecessary excepting two cases: (a) screenshots, (b) background blur. Blur is cached, and screenshots are occasional. * GUI2 widgets no longer keep track of dirty state. They are redrawn as necessary. Most places which previously set dirty state now queue a redraw in their part of the screen in stead. * A consequence is that active translucency is enabled across all UI elements, and the game display can (and does) continue to animate while menus and dialogs are showing. * performance is drastically increased for basically everything, most notably map scrolling, floating text, and halos. * CPU usage is drastically decreased. With animations disabled it is essentially zero while nothing is moving. * GPU usage is also minimal. The display is only flipped if something is drawn.
This commit is contained in:
parent
3dbf212f8c
commit
06254e5581
136 changed files with 1514 additions and 1893 deletions
|
@ -218,7 +218,8 @@ bool uninstall_local_addons()
|
|||
|
||||
gui2::show_transient_message(
|
||||
dlg_title,
|
||||
dlg_msg + list_lead + utils::bullet_list(succeeded_names), "", false, false, true);
|
||||
dlg_msg + list_lead + utils::bullet_list(succeeded_names)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace soundsource
|
|||
class manager;
|
||||
}
|
||||
|
||||
class controller_base : public video2::draw_layering, public events::pump_monitor
|
||||
class controller_base : public events::sdl_handler, public events::pump_monitor
|
||||
{
|
||||
public:
|
||||
controller_base();
|
||||
|
|
531
src/display.cpp
531
src/display.cpp
|
@ -23,6 +23,7 @@
|
|||
#include "cursor.hpp"
|
||||
#include "display.hpp"
|
||||
#include "draw.hpp"
|
||||
#include "draw_manager.hpp"
|
||||
#include "fake_unit_manager.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "font/sdl_ttf_compat.hpp"
|
||||
|
@ -84,6 +85,8 @@ static lg::log_domain log_display("display");
|
|||
#define MinZoom (zoom_levels.front())
|
||||
#define MaxZoom (zoom_levels.back())
|
||||
|
||||
using std::endl;
|
||||
|
||||
namespace {
|
||||
// if this is enabled with :benchmark, then everything is marked as invalid and redrawn each time
|
||||
bool benchmark = false;
|
||||
|
@ -139,17 +142,15 @@ void display::parse_team_overlays()
|
|||
|
||||
void display::add_overlay(const map_location& loc, const std::string& img, const std::string& halo, const std::string& team_name, const std::string& item_id, bool visible_under_fog, float z_order)
|
||||
{
|
||||
if (halo_man_) {
|
||||
halo::handle halo_handle;
|
||||
if(halo != "") {
|
||||
halo_handle = halo_man_->add(get_location_x(loc) + hex_size() / 2,
|
||||
get_location_y(loc) + hex_size() / 2, halo, loc);
|
||||
}
|
||||
|
||||
std::vector<overlay>& overlays = get_overlays()[loc];
|
||||
auto it = std::find_if(overlays.begin(), overlays.end(), [z_order](const overlay& ov) { return ov.z_order > z_order; });
|
||||
overlays.emplace(it, img, halo, halo_handle, team_name, item_id, visible_under_fog, z_order);
|
||||
halo::handle halo_handle;
|
||||
if(halo != "") {
|
||||
halo_handle = halo_man_.add(get_location_x(loc) + hex_size() / 2,
|
||||
get_location_y(loc) + hex_size() / 2, halo, loc);
|
||||
}
|
||||
|
||||
std::vector<overlay>& overlays = get_overlays()[loc];
|
||||
auto it = std::find_if(overlays.begin(), overlays.end(), [z_order](const overlay& ov) { return ov.z_order > z_order; });
|
||||
overlays.emplace(it, img, halo, halo_handle, team_name, item_id, visible_under_fog, z_order);
|
||||
}
|
||||
|
||||
void display::remove_overlay(const map_location& loc)
|
||||
|
@ -173,11 +174,9 @@ display::display(const display_context* dc,
|
|||
std::weak_ptr<wb::manager> wb,
|
||||
reports& reports_object,
|
||||
const std::string& theme_id,
|
||||
const config& level,
|
||||
bool auto_join)
|
||||
: video2::draw_layering(auto_join)
|
||||
, dc_(dc)
|
||||
, halo_man_(new halo::manager(*this))
|
||||
const config& level)
|
||||
: dc_(dc)
|
||||
, halo_man_()
|
||||
, wb_(wb)
|
||||
, exclusive_unit_draw_requests_()
|
||||
, screen_(CVideo::get_singleton())
|
||||
|
@ -192,11 +191,9 @@ display::display(const display_context* dc,
|
|||
, builder_(new terrain_builder(level, (dc_ ? &dc_->map() : nullptr), theme_.border().tile_image, theme_.border().show_border))
|
||||
, minimap_(nullptr)
|
||||
, minimap_location_(sdl::empty_rect)
|
||||
, redrawMinimap_(false)
|
||||
, redraw_background_(true)
|
||||
, invalidateAll_(true)
|
||||
, diagnostic_label_(0)
|
||||
, panelsDrawn_(false)
|
||||
, invalidateGameStatus_(true)
|
||||
, map_labels_(new map_labels(nullptr))
|
||||
, reports_object_(&reports_object)
|
||||
|
@ -205,7 +202,7 @@ display::display(const display_context* dc,
|
|||
, fps_counter_()
|
||||
, fps_start_()
|
||||
, fps_actual_()
|
||||
, reportRects_()
|
||||
, reportLocations_()
|
||||
, reportSurfaces_()
|
||||
, reports_()
|
||||
, menu_buttons_()
|
||||
|
@ -298,9 +295,8 @@ void display::set_theme(const std::string& new_theme)
|
|||
menu_buttons_.clear();
|
||||
action_buttons_.clear();
|
||||
create_buttons();
|
||||
invalidate_theme();
|
||||
rebuild_all();
|
||||
redraw_everything();
|
||||
redraw_everything(); // TODO: draw_manager - rename?
|
||||
}
|
||||
|
||||
void display::init_flags() {
|
||||
|
@ -511,16 +507,6 @@ void display::change_display_context(const display_context * dc)
|
|||
builder_->change_map(&dc_->map()); //TODO: Should display_context own and initialize the builder object?
|
||||
}
|
||||
|
||||
void display::reset_halo_manager()
|
||||
{
|
||||
halo_man_.reset(new halo::manager(*this));
|
||||
}
|
||||
|
||||
void display::reset_halo_manager(halo::manager & halo_man)
|
||||
{
|
||||
halo_man_.reset(&halo_man);
|
||||
}
|
||||
|
||||
void display::blindfold(bool value)
|
||||
{
|
||||
if(value == true)
|
||||
|
@ -908,10 +894,9 @@ void display::create_buttons()
|
|||
}
|
||||
|
||||
auto b = std::make_shared<gui::button>(screen_, menu.title(), gui::button::TYPE_PRESS, menu.image(),
|
||||
gui::button::DEFAULT_SPACE, false, menu.overlay(), font::SIZE_BUTTON_SMALL);
|
||||
gui::button::DEFAULT_SPACE, true, menu.overlay(), font::SIZE_BUTTON_SMALL);
|
||||
|
||||
DBG_DP << "drawing button " << menu.get_id() << "\n";
|
||||
b->join_same(this);
|
||||
b->set_id(menu.get_id());
|
||||
if(!menu.tooltip().empty()) {
|
||||
b->set_tooltip_string(menu.tooltip());
|
||||
|
@ -927,11 +912,10 @@ void display::create_buttons()
|
|||
DBG_DP << "creating action buttons...\n";
|
||||
for(const auto& action : theme_.actions()) {
|
||||
auto b = std::make_shared<gui::button>(screen_, action.title(), string_to_button_type(action.type()),
|
||||
action.image(), gui::button::DEFAULT_SPACE, false, action.overlay(), font::SIZE_BUTTON_SMALL);
|
||||
action.image(), gui::button::DEFAULT_SPACE, true, action.overlay(), font::SIZE_BUTTON_SMALL);
|
||||
|
||||
DBG_DP << "drawing button " << action.get_id() << "\n";
|
||||
b->set_id(action.get_id());
|
||||
b->join_same(this);
|
||||
if(!action.tooltip(0).empty()) {
|
||||
b->set_tooltip_string(action.tooltip(0));
|
||||
}
|
||||
|
@ -950,16 +934,22 @@ void display::create_buttons()
|
|||
DBG_DP << "buttons created\n";
|
||||
}
|
||||
|
||||
void display::render_buttons()
|
||||
void display::draw_buttons()
|
||||
{
|
||||
const rect clip = draw::get_clip();
|
||||
for(auto& btn : menu_buttons_) {
|
||||
btn->set_dirty(true);
|
||||
btn->draw();
|
||||
if(clip.overlaps(btn->location())) {
|
||||
//btn->set_dirty(true);
|
||||
// TODO: draw_manager - this won't actually draw, because it's not "dirty", but dirty can't be set because that invalidates. Overhaul.
|
||||
btn->draw();
|
||||
}
|
||||
}
|
||||
|
||||
for(auto& btn : action_buttons_) {
|
||||
btn->set_dirty(true);
|
||||
btn->draw();
|
||||
if(clip.overlaps(btn->location())) {
|
||||
//btn->set_dirty(true);
|
||||
btn->draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1338,13 +1328,9 @@ void display::flip()
|
|||
return;
|
||||
}
|
||||
|
||||
font::draw_floating_labels();
|
||||
events::raise_volatile_draw_event();
|
||||
// TODO: draw_manager - remove this function
|
||||
return;
|
||||
|
||||
video().render_screen();
|
||||
|
||||
events::raise_volatile_undraw_event();
|
||||
font::undraw_floating_labels();
|
||||
}
|
||||
|
||||
// frametime is in milliseconds
|
||||
|
@ -1416,42 +1402,46 @@ void display::update_display()
|
|||
|
||||
flip();
|
||||
}
|
||||
static void draw_panel(CVideo &video, const theme::panel& panel, std::vector<std::shared_ptr<gui::button>>& /*buttons*/)
|
||||
|
||||
void display::draw_panel(const theme::panel& panel)
|
||||
{
|
||||
//log_scope("draw panel");
|
||||
DBG_DP << "drawing panel " << panel.get_id() << "\n";
|
||||
|
||||
// TODO: highdpi - draw area should probably be moved to new drawing API
|
||||
const SDL_Rect screen = video.draw_area();
|
||||
SDL_Rect& loc = panel.location(screen);
|
||||
|
||||
DBG_DP << "panel location: " << loc << std::endl;
|
||||
|
||||
// Most panels are transparent.
|
||||
if (panel.image().empty()) {
|
||||
DBG_DP << "no panel image given" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: highdpi - draw area should probably be moved to new drawing API
|
||||
const rect& loc = panel.location(video().draw_area());
|
||||
|
||||
if (!loc.overlaps(draw::get_clip())) {
|
||||
return;
|
||||
}
|
||||
|
||||
DBG_DP << "drawing panel " << panel.get_id() << ' ' << loc << endl;
|
||||
|
||||
texture tex(image::get_texture(panel.image()));
|
||||
if (!tex) {
|
||||
ERR_DP << "failed to load panel texture ("
|
||||
<< "id: " << panel.get_id()
|
||||
<< ", image: " << panel.image()
|
||||
<< ")" << std::endl;
|
||||
ERR_DP << "failed to load panel " << panel.get_id()
|
||||
<< " texture: " << panel.image() << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
draw::tiled(tex, loc);
|
||||
}
|
||||
|
||||
static void draw_label(CVideo& video, const theme::label& label)
|
||||
void display::draw_label(const theme::label& label)
|
||||
{
|
||||
//log_scope("draw label");
|
||||
const rect& loc = label.location(video().draw_area());
|
||||
|
||||
if (!loc.overlaps(draw::get_clip())) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string& text = label.text();
|
||||
const color_t text_color = label.font_rgb_set() ? label.font_rgb() : font::NORMAL_COLOR;
|
||||
const std::string& icon = label.icon();
|
||||
SDL_Rect& loc = label.location(video.draw_area());
|
||||
|
||||
DBG_DP << "drawing label " << label.get_id() << ' ' << loc << endl;
|
||||
|
||||
if(icon.empty() == false) {
|
||||
draw::blit(image::get_texture(icon), loc);
|
||||
|
@ -1460,27 +1450,21 @@ static void draw_label(CVideo& video, const theme::label& label)
|
|||
tooltips::add_tooltip(loc,text);
|
||||
}
|
||||
} else if(text.empty() == false) {
|
||||
font::pango_draw_text(&video, loc, label.font_size(), text_color, text, loc.x, loc.y);
|
||||
font::pango_draw_text(&video(), loc, label.font_size(),
|
||||
text_color, text, loc.x, loc.y
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void display::draw_all_panels()
|
||||
{
|
||||
/*
|
||||
* The minimap is also a panel, force it to update its contents.
|
||||
* This is required when the size of the minimap has been modified.
|
||||
*/
|
||||
recalculate_minimap();
|
||||
|
||||
for(const auto& panel : theme_.panels()) {
|
||||
draw_panel(video(), panel, menu_buttons_);
|
||||
draw_panel(panel);
|
||||
}
|
||||
|
||||
for(const auto& label : theme_.labels()) {
|
||||
draw_label(video(), label);
|
||||
draw_label(label);
|
||||
}
|
||||
|
||||
render_buttons();
|
||||
}
|
||||
|
||||
void display::draw_text_in_hex(const map_location& loc,
|
||||
|
@ -1620,6 +1604,9 @@ void display::select_hex(map_location hex)
|
|||
|
||||
void display::highlight_hex(map_location hex)
|
||||
{
|
||||
if(mouseoverHex_ == hex) {
|
||||
return;
|
||||
}
|
||||
invalidate(mouseoverHex_);
|
||||
mouseoverHex_ = hex;
|
||||
invalidate(mouseoverHex_);
|
||||
|
@ -1653,22 +1640,7 @@ void display::draw_init()
|
|||
invalidateAll_ = true;
|
||||
}
|
||||
|
||||
if(!panelsDrawn_) {
|
||||
draw_all_panels();
|
||||
panelsDrawn_ = true;
|
||||
}
|
||||
|
||||
if(redraw_background_) {
|
||||
// Full redraw of the background
|
||||
const SDL_Rect clip_rect = map_outside_area();
|
||||
draw::fill(clip_rect, 0, 0, 0);
|
||||
draw::tiled(
|
||||
image::get_texture(theme_.border().background_image),
|
||||
clip_rect
|
||||
);
|
||||
redraw_background_ = false;
|
||||
|
||||
// Force a full map redraw
|
||||
invalidateAll_ = true;
|
||||
}
|
||||
|
||||
|
@ -1679,7 +1651,7 @@ void display::draw_init()
|
|||
invalidateAll_ = false;
|
||||
invalidate_locations_in_rect(map_area());
|
||||
|
||||
redrawMinimap_ = true;
|
||||
redraw_minimap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1690,11 +1662,6 @@ void display::draw_wrap(bool update, bool force)
|
|||
time_between_draws = 1000 / screen_.current_refresh_rate();
|
||||
}
|
||||
|
||||
if(redrawMinimap_ && !map_screenshot_) {
|
||||
redrawMinimap_ = false;
|
||||
draw_minimap();
|
||||
}
|
||||
|
||||
if(update) {
|
||||
update_display();
|
||||
|
||||
|
@ -1769,26 +1736,36 @@ void display::announce(const std::string& message, const color_t& color, const a
|
|||
prevLabel = font::add_floating_label(flabel);
|
||||
}
|
||||
|
||||
void display::recalculate_minimap()
|
||||
{
|
||||
const rect& area = minimap_area();
|
||||
minimap_ = texture(image::getMinimap(
|
||||
area.w, area.h, get_map(),
|
||||
dc_->teams().empty() ? nullptr : &dc_->teams()[currentTeam_],
|
||||
(selectedHex_.valid() && !is_blindfolded()) ? &reach_map_ : nullptr
|
||||
));
|
||||
redraw_minimap();
|
||||
}
|
||||
|
||||
void display::redraw_minimap()
|
||||
{
|
||||
draw_manager::invalidate_region(minimap_area());
|
||||
}
|
||||
|
||||
void display::draw_minimap()
|
||||
{
|
||||
const SDL_Rect& area = minimap_area();
|
||||
const rect& area = minimap_area();
|
||||
|
||||
if(area.w == 0 || area.h == 0) {
|
||||
if(area.empty() || !area.overlaps(draw::get_clip())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: highdpi - high DPI minimap
|
||||
// TODO: highdpi - is this the best place to convert to texture?
|
||||
if(!minimap_ || minimap_.w() > area.w || minimap_.h() > area.h) {
|
||||
minimap_ = texture(image::getMinimap(area.w, area.h, get_map(),
|
||||
dc_->teams().empty() ? nullptr : &dc_->teams()[currentTeam_],
|
||||
(selectedHex_.valid() && !is_blindfolded()) ? &reach_map_ : nullptr));
|
||||
if(!minimap_) {
|
||||
return;
|
||||
}
|
||||
if(!minimap_) {
|
||||
ERR_DP << "trying to draw null minimap" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
auto clipper = draw::set_clip(area);
|
||||
auto clipper = draw::reduce_clip(area);
|
||||
|
||||
// Draw the minimap background.
|
||||
draw::fill(area, 31, 31, 23);
|
||||
|
@ -1933,18 +1910,26 @@ bool display::scroll(int xmove, int ymove, bool force)
|
|||
//
|
||||
|
||||
if(!screen_.update_locked()) {
|
||||
rect dstrect = map_area();
|
||||
dstrect.x += diff_x;
|
||||
dstrect.y += diff_y;
|
||||
dstrect.clip(map_area());
|
||||
rect dst = map_area();
|
||||
dst.x += diff_x;
|
||||
dst.y += diff_y;
|
||||
dst.clip(map_area());
|
||||
|
||||
SDL_Rect srcrect = dstrect;
|
||||
srcrect.x -= diff_x;
|
||||
srcrect.y -= diff_y;
|
||||
rect src = dst;
|
||||
src.x -= diff_x;
|
||||
src.y -= diff_y;
|
||||
|
||||
// TODO: highdpi - This is gross and should be replaced
|
||||
texture t = screen_.read_texture(&srcrect);
|
||||
draw::blit(t, dstrect);
|
||||
src = video().to_output(src);
|
||||
|
||||
// swap buffers
|
||||
std::swap(front_, back_);
|
||||
|
||||
// copy from the back to the front buffer
|
||||
auto rts = draw::set_render_target(front_);
|
||||
draw::blit(back_, dst, src);
|
||||
|
||||
// queue repaint
|
||||
draw_manager::invalidate_region(map_area());
|
||||
}
|
||||
|
||||
if(diff_y != 0) {
|
||||
|
@ -1971,7 +1956,7 @@ bool display::scroll(int xmove, int ymove, bool force)
|
|||
|
||||
scroll_event_.notify_observers();
|
||||
|
||||
redrawMinimap_ = true;
|
||||
redraw_minimap();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2047,10 +2032,6 @@ bool display::set_zoom(unsigned int amount, const bool validate_value_and_set_in
|
|||
redraw_background_ = true;
|
||||
invalidate_all();
|
||||
|
||||
// Forces a redraw after zooming.
|
||||
// This prevents some graphic glitches from occurring.
|
||||
draw();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2101,7 +2082,8 @@ void display::scroll_to_xy(int screenxpos, int screenypos, SCROLL_TYPE scroll_ty
|
|||
|
||||
if(scroll_type == WARP || scroll_type == ONSCREEN_WARP || turbo_speed() > 2.0 || preferences::scroll_speed() > 99) {
|
||||
scroll(xmove,ymove,true);
|
||||
draw();
|
||||
redraw_minimap();
|
||||
events::raise_draw_event();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2158,7 +2140,9 @@ void display::scroll_to_xy(int screenxpos, int screenypos, SCROLL_TYPE scroll_ty
|
|||
scroll(dx,dy,true);
|
||||
x_old += dx;
|
||||
y_old += dy;
|
||||
draw();
|
||||
|
||||
redraw_minimap();
|
||||
events::raise_draw_event();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2378,9 +2362,11 @@ void display::redraw_everything()
|
|||
if(screen_.update_locked())
|
||||
return;
|
||||
|
||||
DBG_DP << "redrawing everything" << endl;
|
||||
|
||||
invalidateGameStatus_ = true;
|
||||
|
||||
reportRects_.clear();
|
||||
reportLocations_.clear();
|
||||
reportSurfaces_.clear();
|
||||
reports_.clear();
|
||||
|
||||
|
@ -2403,7 +2389,6 @@ void display::redraw_everything()
|
|||
}
|
||||
}
|
||||
|
||||
panelsDrawn_ = false;
|
||||
if (!gui::in_dialog()) {
|
||||
labels().recalculate_labels();
|
||||
}
|
||||
|
@ -2447,28 +2432,39 @@ void display::draw(bool update, bool force)
|
|||
// log_scope("display::draw");
|
||||
|
||||
if(screen_.update_locked() || screen_.faked()) {
|
||||
DBG_DP << "display::draw denied" << endl;
|
||||
// TODO: draw_manager - deny drawing in draw_manager if appropriate
|
||||
return;
|
||||
}
|
||||
//DBG_DP << "display::draw" << endl;
|
||||
|
||||
// TODO: draw_manager - make this check better / kill it
|
||||
if(dirty_) {
|
||||
DBG_DP << "display::draw dirty redraw all" << endl;
|
||||
// TODO: draw_manager - flip_locker is almost certainly unnecessary
|
||||
flip_locker flip_lock(screen_);
|
||||
dirty_ = false;
|
||||
// TODO: draw_manager - remove this and integrate here
|
||||
redraw_everything();
|
||||
return;
|
||||
}
|
||||
|
||||
// Trigger cache rebuild when preference gets changed
|
||||
if(animate_water_ != preferences::animate_water()) {
|
||||
animate_water_ = preferences::animate_water();
|
||||
builder_->rebuild_cache_all();
|
||||
}
|
||||
|
||||
// TODO: draw_manager - why on earth does this need to mess with sync context?
|
||||
set_scontext_unsynced leave_synced_context;
|
||||
|
||||
draw_init();
|
||||
pre_draw();
|
||||
// invalidate animated terrain, units and haloes
|
||||
invalidate_animations();
|
||||
// TODO: draw_manager - redraw background more judiciously
|
||||
if(redraw_background_) {
|
||||
DBG_DP << "display::draw redraw background" << endl;
|
||||
// Full redraw of the background
|
||||
const SDL_Rect clip_rect = map_outside_area();
|
||||
draw::fill(clip_rect, 0, 0, 0);
|
||||
draw::tiled(
|
||||
image::get_texture(theme_.border().background_image),
|
||||
clip_rect
|
||||
);
|
||||
draw_manager::invalidate_region(map_outside_area());
|
||||
redraw_background_ = false;
|
||||
}
|
||||
|
||||
if(!get_map().empty()) {
|
||||
if(!invalidated_.empty()) {
|
||||
|
@ -2477,12 +2473,129 @@ void display::draw(bool update, bool force)
|
|||
}
|
||||
drawing_buffer_commit();
|
||||
post_commit();
|
||||
if (!map_screenshot_) {
|
||||
draw_sidebar();
|
||||
}
|
||||
|
||||
// TODO: draw_manager - what even is this for
|
||||
draw_wrap(update, force);
|
||||
|
||||
// TODO: draw_manager - event hooks rather than this, maybe?
|
||||
post_draw();
|
||||
//DBG_DP << "display::draw done" << endl;
|
||||
}
|
||||
|
||||
void display::layout()
|
||||
{
|
||||
// Ensure render textures are correctly sized and up-to-date
|
||||
update_render_textures(); // TODO
|
||||
|
||||
//DBG_DP << "display::layout" << endl;
|
||||
// TODO: draw_manager - the layout part of this, perhaps
|
||||
|
||||
// TODO: draw_manager - check usage of this and maybe delete, move or rename
|
||||
pre_draw();
|
||||
|
||||
// TODO: draw_manager - should this just be inlined here?
|
||||
draw_init();
|
||||
|
||||
// Trigger cache rebuild when preference gets changed
|
||||
if(animate_water_ != preferences::animate_water()) {
|
||||
animate_water_ = preferences::animate_water();
|
||||
builder_->rebuild_cache_all();
|
||||
}
|
||||
|
||||
// invalidate animated terrain, units and haloes
|
||||
invalidate_animations();
|
||||
|
||||
// update and invalidate reports
|
||||
refresh_reports();
|
||||
|
||||
// Update and invalidate floating labels as necessary
|
||||
font::update_floating_labels();
|
||||
// TODO: draw_manager - rename and organize this sort of stuff
|
||||
}
|
||||
|
||||
void display::render()
|
||||
{
|
||||
// This should render the game map and units.
|
||||
// It is not responsible for halos and floating labels.
|
||||
//DBG_DP << "display::render" << endl;
|
||||
|
||||
// render to the offscreen buffer
|
||||
auto target_setter = draw::set_render_target(front_);
|
||||
draw();
|
||||
|
||||
// update the minimap texture, if necessary
|
||||
// TODO: highdpi - high DPI minimap
|
||||
const rect& area = minimap_area();
|
||||
if(!minimap_ || minimap_.w() > area.w || minimap_.h() > area.h) {
|
||||
recalculate_minimap();
|
||||
if(!minimap_) {
|
||||
ERR_DP << "error creating minimap" << endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
draw_wrap(update, force);
|
||||
post_draw();
|
||||
}
|
||||
|
||||
bool display::expose(const SDL_Rect& region)
|
||||
{
|
||||
if (region == sdl::empty_rect) { return false; } // TODO temp
|
||||
//DBG_DP << "display::expose " << region << endl;
|
||||
//invalidate_locations_in_rect(region);
|
||||
// TODO: draw_manager - API to get src region in output space
|
||||
rect src_region = region;
|
||||
src_region *= video().get_pixel_scale();
|
||||
//DBG_DP << " src region " << src_region << endl;
|
||||
//draw::blit(front_, region);
|
||||
draw::blit(front_, region, src_region);
|
||||
//draw();
|
||||
// TODO: draw_manager - halo render region not rely on clip?
|
||||
// TODO: draw_manager - can we rely on clip already being set?
|
||||
auto clipper = draw::set_clip(region);
|
||||
halo_man_.render();
|
||||
|
||||
// These all check for clip region overlap before drawing
|
||||
draw_all_panels();
|
||||
draw_reports();
|
||||
draw_minimap();
|
||||
draw_buttons();
|
||||
|
||||
// TODO: draw_manager - hmm... buttons redraw over tooltips, because they are TLDs
|
||||
font::draw_floating_labels();
|
||||
|
||||
return true; // TODO: draw_manager - maybe don't flip yeah?
|
||||
}
|
||||
|
||||
rect display::screen_location()
|
||||
{
|
||||
assert(!map_screenshot_);
|
||||
//return map_outside_area();
|
||||
// well actually it also has to draw the panels, so
|
||||
return video().draw_area();
|
||||
// TODO: draw_manager - get this from theme perhaps?
|
||||
}
|
||||
|
||||
void display::update_render_textures()
|
||||
{
|
||||
// TODO: draw_manager - tidy these video accessors
|
||||
rect darea = video().draw_area();
|
||||
rect oarea = darea * video().get_pixel_scale();
|
||||
|
||||
// Check that the front buffer size is correct.
|
||||
// Buffers are always resized together, so we only need to check one.
|
||||
point size = front_.get_raw_size();
|
||||
if (size.x == oarea.w && size.y == oarea.h) {
|
||||
// buffers are fine
|
||||
return;
|
||||
}
|
||||
|
||||
// For now, just clobber and regenerate both textures.
|
||||
LOG_DP << "updating display render buffers to " << oarea << endl;
|
||||
front_ = texture(oarea.w, oarea.h, SDL_TEXTUREACCESS_TARGET);
|
||||
front_.set_draw_size(darea.w, darea.h);
|
||||
back_ = texture(oarea.w, oarea.h, SDL_TEXTUREACCESS_TARGET);
|
||||
back_.set_draw_size(darea.w, darea.h);
|
||||
// TODO: draw_manager - this is gross
|
||||
dirty_ = true;
|
||||
}
|
||||
|
||||
map_labels& display::labels()
|
||||
|
@ -2504,6 +2617,8 @@ void display::draw_invalidated() {
|
|||
// log_scope("display::draw_invalidated");
|
||||
SDL_Rect clip_rect = get_clip_rect();
|
||||
auto clipper = draw::set_clip(clip_rect);
|
||||
DBG_DP << "drawing " << invalidated_.size() << " invalidated hexes"
|
||||
<< " with clip " << clip_rect << endl;
|
||||
for (const map_location& loc : invalidated_) {
|
||||
int xpos = get_location_x(loc);
|
||||
int ypos = get_location_y(loc);
|
||||
|
@ -2515,6 +2630,7 @@ void display::draw_invalidated() {
|
|||
}
|
||||
draw_hex(loc);
|
||||
drawn_hexes_+=1;
|
||||
draw_manager::invalidate_region(hex_rect.intersect(clip_rect));
|
||||
}
|
||||
invalidated_hexes_ += invalidated_.size();
|
||||
|
||||
|
@ -2734,7 +2850,8 @@ void display::refresh_report(const std::string& report_name, const config * new_
|
|||
{
|
||||
const theme::status_item *item = theme_.get_status_item(report_name);
|
||||
if (!item) {
|
||||
reportSurfaces_[report_name].reset();
|
||||
// TODO: draw_manager omfg why are there unused reports here
|
||||
//WRN_DP << "no report '" << report_name << "' in theme" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2752,48 +2869,31 @@ void display::refresh_report(const std::string& report_name, const config * new_
|
|||
if ( new_cfg == nullptr )
|
||||
new_cfg = &generated_cfg;
|
||||
|
||||
SDL_Rect &rect = reportRects_[report_name];
|
||||
const SDL_Rect &new_rect = item->location(screen_.draw_area());
|
||||
texture &bg_restore = reportSurfaces_[report_name];
|
||||
rect& loc = reportLocations_[report_name];
|
||||
// TODO: draw_manager - rect
|
||||
const SDL_Rect& new_loc = item->location(screen_.draw_area());
|
||||
config &report = reports_[report_name];
|
||||
|
||||
// Report and its location is unchanged since last time. Do nothing.
|
||||
if (bg_restore && rect == new_rect && report == *new_cfg) {
|
||||
if (loc == new_loc && report == *new_cfg) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the config in reports_.
|
||||
DBG_DP << "updating report: " << report_name << endl;
|
||||
|
||||
// Mark both old and new locations for redraw.
|
||||
draw_manager::invalidate_region(loc);
|
||||
draw_manager::invalidate_region(new_loc);
|
||||
|
||||
// Update the config and current location.
|
||||
report = *new_cfg;
|
||||
loc = new_loc;
|
||||
|
||||
// TODO: highdpi - remove background restorer
|
||||
if (bg_restore) {
|
||||
draw::blit(bg_restore, rect);
|
||||
}
|
||||
|
||||
// If the rectangle has just changed, assign the surface to it
|
||||
if (!bg_restore || new_rect != rect)
|
||||
{
|
||||
bg_restore.reset();
|
||||
rect = new_rect;
|
||||
|
||||
// If the rectangle is present, and we are blitting text,
|
||||
// then we need to backup the surface.
|
||||
// (Images generally won't need backing up,
|
||||
// unless they are transparent, but that is done later).
|
||||
if (rect.w > 0 && rect.h > 0) {
|
||||
bg_restore = texture(screen_.read_pixels_low_res(&rect));
|
||||
if (!reportSurfaces_[report_name]) {
|
||||
ERR_DP << "Could not backup background for report!" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tooltips::clear_tooltips(rect);
|
||||
// TODO: draw_manager - verify this is okay here
|
||||
tooltips::clear_tooltips(loc);
|
||||
|
||||
if (report.empty()) return;
|
||||
|
||||
int x = rect.x, y = rect.y;
|
||||
|
||||
// Add prefix, postfix elements.
|
||||
// Make sure that they get the same tooltip
|
||||
// as the guys around them.
|
||||
|
@ -2810,17 +2910,36 @@ void display::refresh_report(const std::string& report_name, const config * new_
|
|||
e["tooltip"] = report.child("element", -1)["tooltip"];
|
||||
}
|
||||
|
||||
// Do a fake run of drawing the report, so tooltips can be determined.
|
||||
// TODO: this is horrible, refactor reports to actually make sense
|
||||
draw_report(report_name, true);
|
||||
}
|
||||
|
||||
void display::draw_report(const std::string& report_name, bool tooltip_test)
|
||||
{
|
||||
const theme::status_item *item = theme_.get_status_item(report_name);
|
||||
if (!item) {
|
||||
// TODO: draw_manager unused report_clock report_battery WTF
|
||||
//WRN_DP << "no report '" << report_name << "' in theme" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
const rect& loc = reportLocations_[report_name];
|
||||
const config& report = reports_[report_name];
|
||||
|
||||
int x = loc.x, y = loc.y;
|
||||
|
||||
// Loop through and display each report element.
|
||||
int tallest = 0;
|
||||
int image_count = 0;
|
||||
bool used_ellipsis = false;
|
||||
std::ostringstream ellipsis_tooltip;
|
||||
SDL_Rect ellipsis_area = rect;
|
||||
SDL_Rect ellipsis_area = loc;
|
||||
|
||||
for (config::const_child_itors elements = report.child_range("element");
|
||||
elements.begin() != elements.end(); elements.pop_front())
|
||||
{
|
||||
SDL_Rect area {x, y, rect.w + rect.x - x, rect.h + rect.y - y};
|
||||
SDL_Rect area {x, y, loc.w + loc.x - x, loc.h + loc.y - y};
|
||||
if (area.h <= 0) break;
|
||||
|
||||
std::string t = elements.front()["text"];
|
||||
|
@ -2828,6 +2947,7 @@ void display::refresh_report(const std::string& report_name, const config * new_
|
|||
{
|
||||
if (used_ellipsis) goto skip_element;
|
||||
|
||||
// TODO: draw_manager - don't render if faking
|
||||
// Draw a text element.
|
||||
font::pango_text& text = font::get_text_renderer();
|
||||
bool eol = false;
|
||||
|
@ -2838,7 +2958,7 @@ void display::refresh_report(const std::string& report_name, const config * new_
|
|||
text.set_link_aware(false)
|
||||
.set_text(t, true);
|
||||
text.set_family_class(font::FONT_SANS_SERIF)
|
||||
.set_font_size(item->font_size())
|
||||
.set_font_size(item->font_size())
|
||||
.set_font_style(font::pango_text::STYLE_NORMAL)
|
||||
.set_alignment(PANGO_ALIGN_LEFT)
|
||||
.set_foreground_color(item->font_rgb_set() ? item->font_rgb() : font::NORMAL_COLOR)
|
||||
|
@ -2852,7 +2972,7 @@ void display::refresh_report(const std::string& report_name, const config * new_
|
|||
// check if next element is text with almost no space to show it
|
||||
const int minimal_text = 12; // width in pixels
|
||||
config::const_child_iterator ee = elements.begin();
|
||||
if (!eol && rect.w - (x - rect.x + s.w()) < minimal_text &&
|
||||
if (!eol && loc.w - (x - loc.x + s.w()) < minimal_text &&
|
||||
++ee != elements.end() && !(*ee)["text"].empty())
|
||||
{
|
||||
// make this element longer to trigger rendering of ellipsis
|
||||
|
@ -2871,12 +2991,14 @@ void display::refresh_report(const std::string& report_name, const config * new_
|
|||
|
||||
area.w = s.w();
|
||||
area.h = s.h();
|
||||
draw::blit(s, area);
|
||||
if (!tooltip_test) {
|
||||
draw::blit(s, area);
|
||||
}
|
||||
if (area.h > tallest) {
|
||||
tallest = area.h;
|
||||
}
|
||||
if (eol) {
|
||||
x = rect.x;
|
||||
x = loc.x;
|
||||
y += tallest;
|
||||
tallest = 0;
|
||||
} else {
|
||||
|
@ -2891,7 +3013,7 @@ void display::refresh_report(const std::string& report_name, const config * new_
|
|||
texture img(image::get_texture(t));
|
||||
|
||||
if (!img) {
|
||||
ERR_DP << "could not find image for report: '" << t << "'" << std::endl;
|
||||
ERR_DP << "could not find image for report: '" << t << "'" << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2903,7 +3025,9 @@ void display::refresh_report(const std::string& report_name, const config * new_
|
|||
|
||||
if (img.w() < area.w) area.w = img.w();
|
||||
if (img.h() < area.h) area.h = img.h();
|
||||
draw::blit(img, area);
|
||||
if (!tooltip_test) {
|
||||
draw::blit(img, area);
|
||||
}
|
||||
|
||||
++image_count;
|
||||
if (area.h > tallest) {
|
||||
|
@ -2925,7 +3049,7 @@ void display::refresh_report(const std::string& report_name, const config * new_
|
|||
skip_element:
|
||||
t = elements.front()["tooltip"].t_str().c_str();
|
||||
if (!t.empty()) {
|
||||
if (!used_ellipsis) {
|
||||
if (tooltip_test && !used_ellipsis) {
|
||||
tooltips::add_tooltip(area, t, elements.front()["help"].t_str().c_str());
|
||||
} else {
|
||||
// Collect all tooltips for the ellipsis.
|
||||
|
@ -2939,11 +3063,24 @@ void display::refresh_report(const std::string& report_name, const config * new_
|
|||
}
|
||||
}
|
||||
|
||||
if (used_ellipsis) {
|
||||
if (tooltip_test && used_ellipsis) {
|
||||
tooltips::add_tooltip(ellipsis_area, ellipsis_tooltip.str());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: draw_manager - pass in bounds in stead of using clip region
|
||||
// TODO: draw_manager - return whether anything was drawn
|
||||
void display::draw_reports()
|
||||
{
|
||||
for(const auto& it : reports_) {
|
||||
const std::string& name = it.first;
|
||||
const rect& loc = reportLocations_[name];
|
||||
if(loc.overlaps(draw::get_clip())) {
|
||||
draw_report(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void display::invalidate_all()
|
||||
{
|
||||
DBG_DP << "invalidate_all()\n";
|
||||
|
@ -3009,8 +3146,11 @@ bool display::invalidate_locations_in_rect(const SDL_Rect& rect)
|
|||
if(invalidateAll_)
|
||||
return false;
|
||||
|
||||
DBG_DP << "invalidating locations in " << rect << endl;
|
||||
|
||||
bool result = false;
|
||||
for(const map_location& loc : hexes_under_rect(rect)) {
|
||||
//DBG_DP << "invalidating " << loc.x << ',' << loc.y << endl;
|
||||
result |= invalidate(loc);
|
||||
}
|
||||
return result;
|
||||
|
@ -3029,6 +3169,7 @@ void display::invalidate_animations_location(const map_location& loc)
|
|||
|
||||
void display::invalidate_animations()
|
||||
{
|
||||
// TODO: draw_manager - WTF... how does this timing even work?
|
||||
new_animation_frame();
|
||||
animate_map_ = preferences::animate_map();
|
||||
if(animate_map_) {
|
||||
|
@ -3061,7 +3202,7 @@ void display::invalidate_animations()
|
|||
}
|
||||
} while(new_inval);
|
||||
|
||||
halo_man_->unrender(invalidated_);
|
||||
halo_man_.update();
|
||||
}
|
||||
|
||||
void display::reset_standing_animations()
|
||||
|
@ -3158,28 +3299,4 @@ void display::process_reachmap_changes()
|
|||
reach_map_changed_ = false;
|
||||
}
|
||||
|
||||
void display::handle_window_event(const SDL_Event& event)
|
||||
{
|
||||
if(event.type == SDL_WINDOWEVENT) {
|
||||
switch(event.window.event) {
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
case SDL_WINDOWEVENT_RESTORED:
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
dirty_ = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void display::handle_event(const SDL_Event& event)
|
||||
{
|
||||
if(gui2::dialogs::loading_screen::displaying()) {
|
||||
return;
|
||||
}
|
||||
if(event.type == DRAW_ALL_EVENT) {
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
display *display::singleton_ = nullptr;
|
||||
|
|
|
@ -55,6 +55,8 @@ namespace wb {
|
|||
#include "filesystem.hpp"
|
||||
#include "font/standard_colors.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "gui/core/top_level_drawable.hpp"
|
||||
#include "halo.hpp"
|
||||
#include "picture.hpp" //only needed for enums (!)
|
||||
#include "key.hpp"
|
||||
#include "time_of_day.hpp"
|
||||
|
@ -78,15 +80,14 @@ namespace wb {
|
|||
|
||||
class gamemap;
|
||||
|
||||
class display : public video2::draw_layering
|
||||
class display : public gui2::top_level_drawable
|
||||
{
|
||||
public:
|
||||
display(const display_context* dc,
|
||||
std::weak_ptr<wb::manager> wb,
|
||||
reports& reports_object,
|
||||
const std::string& theme_id,
|
||||
const config& level,
|
||||
bool auto_join = true);
|
||||
const config& level);
|
||||
|
||||
virtual ~display();
|
||||
/**
|
||||
|
@ -179,9 +180,7 @@ public:
|
|||
return *dc_;
|
||||
}
|
||||
|
||||
void reset_halo_manager();
|
||||
void reset_halo_manager(halo::manager & hm);
|
||||
halo::manager & get_halo_manager() { return *halo_man_; }
|
||||
halo::manager& get_halo_manager() { return halo_man_; }
|
||||
|
||||
/**
|
||||
* Applies r,g,b coloring to the map.
|
||||
|
@ -404,12 +403,23 @@ public:
|
|||
|
||||
void layout_buttons();
|
||||
|
||||
void render_buttons();
|
||||
|
||||
void invalidate_theme() { panelsDrawn_ = false; }
|
||||
void draw_buttons();
|
||||
|
||||
/** Update the given report. Actual drawing is done in draw_report(). */
|
||||
void refresh_report(const std::string& report_name, const config * new_cfg=nullptr);
|
||||
|
||||
/**
|
||||
* Draw the specified report.
|
||||
*
|
||||
* If test_run is true, it will simulate the draw without actually
|
||||
* drawing anything. This will add any overflowing information to the
|
||||
* report tooltip, and also registers the tooltip.
|
||||
*/
|
||||
void draw_report(const std::string& report_name, bool test_run = false);
|
||||
|
||||
/** Draw all reports. This will respect the clipping region, if set. */
|
||||
void draw_reports();
|
||||
|
||||
void draw_minimap_units();
|
||||
|
||||
/** Function to invalidate all tiles. */
|
||||
|
@ -566,6 +576,27 @@ public:
|
|||
|
||||
void draw(bool update, bool force);
|
||||
|
||||
/** Called by draw_manager to finalize screen layout. */
|
||||
virtual void layout() override;
|
||||
|
||||
/** Called by draw_manager to update offscreen render buffers. */
|
||||
virtual void render() override;
|
||||
|
||||
/** Called by draw_manager when it believes a redraw is necessary. */
|
||||
virtual bool expose(const SDL_Rect& region) override;
|
||||
|
||||
/** The current draw location of the display, on the screen. */
|
||||
virtual rect screen_location() override;
|
||||
|
||||
private:
|
||||
/** Render textures, for intermediate rendering. */
|
||||
texture front_ = {};
|
||||
texture back_ = {};
|
||||
|
||||
/** Ensure render textures are valid and correct. */
|
||||
void update_render_textures();
|
||||
|
||||
public:
|
||||
map_labels& labels();
|
||||
const map_labels& labels() const;
|
||||
|
||||
|
@ -598,13 +629,19 @@ public:
|
|||
* Schedule the minimap for recalculation.
|
||||
* Useful if any terrain in the map has changed.
|
||||
*/
|
||||
void recalculate_minimap() {minimap_.reset(); redrawMinimap_ = true; }
|
||||
void recalculate_minimap();
|
||||
|
||||
/**
|
||||
* Schedule the minimap to be redrawn.
|
||||
* Useful if units have moved about on the map.
|
||||
*/
|
||||
void redraw_minimap() { redrawMinimap_ = true; }
|
||||
void redraw_minimap();
|
||||
|
||||
private:
|
||||
/** Actually draw the minimap. */
|
||||
void draw_minimap();
|
||||
|
||||
public:
|
||||
|
||||
virtual const time_of_day& get_time_of_day(const map_location& loc = map_location::null_location()) const;
|
||||
|
||||
|
@ -615,9 +652,6 @@ public:
|
|||
|
||||
void write(config& cfg) const;
|
||||
|
||||
virtual void handle_event(const SDL_Event& );
|
||||
virtual void handle_window_event(const SDL_Event& event);
|
||||
|
||||
private:
|
||||
void read(const config& cfg);
|
||||
|
||||
|
@ -640,7 +674,7 @@ private:
|
|||
protected:
|
||||
//TODO sort
|
||||
const display_context * dc_;
|
||||
std::unique_ptr<halo::manager> halo_man_;
|
||||
halo::manager halo_man_;
|
||||
std::weak_ptr<wb::manager> wb_;
|
||||
|
||||
typedef std::map<map_location, std::string> exclusive_unit_draw_requests_t;
|
||||
|
@ -688,12 +722,12 @@ protected:
|
|||
virtual void draw_hex(const map_location& loc);
|
||||
|
||||
/**
|
||||
* Called near the end of a draw operation, derived classes can use this
|
||||
* to render a specific sidebar. Very similar to post_commit.
|
||||
* Choose which reports, if any, to refresh.
|
||||
*
|
||||
* This function should make individual refresh_report() calls for
|
||||
* whichever reports need to be updated.
|
||||
*/
|
||||
virtual void draw_sidebar() {}
|
||||
|
||||
void draw_minimap();
|
||||
virtual void refresh_reports() {}
|
||||
|
||||
enum TERRAIN_TYPE { BACKGROUND, FOREGROUND};
|
||||
|
||||
|
@ -733,11 +767,9 @@ protected:
|
|||
const std::unique_ptr<terrain_builder> builder_;
|
||||
texture minimap_;
|
||||
SDL_Rect minimap_location_;
|
||||
bool redrawMinimap_;
|
||||
bool redraw_background_;
|
||||
bool invalidateAll_;
|
||||
int diagnostic_label_;
|
||||
bool panelsDrawn_;
|
||||
bool invalidateGameStatus_;
|
||||
const std::unique_ptr<map_labels> map_labels_;
|
||||
reports * reports_object_;
|
||||
|
@ -752,7 +784,7 @@ protected:
|
|||
uint32_t last_frame_finished_ = 0u;
|
||||
|
||||
// Not set by the initializer:
|
||||
std::map<std::string, SDL_Rect> reportRects_;
|
||||
std::map<std::string, rect> reportLocations_;
|
||||
std::map<std::string, texture> reportSurfaces_;
|
||||
std::map<std::string, config> reports_;
|
||||
std::vector<std::shared_ptr<gui::button>> menu_buttons_, action_buttons_;
|
||||
|
@ -1012,7 +1044,11 @@ protected:
|
|||
|
||||
/** redraw all panels associated with the map display */
|
||||
void draw_all_panels();
|
||||
private:
|
||||
void draw_panel(const theme::panel& panel);
|
||||
void draw_label(const theme::label& label);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Initiate a redraw.
|
||||
|
|
|
@ -118,6 +118,14 @@ void sparkle()
|
|||
// Ensure layout and animations are up-to-date.
|
||||
draw_manager::layout();
|
||||
|
||||
// Unit tests rely on not doing any rendering, or waiting at all...
|
||||
// "behave differently when being tested" is really not good policy
|
||||
// but whatever.
|
||||
if(CVideo::get_singleton().any_fake()) {
|
||||
invalidated_regions_.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure any off-screen render buffers are up-to-date.
|
||||
draw_manager::render();
|
||||
|
||||
|
@ -164,8 +172,6 @@ static void render()
|
|||
|
||||
static bool draw()
|
||||
{
|
||||
// TODO: draw_manager - some things were skipping draw when video is faked. Should this skip all in this case?
|
||||
|
||||
drawing_ = true;
|
||||
|
||||
// For now just send all regions to all TLDs in the correct order.
|
||||
|
|
|
@ -32,10 +32,12 @@ bool mouse_action::has_context_menu() const
|
|||
|
||||
void mouse_action::move(editor_display& disp, const map_location& hex)
|
||||
{
|
||||
if (hex != previous_move_hex_) {
|
||||
update_brush_highlights(disp, hex);
|
||||
previous_move_hex_ = hex;
|
||||
if (hex == previous_move_hex_) {
|
||||
return;
|
||||
}
|
||||
|
||||
update_brush_highlights(disp, hex);
|
||||
previous_move_hex_ = hex;
|
||||
}
|
||||
|
||||
void mouse_action::update_brush_highlights(editor_display& disp, const map_location& hex)
|
||||
|
|
|
@ -29,18 +29,19 @@ namespace editor {
|
|||
|
||||
void mouse_action_item::move(editor_display& disp, const map_location& hex)
|
||||
{
|
||||
if (hex != previous_move_hex_) {
|
||||
|
||||
update_brush_highlights(disp, hex);
|
||||
|
||||
std::set<map_location> adjacent_set;
|
||||
for(const map_location& adj : get_adjacent_tiles(previous_move_hex_)) {
|
||||
adjacent_set.insert(adj);
|
||||
}
|
||||
|
||||
disp.invalidate(adjacent_set);
|
||||
previous_move_hex_ = hex;
|
||||
if (hex == previous_move_hex_) {
|
||||
return;
|
||||
}
|
||||
|
||||
update_brush_highlights(disp, hex);
|
||||
|
||||
std::set<map_location> adjacent_set;
|
||||
for(const map_location& adj : get_adjacent_tiles(previous_move_hex_)) {
|
||||
adjacent_set.insert(adj);
|
||||
}
|
||||
|
||||
disp.invalidate(adjacent_set);
|
||||
previous_move_hex_ = hex;
|
||||
}
|
||||
|
||||
std::unique_ptr<editor_action> mouse_action_item::click_left(editor_display& disp, int x, int y)
|
||||
|
|
|
@ -35,43 +35,44 @@ namespace editor {
|
|||
|
||||
void mouse_action_unit::move(editor_display& disp, const map_location& hex)
|
||||
{
|
||||
if (hex != previous_move_hex_) {
|
||||
if (hex == previous_move_hex_) {
|
||||
return;
|
||||
}
|
||||
|
||||
update_brush_highlights(disp, hex);
|
||||
update_brush_highlights(disp, hex);
|
||||
|
||||
std::set<map_location> adjacent_set;
|
||||
for(const map_location& adj : get_adjacent_tiles(previous_move_hex_)) {
|
||||
adjacent_set.insert(adj);
|
||||
}
|
||||
|
||||
disp.invalidate(adjacent_set);
|
||||
previous_move_hex_ = hex;
|
||||
|
||||
const unit_map& units = disp.get_units();
|
||||
const unit_map::const_unit_iterator unit_it = units.find(hex);
|
||||
if (unit_it != units.end()) {
|
||||
|
||||
disp.clear_mouseover_hex_overlay();
|
||||
|
||||
SDL_Rect rect;
|
||||
rect.x = disp.get_location_x(hex);
|
||||
rect.y = disp.get_location_y(hex);
|
||||
rect.h = disp.hex_size();
|
||||
rect.w = disp.hex_size();
|
||||
std::stringstream str;
|
||||
str << _("Identifier: ") << unit_it->id() << "\n";
|
||||
if(unit_it->name() != "") {
|
||||
str << _("Name: ") << unit_it->name() << "\n";
|
||||
}
|
||||
str << _("Type: ") << unit_it->type_name() << "\n"
|
||||
<< _("Level: ") << unit_it->level() << "\n"
|
||||
<< _("Cost: ") << unit_it->cost() << "\n";
|
||||
tooltips::clear_tooltips();
|
||||
tooltips::add_tooltip(rect, str.str());
|
||||
}
|
||||
else {
|
||||
set_mouse_overlay(disp);
|
||||
std::set<map_location> adjacent_set;
|
||||
for(const map_location& adj : get_adjacent_tiles(previous_move_hex_)) {
|
||||
adjacent_set.insert(adj);
|
||||
}
|
||||
|
||||
disp.invalidate(adjacent_set);
|
||||
previous_move_hex_ = hex;
|
||||
|
||||
const unit_map& units = disp.get_units();
|
||||
const unit_map::const_unit_iterator unit_it = units.find(hex);
|
||||
if (unit_it != units.end()) {
|
||||
|
||||
disp.clear_mouseover_hex_overlay();
|
||||
|
||||
SDL_Rect rect;
|
||||
rect.x = disp.get_location_x(hex);
|
||||
rect.y = disp.get_location_y(hex);
|
||||
rect.h = disp.hex_size();
|
||||
rect.w = disp.hex_size();
|
||||
std::stringstream str;
|
||||
str << _("Identifier: ") << unit_it->id() << "\n";
|
||||
if(unit_it->name() != "") {
|
||||
str << _("Name: ") << unit_it->name() << "\n";
|
||||
}
|
||||
str << _("Type: ") << unit_it->type_name() << "\n"
|
||||
<< _("Level: ") << unit_it->level() << "\n"
|
||||
<< _("Cost: ") << unit_it->cost() << "\n";
|
||||
tooltips::clear_tooltips();
|
||||
tooltips::add_tooltip(rect, str.str());
|
||||
}
|
||||
else {
|
||||
set_mouse_overlay(disp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
class map_generator;
|
||||
|
||||
namespace tooltips {
|
||||
struct manager;
|
||||
class manager;
|
||||
}
|
||||
|
||||
namespace font {
|
||||
|
|
|
@ -98,7 +98,7 @@ rect editor_display::get_clip_rect() const
|
|||
return map_outside_area();
|
||||
}
|
||||
|
||||
void editor_display::draw_sidebar()
|
||||
void editor_display::refresh_reports()
|
||||
{
|
||||
config element;
|
||||
config::attribute_value &text = element.add_child("element")["text"];
|
||||
|
|
|
@ -50,7 +50,7 @@ protected:
|
|||
virtual overlay_map& get_overlays() override;
|
||||
|
||||
rect get_clip_rect() const override;
|
||||
void draw_sidebar() override;
|
||||
void refresh_reports() override;
|
||||
|
||||
std::set<map_location> brush_locations_;
|
||||
|
||||
|
|
|
@ -66,7 +66,6 @@ public:
|
|||
|
||||
//drawing
|
||||
virtual void adjust_size(const SDL_Rect& target) = 0;
|
||||
virtual void draw() = 0;
|
||||
|
||||
//group
|
||||
virtual void set_group(std::size_t index) = 0;
|
||||
|
|
|
@ -246,8 +246,12 @@ bool editor_palette<Item>::is_selected_bg_item(const std::string& id)
|
|||
}
|
||||
|
||||
template<class Item>
|
||||
void editor_palette<Item>::draw_contents()
|
||||
void editor_palette<Item>::layout()
|
||||
{
|
||||
if (!dirty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
toolkit_.set_mouseover_overlay(gui_);
|
||||
|
||||
std::shared_ptr<gui::button> palette_menu_button = gui_.find_menu_button("menu-editor-terrain");
|
||||
|
@ -324,6 +328,16 @@ void editor_palette<Item>::draw_contents()
|
|||
|
||||
tile.set_dirty(true);
|
||||
tile.hide(false);
|
||||
}
|
||||
|
||||
set_dirty(false);
|
||||
}
|
||||
|
||||
template<class Item>
|
||||
void editor_palette<Item>::draw_contents()
|
||||
{
|
||||
for(std::size_t i = 0; i < buttons_.size(); ++i) {
|
||||
gui::tristate_button& tile = buttons_[i];
|
||||
tile.draw();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,9 +66,9 @@ public:
|
|||
|
||||
const std::vector<item_group>& get_groups() const override { return groups_; }
|
||||
|
||||
virtual void draw() override {
|
||||
widget::draw();
|
||||
}
|
||||
/** Called by draw_manager to validate layout before drawing. */
|
||||
virtual void layout() override;
|
||||
/** Called by widget::draw() */
|
||||
virtual void draw_contents() override;
|
||||
|
||||
void next_group() override {
|
||||
|
|
|
@ -336,8 +336,12 @@ bool location_palette::is_selected_item(const std::string& id)
|
|||
return selected_item_ == id;
|
||||
}
|
||||
|
||||
void location_palette::draw_contents()
|
||||
void location_palette::layout()
|
||||
{
|
||||
if (!dirty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
toolkit_.set_mouseover_overlay(disp_);
|
||||
|
||||
// The hotkey system will automatically enable and disable the buttons when it runs, but it doesn't
|
||||
|
@ -381,6 +385,15 @@ void location_palette::draw_contents()
|
|||
tile.set_selected(is_selected_item(item_id));
|
||||
tile.set_dirty(true);
|
||||
tile.hide(false);
|
||||
}
|
||||
|
||||
set_dirty(false);
|
||||
}
|
||||
|
||||
void location_palette::draw_contents()
|
||||
{
|
||||
for(std::size_t i = 0; i < num_visible_items(); ++i) {
|
||||
location_palette_item& tile = buttons_[i];
|
||||
tile.draw();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,9 +55,9 @@ public:
|
|||
virtual void prev_group() override {}
|
||||
virtual const std::vector<item_group>& get_groups() const override { static const std::vector<item_group> empty; return empty; }
|
||||
|
||||
virtual void draw() override {
|
||||
widget::draw();
|
||||
}
|
||||
/** Called by draw_manager to validate layout before drawing. */
|
||||
virtual void layout() override;
|
||||
/** Called by widget::draw() */
|
||||
virtual void draw_contents() override;
|
||||
|
||||
/**
|
||||
|
|
|
@ -62,11 +62,7 @@ void palette_manager::scroll_down()
|
|||
bool scrolled = active_palette().scroll_down();
|
||||
|
||||
if (scrolled) {
|
||||
|
||||
// const SDL_Rect& rect = gui_.palette_area();
|
||||
// bg_restore(rect);
|
||||
set_dirty();
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,11 +79,9 @@ bool palette_manager::can_scroll_down()
|
|||
void palette_manager::scroll_up()
|
||||
{
|
||||
bool scrolled_up = active_palette().scroll_up();
|
||||
|
||||
if(scrolled_up) {
|
||||
// const SDL_Rect rect = gui_.palette_area();
|
||||
// bg_restore(rect);
|
||||
set_dirty();
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,6 +90,7 @@ void palette_manager::scroll_top()
|
|||
restore_palette_bg(true);
|
||||
}
|
||||
|
||||
// TODO: draw_manager - can probably remove this...
|
||||
void palette_manager::restore_palette_bg(bool scroll_top)
|
||||
{
|
||||
const SDL_Rect rect = gui_.palette_area();
|
||||
|
@ -121,15 +116,11 @@ void palette_manager::scroll_bottom()
|
|||
}
|
||||
}
|
||||
|
||||
void palette_manager::draw_contents()
|
||||
void palette_manager::layout()
|
||||
{
|
||||
//if (!dirty() && !force) {
|
||||
// return;
|
||||
//}
|
||||
|
||||
const SDL_Rect &loc = location();
|
||||
|
||||
tooltips::clear_tooltips(loc);
|
||||
if (!dirty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<gui::button> upscroll_button = gui_.find_action_button("upscroll-button-editor");
|
||||
if (upscroll_button)
|
||||
|
@ -141,12 +132,15 @@ void palette_manager::draw_contents()
|
|||
if (palette_menu_button)
|
||||
palette_menu_button->hide(false);
|
||||
|
||||
// bg_restore(loc);
|
||||
active_palette().set_dirty(true);
|
||||
active_palette().hide(false);
|
||||
active_palette().draw();
|
||||
|
||||
// set_dirty(false);
|
||||
set_dirty(false);
|
||||
}
|
||||
|
||||
void palette_manager::draw_contents()
|
||||
{
|
||||
active_palette().draw();
|
||||
}
|
||||
|
||||
sdl_handler_vector palette_manager::handler_members()
|
||||
|
@ -166,10 +160,14 @@ void palette_manager::handle_event(const SDL_Event& event) {
|
|||
if (event.type == SDL_MOUSEMOTION) {
|
||||
// If the mouse is inside the palette, give it focus.
|
||||
if (location().contains(event.button.x, event.button.y)) {
|
||||
if (!focus(&event)) set_focus(true);
|
||||
if (!focus(&event)) {
|
||||
set_focus(true);
|
||||
}
|
||||
}
|
||||
// If the mouse is outside, remove focus.
|
||||
else if (focus(&event)) set_focus(false);
|
||||
else if (focus(&event)) {
|
||||
set_focus(false);
|
||||
}
|
||||
}
|
||||
if (!focus(&event)) {
|
||||
return;
|
||||
|
|
|
@ -58,8 +58,11 @@ public:
|
|||
|
||||
void adjust_size();
|
||||
|
||||
sdl_handler_vector handler_members();
|
||||
virtual void handle_event(const SDL_Event& event);
|
||||
sdl_handler_vector handler_members() override;
|
||||
virtual void handle_event(const SDL_Event& event) override;
|
||||
|
||||
/** Called by draw_manager to validate layout before drawing. */
|
||||
virtual void layout() override;
|
||||
|
||||
/**
|
||||
* Draw the palette.
|
||||
|
@ -68,7 +71,7 @@ public:
|
|||
* even though it is not invalidated.
|
||||
*/
|
||||
//void draw(bool force=false);
|
||||
void draw_contents(); // { draw(false); };
|
||||
void draw_contents() override; // { draw(false); };
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -66,10 +66,6 @@ public:
|
|||
item_id_ = id;
|
||||
}
|
||||
|
||||
void draw() override {
|
||||
widget::draw();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual void handle_event(const SDL_Event& event) override;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "cursor.hpp"
|
||||
#include "desktop/clipboard.hpp"
|
||||
#include "log.hpp"
|
||||
#include "draw_manager.hpp"
|
||||
#include "quit_confirmation.hpp"
|
||||
#include "sdl/userevent.hpp"
|
||||
#include "utils/ranges.hpp"
|
||||
|
@ -692,17 +693,9 @@ void pump()
|
|||
}
|
||||
|
||||
case DRAW_ALL_EVENT: {
|
||||
flip_locker flip_lock(CVideo::get_singleton());
|
||||
|
||||
/* Iterate backwards as the most recent things will be at the top */
|
||||
// FIXME? ^ that isn't happening here.
|
||||
for(auto& context : event_contexts) {
|
||||
for(auto handler : context.handlers) {
|
||||
handler->handle_event(event);
|
||||
}
|
||||
}
|
||||
|
||||
continue; // do not do further handling here
|
||||
draw_manager::invalidate_region(CVideo::get_singleton().draw_area());
|
||||
// Nothing else needs to or should ever react to this.
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifndef __APPLE__
|
||||
|
@ -781,51 +774,14 @@ void raise_resize_event()
|
|||
|
||||
void raise_draw_event()
|
||||
{
|
||||
if(event_contexts.empty() == false) {
|
||||
event_contexts.back().add_staging_handlers();
|
||||
|
||||
// Events may cause more event handlers to be added and/or removed,
|
||||
// so we must use indexes instead of iterators here.
|
||||
for(auto handler : event_contexts.back().handlers) {
|
||||
handler->draw();
|
||||
}
|
||||
}
|
||||
draw_manager::sparkle();
|
||||
}
|
||||
|
||||
void raise_draw_all_event()
|
||||
{
|
||||
for(auto& context : event_contexts) {
|
||||
for(auto handler : context.handlers) {
|
||||
handler->draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void raise_volatile_draw_event()
|
||||
{
|
||||
if(event_contexts.empty() == false) {
|
||||
for(auto handler : event_contexts.back().handlers) {
|
||||
handler->volatile_draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void raise_volatile_draw_all_event()
|
||||
{
|
||||
for(auto& context : event_contexts) {
|
||||
for(auto handler : context.handlers) {
|
||||
handler->volatile_draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void raise_volatile_undraw_event()
|
||||
{
|
||||
if(event_contexts.empty() == false) {
|
||||
for(auto handler : event_contexts.back().handlers) {
|
||||
handler->volatile_undraw();
|
||||
}
|
||||
}
|
||||
// TODO: draw_manager - look into usage of this
|
||||
//std::cerr << "draw all event raised" << std::endl;
|
||||
draw_manager::sparkle();
|
||||
}
|
||||
|
||||
void raise_help_string_event(int mousex, int mousey)
|
||||
|
|
|
@ -80,9 +80,6 @@ public:
|
|||
virtual void process_event() {}
|
||||
virtual void draw() {}
|
||||
|
||||
virtual void volatile_draw() {}
|
||||
virtual void volatile_undraw() {}
|
||||
|
||||
virtual bool requires_event_focus(const SDL_Event * = nullptr) const { return false; }
|
||||
|
||||
virtual void process_help_string(int /*mousex*/, int /*mousey*/) {}
|
||||
|
@ -172,9 +169,6 @@ void raise_process_event();
|
|||
void raise_resize_event();
|
||||
void raise_draw_event();
|
||||
void raise_draw_all_event();
|
||||
void raise_volatile_draw_event();
|
||||
void raise_volatile_draw_all_event();
|
||||
void raise_volatile_undraw_event();
|
||||
void raise_help_string_event(int mousex, int mousey);
|
||||
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "display.hpp"
|
||||
#include "draw.hpp"
|
||||
#include "draw_manager.hpp"
|
||||
#include "font/text.hpp"
|
||||
#include "log.hpp"
|
||||
#include "sdl/utils.hpp"
|
||||
|
@ -32,6 +33,11 @@ static lg::log_domain log_font("font");
|
|||
#define WRN_FT LOG_STREAM(warn, log_font)
|
||||
#define ERR_FT LOG_STREAM(err, log_font)
|
||||
|
||||
static lg::log_domain log_display("display");
|
||||
#define ERR_DP LOG_STREAM(err, log_display)
|
||||
|
||||
using std::endl;
|
||||
|
||||
namespace
|
||||
{
|
||||
typedef std::map<int, font::floating_label> label_map;
|
||||
|
@ -41,16 +47,13 @@ int label_id = 1;
|
|||
std::stack<std::set<int>> label_contexts;
|
||||
}
|
||||
|
||||
// TODO: draw_manager - why tf is this in namespace font?
|
||||
namespace font
|
||||
{
|
||||
floating_label::floating_label(const std::string& text, const surface& surf)
|
||||
#if 0
|
||||
: img_(),
|
||||
#else
|
||||
: tex_()
|
||||
, buf_()
|
||||
, buf_pos_()
|
||||
#endif
|
||||
, screen_loc_()
|
||||
, alpha_(0)
|
||||
, fadeout_(0)
|
||||
, time_start_(0)
|
||||
, text_(text)
|
||||
|
@ -97,8 +100,13 @@ int floating_label::xpos(std::size_t width) const
|
|||
|
||||
bool floating_label::create_texture()
|
||||
{
|
||||
if(CVideo::get_singleton().faked()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: highdpi - this really does not need the extra indent
|
||||
if(tex_ == nullptr) {
|
||||
DBG_FT << "creating floating label texture" << std::endl;
|
||||
DBG_FT << "creating floating label texture" << endl;
|
||||
font::pango_text& text = font::get_text_renderer();
|
||||
|
||||
text.set_link_aware(false)
|
||||
|
@ -127,7 +135,7 @@ bool floating_label::create_texture()
|
|||
const int sf = ps * display::get_singleton()->get_zoom_factor();
|
||||
|
||||
if(foreground == nullptr) {
|
||||
ERR_FT << "could not create floating label's text" << std::endl;
|
||||
ERR_FT << "could not create floating label's text" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -137,7 +145,7 @@ bool floating_label::create_texture()
|
|||
surface background(foreground->w + border_ * 2 * sf, foreground->h + border_ * 2 * sf);
|
||||
|
||||
if(background == nullptr) {
|
||||
ERR_FT << "could not create tooltip box" << std::endl;
|
||||
ERR_FT << "could not create tooltip box" << endl;
|
||||
tex_ = texture(foreground);
|
||||
return tex_ != nullptr;
|
||||
}
|
||||
|
@ -159,7 +167,7 @@ bool floating_label::create_texture()
|
|||
background = shadow_image(background, sf);
|
||||
|
||||
if(background == nullptr) {
|
||||
ERR_FT << "could not create floating label's shadow" << std::endl;
|
||||
ERR_FT << "could not create floating label's shadow" << endl;
|
||||
tex_ = texture(foreground);
|
||||
return tex_ != nullptr;
|
||||
}
|
||||
|
@ -175,34 +183,73 @@ bool floating_label::create_texture()
|
|||
return tex_ != nullptr;
|
||||
}
|
||||
|
||||
void floating_label::draw(int time)
|
||||
void floating_label::undraw()
|
||||
{
|
||||
DBG_FT << "undrawing floating label from " << screen_loc_ << std::endl;
|
||||
draw_manager::invalidate_region(screen_loc_);
|
||||
screen_loc_ = {};
|
||||
}
|
||||
|
||||
void floating_label::update(int time)
|
||||
{
|
||||
if(CVideo::get_singleton().faked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!create_texture()) {
|
||||
ERR_FT << "failed to create texture for floating label" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
point new_pos = get_pos(time);
|
||||
rect draw_loc = {new_pos.x, new_pos.y, tex_.w(), tex_.h()};
|
||||
|
||||
uint8_t new_alpha = get_alpha(time);
|
||||
|
||||
if(screen_loc_ == draw_loc && alpha_ == new_alpha) {
|
||||
// nothing has changed
|
||||
return;
|
||||
}
|
||||
|
||||
draw_manager::invalidate_region(screen_loc_);
|
||||
draw_manager::invalidate_region(draw_loc);
|
||||
|
||||
DBG_FT << "updating floating label from " << screen_loc_
|
||||
<< " to " << draw_loc << std::endl;
|
||||
|
||||
screen_loc_ = draw_loc;
|
||||
alpha_ = new_alpha;
|
||||
}
|
||||
|
||||
void floating_label::draw()
|
||||
{
|
||||
if(!visible_) {
|
||||
buf_.reset();
|
||||
screen_loc_ = {};
|
||||
return;
|
||||
}
|
||||
|
||||
if (!create_texture()) {
|
||||
if(screen_loc_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_Point pos = get_loc(time);
|
||||
SDL_Rect draw_rect = {pos.x, pos.y, tex_.w(), tex_.h()};
|
||||
buf_pos_ = draw_rect;
|
||||
if(!tex_) {
|
||||
ERR_DP << "trying to draw floating label with no texture!" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
auto clipper = draw::set_clip(clip_rect_);
|
||||
if(!screen_loc_.overlaps(draw::get_clip().intersect(clip_rect_))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Read buf_ back from the screen.
|
||||
// buf_pos_ will be intersected with the drawing area,
|
||||
// so might not match draw_rect after this.
|
||||
CVideo& video = CVideo::get_singleton();
|
||||
buf_ = video.read_texture(&buf_pos_);
|
||||
DBG_FT << "drawing floating label to " << screen_loc_ << std::endl;
|
||||
|
||||
// Fade the label out according to the time.
|
||||
tex_.set_alpha_mod(get_alpha(time));
|
||||
// TODO: draw_manager - is this actually useful?
|
||||
// Clip if appropriate.
|
||||
auto clipper = draw::reduce_clip(clip_rect_);
|
||||
|
||||
// Apply the label texture to the screen.
|
||||
draw::blit(tex_, draw_rect);
|
||||
tex_.set_alpha_mod(alpha_);
|
||||
draw::blit(tex_, screen_loc_);
|
||||
}
|
||||
|
||||
void floating_label::set_lifetime(int lifetime, int fadeout)
|
||||
|
@ -213,7 +260,7 @@ void floating_label::set_lifetime(int lifetime, int fadeout)
|
|||
}
|
||||
|
||||
|
||||
SDL_Point floating_label::get_loc(int time)
|
||||
point floating_label::get_pos(int time)
|
||||
{
|
||||
int time_alive = get_time_alive(time);
|
||||
return {
|
||||
|
@ -239,16 +286,6 @@ uint8_t floating_label::get_alpha(int time)
|
|||
return 255;
|
||||
}
|
||||
|
||||
void floating_label::undraw()
|
||||
{
|
||||
if(buf_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto clipper = draw::set_clip(clip_rect_);
|
||||
draw::blit(buf_, buf_pos_);
|
||||
}
|
||||
|
||||
int add_floating_label(const floating_label& flabel)
|
||||
{
|
||||
if(label_contexts.empty()) {
|
||||
|
@ -289,6 +326,8 @@ void remove_floating_label(int handle, int fadeout)
|
|||
i->second.set_lifetime(0, i->second.get_fade_time());
|
||||
return;
|
||||
}
|
||||
// Queue a redraw of where the label was.
|
||||
i->second.undraw();
|
||||
labels.erase(i);
|
||||
}
|
||||
|
||||
|
@ -342,20 +381,19 @@ void draw_floating_labels()
|
|||
if(label_contexts.empty()) {
|
||||
return;
|
||||
}
|
||||
int time = SDL_GetTicks();
|
||||
|
||||
const std::set<int>& context = label_contexts.top();
|
||||
|
||||
// draw the labels in the order they were added, so later added labels (likely to be tooltips)
|
||||
// are displayed over earlier added labels.
|
||||
for(label_map::iterator i = labels.begin(); i != labels.end(); ++i) {
|
||||
if(context.count(i->first) > 0) {
|
||||
i->second.draw(time);
|
||||
for(auto& [id, label] : labels) {
|
||||
if(context.count(id) > 0) {
|
||||
label.draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void undraw_floating_labels()
|
||||
void update_floating_labels()
|
||||
{
|
||||
if(label_contexts.empty()) {
|
||||
return;
|
||||
|
@ -364,17 +402,16 @@ void undraw_floating_labels()
|
|||
|
||||
std::set<int>& context = label_contexts.top();
|
||||
|
||||
//undraw labels in reverse order, so that a LIFO process occurs, and the screen is restored
|
||||
//into the exact state it started in.
|
||||
for(label_map::reverse_iterator i = labels.rbegin(); i != labels.rend(); ++i) {
|
||||
if(context.count(i->first) > 0) {
|
||||
i->second.undraw();
|
||||
for(auto& [id, label] : labels) {
|
||||
if(context.count(id) > 0) {
|
||||
label.update(time);
|
||||
}
|
||||
}
|
||||
|
||||
//remove expired labels
|
||||
for(label_map::iterator j = labels.begin(); j != labels.end(); ) {
|
||||
if(context.count(j->first) > 0 && j->second.expired(time)) {
|
||||
DBG_FT << "removing expired floating label " << j->first << std::endl;
|
||||
context.erase(j->first);
|
||||
labels.erase(j++);
|
||||
} else {
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "color.hpp"
|
||||
#include "sdl/point.hpp"
|
||||
#include "sdl/rect.hpp"
|
||||
#include "sdl/surface.hpp"
|
||||
#include "sdl/texture.hpp"
|
||||
#include <string>
|
||||
|
@ -69,9 +71,14 @@ public:
|
|||
void set_scroll_mode(LABEL_SCROLL_MODE scroll) {scroll_ = scroll;}
|
||||
void use_markup(bool b) {use_markup_ = b;}
|
||||
|
||||
void move(double xmove, double ymove);
|
||||
void draw(int time);
|
||||
/** Mark the last drawn location as requiring redraw. */
|
||||
void undraw();
|
||||
/** Change the floating label's position. */
|
||||
void move(double xmove, double ymove);
|
||||
/** Finalize draw position and alpha, and queue redrawing if changed. */
|
||||
void update(int time);
|
||||
/** Draw the label to the screen. */
|
||||
void draw();
|
||||
|
||||
/**
|
||||
* Ensure a texture for this floating label exists, creating one if needed.
|
||||
|
@ -96,10 +103,11 @@ private:
|
|||
|
||||
int get_time_alive(int current_time) const { return current_time - time_start_; }
|
||||
int xpos(std::size_t width) const;
|
||||
SDL_Point get_loc(int time);
|
||||
point get_pos(int time);
|
||||
uint8_t get_alpha(int time);
|
||||
texture tex_, buf_;
|
||||
SDL_Rect buf_pos_;
|
||||
texture tex_;
|
||||
rect screen_loc_;
|
||||
uint8_t alpha_;
|
||||
int fadeout_;
|
||||
int time_start_;
|
||||
std::string text_;
|
||||
|
@ -141,6 +149,6 @@ void show_floating_label(int handle, bool show);
|
|||
|
||||
SDL_Rect get_floating_label_rect(int handle);
|
||||
void draw_floating_labels();
|
||||
void undraw_floating_labels();
|
||||
void update_floating_labels();
|
||||
|
||||
} // end namespace font
|
||||
|
|
|
@ -88,7 +88,6 @@ namespace gui{
|
|||
}
|
||||
|
||||
if(box_ != nullptr) {
|
||||
box_->set_volatile(true);
|
||||
const SDL_Rect rect {
|
||||
area.x + label_area.w + border_size * 2
|
||||
, ypos
|
||||
|
@ -100,7 +99,6 @@ namespace gui{
|
|||
}
|
||||
|
||||
if(check_ != nullptr) {
|
||||
check_->set_volatile(true);
|
||||
check_->set_location(box_->location().x,box_->location().y + box_->location().h + border_size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "font/font_options.hpp"
|
||||
#include "color.hpp"
|
||||
#include "sdl/surface.hpp"
|
||||
#include "sdl/texture.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
|
||||
#include <pango/pango.h>
|
||||
|
|
|
@ -68,7 +68,7 @@ game_display::game_display(game_board& board,
|
|||
reports& reports_object,
|
||||
const std::string& theme_id,
|
||||
const config& level)
|
||||
: display(&board, wb, reports_object, theme_id, level, false)
|
||||
: display(&board, wb, reports_object, theme_id, level)
|
||||
, overlay_map_()
|
||||
, attack_indicator_src_()
|
||||
, attack_indicator_dst_()
|
||||
|
@ -247,11 +247,6 @@ void game_display::draw_invalidated()
|
|||
}
|
||||
}
|
||||
|
||||
void game_display::post_commit()
|
||||
{
|
||||
halo_man_->render();
|
||||
}
|
||||
|
||||
void game_display::draw_hex(const map_location& loc)
|
||||
{
|
||||
const bool on_map = get_map().on_board(loc);
|
||||
|
@ -369,7 +364,7 @@ bool game_display::has_time_area() const
|
|||
return resources::tod_manager->has_time_area();
|
||||
}
|
||||
|
||||
void game_display::draw_sidebar()
|
||||
void game_display::refresh_reports()
|
||||
{
|
||||
if ( !team_valid() )
|
||||
return;
|
||||
|
|
|
@ -148,7 +148,8 @@ protected:
|
|||
|
||||
virtual void draw_invalidated() override;
|
||||
|
||||
virtual void post_commit() override;
|
||||
// TODO: draw_manager - maybe delete
|
||||
//virtual void post_commit() override;
|
||||
|
||||
virtual void draw_hex(const map_location& loc) override;
|
||||
|
||||
|
@ -219,7 +220,7 @@ private:
|
|||
game_display(const game_display&);
|
||||
void operator=(const game_display&);
|
||||
|
||||
virtual void draw_sidebar() override;
|
||||
virtual void refresh_reports() override;
|
||||
|
||||
overlay_map overlay_map_;
|
||||
|
||||
|
|
|
@ -139,12 +139,6 @@ public:
|
|||
variables_.add(key, std::move(value));
|
||||
}
|
||||
|
||||
// TODO: highdpi - find everywhere that is calling this, and determine why.
|
||||
void set_is_dirty(bool)
|
||||
{
|
||||
update_size_variables();
|
||||
}
|
||||
|
||||
private:
|
||||
/** Vector with the shapes to draw. */
|
||||
std::vector<std::unique_ptr<shape>> shapes_;
|
||||
|
|
|
@ -249,17 +249,6 @@ public:
|
|||
widget* keyboard_focus() const;
|
||||
|
||||
private:
|
||||
class layer : public video2::draw_layering
|
||||
{
|
||||
public:
|
||||
virtual void handle_event(const SDL_Event& ) {}
|
||||
virtual void handle_window_event(const SDL_Event& ) {}
|
||||
layer() : video2::draw_layering(false) { }
|
||||
};
|
||||
|
||||
// make sure the appropriate things happens when we close.
|
||||
layer layer_;
|
||||
|
||||
/** The widget that holds the keyboard focus_. */
|
||||
widget* keyboard_focus_;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "gui/core/event/handler.hpp"
|
||||
|
||||
#include "draw_manager.hpp"
|
||||
#include "gui/core/event/dispatcher.hpp"
|
||||
#include "gui/core/timer.hpp"
|
||||
#include "gui/core/log.hpp"
|
||||
|
@ -563,13 +564,8 @@ void sdl_event_handler::disconnect(dispatcher* disp)
|
|||
keyboard_focus_ = nullptr;
|
||||
}
|
||||
|
||||
/***** Set proper state for the other dispatchers. *****/
|
||||
for(auto d : dispatchers_)
|
||||
{
|
||||
dynamic_cast<widget&>(*d).set_is_dirty(true);
|
||||
}
|
||||
|
||||
activate();
|
||||
// TODO: draw_manager - Why TF was this "activate"ing on "disconnect"? Seriously WTF?
|
||||
//activate();
|
||||
|
||||
/***** Validate post conditions. *****/
|
||||
assert(std::find(dispatchers_.begin(), dispatchers_.end(), disp)
|
||||
|
@ -592,6 +588,7 @@ void sdl_event_handler::activate()
|
|||
|
||||
void sdl_event_handler::draw()
|
||||
{
|
||||
/*
|
||||
for(auto dispatcher : dispatchers_)
|
||||
{
|
||||
dispatcher->fire(DRAW, dynamic_cast<widget&>(*dispatcher));
|
||||
|
@ -600,14 +597,16 @@ void sdl_event_handler::draw()
|
|||
if(!dispatchers_.empty()) {
|
||||
CVideo::get_singleton().render_screen();
|
||||
}
|
||||
*/
|
||||
|
||||
draw_manager::sparkle();
|
||||
}
|
||||
|
||||
void sdl_event_handler::draw_everything()
|
||||
{
|
||||
for(auto dispatcher : dispatchers_) {
|
||||
dynamic_cast<widget&>(*dispatcher).set_is_dirty(true);
|
||||
}
|
||||
|
||||
// TODO: draw_manager - look into usage of this
|
||||
//std::cerr << "sdl_event_handler::draw_everything" << std::endl;
|
||||
draw_manager::invalidate_region(CVideo::get_singleton().draw_area());
|
||||
draw();
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ addon_connect::addon_connect(std::string& host_name,
|
|||
const bool allow_remove)
|
||||
: allow_remove_(allow_remove)
|
||||
{
|
||||
set_restore(true);
|
||||
register_text("host_name", false, host_name, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,8 +31,6 @@ REGISTER_DIALOG(addon_uninstall_list)
|
|||
|
||||
void addon_uninstall_list::pre_show(window& window)
|
||||
{
|
||||
set_restore(true);
|
||||
|
||||
listbox& list = find_widget<listbox>(&window, "addons_list", false);
|
||||
window.keyboard_capture(&list);
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ campaign_difficulty::campaign_difficulty(const config& campaign)
|
|||
, campaign_id_(campaign["id"])
|
||||
, selected_difficulty_("CANCEL")
|
||||
{
|
||||
set_restore(true);
|
||||
}
|
||||
|
||||
void campaign_difficulty::pre_show(window& window)
|
||||
|
|
|
@ -67,7 +67,6 @@ public:
|
|||
, current_sorting_(RANK)
|
||||
, currently_sorted_asc_(true)
|
||||
{
|
||||
set_restore(true);
|
||||
}
|
||||
|
||||
/***** ***** ***** setters / getters for members ***** ****** *****/
|
||||
|
|
|
@ -109,7 +109,7 @@ void debug_clock::update_time(const bool force)
|
|||
canvas.set_variable("minute", wfl::variant(minute_stamp));
|
||||
canvas.set_variable("second", wfl::variant(second_stamp));
|
||||
}
|
||||
clock_->set_is_dirty(true);
|
||||
clock_->queue_redraw();
|
||||
}
|
||||
|
||||
const std::map<std::string, std::string> tags;
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include "gui/core/event/dispatcher.hpp"
|
||||
|
||||
class CVideo;
|
||||
|
||||
namespace gui2
|
||||
{
|
||||
|
||||
|
|
|
@ -91,7 +91,6 @@ drop_down_menu::drop_down_menu(styled_widget* parent, const std::vector<config>&
|
|||
, keep_open_(keep_open)
|
||||
, mouse_down_happened_(false)
|
||||
{
|
||||
set_restore(true);
|
||||
}
|
||||
|
||||
drop_down_menu::drop_down_menu(SDL_Rect button_pos, const std::vector<config>& items, int selected_item, bool use_markup, bool keep_open)
|
||||
|
@ -103,7 +102,6 @@ drop_down_menu::drop_down_menu(SDL_Rect button_pos, const std::vector<config>& i
|
|||
, keep_open_(keep_open)
|
||||
, mouse_down_happened_(false)
|
||||
{
|
||||
set_restore(true);
|
||||
}
|
||||
|
||||
void drop_down_menu::mouse_up_callback(bool&, bool&, const point& coordinate)
|
||||
|
|
|
@ -238,6 +238,7 @@ void custom_tod::update_tod_display()
|
|||
// theme UI sidebar after redrawing tiles and before we have a
|
||||
// chance to redraw the rest of this window.
|
||||
get_window()->undraw();
|
||||
// TODO: draw_manager - do this properly, probably by removing this undraw
|
||||
|
||||
// NOTE: We only really want to re-render the gamemap tiles here.
|
||||
// Redrawing everything is a significantly more expensive task.
|
||||
|
@ -253,11 +254,8 @@ void custom_tod::update_tod_display()
|
|||
// invalidate all tiles so they are redrawn with the new ToD tint next
|
||||
disp->invalidate_all();
|
||||
|
||||
// redraw tiles
|
||||
disp->draw(false);
|
||||
|
||||
// NOTE: revert to invalidate_layout if necessary to display the ToD mask image.
|
||||
get_window()->set_is_dirty(true);
|
||||
get_window()->queue_redraw();
|
||||
}
|
||||
|
||||
void custom_tod::update_lawful_bonus()
|
||||
|
|
|
@ -48,11 +48,8 @@ end_credits::end_credits(const std::string& campaign)
|
|||
|
||||
void end_credits::pre_show(window& window)
|
||||
{
|
||||
window.set_callback_next_draw([this]()
|
||||
{
|
||||
// Delay a little before beginning the scrolling
|
||||
last_scroll_ = SDL_GetTicks() + 3000;
|
||||
});
|
||||
// Delay a little before beginning the scrolling
|
||||
last_scroll_ = SDL_GetTicks() + 3000;
|
||||
|
||||
connect_signal_on_draw(window, std::bind(&end_credits::timer_callback, this));
|
||||
|
||||
|
|
|
@ -117,7 +117,6 @@ file_dialog::file_dialog()
|
|||
, current_bookmark_()
|
||||
, user_bookmarks_begin_()
|
||||
{
|
||||
set_restore(true);
|
||||
}
|
||||
|
||||
std::string file_dialog::path() const
|
||||
|
|
|
@ -45,8 +45,6 @@ static void set_dont_ask_again(const bool ask_again)
|
|||
|
||||
game_delete::game_delete()
|
||||
{
|
||||
set_restore(true);
|
||||
|
||||
register_bool(
|
||||
"dont_ask_again", true, &get_dont_ask_again, &set_dont_ask_again);
|
||||
}
|
||||
|
|
|
@ -30,8 +30,6 @@ REGISTER_DIALOG(game_save)
|
|||
|
||||
game_save::game_save(std::string& filename, const std::string& title)
|
||||
{
|
||||
set_restore(true);
|
||||
|
||||
register_text("txtFilename", false, filename, true);
|
||||
register_label("lblTitle", true, title);
|
||||
}
|
||||
|
@ -42,8 +40,6 @@ game_save_message::game_save_message(std::string& filename,
|
|||
const std::string& title,
|
||||
const std::string& message)
|
||||
{
|
||||
set_restore(true);
|
||||
|
||||
register_label("lblTitle", true, title);
|
||||
register_text("txtFilename", false, filename, true);
|
||||
register_label("lblMessage", true, message);
|
||||
|
|
|
@ -30,7 +30,6 @@ hotkey_bind::hotkey_bind(const std::string& hotkey_id)
|
|||
: hotkey_id_(hotkey_id)
|
||||
, new_binding_()
|
||||
{
|
||||
set_restore(true);
|
||||
}
|
||||
|
||||
void hotkey_bind::pre_show(window& window)
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "gui/dialogs/loading_screen.hpp"
|
||||
|
||||
#include "cursor.hpp"
|
||||
#include "draw_manager.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "gui/auxiliary/find_widget.hpp"
|
||||
#include "gui/core/timer.hpp"
|
||||
|
@ -31,6 +32,7 @@
|
|||
#include "gui/widgets/window.hpp"
|
||||
#include "log.hpp"
|
||||
#include "preferences/general.hpp"
|
||||
#include "sdl/rect.hpp"
|
||||
#include "video.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
|
@ -41,6 +43,9 @@ static lg::log_domain log_loadscreen("loadscreen");
|
|||
#define ERR_LS LOG_STREAM(err, log_loadscreen)
|
||||
#define WRN_LS LOG_STREAM(warn, log_loadscreen)
|
||||
|
||||
static lg::log_domain log_display("display");
|
||||
#define DBG_DP LOG_STREAM(debug, log_display)
|
||||
|
||||
static const std::map<loading_stage, std::string> stage_names {
|
||||
{ loading_stage::build_terrain, N_("Building terrain rules") },
|
||||
{ loading_stage::create_cache, N_("Reading files and creating cache") },
|
||||
|
@ -104,10 +109,6 @@ void loading_screen::pre_show(window& window)
|
|||
|
||||
progress_stage_label_ = find_widget<label>(&window, "status", false, true);
|
||||
animation_ = find_widget<drawing>(&window, "animation", false, true);
|
||||
|
||||
// Add a draw callback to handle the animation, et al.
|
||||
window.connect_signal<event::DRAW>(
|
||||
std::bind(&loading_screen::draw_callback, this), event::dispatcher::front_child);
|
||||
}
|
||||
|
||||
void loading_screen::post_show(window& /*window*/)
|
||||
|
@ -120,6 +121,7 @@ void loading_screen::progress(loading_stage stage)
|
|||
if(singleton_ && stage != loading_stage::none) {
|
||||
singleton_->current_stage_.store(stage, std::memory_order_release);
|
||||
// Allow display to update, close events to be handled, etc.
|
||||
// TODO: draw_manager - draws should probably go after pumping
|
||||
events::raise_draw_event();
|
||||
events::pump();
|
||||
}
|
||||
|
@ -167,12 +169,16 @@ void loading_screen::process(events::pump_info&)
|
|||
|
||||
// If there's nothing more to do, close.
|
||||
if (load_funcs_.empty()) {
|
||||
draw_manager::invalidate_region(get_window()->get_rectangle());
|
||||
draw_manager::deregister_drawable(this);
|
||||
get_window()->close();
|
||||
}
|
||||
}
|
||||
|
||||
void loading_screen::draw_callback()
|
||||
void loading_screen::layout()
|
||||
{
|
||||
DBG_DP << "loading_screen::layout" << std::endl;
|
||||
|
||||
loading_stage stage = current_stage_.load(std::memory_order_acquire);
|
||||
|
||||
if(stage != loading_stage::none && (current_visible_stage_ == visible_stages_.end() || stage != current_visible_stage_->first)) {
|
||||
|
@ -195,7 +201,18 @@ void loading_screen::draw_callback()
|
|||
}
|
||||
|
||||
animation_->get_drawing_canvas().set_variable("time", wfl::variant(duration_cast<milliseconds>(now - *animation_start_).count()));
|
||||
animation_->set_is_dirty(true);
|
||||
animation_->queue_redraw();
|
||||
}
|
||||
|
||||
bool loading_screen::expose(const SDL_Rect& region)
|
||||
{
|
||||
DBG_DP << "loading_screen::expose " << region << std::endl;
|
||||
return get_window()->expose(region);
|
||||
}
|
||||
|
||||
rect loading_screen::screen_location()
|
||||
{
|
||||
return get_window()->screen_location();
|
||||
}
|
||||
|
||||
loading_screen::~loading_screen()
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "gui/core/top_level_drawable.hpp"
|
||||
#include "gui/dialogs/modal_dialog.hpp"
|
||||
|
||||
#include "events.hpp"
|
||||
|
@ -72,7 +73,7 @@ class window;
|
|||
|
||||
namespace dialogs
|
||||
{
|
||||
class loading_screen : public modal_dialog, public events::pump_monitor
|
||||
class loading_screen : public modal_dialog, public events::pump_monitor, public gui2::top_level_drawable
|
||||
{
|
||||
public:
|
||||
loading_screen(std::function<void()> f);
|
||||
|
@ -118,8 +119,18 @@ private:
|
|||
/** Inherited from events::pump_monitor. */
|
||||
virtual void process(events::pump_info&) override;
|
||||
|
||||
/** Callback to handle drawing the progress animation. */
|
||||
void draw_callback();
|
||||
/** Called by draw_manager to assign concrete layout. */
|
||||
virtual void layout() override;
|
||||
|
||||
/**
|
||||
* Called by draw_manager when it believes a redraw is necessary.
|
||||
*
|
||||
* Currently this is every frame, as pre_show() registers as an animator.
|
||||
*/
|
||||
virtual bool expose(const SDL_Rect& region) override;
|
||||
|
||||
/** The current draw location of the window, on the screen. */
|
||||
virtual rect screen_location() override;
|
||||
|
||||
static loading_screen* singleton_;
|
||||
|
||||
|
|
|
@ -57,8 +57,6 @@ log_settings::log_settings()
|
|||
|
||||
void log_settings::pre_show(window& window)
|
||||
{
|
||||
set_restore(true); //why is this done manually?
|
||||
|
||||
listbox& logger_box = find_widget<listbox>(&window, "logger_listbox", false);
|
||||
|
||||
for(unsigned int i = 0; i < domain_list_.size(); i++){
|
||||
|
|
|
@ -85,12 +85,8 @@ public:
|
|||
void update_contents(const std::string & str)
|
||||
{
|
||||
assert(msg_label);
|
||||
|
||||
msg_label->set_label(str);
|
||||
window_->set_callback_next_draw([this]()
|
||||
{
|
||||
msg_label->scroll_vertical_scrollbar(scrollbar_base::END);
|
||||
});
|
||||
msg_label->scroll_vertical_scrollbar(scrollbar_base::END);
|
||||
}
|
||||
|
||||
void pg_up()
|
||||
|
@ -516,7 +512,7 @@ void lua_interpreter::controller::input_keypress_callback(bool& handled,
|
|||
|
||||
// Commands such as `wesnoth.interface.zoom` might cause the display to redraw and leave the window half-drawn.
|
||||
// This preempts that.
|
||||
window.set_is_dirty(true);
|
||||
window.queue_redraw();
|
||||
|
||||
LOG_LUA << "finished executing\n";
|
||||
} else if(key == SDLK_TAB) { // handle tab completion
|
||||
|
|
|
@ -67,8 +67,6 @@ struct message_implementation
|
|||
|
||||
void message::pre_show(window& window)
|
||||
{
|
||||
set_restore(true);
|
||||
|
||||
// ***** Validate the required buttons ***** ***** ***** *****
|
||||
message_implementation::init_button(window, buttons_[left_1], "left_side");
|
||||
message_implementation::init_button(window, buttons_[cancel], "cancel");
|
||||
|
|
|
@ -24,6 +24,10 @@
|
|||
#include "scripting/plugins/manager.hpp"
|
||||
#include "video.hpp"
|
||||
|
||||
static lg::log_domain log_display("display");
|
||||
#define DBG_DP LOG_STREAM(debug, log_display)
|
||||
#define WRN_DP LOG_STREAM(warn, log_display)
|
||||
|
||||
namespace gui2::dialogs
|
||||
{
|
||||
modal_dialog::modal_dialog()
|
||||
|
@ -32,7 +36,6 @@ modal_dialog::modal_dialog()
|
|||
, always_save_fields_(false)
|
||||
, fields_()
|
||||
, focus_()
|
||||
, restore_(false)
|
||||
, allow_plugin_skip_(true)
|
||||
, show_even_without_video_(false)
|
||||
{
|
||||
|
@ -57,6 +60,7 @@ namespace {
|
|||
bool modal_dialog::show(const unsigned auto_close_time)
|
||||
{
|
||||
if(CVideo::get_singleton().faked() && !show_even_without_video_) {
|
||||
DBG_DP << "modal_dialog::show denied" << std::endl;
|
||||
if(!allow_plugin_skip_) {
|
||||
return false;
|
||||
}
|
||||
|
@ -87,7 +91,7 @@ bool modal_dialog::show(const unsigned auto_close_time)
|
|||
{ // Scope the window stack
|
||||
cursor::setter cur{cursor::NORMAL};
|
||||
window_stack_handler push_window_stack(window_);
|
||||
retval_ = window_->show(restore_, auto_close_time);
|
||||
retval_ = window_->show(auto_close_time);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -190,11 +190,6 @@ public:
|
|||
always_save_fields_ = always_save_fields;
|
||||
}
|
||||
|
||||
void set_restore(const bool restore)
|
||||
{
|
||||
restore_ = restore;
|
||||
}
|
||||
|
||||
void set_allow_plugin_skip(const bool allow_plugin_skip)
|
||||
{
|
||||
allow_plugin_skip_ = allow_plugin_skip;
|
||||
|
@ -380,15 +375,6 @@ private:
|
|||
*/
|
||||
std::string focus_;
|
||||
|
||||
/**
|
||||
* Restore the screen after showing?
|
||||
*
|
||||
* Most windows should restore the display after showing so this value
|
||||
* defaults to true. Toplevel windows (like the titlescreen don't want this
|
||||
* behavior so they can change it in pre_show().
|
||||
*/
|
||||
bool restore_;
|
||||
|
||||
/**
|
||||
* Allow plugins to skip through the dialog?
|
||||
* Most dialogs install a plugins context to allow plugins to accept whatever the dialog is offering
|
||||
|
|
|
@ -71,7 +71,6 @@ mp_connect::mp_connect()
|
|||
, builtin_servers_(preferences::builtin_servers_list())
|
||||
, user_servers_(preferences::user_servers_list())
|
||||
{
|
||||
set_restore(true);
|
||||
}
|
||||
|
||||
std::array<mp_connect::server_list*, 2> mp_connect::server_lists()
|
||||
|
|
|
@ -42,8 +42,6 @@ static void set_do_not_show_again(const bool do_not_show_again)
|
|||
|
||||
mp_host_game_prompt::mp_host_game_prompt()
|
||||
{
|
||||
set_restore(true);
|
||||
|
||||
register_bool("do_not_show_again",
|
||||
true,
|
||||
&get_do_not_show_again,
|
||||
|
|
|
@ -68,7 +68,6 @@ network_transmission::network_transmission(
|
|||
, subtitle_(subtitle)
|
||||
{
|
||||
register_label("title", true, title, false);
|
||||
set_restore(true);
|
||||
}
|
||||
|
||||
void network_transmission::pre_show(window& window)
|
||||
|
|
|
@ -138,9 +138,8 @@ void outro::draw_callback()
|
|||
}
|
||||
|
||||
window_canvas.set_variable("fade_step", wfl::variant(fade_step_));
|
||||
window_canvas.set_is_dirty(true);
|
||||
|
||||
get_window()->set_is_dirty(true);
|
||||
window_canvas.update_size_variables();
|
||||
get_window()->queue_redraw();
|
||||
|
||||
if(fading_in_) {
|
||||
fade_step_++;
|
||||
|
|
|
@ -211,7 +211,7 @@ void preferences_dialog::add_friend_list_entry(const bool is_friend, text_box& t
|
|||
{
|
||||
std::string username = textbox.text();
|
||||
if(username.empty()) {
|
||||
gui2::show_transient_message("", _("No username specified"), "", false, false, true);
|
||||
gui2::show_transient_message("", _("No username specified"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -226,7 +226,7 @@ void preferences_dialog::add_friend_list_entry(const bool is_friend, text_box& t
|
|||
auto [entry, added_new] = add_acquaintance(username, (is_friend ? "friend": "ignore"), reason);
|
||||
|
||||
if(!entry) {
|
||||
gui2::show_transient_message(_("Error"), _("Invalid username"), "", false, false, true);
|
||||
gui2::show_transient_message(_("Error"), _("Invalid username"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -268,7 +268,7 @@ void preferences_dialog::remove_friend_list_entry(listbox& friends_list, text_bo
|
|||
const std::string to_remove = !textbox.text().empty() ? textbox.text() : who->second.get_nick();
|
||||
|
||||
if(to_remove.empty()) {
|
||||
gui2::show_transient_message("", _("No username specified"), "", false, false, true);
|
||||
gui2::show_transient_message("", _("No username specified"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -887,8 +887,7 @@ void preferences_dialog::add_hotkey_callback(listbox& hotkeys)
|
|||
|
||||
void preferences_dialog::default_hotkey_callback()
|
||||
{
|
||||
gui2::show_transient_message(_("Hotkeys Reset"), _("All hotkeys have been reset to their default values."),
|
||||
std::string(), false, false, true);
|
||||
gui2::show_transient_message(_("Hotkeys Reset"), _("All hotkeys have been reset to their default values."));
|
||||
|
||||
clear_hotkeys();
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ sp_options_configure::sp_options_configure(ng::create_engine& create_engine, ng:
|
|||
, config_engine_(config_engine)
|
||||
, options_manager_()
|
||||
{
|
||||
set_restore(true);
|
||||
}
|
||||
|
||||
void sp_options_configure::pre_show(window& window)
|
||||
|
|
|
@ -60,7 +60,6 @@ statistics_dialog::statistics_dialog(const team& current_team)
|
|||
, selection_index_(scenarios_.size()) // The extra All Scenarios menu entry makes size() a valid initial index.
|
||||
, main_stat_table_()
|
||||
{
|
||||
set_restore(true);
|
||||
}
|
||||
|
||||
void statistics_dialog::pre_show(window& window)
|
||||
|
|
|
@ -91,9 +91,6 @@ void story_viewer::pre_show(window& window)
|
|||
connect_signal_mouse_left_click(find_widget<button>(&window, "back", false),
|
||||
std::bind(&story_viewer::nav_button_callback, this, DIR_BACKWARDS));
|
||||
|
||||
connect_signal_on_draw(window,
|
||||
std::bind(&story_viewer::draw_callback, this));
|
||||
|
||||
display_part();
|
||||
}
|
||||
|
||||
|
@ -223,8 +220,8 @@ void story_viewer::display_part()
|
|||
window_canvas.set_cfg(cfg);
|
||||
|
||||
// Needed to make the background redraw correctly.
|
||||
window_canvas.set_is_dirty(true);
|
||||
get_window()->set_is_dirty(true);
|
||||
window_canvas.update_size_variables();
|
||||
get_window()->queue_redraw();
|
||||
|
||||
//
|
||||
// Title
|
||||
|
@ -358,8 +355,8 @@ void story_viewer::draw_floating_image(floating_image_list::const_iterator image
|
|||
window_canvas.append_cfg(std::move(cfg));
|
||||
|
||||
// Needed to make the background redraw correctly.
|
||||
window_canvas.set_is_dirty(true);
|
||||
get_window()->set_is_dirty(true);
|
||||
window_canvas.update_size_variables();
|
||||
get_window()->queue_redraw();
|
||||
|
||||
// If a delay is specified, schedule the next image draw and break out of the loop.
|
||||
const unsigned int draw_delay = floating_image.display_delay();
|
||||
|
@ -451,7 +448,7 @@ void story_viewer::halt_fade_draw()
|
|||
fade_state_ = NOT_FADING;
|
||||
}
|
||||
|
||||
void story_viewer::draw_callback()
|
||||
void story_viewer::layout()
|
||||
{
|
||||
if(next_draw_ && SDL_GetTicks() < next_draw_) {
|
||||
return;
|
||||
|
@ -492,7 +489,7 @@ void story_viewer::draw_callback()
|
|||
|
||||
void story_viewer::flag_stack_as_dirty()
|
||||
{
|
||||
find_widget<stacked_widget>(get_window(), "text_and_control_stack", false).set_is_dirty(true);
|
||||
find_widget<stacked_widget>(get_window(), "text_and_control_stack", false).queue_redraw();
|
||||
}
|
||||
|
||||
} // namespace dialogs
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace gui2::dialogs
|
|||
{
|
||||
|
||||
/** Dialog to view the storyscreen. */
|
||||
class story_viewer : public modal_dialog
|
||||
class story_viewer : public modal_dialog, public top_level_drawable
|
||||
{
|
||||
public:
|
||||
story_viewer(const std::string& scenario_name, const config& cfg_parsed);
|
||||
|
@ -42,6 +42,14 @@ public:
|
|||
} catch(const std::out_of_range&) {}
|
||||
}
|
||||
|
||||
// top_level_drawable overrides
|
||||
// used to animate the view
|
||||
// TODO: draw_manager - better animation step / hook
|
||||
// TODO: draw_manager - i still am horrified that a modal_dialog is not a window
|
||||
virtual void layout() override;
|
||||
virtual bool expose(const SDL_Rect&) override { return false; }
|
||||
virtual rect screen_location() override { return {0,0,0,0}; }
|
||||
|
||||
private:
|
||||
virtual const std::string& window_id() const override;
|
||||
|
||||
|
@ -69,8 +77,6 @@ private:
|
|||
void begin_fade_draw(bool fade_in);
|
||||
void halt_fade_draw();
|
||||
|
||||
void draw_callback();
|
||||
|
||||
void flag_stack_as_dirty();
|
||||
|
||||
storyscreen::controller controller_;
|
||||
|
|
|
@ -25,7 +25,6 @@ REGISTER_DIALOG(surrender_quit)
|
|||
|
||||
surrender_quit::surrender_quit()
|
||||
{
|
||||
set_restore(true);
|
||||
}
|
||||
|
||||
} // namespace dialogs
|
||||
|
|
|
@ -76,8 +76,6 @@ title_screen::title_screen(game_launcher& game)
|
|||
: debug_clock_()
|
||||
, game_(game)
|
||||
{
|
||||
set_restore(false);
|
||||
|
||||
// Need to set this in the constructor, pre_show() / post_build() is too late
|
||||
set_allow_plugin_skip(false);
|
||||
}
|
||||
|
@ -404,15 +402,6 @@ void title_screen::update_tip(const bool previous)
|
|||
}
|
||||
|
||||
tip_pages->select_page(page);
|
||||
|
||||
/**
|
||||
* @todo Look for a proper fix.
|
||||
*
|
||||
* This dirtying is required to avoid the blurring to be rendered wrong.
|
||||
* Not entirely sure why, but since we plan to move to SDL2 that change
|
||||
* will probably fix this issue automatically.
|
||||
*/
|
||||
get_window()->set_is_dirty(true);
|
||||
}
|
||||
|
||||
void title_screen::show_debug_clock_window()
|
||||
|
|
|
@ -61,13 +61,11 @@ void show_transient_message(const std::string& title,
|
|||
const std::string& message,
|
||||
const std::string& image,
|
||||
const bool message_use_markup,
|
||||
const bool title_use_markup,
|
||||
const bool restore_background)
|
||||
const bool title_use_markup)
|
||||
{
|
||||
dialogs::transient_message dlg(
|
||||
title, title_use_markup, message, message_use_markup, image);
|
||||
|
||||
dlg.set_restore(restore_background);
|
||||
dlg.show();
|
||||
}
|
||||
|
||||
|
|
|
@ -58,15 +58,12 @@ private:
|
|||
* @param image An image to show in the dialog.
|
||||
* @param message_use_markup Use markup for the message?
|
||||
* @param title_use_markup Use markup for the title?
|
||||
* @param restore_background Restore the background to the state it was before
|
||||
* the message appeared
|
||||
*/
|
||||
void show_transient_message(const std::string& title,
|
||||
const std::string& message,
|
||||
const std::string& image = std::string(),
|
||||
const bool message_use_markup = false,
|
||||
const bool title_use_markup = false,
|
||||
const bool restore_background = false);
|
||||
const bool title_use_markup = false);
|
||||
|
||||
/**
|
||||
* Shows a transient error message to the user.
|
||||
|
|
|
@ -53,7 +53,6 @@ unit_create::unit_create()
|
|||
, variation_(last_variation)
|
||||
, last_words_()
|
||||
{
|
||||
set_restore(true);
|
||||
}
|
||||
|
||||
void unit_create::pre_show(window& window)
|
||||
|
|
|
@ -143,8 +143,6 @@ wml_error::wml_error(const std::string& summary,
|
|||
, have_post_summary_(!post_summary.empty())
|
||||
, report_()
|
||||
{
|
||||
set_restore(true);
|
||||
|
||||
const std::string& file_list_text = format_file_list(files);
|
||||
|
||||
report_ = summary;
|
||||
|
|
|
@ -58,8 +58,6 @@ void wml_message_base::set_option_list(const std::vector<wml_message_option>& op
|
|||
*/
|
||||
void wml_message_base::pre_show(window& window)
|
||||
{
|
||||
set_restore(true);
|
||||
|
||||
window.get_canvas(1).set_variable("portrait_image", wfl::variant(portrait_));
|
||||
window.get_canvas(1).set_variable("portrait_mirror", wfl::variant(mirror_));
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ void button::set_state(const state_t state)
|
|||
{
|
||||
if(state != state_) {
|
||||
state_ = state;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -209,14 +209,6 @@ void container_base::layout_children()
|
|||
grid_.layout_children();
|
||||
}
|
||||
|
||||
void
|
||||
container_base::child_populate_dirty_list(window& caller,
|
||||
const std::vector<widget*>& call_stack)
|
||||
{
|
||||
std::vector<widget*> child_call_stack = call_stack;
|
||||
grid_.populate_dirty_list(caller, child_call_stack);
|
||||
}
|
||||
|
||||
widget* container_base::find_at(const point& coordinate,
|
||||
const bool must_be_active)
|
||||
{
|
||||
|
@ -252,7 +244,7 @@ void container_base::set_active(const bool active)
|
|||
return;
|
||||
}
|
||||
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
|
||||
set_self_active(active);
|
||||
}
|
||||
|
|
|
@ -114,11 +114,6 @@ protected:
|
|||
/** See @ref widget::layout_children. */
|
||||
virtual void layout_children() override;
|
||||
|
||||
/** See @ref widget::child_populate_dirty_list. */
|
||||
virtual void
|
||||
child_populate_dirty_list(window& caller,
|
||||
const std::vector<widget*>& call_stack) override;
|
||||
|
||||
public:
|
||||
/** See @ref widget::find_at. */
|
||||
virtual widget* find_at(const point& coordinate,
|
||||
|
|
|
@ -282,13 +282,6 @@ public:
|
|||
/** See @ref widget::impl_draw_children. */
|
||||
virtual void impl_draw_children() override = 0;
|
||||
|
||||
protected:
|
||||
/** See @ref widget::child_populate_dirty_list. */
|
||||
virtual void
|
||||
child_populate_dirty_list(window& caller,
|
||||
const std::vector<widget*>& call_stack) override
|
||||
= 0;
|
||||
|
||||
public:
|
||||
/** See @ref widget::find_at. */
|
||||
virtual widget* find_at(const point& coordinate,
|
||||
|
|
|
@ -843,15 +843,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/** See @ref widget::child_populate_dirty_list. */
|
||||
virtual void child_populate_dirty_list(window& caller, const std::vector<widget*>& call_stack) override
|
||||
{
|
||||
for(auto& item : items_) {
|
||||
std::vector<widget*> child_call_stack = call_stack;
|
||||
item->child_grid.populate_dirty_list(caller, child_call_stack);
|
||||
}
|
||||
}
|
||||
|
||||
/** See @ref widget::find_at. */
|
||||
virtual widget* find_at(const point& coordinate, const bool must_be_active) override
|
||||
{
|
||||
|
@ -985,7 +976,7 @@ private:
|
|||
{
|
||||
order_func_ = order;
|
||||
order_dirty_ = true;
|
||||
this->set_is_dirty(true);
|
||||
this->queue_redraw();
|
||||
}
|
||||
|
||||
virtual unsigned get_ordered_index(unsigned index) const override
|
||||
|
|
|
@ -629,21 +629,6 @@ void grid::layout_children()
|
|||
}
|
||||
}
|
||||
|
||||
void grid::child_populate_dirty_list(window& caller,
|
||||
const std::vector<widget*>& call_stack)
|
||||
{
|
||||
assert(!call_stack.empty() && call_stack.back() == this);
|
||||
|
||||
for(auto & child : children_)
|
||||
{
|
||||
|
||||
assert(child.get_widget());
|
||||
|
||||
std::vector<widget*> child_call_stack = call_stack;
|
||||
child.get_widget()->populate_dirty_list(caller, child_call_stack);
|
||||
}
|
||||
}
|
||||
|
||||
widget* grid::find_at(const point& coordinate, const bool must_be_active)
|
||||
{
|
||||
return grid_implementation::find_at<widget>(
|
||||
|
@ -997,6 +982,7 @@ void grid::layout(const point& origin)
|
|||
|
||||
void grid::impl_draw_children()
|
||||
{
|
||||
// TODO: draw_manager - what is this comment talking about here? something that was removed?
|
||||
/*
|
||||
* The call to SDL_PumpEvents seems a bit like black magic.
|
||||
* With the call the resizing doesn't seem to lose resize events.
|
||||
|
@ -1008,11 +994,10 @@ void grid::impl_draw_children()
|
|||
*/
|
||||
|
||||
assert(get_visible() == widget::visibility::visible);
|
||||
set_is_dirty(false);
|
||||
|
||||
// TODO: draw_manager - don't draw children outside clip area. This is problematic because either clip area is not correct here or widget positions are not absolute
|
||||
for(auto & child : children_)
|
||||
{
|
||||
|
||||
widget* widget = child.get_widget();
|
||||
assert(widget);
|
||||
|
||||
|
@ -1027,7 +1012,6 @@ void grid::impl_draw_children()
|
|||
widget->draw_background();
|
||||
widget->draw_children();
|
||||
widget->draw_foreground();
|
||||
widget->set_is_dirty(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ public:
|
|||
{
|
||||
assert(row < row_grow_factor_.size());
|
||||
row_grow_factor_[row] = factor;
|
||||
set_is_dirty(true);
|
||||
queue_redraw(); // TODO: draw_manager - relayout?
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,7 +103,7 @@ public:
|
|||
{
|
||||
assert(column < col_grow_factor_.size());
|
||||
col_grow_factor_[column] = factor;
|
||||
set_is_dirty(true);
|
||||
queue_redraw(); // TODO: draw_manager - relayout?
|
||||
}
|
||||
|
||||
/***** ***** ***** ***** CHILD MANIPULATION ***** ***** ***** *****/
|
||||
|
@ -273,11 +273,6 @@ public:
|
|||
/** See @ref widget::layout_children. */
|
||||
virtual void layout_children() override;
|
||||
|
||||
/** See @ref widget::child_populate_dirty_list. */
|
||||
virtual void
|
||||
child_populate_dirty_list(window& caller,
|
||||
const std::vector<widget*>& call_stack) override;
|
||||
|
||||
/** See @ref widget::find_at. */
|
||||
virtual widget* find_at(const point& coordinate,
|
||||
const bool must_be_active) override;
|
||||
|
|
|
@ -77,7 +77,7 @@ void label::set_text_alpha(unsigned short alpha)
|
|||
if(alpha != text_alpha_) {
|
||||
text_alpha_ = alpha;
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ void label::set_link_aware(bool link_aware)
|
|||
if(link_aware != link_aware_) {
|
||||
link_aware_ = link_aware;
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,7 @@ void label::set_link_color(const color_t& color)
|
|||
if(color != link_color_) {
|
||||
link_color_ = color;
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ void label::set_state(const state_t state)
|
|||
{
|
||||
if(state != state_) {
|
||||
state_ = state;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ void listbox::set_row_shown(const unsigned row, const bool shown)
|
|||
window->invalidate_layout();
|
||||
} else {
|
||||
content_grid_->set_visible_rectangle(content_visible_area());
|
||||
set_is_dirty(true);
|
||||
queue_redraw(); // TODO: draw_manager - does this get the right area?
|
||||
}
|
||||
|
||||
if(selected_row != get_selected_row()) {
|
||||
|
@ -206,7 +206,7 @@ void listbox::set_row_shown(const boost::dynamic_bitset<>& shown)
|
|||
window->invalidate_layout();
|
||||
} else {
|
||||
content_grid_->set_visible_rectangle(content_visible_area());
|
||||
set_is_dirty(true);
|
||||
queue_redraw(); // TODO: draw_manager - does this get the right area?
|
||||
}
|
||||
|
||||
if(selected_row != get_selected_row()) {
|
||||
|
@ -337,7 +337,7 @@ bool listbox::update_content_size()
|
|||
|
||||
if(content_resize_request(true)) {
|
||||
content_grid_->set_visible_rectangle(content_visible_area());
|
||||
set_is_dirty(true);
|
||||
queue_redraw(); // TODO: draw_manager - does this get the right area?
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -400,7 +400,7 @@ void listbox::resize_content(const int width_modification,
|
|||
|
||||
// If the content grows assume it "overwrites" the old content.
|
||||
if(width_modification < 0 || height_modification < 0) {
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
|
||||
DBG_GUI_L << LOG_HEADER << " succeeded.\n";
|
||||
|
@ -435,16 +435,6 @@ void listbox::layout_children()
|
|||
layout_children(false);
|
||||
}
|
||||
|
||||
void listbox::child_populate_dirty_list(window& caller, const std::vector<widget*>& call_stack)
|
||||
{
|
||||
// Inherited.
|
||||
scrollbar_container::child_populate_dirty_list(caller, call_stack);
|
||||
|
||||
assert(generator_);
|
||||
std::vector<widget*> child_call_stack = call_stack;
|
||||
generator_->populate_dirty_list(caller, child_call_stack);
|
||||
}
|
||||
|
||||
point listbox::calculate_best_size() const
|
||||
{
|
||||
// Get the size from the base class, then add any extra space for the header and footer.
|
||||
|
@ -618,7 +608,7 @@ void listbox::order_by(const generator_base::order_func& func)
|
|||
{
|
||||
generator_->set_order(func);
|
||||
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
need_layout_ = true;
|
||||
}
|
||||
|
||||
|
@ -704,7 +694,7 @@ void listbox::layout_children(const bool force)
|
|||
content_grid()->set_visible_rectangle(visible);
|
||||
|
||||
need_layout_ = false;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -256,9 +256,6 @@ public:
|
|||
/** See @ref widget::layout_children. */
|
||||
virtual void layout_children() override;
|
||||
|
||||
/** See @ref widget::child_populate_dirty_list. */
|
||||
virtual void child_populate_dirty_list(window& caller, const std::vector<widget*>& call_stack) override;
|
||||
|
||||
/***** ***** ***** setters / getters for members ***** ****** *****/
|
||||
|
||||
void order_by(const generator_base::order_func& func);
|
||||
|
|
|
@ -118,13 +118,6 @@ void matrix::layout_children()
|
|||
content_.layout_children();
|
||||
}
|
||||
|
||||
void matrix::child_populate_dirty_list(window& caller,
|
||||
const std::vector<widget*>& call_stack)
|
||||
{
|
||||
std::vector<widget*> child_call_stack = call_stack;
|
||||
content_.populate_dirty_list(caller, child_call_stack);
|
||||
}
|
||||
|
||||
void matrix::request_reduce_width(const unsigned /*maximum_width*/)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -131,11 +131,6 @@ public:
|
|||
/** See @ref widget::layout_children. */
|
||||
virtual void layout_children() override;
|
||||
|
||||
/** See @ref widget::child_populate_dirty_list. */
|
||||
virtual void
|
||||
child_populate_dirty_list(window& caller,
|
||||
const std::vector<widget*>& call_stack) override;
|
||||
|
||||
/** See @ref widget::request_reduce_width. */
|
||||
virtual void request_reduce_width(const unsigned maximum_width) override;
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ void menu_button::set_state(const state_t state)
|
|||
{
|
||||
if(state != state_) {
|
||||
state_ = state;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ void menu_button::set_values(const std::vector<::config>& values, unsigned selec
|
|||
assert(selected_ < values_.size());
|
||||
|
||||
if(values[selected]["label"] != values_[selected_]["label"]) {
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
|
||||
values_ = values;
|
||||
|
@ -204,7 +204,7 @@ void menu_button::set_selected(unsigned selected, bool fire_event)
|
|||
assert(selected_ < values_.size());
|
||||
|
||||
if(selected != selected_) {
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
|
||||
selected_ = selected;
|
||||
|
|
|
@ -81,7 +81,7 @@ void minimap::set_map_data(const std::string& map_data)
|
|||
}
|
||||
|
||||
map_data_ = map_data;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
|
||||
try {
|
||||
map_ = std::make_unique<gamemap>(map_data_);
|
||||
|
|
|
@ -89,7 +89,7 @@ void multimenu_button::set_state(const state_t state)
|
|||
{
|
||||
if(state != state_) {
|
||||
state_ = state;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,7 +229,7 @@ void multimenu_button::select_options(boost::dynamic_bitset<> states)
|
|||
|
||||
void multimenu_button::set_values(const std::vector<::config>& values)
|
||||
{
|
||||
set_is_dirty(true);
|
||||
queue_redraw(); // TODO: draw_manager - does this need a relayout first?
|
||||
|
||||
values_ = values;
|
||||
toggle_states_.resize(values_.size(), false);
|
||||
|
|
|
@ -177,16 +177,6 @@ void pane::impl_draw_children()
|
|||
}
|
||||
}
|
||||
|
||||
void pane::child_populate_dirty_list(window& caller,
|
||||
const std::vector<widget*>& call_stack)
|
||||
{
|
||||
for(auto & item : items_)
|
||||
{
|
||||
std::vector<widget*> child_call_stack = call_stack;
|
||||
item.item_grid->populate_dirty_list(caller, child_call_stack);
|
||||
}
|
||||
}
|
||||
|
||||
void pane::sort(const compare_functor_t& compare_functor)
|
||||
{
|
||||
items_.sort(compare_functor);
|
||||
|
|
|
@ -77,11 +77,6 @@ public:
|
|||
/** See @ref widget::impl_draw_children. */
|
||||
virtual void impl_draw_children() override;
|
||||
|
||||
/** See @ref widget::child_populate_dirty_list. */
|
||||
virtual void
|
||||
child_populate_dirty_list(window& caller,
|
||||
const std::vector<widget*>& call_stack) override;
|
||||
|
||||
/** See @ref widget::request_reduce_width. */
|
||||
virtual void request_reduce_width(const unsigned maximum_width) override;
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ void progress_bar::set_percentage(unsigned percentage)
|
|||
c.set_variable("percentage", wfl::variant(percentage));
|
||||
}
|
||||
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ void repeating_button::set_state(const state_t state)
|
|||
{
|
||||
if(state != state_) {
|
||||
state_ = state;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
|
||||
if(state_ == DISABLED && repeat_timer_) {
|
||||
remove_timer(repeat_timer_);
|
||||
|
|
|
@ -183,14 +183,14 @@ void scrollbar_base::update_canvas()
|
|||
tmp.set_variable("positioner_offset", wfl::variant(positioner_offset_));
|
||||
tmp.set_variable("positioner_length", wfl::variant(positioner_length_));
|
||||
}
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
|
||||
void scrollbar_base::set_state(const state_t state)
|
||||
{
|
||||
if(state != state_) {
|
||||
state_ = state;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -821,16 +821,6 @@ void scrollbar_container::layout_children()
|
|||
content_grid_->layout_children();
|
||||
}
|
||||
|
||||
void scrollbar_container::child_populate_dirty_list(window& caller, const std::vector<widget*>& call_stack)
|
||||
{
|
||||
// Inherited.
|
||||
container_base::child_populate_dirty_list(caller, call_stack);
|
||||
|
||||
assert(content_grid_);
|
||||
std::vector<widget*> child_call_stack(call_stack);
|
||||
content_grid_->populate_dirty_list(caller, child_call_stack);
|
||||
}
|
||||
|
||||
void scrollbar_container::set_content_size(const point& origin, const point& size)
|
||||
{
|
||||
content_grid_->place(origin, size);
|
||||
|
@ -1083,7 +1073,7 @@ void scrollbar_container::scrollbar_moved()
|
|||
|
||||
content_grid_->set_origin(content_origin);
|
||||
content_grid_->set_visible_rectangle(content_visible_area_);
|
||||
content_grid_->set_is_dirty(true);
|
||||
queue_redraw(content_visible_area_);
|
||||
|
||||
// Update scrollbar.
|
||||
set_scrollbar_button_status();
|
||||
|
|
|
@ -512,9 +512,6 @@ private:
|
|||
/** See @ref widget::impl_draw_children. */
|
||||
virtual void impl_draw_children() override;
|
||||
|
||||
/** See @ref widget::child_populate_dirty_list. */
|
||||
virtual void child_populate_dirty_list(window& caller, const std::vector<widget*>& call_stack) override;
|
||||
|
||||
/**
|
||||
* Sets the size of the content grid.
|
||||
*
|
||||
|
|
|
@ -111,7 +111,7 @@ public:
|
|||
void set_best_slider_length(const unsigned length)
|
||||
{
|
||||
best_slider_length_ = length;
|
||||
set_is_dirty(true);
|
||||
queue_redraw(); // TODO: draw_manager - does the above change the size?
|
||||
}
|
||||
|
||||
void set_value_range(int min_value, int max_value);
|
||||
|
|
|
@ -148,14 +148,14 @@ void slider_base::update_canvas()
|
|||
tmp.set_variable("positioner_length", wfl::variant(positioner_length_));
|
||||
}
|
||||
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
|
||||
void slider_base::set_state(const state_t state)
|
||||
{
|
||||
if(state != state_) {
|
||||
state_ = state;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -329,7 +329,7 @@ void styled_widget::set_label(const t_string& label)
|
|||
label_ = label;
|
||||
set_layout_size(point());
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
|
||||
// FIXME: This isn't the most elegant solution. Typically, we don't rely on the text rendering
|
||||
// cache for anything except size calculations, but since we have link awareness now we need to
|
||||
|
@ -349,7 +349,7 @@ void styled_widget::set_use_markup(bool use_markup)
|
|||
|
||||
use_markup_ = use_markup;
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
|
||||
void styled_widget::set_text_alignment(const PangoAlignment text_alignment)
|
||||
|
@ -360,7 +360,7 @@ void styled_widget::set_text_alignment(const PangoAlignment text_alignment)
|
|||
|
||||
text_alignment_ = text_alignment;
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
|
||||
void styled_widget::set_text_ellipse_mode(const PangoEllipsizeMode ellipse_mode)
|
||||
|
@ -371,7 +371,7 @@ void styled_widget::set_text_ellipse_mode(const PangoEllipsizeMode ellipse_mode)
|
|||
|
||||
text_ellipse_mode_ = ellipse_mode;
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
|
||||
void styled_widget::update_canvas()
|
||||
|
|
|
@ -267,7 +267,7 @@ void text_box::handle_mouse_selection(point mouse, const bool start_selection)
|
|||
|
||||
set_cursor(offset, !start_selection);
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
dragging_ |= start_selection;
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ void text_box_base::set_maximum_length(const std::size_t maximum_length)
|
|||
selection_length_ = maximum_length - selection_start_;
|
||||
}
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,7 +129,7 @@ void text_box_base::set_value(const std::string& text)
|
|||
selection_start_ = text_.get_length();
|
||||
selection_length_ = 0;
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ void text_box_base::set_cursor(const std::size_t offset, const bool select)
|
|||
copy_selection(true);
|
||||
#endif
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
|
||||
} else {
|
||||
assert(offset <= text_.get_length());
|
||||
|
@ -158,7 +158,7 @@ void text_box_base::set_cursor(const std::size_t offset, const bool select)
|
|||
selection_length_ = 0;
|
||||
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,7 +171,7 @@ void text_box_base::insert_char(const std::string& unicode)
|
|||
// Update status
|
||||
set_cursor(selection_start_ + utf8::size(unicode), false);
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,7 +230,7 @@ void text_box_base::paste_selection(const bool mouse)
|
|||
selection_start_ += text_.insert_text(selection_start_, text);
|
||||
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
fire(event::NOTIFY_MODIFIED, *this, nullptr);
|
||||
}
|
||||
|
||||
|
@ -238,7 +238,7 @@ void text_box_base::set_selection_start(const std::size_t selection_start)
|
|||
{
|
||||
if(selection_start != selection_start_) {
|
||||
selection_start_ = selection_start;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -246,7 +246,7 @@ void text_box_base::set_selection_length(const int selection_length)
|
|||
{
|
||||
if(selection_length != selection_length_) {
|
||||
selection_length_ = selection_length;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,7 +286,7 @@ void text_box_base::set_state(const state_t state)
|
|||
{
|
||||
if(state != state_) {
|
||||
state_ = state;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -331,7 +331,7 @@ void text_box_base::cursor_timer_callback()
|
|||
tmp.set_variable("cursor_alpha", wfl::variant(cursor_alpha_));
|
||||
}
|
||||
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
|
||||
void text_box_base::reset_cursor_state()
|
||||
|
@ -501,7 +501,7 @@ void text_box_base::handle_editing(bool& handled, const std::string& unicode, in
|
|||
set_cursor(std::min(maximum_length, ime_start_point_ + start + len), true);
|
||||
}
|
||||
update_canvas();
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ void toggle_button::update_canvas()
|
|||
canvas.set_variable("icon", wfl::variant(icon_name_));
|
||||
}
|
||||
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
|
||||
void toggle_button::set_value(unsigned selected, bool fire_event)
|
||||
|
@ -117,7 +117,7 @@ void toggle_button::set_value(unsigned selected, bool fire_event)
|
|||
return;
|
||||
}
|
||||
state_num_ = selected;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
|
||||
// Check for get_window() is here to prevent the callback from
|
||||
// being called when the initial value is set.
|
||||
|
@ -143,7 +143,7 @@ void toggle_button::set_state(const state_t state)
|
|||
{
|
||||
if(state != state_) {
|
||||
state_ = state;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -166,7 +166,7 @@ void toggle_panel::set_value(unsigned selected, bool fire_event)
|
|||
return;
|
||||
}
|
||||
state_num_ = selected;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
|
||||
// Check for get_window() is here to prevent the callback from
|
||||
// being called when the initial value is set.
|
||||
|
@ -187,7 +187,7 @@ void toggle_panel::set_state(const state_t state)
|
|||
}
|
||||
|
||||
state_ = state;
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
|
||||
const auto conf = cast_config_to<toggle_panel_definition>();
|
||||
assert(conf);
|
||||
|
|
|
@ -92,17 +92,6 @@ void tree_view::clear()
|
|||
resize_content(0, -content_grid()->get_size().y);
|
||||
}
|
||||
|
||||
void
|
||||
tree_view::child_populate_dirty_list(window& caller,
|
||||
const std::vector<widget*>& call_stack)
|
||||
{
|
||||
// Inherited.
|
||||
scrollbar_container::child_populate_dirty_list(caller, call_stack);
|
||||
|
||||
assert(root_node_);
|
||||
root_node_->impl_populate_dirty_list(caller, call_stack);
|
||||
}
|
||||
|
||||
void tree_view::set_self_active(const bool /*active*/)
|
||||
{
|
||||
/* DO NOTHING */
|
||||
|
@ -144,7 +133,7 @@ void tree_view::resize_content(const int width_modification,
|
|||
need_layout_ = true;
|
||||
// If the content grows assume it "overwrites" the old content.
|
||||
if(width_modification < 0 || height_modification < 0) {
|
||||
set_is_dirty(true);
|
||||
queue_redraw();
|
||||
}
|
||||
horizontal_scrollbar_moved();
|
||||
DBG_GUI_L << LOG_HEADER << " succeeded.\n";
|
||||
|
|
|
@ -92,11 +92,6 @@ public:
|
|||
|
||||
void clear();
|
||||
|
||||
/** See @ref widget::child_populate_dirty_list. */
|
||||
virtual void
|
||||
child_populate_dirty_list(window& caller,
|
||||
const std::vector<widget*>& call_stack) override;
|
||||
|
||||
/** See @ref container_base::set_self_active. */
|
||||
virtual void set_self_active(const bool active) override;
|
||||
|
||||
|
|
|
@ -452,21 +452,6 @@ const widget* tree_view_node::find(const std::string& id, const bool must_be_act
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void tree_view_node::impl_populate_dirty_list(window& caller, const std::vector<widget*>& call_stack)
|
||||
{
|
||||
std::vector<widget*> my_call_stack = call_stack;
|
||||
grid_.populate_dirty_list(caller, my_call_stack);
|
||||
|
||||
if(is_folded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(auto& node : children_) {
|
||||
std::vector<widget*> child_call_stack = call_stack;
|
||||
node->impl_populate_dirty_list(caller, child_call_stack);
|
||||
}
|
||||
}
|
||||
|
||||
point tree_view_node::calculate_best_size() const
|
||||
{
|
||||
return calculate_best_size(-1, get_tree_view().indentation_step_size_);
|
||||
|
|
|
@ -290,14 +290,6 @@ private:
|
|||
void fold_internal();
|
||||
void unfold_internal();
|
||||
|
||||
/**
|
||||
* "Inherited" from widget.
|
||||
*
|
||||
* This version needs to call its children, which are it's child nodes.
|
||||
*/
|
||||
void impl_populate_dirty_list(window& caller,
|
||||
const std::vector<widget*>& call_stack);
|
||||
|
||||
/** See @ref widget::calculate_best_size. */
|
||||
virtual point calculate_best_size() const override;
|
||||
|
||||
|
|
|
@ -113,18 +113,9 @@ void viewport::impl_draw_children()
|
|||
widget_->draw_background();
|
||||
widget_->draw_children();
|
||||
widget_->draw_foreground();
|
||||
widget_->set_is_dirty(false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
viewport::child_populate_dirty_list(window& caller,
|
||||
const std::vector<widget*>& call_stack)
|
||||
{
|
||||
std::vector<widget*> child_call_stack = call_stack;
|
||||
widget_->populate_dirty_list(caller, child_call_stack);
|
||||
}
|
||||
|
||||
void viewport::request_reduce_width(const unsigned /*maximum_width*/)
|
||||
{
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue