Add event handling to GUI and redraw on window events.

This fixes bugs #24211, #24214, #24213, #24209, #19666, #23534.

The GUI1 components have been made window event aware and will redraw
themselves after a window event.
This commit is contained in:
Andreas Löf 2015-12-31 00:27:38 +13:00
parent 126ba58a44
commit 422ab07191
15 changed files with 84 additions and 14 deletions

View file

@ -318,6 +318,8 @@ int dialog::show()
const dialog_manager manager;
const resize_lock prevent_resizing;
get_frame().join();
//draw
draw_frame();
update_widget_positions();
@ -397,11 +399,13 @@ void dialog::update_widget_positions()
if(!preview_panes_.empty()) {
for(pp_iterator i = preview_panes_.begin(); i != preview_panes_.end(); ++i) {
preview_pane *pane = *i;
pane->leave();
pane->join();
pane->set_location(dim_.panes.find(pane)->second);
}
}
if(text_widget_) {
text_widget_->leave();
text_widget_->join();
text_widget_->set_location(dim_.textbox);
if(text_widget_->get_label()) {
@ -409,6 +413,7 @@ void dialog::update_widget_positions()
}
}
if(get_menu().height() > 0) {
menu_->leave();
menu_->join();
menu_->set_numeric_keypress_selection(text_widget_ == NULL);
menu_->set_width( dim_.menu_width );
@ -419,6 +424,7 @@ void dialog::update_widget_positions()
menu_->set_location( dim_.menu_x, dim_.menu_y );
}
if(image_) {
image_->leave();
image_->join();
image_->set_location(dim_.image_x, dim_.image_y);
if(image_->caption()) {
@ -428,24 +434,29 @@ void dialog::update_widget_positions()
button_iterator b;
for(b = top_buttons_.begin(); b != top_buttons_.end(); ++b) {
dialog_button *btn = *b;
btn->leave();
btn->join();
std::pair<int,int> coords = dim_.buttons.find(btn)->second;
btn->set_location(coords.first, coords.second);
}
for(b = extra_buttons_.begin(); b != extra_buttons_.end(); ++b) {
dialog_button *btn = *b;
btn->leave();
btn->join();
std::pair<int,int> coords = dim_.buttons.find(btn)->second;
btn->set_location(coords.first, coords.second);
}
for(b = standard_buttons_.begin(); b != standard_buttons_.end(); ++b) {
dialog_button *btn = *b;
btn->leave();
btn->join();
}
if(help_button_) {
help_button_->leave();
help_button_->join();
}
message_->set_location(dim_.message);
message_->leave();
message_->join();
}
@ -799,6 +810,9 @@ int dialog::process(dialog_process_info &info)
}
}
draw_frame();
//draw_contents();
events::raise_process_event();
events::raise_draw_event();

View file

@ -45,6 +45,7 @@
#include "unit_animation_component.hpp"
#include "unit_drawer.hpp"
#include "whiteboard/manager.hpp"
#include "show_dialog.hpp"
#include "SDL_image.h"
@ -1654,7 +1655,6 @@ static void draw_background(surface screen, const SDL_Rect& area, const std::str
}
#endif
//TODO: convert this to use sdl::ttexture
void display::draw_text_in_hex(const map_location& loc,
const tdrawing_layer layer, const std::string& text,
size_t font_size, SDL_Color color, double x_in_hex, double y_in_hex)
@ -2692,8 +2692,9 @@ void display::redraw_everything()
}
panelsDrawn_ = false;
labels().recalculate_labels();
if (!gui::in_dialog()) {
labels().recalculate_labels();
}
redraw_background_ = true;

View file

@ -279,6 +279,7 @@ bool has_focus(const sdl_handler* hand, const SDL_Event* event)
#if SDL_VERSION_ATLEAST(2,0,0)
const Uint32 resize_timeout = 100;
SDL_Event last_resize_event;
bool last_resize_event_used = true;
@ -289,13 +290,19 @@ bool resize_comparer(SDL_Event a, SDL_Event b) {
}
bool remove_on_resize(const SDL_Event &a) {
if (a.type == DRAW_EVENT)
if (a.type == DRAW_EVENT) {
return true;
if (a.type == SHOW_HELPTIP_EVENT)
}
if (a.type == SHOW_HELPTIP_EVENT) {
return true;
if (a.type == SDL_WINDOWEVENT) // &&
//(a.window.event == SDL_WINDOWEVENT_RESIZED || a.window.event == SDL_WINDOWEVENT_SIZE_CHANGED || a.window.event == SDL_WINDOWEVENT_EXPOSED))
}
if ((a.type == SDL_WINDOWEVENT) &&
(a.window.event == SDL_WINDOWEVENT_RESIZED ||
a.window.event == SDL_WINDOWEVENT_SIZE_CHANGED ||
a.window.event == SDL_WINDOWEVENT_EXPOSED)) {
return true;
}
return false;
}
@ -362,9 +369,9 @@ void pump()
}
// remove all inputs, draw events and only keep the last of the resize events
// This will turn horrible after ~38 days when the Uint32 wraps.
if (resize_found || SDL_GetTicks() <= last_resize_event.window.timestamp + RESIZE_TIMEOUT) {
if (resize_found || SDL_GetTicks() <= last_resize_event.window.timestamp + resize_timeout) {
events.erase(std::remove_if(events.begin(), events.end(), remove_on_resize), events.end());
} else if(SDL_GetTicks() > last_resize_event.window.timestamp + RESIZE_TIMEOUT && !last_resize_event_used) {
} else if(SDL_GetTicks() > last_resize_event.window.timestamp + resize_timeout && !last_resize_event_used) {
events.insert(events.begin(), last_resize_event);
last_resize_event_used = true;
}

View file

@ -27,8 +27,6 @@
#define CLOSE_WINDOW_EVENT (SDL_USEREVENT + 4)
#define SHOW_HELPTIP_EVENT (SDL_USEREVENT + 5)
#define RESIZE_TIMEOUT 100
namespace events
{

View file

@ -287,6 +287,7 @@ void default_map_generator::user_config(display& disp)
width_slider.set_min(min_width+(players_slider.value()-2)*extra_size_per_player);
height_slider.set_min(min_width+(players_slider.value()-2)*extra_size_per_player);
f.draw();
events::raise_process_event();
events::raise_draw_event();

View file

@ -117,6 +117,7 @@ help_manager::~help_manager()
void show_help(display &disp, const std::string& show_topic, int xloc, int yloc)
{
show_help(disp, toplevel, show_topic, xloc, yloc);
disp.redraw_everything();
}
/**
@ -128,6 +129,7 @@ void show_unit_help(display &disp, const std::string& show_topic, bool has_varia
{
show_help(disp, toplevel,
hidden_symbol(hidden) + (has_variations ? ".." : "") + unit_prefix + show_topic, xloc, yloc);
disp.redraw_everything();
}
/**
@ -138,6 +140,7 @@ void show_unit_help(display &disp, const std::string& show_topic, bool has_varia
void show_terrain_help(display &disp, const std::string& show_topic, bool hidden, int xloc, int yloc)
{
show_help(disp, toplevel, hidden_symbol(hidden) + terrain_prefix + show_topic, xloc, yloc);
disp.redraw_everything();
}
@ -148,6 +151,7 @@ void show_terrain_help(display &disp, const std::string& show_topic, bool hidden
void show_variation_help(display &disp, const std::string& unit, const std::string &variation, bool hidden, int xloc, int yloc)
{
show_help(disp, toplevel, hidden_symbol(hidden) + variation_prefix + unit + "_" + variation, xloc, yloc);
disp.redraw_everything();
}
/**
@ -222,6 +226,7 @@ void show_help(display &disp, const section &toplevel_sec,
for (;;) {
events::pump();
events::raise_process_event();
f.draw();
events::raise_draw_event();
if (key[SDLK_ESCAPE]) {
// Escape quits from the dialog.

View file

@ -111,7 +111,8 @@ dialog_frame::dialog_frame(CVideo &video, const std::string& title,
top_right_(image::get_image("dialogs/" + dialog_style_.panel + "-border-topright.png")),
bot_right_(image::get_image("dialogs/" + dialog_style_.panel + "-border-botright.png")),
bg_(image::get_image("dialogs/" + dialog_style_.panel + "-background.png")),
have_border_(top_ != NULL && bot_ != NULL && left_ != NULL && right_ != NULL)
have_border_(top_ != NULL && bot_ != NULL && left_ != NULL && right_ != NULL),
dirty_(true)
#endif
{
}
@ -144,6 +145,20 @@ int dialog_frame::top_padding() const {
return padding;
}
void dialog_frame::set_dirty(bool dirty) {
dirty_ = dirty;
}
void dialog_frame::handle_event(const SDL_Event& event) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
if (event.type == SDL_WINDOWEVENT) {
dirty_ = true;
}
#else
UNUSED(event);
#endif
}
int dialog_frame::bottom_padding() const {
int padding = 0;
if(buttons_ != NULL) {
@ -376,6 +391,9 @@ SDL_Rect dialog_frame::draw_title(CVideo* video)
void dialog_frame::draw()
{
if (!dirty_)
return;
//draw background
draw_background();
@ -402,6 +420,8 @@ void dialog_frame::draw()
if(help_button_ != NULL) {
help_button_->set_location(dim_.interior.x+ButtonHPadding, buttons_area.y);
}
dirty_ = false;
}
} //end namespace gui

View file

@ -52,7 +52,7 @@ private:
bool reset_to;
};
class dialog_frame {
class dialog_frame :public events::sdl_handler {
public:
struct dimension_measurements {
dimension_measurements();
@ -95,6 +95,10 @@ public:
//also called by layout with null param
SDL_Rect draw_title(CVideo *video);
void set_dirty(bool dirty = true);
virtual void handle_event(const SDL_Event& event);
private:
void clear_background();
@ -112,6 +116,7 @@ private:
surface top_, bot_, left_, right_, top_left_, bot_left_, top_right_, bot_right_, bg_;
#endif
bool have_border_;
bool dirty_;
};
//frame_measurements draw_dialog_frame(int x, int y, int w, int h, CVideo &video, const std::string* dialog_style=NULL, surface_restorer* restorer=NULL);

View file

@ -718,6 +718,8 @@ void button::mouse_up(SDL_MouseButtonEvent const &event)
void button::handle_event(const SDL_Event& event)
{
gui::widget::handle_event(event);
if (hidden() || !enabled())
return;

View file

@ -150,6 +150,8 @@ unsigned scrollarea::scrollbar_width() const
void scrollarea::handle_event(const SDL_Event& event)
{
gui::widget::handle_event(event);
if (mouse_locked() || hidden())
return;

View file

@ -321,6 +321,8 @@ void scrollbar::draw_contents()
void scrollbar::handle_event(const SDL_Event& event)
{
gui::widget::handle_event(event);
if (mouse_locked() || hidden())
return;

View file

@ -314,6 +314,8 @@ bool slider::requires_event_focus(const SDL_Event* event) const
void slider::handle_event(const SDL_Event& event)
{
gui::widget::handle_event(event);
if (!enabled() || hidden())
return;

View file

@ -447,6 +447,7 @@ bool textbox::requires_event_focus(const SDL_Event* event) const
void textbox::handle_event(const SDL_Event& event)
{
gui::widget::handle_event(event);
handle_event(event, false);
}

View file

@ -342,5 +342,15 @@ void widget::process_tooltip_string(int mousex, int mousey)
}
}
void widget::handle_event(SDL_Event const &event) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
if (event.type == SDL_WINDOWEVENT) {
set_dirty();
}
#else
UNUSED(event);
#endif
}
}

View file

@ -89,7 +89,7 @@ protected:
const SDL_Rect* clip_rect() const;
virtual sdl_handler_vector member_handlers() { return sdl_handler::handler_members(); }
virtual void handle_event(SDL_Event const &/*event*/) {}
virtual void handle_event(SDL_Event const &event);
bool focus_; // Should user input be ignored?
bool mouse_locked() const;