Add the autoclose feature for dialogs/windows.

This might not be really useful for normal usage, but allows the
unit tests to show a window. (This will be implemented later.)
This commit is contained in:
Mark de Wever 2009-04-30 20:56:41 +00:00
parent a94e980c38
commit 692e5f78bc
6 changed files with 78 additions and 6 deletions

View File

@ -23,6 +23,7 @@
#define HOVER_EVENT (SDL_USEREVENT + 1) #define HOVER_EVENT (SDL_USEREVENT + 1)
#define HOVER_REMOVE_POPUP_EVENT (SDL_USEREVENT + 2) #define HOVER_REMOVE_POPUP_EVENT (SDL_USEREVENT + 2)
#define DRAW_EVENT (SDL_USEREVENT + 3) #define DRAW_EVENT (SDL_USEREVENT + 3)
#define CLOSE_WINDOW_EVENT (SDL_USEREVENT + 4)
namespace events namespace events
{ {

View File

@ -29,7 +29,7 @@ tdialog::~tdialog()
} }
} }
void tdialog::show(CVideo& video) void tdialog::show(CVideo& video, const unsigned auto_close_time)
{ {
std::auto_ptr<twindow> window(build_window(video)); std::auto_ptr<twindow> window(build_window(video));
assert(window.get()); assert(window.get());
@ -40,7 +40,7 @@ void tdialog::show(CVideo& video)
pre_show(video, *window); pre_show(video, *window);
retval_ = window->show(restore_); retval_ = window->show(restore_, auto_close_time);
if(retval_ == twindow::OK) { if(retval_ == twindow::OK) {
finalize_fields(*window); finalize_fields(*window);

View File

@ -43,8 +43,18 @@ public:
virtual ~tdialog(); virtual ~tdialog();
/** Shows the window */ /**
void show(CVideo& video); * Shows the window.
*
* @param video The video which contains the surface to draw
* upon.
* @param auto_close_time The time in ms after which the dialog will
* automatically close, if 0 it doesn't close.
* @note the timeout is a minimum time and
* there's no quarantee about how fast it closes
* after the minimum.
*/
void show(CVideo& video, const unsigned auto_close_time = 0);
/***** ***** ***** setters / getters for members ***** ****** *****/ /***** ***** ***** setters / getters for members ***** ****** *****/

View File

@ -258,6 +258,15 @@ void tevent_handler::handle_event(const SDL_Event& event)
get_window().draw(); get_window().draw();
break; break;
case CLOSE_WINDOW_EVENT:
{
twindow* window = twindow::window_instance(event.user.code);
if(window) {
window->set_retval(twindow::AUTO_CLOSE);
}
}
break;
case SDL_KEYDOWN: case SDL_KEYDOWN:
key_down(event); key_down(event);
break; break;

View File

@ -86,6 +86,33 @@ static Uint32 draw_timer(Uint32, void*)
return draw_interval; return draw_interval;
} }
/**
* SDL_AddTimer() callback for delay_event.
*
* @param event The event to push in the event queue.
*
* @return The new timer interval (always 0).
*/
static Uint32 delay_event_callback(const Uint32, void* event)
{
SDL_PushEvent(static_cast<SDL_Event*>(event));
return 0;
}
/**
* Allows an event to be delayed a certain amount of time.
*
* @note the delay is the minimum time, after the time has passed the event
* will be pushed in the SDL event queue, so it might delay more.
*
* @param event The event to delay.
* @param delay The number of ms to delay the event.
*/
static void delay_event(const SDL_Event& event, const Uint32 delay)
{
SDL_AddTimer(delay, delay_event_callback, new SDL_Event(event));
}
/** /**
* Small helper class to get an unique id for every window instance. * Small helper class to get an unique id for every window instance.
* *
@ -322,7 +349,7 @@ twindow::tretval twindow::get_retval_by_id(const std::string& id)
} }
} }
int twindow::show(const bool restore) int twindow::show(const bool restore, const unsigned auto_close_timeout)
{ {
log_scope2(log_gui_draw, "Window: show."); log_scope2(log_gui_draw, "Window: show.");
@ -348,6 +375,25 @@ int twindow::show(const bool restore)
invalidate_layout(); invalidate_layout();
suspend_drawing_ = false; suspend_drawing_ = false;
if(auto_close_timeout) {
// Make sure we're drawn before we try to close ourselves, which can
// happen if the timeout is small.
draw();
SDL_Event event;
SDL_UserEvent data;
data.type = CLOSE_WINDOW_EVENT;
data.code = tmanager::instance().get_id(*this);
data.data1 = NULL;
data.data2 = NULL;
event.type = CLOSE_WINDOW_EVENT;
event.user = data;
delay_event(event, auto_close_timeout);
}
// Start our loop drawing will happen here as well. // Start our loop drawing will happen here as well.
for(status_ = SHOWING; status_ != REQUEST_CLOSE; ) { for(status_ = SHOWING; status_ != REQUEST_CLOSE; ) {
process_events(); process_events();

View File

@ -133,11 +133,17 @@ public:
* *
* @param restore Restore the screenarea the window was on * @param restore Restore the screenarea the window was on
* after closing it? * after closing it?
* @param auto_close_time The time in ms after which the window will
* automatically close, if 0 it doesn't close.
* @note the timeout is a minimum time and
* there's no quarantee about how fast it closes
* after the minimum.
* *
* @returns The close code of the window, predefined * @returns The close code of the window, predefined
* values are listed in tretval. * values are listed in tretval.
*/ */
int show(const bool restore = true); int show(const bool restore = true,
const unsigned auto_close_timeout = 0);
/** /**
* Draws the window. * Draws the window.