diff --git a/Makefile b/Makefile index 760d700..3ac2044 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -OBJS=menu.oo main.oo utils.oo gui.oo dialogue_box.oo menu_messages.oo +OBJS=menu.oo main.oo utils.oo gui.oo dialogue_box.oo menu_messages.oo timer.oo all: menu @@ -9,10 +9,12 @@ menu.oo: menu.cpp menu.hh utils.hh font.hh Makefile gui.oo: Makefile gui.cpp gui.hh font.hh menu.hh sdl_ttf_font.hh \ dialogue_box.hh help_box.hh main_menu.cpp disc_menu.cpp \ - file_browser.hh + file_browser.hh timer.hh utils.oo: utils.cpp utils.hh Makefile +timer.oo: timer.cpp timer.hh utils.hh Makefile + dialogue_box.oo: dialogue_box.cpp dialogue_box.hh menu.hh Makefile main.oo: menu.hh utils.hh sdl_ttf_font.hh Makefile diff --git a/disc_menu.cpp b/disc_menu.cpp index 327d4ed..244c5e9 100644 --- a/disc_menu.cpp +++ b/disc_menu.cpp @@ -5,13 +5,13 @@ static const char *game_exts[] = {".d64", ".D64", ".t64", ".T64", ".prg",".PRG", ".p00", ".P00", NULL}; class DiscView; -class DiscMenu : public FileBrowser +class DiscMenu : public FileBrowser, TimeoutHandler { friend class DiscView; public: DiscMenu(Font *font, GuiView *parent) : - FileBrowser(game_exts, font, parent) + FileBrowser(game_exts, font, parent), TimeoutHandler() { } @@ -22,14 +22,23 @@ public: virtual void selectCallback(int which) { printf("entry %d selected: %s\n", which, this->pp_msgs[which]); + Gui::gui->timerController->disarm(this); } virtual void hoverCallback(int which) { + Gui::gui->timerController->arm(this, 10); + } + + virtual void timeoutCallback() + { + printf("Hovering timed out over %s\n", + this->pp_msgs[this->cur_sel]); } virtual void escapeCallback(int which) { + Gui::gui->timerController->disarm(this); Gui::gui->exitMenu(); } }; diff --git a/gui.cpp b/gui.cpp index c81db07..3612ba6 100644 --- a/gui.cpp +++ b/gui.cpp @@ -52,6 +52,7 @@ Gui::Gui() this->n_views = 0; this->views = NULL; + this->timerController = new TimerController(); /* Create the views */ this->mv = new MainView(); @@ -121,6 +122,7 @@ void Gui::runLogic(void) if (!this->is_active || !cur_view) return; cur_view->runLogic(); + this->timerController->tick(); } void Gui::pushView(GuiView *view) diff --git a/gui.hh b/gui.hh index 0459139..38bf4a7 100644 --- a/gui.hh +++ b/gui.hh @@ -5,6 +5,7 @@ #include "menu.hh" #include "font.hh" +#include "timer.hh" class Gui; class MainView; @@ -78,6 +79,7 @@ public: Font *default_font; Font *small_font; + TimerController *timerController; MainView *mv; DiscView *dv; diff --git a/timer.cpp b/timer.cpp new file mode 100644 index 0000000..3cf8815 --- /dev/null +++ b/timer.cpp @@ -0,0 +1,64 @@ +#include "timer.hh" +#include "utils.hh" + +#define MS_TO_TICKS(x) (x) + +TimerController::TimerController() +{ + this->n_handlers = 0; + this->handlers = NULL; +} + +int TimerController::arm(TimeoutHandler *which, int ms) +{ + int i; + + /* Set the timeout */ + which->timeout = MS_TO_TICKS(ms); + + /* Re-register? */ + for (i = 0; i < this->n_handlers; i++) + if (this->handlers[i] == which) + return i; + + /* Not already there */ + for (i = 0; i < this->n_handlers; i++) + if (this->handlers[i] == NULL) + break; + + if (i == this->n_handlers) + { + this->n_handlers++; + this->handlers = (TimeoutHandler**)xrealloc(this->handlers, + (this->n_handlers + 1) * sizeof(TimeoutHandler*)); + } + this->handlers[i] = which; + which->timer_id = i; + + return i; +} + +void TimerController::disarm(TimeoutHandler *which) +{ + panic_if(which->timer_id >= this->n_handlers, + "timer_id %d is too out of bounds (max %d)\n", + which->timer_id, this->n_handlers); + + this->handlers[which->timer_id] = NULL; + which->timer_id = -1; +} + +void TimerController::tick() +{ + for (int i = 0; i < this->n_handlers; i++) + { + TimeoutHandler *cur = this->handlers[i]; + + if (!cur) + continue; + + cur->tick(); + if (cur->timeout == 0) + this->disarm(cur); + } +} diff --git a/timer.hh b/timer.hh new file mode 100644 index 0000000..57801b8 --- /dev/null +++ b/timer.hh @@ -0,0 +1,46 @@ +#ifndef __TIMER_HH__ +#define __TIMER_HH__ + +class TimeoutHandler; + +class TimerController +{ +public: + TimerController(); + + int arm(TimeoutHandler *which, int ms); + + void disarm(TimeoutHandler *which); + + void tick(); + +private: + int n_handlers; + TimeoutHandler **handlers; +}; + +class TimeoutHandler +{ + friend class TimerController; +public: + TimeoutHandler() + { + this->timeout = 0; + this->timer_id = -1; + } + + void tick() + { + this->timeout--; + if (this->timeout == 0) + this->timeoutCallback(); + } + + virtual void timeoutCallback() = 0; + +protected: + int timeout; + int timer_id; +}; + +#endif /* __TIMER_HH__ */ diff --git a/utils.hh b/utils.hh index c65c77d..48f719a 100644 --- a/utils.hh +++ b/utils.hh @@ -1,6 +1,12 @@ #ifndef __UTILS_H__ #define __UTILS_H__ +#include +#include +#include + +#include + #define BUG_ON(cond) #define panic(x...) do \