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:
parent
126ba58a44
commit
422ab07191
15 changed files with 84 additions and 14 deletions
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
#define CLOSE_WINDOW_EVENT (SDL_USEREVENT + 4)
|
||||
#define SHOW_HELPTIP_EVENT (SDL_USEREVENT + 5)
|
||||
|
||||
#define RESIZE_TIMEOUT 100
|
||||
|
||||
namespace events
|
||||
{
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue