Added IAppHook interface for a cleaner event/hook interface.

This commit is contained in:
David Capello 2009-10-14 14:09:59 +00:00
parent b758b113e8
commit f2f78377ad
15 changed files with 251 additions and 212 deletions

View File

@ -1,3 +1,10 @@
2009-10-14 David Capello <davidcapello@gmail.com>
* src/core/app.h (IAppHook, AppEvent): Added IAppHook interface
for a cleaner event/hook interface.
* src/core/app.cpp (Option): Converted to a class.
2009-10-08 David Capello <davidcapello@gmail.com> 2009-10-08 David Capello <davidcapello@gmail.com>
* src/modules/tools.cpp (tool_marker): Modified marquee tooltip. * src/modules/tools.cpp (tool_marker): Modified marquee tooltip.

View File

@ -65,7 +65,7 @@ void AboutCommand::execute(Context* context)
box1 = jbox_new(JI_VERTICAL); box1 = jbox_new(JI_VERTICAL);
label1 = jlabel_new("Allegro Sprite Editor - " VERSION); label1 = jlabel_new("Allegro Sprite Editor - " VERSION);
label2 = jlabel_new(_("Just Another Tool to Create Sprites")); label2 = jlabel_new(_("Just another tool to create sprites"));
separator1 = ji_separator_new(NULL, JI_HORIZONTAL); separator1 = ji_separator_new(NULL, JI_HORIZONTAL);
if (authors_txt) { if (authors_txt) {

View File

@ -40,6 +40,17 @@
#include "widgets/statebar.h" #include "widgets/statebar.h"
#include "sprite_wrappers.h" #include "sprite_wrappers.h"
class FreeWidget : public IAppHook
{
JWidget m_widget;
public:
FreeWidget(JWidget widget) : m_widget(widget) { }
void on_event()
{
jwidget_free(m_widget);
}
};
static JWidget window = NULL; static JWidget window = NULL;
static bool brush_preview_msg_proc(JWidget widget, JMessage msg); static bool brush_preview_msg_proc(JWidget widget, JMessage msg);
@ -201,9 +212,7 @@ void ConfigureTools::execute(Context* context)
HOOK(cursor_color, SIGNAL_COLORBUTTON_CHANGE, cursor_button_change_hook, 0); HOOK(cursor_color, SIGNAL_COLORBUTTON_CHANGE, cursor_button_change_hook, 0);
HOOK(check_onionskin, JI_SIGNAL_CHECK_CHANGE, onionskin_check_change_hook, 0); HOOK(check_onionskin, JI_SIGNAL_CHECK_CHANGE, onionskin_check_change_hook, 0);
app_add_hook(APP_EXIT, App::instance()->add_hook(AppEvent::Exit, new FreeWidget(window));
reinterpret_cast<void(*)(void*)>(jwidget_free),
window);
} }
/* default position */ /* default position */

View File

@ -72,6 +72,17 @@ bool ColorCurveCommand::enabled(Context* context)
sprite != NULL; sprite != NULL;
} }
class DestroyCurve : public IAppHook
{
Curve* m_curve;
public:
DestroyCurve(Curve* curve) : m_curve(curve) { }
void on_event()
{
curve_free(m_curve);
}
};
void ColorCurveCommand::execute(Context* context) void ColorCurveCommand::execute(Context* context)
{ {
const CurrentSpriteReader sprite(context); const CurrentSpriteReader sprite(context);
@ -85,9 +96,7 @@ void ColorCurveCommand::execute(Context* context)
curve_add_point(the_curve, curve_point_new(0, 0)); curve_add_point(the_curve, curve_point_new(0, 0));
curve_add_point(the_curve, curve_point_new(255, 255)); curve_add_point(the_curve, curve_point_new(255, 255));
app_add_hook(APP_EXIT, App::instance()->add_hook(AppEvent::Exit, new DestroyCurve(the_curve));
reinterpret_cast<void(*)(void*)>(curve_free),
the_curve);
} }
JWidgetPtr window(load_widget("colcurv.jid", "color_curve")); JWidgetPtr window(load_widget("colcurv.jid", "color_curve"));

View File

@ -68,34 +68,44 @@
#include <winalleg.h> #include <winalleg.h>
#endif #endif
/* options */ class Option
{
int m_type;
jstring m_data;
public:
enum { enum {
OPEN_GFX_FILE, OpenSprite,
}; };
struct Option Option(int type, const char* data)
{ {
int type; m_type = type;
char *data; m_data = data;
};
struct AppHook
{
void (*proc)(void *);
void *data;
AppHook(void (*proc)(void *), void *data) {
this->proc = proc;
this->data = data;
} }
int type() const { return m_type; }
const char* data() const { return m_data.c_str(); }
};
class App::Pimpl
{
public:
const char* m_exe_name;
std::vector<Option*> m_options;
CommandsModule m_commands_modules;
UIContext m_ui_context;
int m_return_code;
std::vector<std::vector<IAppHook*> > m_apphooks;
Pimpl() { }
~Pimpl() { }
}; };
App* App::m_instance = NULL; App* App::m_instance = NULL;
static char *exe_name; /* name of the program */
static JList apphooks[APP_EVENTS];
static JWidget top_window = NULL; /* top level window (the desktop) */ static JWidget top_window = NULL; /* top level window (the desktop) */
static JWidget box_menubar = NULL; /* box where the menu bar is */ static JWidget box_menubar = NULL; /* box where the menu bar is */
static JWidget box_colorbar = NULL; /* box where the color bar is */ static JWidget box_colorbar = NULL; /* box where the color bar is */
@ -108,26 +118,10 @@ static JWidget colorbar = NULL; /* the color bar widget */
static JWidget toolbar = NULL; /* the tool bar widget */ static JWidget toolbar = NULL; /* the tool bar widget */
static JWidget tabsbar = NULL; /* the tabs bar widget */ static JWidget tabsbar = NULL; /* the tabs bar widget */
static JList options; /* list of "Option" structures (options to execute) */
static char *palette_filename = NULL; static char *palette_filename = NULL;
static void tabsbar_select_callback(JWidget tabs, void *data, int button); static void tabsbar_select_callback(JWidget tabs, void *data, int button);
static void check_args(int argc, char *argv[]);
static void usage(int status);
static Option *option_new(int type, const char *data);
static void option_free(Option *option);
class App::Pimpl
{
CommandsModule m_commands_modules;
UIContext m_ui_context;
public:
Pimpl() { }
~Pimpl() { }
};
/** /**
* Initializes the application loading the modules, setting the * Initializes the application loading the modules, setting the
* graphics mode, loading the configuration and resources, etc. * graphics mode, loading the configuration and resources, etc.
@ -137,11 +131,11 @@ App::App(int argc, char *argv[])
assert(m_instance == NULL); assert(m_instance == NULL);
m_instance = this; m_instance = this;
exe_name = argv[0]; // create private implementation data
m_pimpl = new Pimpl;
/* initialize application hooks */ m_pimpl->m_exe_name = argv[0];
for (int c=0; c<APP_EVENTS; ++c) m_pimpl->m_return_code = 0;
apphooks[c] = NULL; m_pimpl->m_apphooks.resize(AppEvent::NumEvents);
/* initialize language suppport */ /* initialize language suppport */
intl_init(); intl_init();
@ -155,7 +149,7 @@ App::App(int argc, char *argv[])
/* init configuration */ /* init configuration */
ase_config_init(); ase_config_init();
/* load the language file */ // load the language file
intl_load_lang(); intl_load_lang();
/* search options in the arguments */ /* search options in the arguments */
@ -168,11 +162,8 @@ App::App(int argc, char *argv[])
/* install 'raster' stuff */ /* install 'raster' stuff */
gfxobj_init(); gfxobj_init();
// create singletons
m_pimpl = new Pimpl;
// install the modules // install the modules
modules_init(REQUIRE_INTERFACE); modules_init(ase_mode & MODE_GUI ? REQUIRE_INTERFACE: 0);
/* custom default palette? */ /* custom default palette? */
if (palette_filename) { if (palette_filename) {
@ -197,11 +188,8 @@ App::App(int argc, char *argv[])
* Runs the ASE application. In GUI mode it's the top-level window, in * Runs the ASE application. In GUI mode it's the top-level window, in
* console/scripting it just runs the specified scripts. * console/scripting it just runs the specified scripts.
*/ */
void App::run() int App::run()
{ {
Option *option;
JLink link;
/* initialize GUI interface */ /* initialize GUI interface */
if (ase_mode & MODE_GUI) { if (ase_mode & MODE_GUI) {
JWidget view, editor; JWidget view, editor;
@ -217,7 +205,7 @@ void App::run()
if (!top_window) { if (!top_window) {
allegro_message("Error loading data data/jids/main.jid file.\n" allegro_message("Error loading data data/jids/main.jid file.\n"
"You have to reinstall the program.\n"); "You have to reinstall the program.\n");
exit(1); return 1;
} }
box_menubar = jwidget_find_name(top_window, "menubar"); box_menubar = jwidget_find_name(top_window, "menubar");
@ -285,23 +273,24 @@ void App::run()
/* set_display_switch_mode(SWITCH_BACKAMNESIA); */ /* set_display_switch_mode(SWITCH_BACKAMNESIA); */
set_display_switch_mode(SWITCH_BACKGROUND); set_display_switch_mode(SWITCH_BACKGROUND);
/* procress options */ // procress options
PRINTF("Processing options...\n"); PRINTF("Processing options...\n");
JI_LIST_FOR_EACH(options, link) { for (std::vector<Option*>::iterator
option = reinterpret_cast<Option*>(link->data); it = m_pimpl->m_options.begin(); it != m_pimpl->m_options.end(); ++it) {
Option* option = *it;
switch (option->type) { switch (option->type()) {
case OPEN_GFX_FILE: { case Option::OpenSprite: {
/* load the sprite */ /* load the sprite */
Sprite *sprite = sprite_load(option->data); Sprite *sprite = sprite_load(option->data());
if (!sprite) { if (!sprite) {
/* error */ /* error */
if (ase_mode & MODE_GUI) if (ase_mode & MODE_GUI)
jalert(_("Error<<Error loading file \"%s\"||&Close"), option->data); jalert(_("Error<<Error loading file \"%s\"||&Close"), option->data());
else else
user_printf(_("Error loading file \"%s\"\n"), option->data); user_printf(_("Error loading file \"%s\"\n"), option->data());
} }
else { else {
/* mount and select the sprite */ /* mount and select the sprite */
@ -314,16 +303,15 @@ void App::run()
set_sprite_in_more_reliable_editor(context->get_first_sprite()); set_sprite_in_more_reliable_editor(context->get_first_sprite());
/* recent file */ /* recent file */
recent_file(option->data); recent_file(option->data());
} }
} }
break; break;
} }
} }
option_free(option); delete option;
} }
m_pimpl->m_options.clear();
jlist_free(options);
/* just batch mode */ /* just batch mode */
if (ase_mode & MODE_BATCH) { if (ase_mode & MODE_BATCH) {
@ -357,6 +345,7 @@ void App::run()
jwidget_free(top_window); jwidget_free(top_window);
top_window = NULL; top_window = NULL;
} }
return 0;
} }
/** /**
@ -364,24 +353,25 @@ void App::run()
*/ */
App::~App() App::~App()
{ {
try {
assert(m_instance == this); assert(m_instance == this);
// remove ase handlers // remove ase handlers
PRINTF("Uninstalling ASE\n"); PRINTF("Uninstalling ASE\n");
app_trigger_event(APP_EXIT); App::trigger_event(AppEvent::Exit);
// destroy application hooks // destroy application hooks
for (int c=0; c<APP_EVENTS; ++c) { for (int c=0; c<AppEvent::NumEvents; ++c) {
if (apphooks[c] != NULL) { for (std::vector<IAppHook*>::iterator
JLink link; it = m_pimpl->m_apphooks[c].begin();
JI_LIST_FOR_EACH(apphooks[c], link) { it != m_pimpl->m_apphooks[c].end(); ++it) {
AppHook* apphook = reinterpret_cast<AppHook*>(link->data); IAppHook* apphook = *it;
delete apphook; delete apphook;
} }
jlist_free(apphooks[c]);
apphooks[c] = NULL; // clear the list of hooks (so nobody can call the deleted hooks)
} m_pimpl->m_apphooks[c].clear();
} }
// finalize modules, configuration and core // finalize modules, configuration and core
@ -398,29 +388,28 @@ App::~App()
m_instance = NULL; m_instance = NULL;
} }
catch (...) {
void app_add_hook(int app_event, void (*proc)(void *data), void *data) allegro_message("Uncaught exception in ~App");
{ // no throw
assert(app_event >= 0 && app_event < APP_EVENTS); }
if (apphooks[app_event] == NULL)
apphooks[app_event] = jlist_new();
jlist_append(apphooks[app_event], new AppHook(proc, data));
} }
void app_trigger_event(int app_event) void App::add_hook(AppEvent::Type event, IAppHook* hook)
{ {
assert(app_event >= 0 && app_event < APP_EVENTS); assert(event >= 0 && event < AppEvent::NumEvents);
if (apphooks[app_event] != NULL) { m_pimpl->m_apphooks[event].push_back(hook);
JList list = apphooks[app_event];
JLink link;
JI_LIST_FOR_EACH(list, link) {
AppHook *h = (AppHook *)link->data;
(h->proc)(h->data);
} }
void App::trigger_event(AppEvent::Type event)
{
assert(event >= 0 && event < AppEvent::NumEvents);
for (std::vector<IAppHook*>::iterator
it = m_pimpl->m_apphooks[event].begin();
it != m_pimpl->m_apphooks[event].end(); ++it) {
IAppHook* apphook = *it;
apphook->on_event();
} }
} }
@ -589,14 +578,12 @@ static void tabsbar_select_callback(JWidget tabs, void *data, int button)
/** /**
* Looks the inpunt arguments in the command line. * Looks the inpunt arguments in the command line.
*/ */
static void check_args(int argc, char *argv[]) void App::check_args(int argc, char *argv[])
{ {
Console console; Console console;
int i, n, len; int i, n, len;
char *arg; char *arg;
options = jlist_new();
for (i=1; i<argc; i++) { for (i=1; i<argc; i++) {
arg = argv[i]; arg = argv[i];
@ -610,7 +597,7 @@ static void check_args(int argc, char *argv[])
if (++i < argc) if (++i < argc)
palette_filename = argv[i]; palette_filename = argv[i];
else else
usage(1); usage(false);
} }
/* video resolution */ /* video resolution */
else if (strncmp(arg+n, "resolution", len) == 0) { else if (strncmp(arg+n, "resolution", len) == 0) {
@ -646,8 +633,9 @@ static void check_args(int argc, char *argv[])
} }
} }
else { else {
console.printf(_("%s: option \"res\" requires an argument\n"), exe_name); console.printf(_("%s: option \"res\" requires an argument\n"),
usage(1); m_pimpl->m_exe_name);
usage(false);
} }
} }
/* verbose mode */ /* verbose mode */
@ -656,7 +644,7 @@ static void check_args(int argc, char *argv[])
} }
/* show help */ /* show help */
else if (strncmp(arg+n, "help", len) == 0) { else if (strncmp(arg+n, "help", len) == 0) {
usage(0); usage(true);
} }
/* show version */ /* show version */
else if (strncmp(arg+n, "version", len) == 0) { else if (strncmp(arg+n, "version", len) == 0) {
@ -666,34 +654,38 @@ static void check_args(int argc, char *argv[])
} }
/* invalid argument */ /* invalid argument */
else { else {
usage(1); usage(false);
} }
} }
/* graphic file to open */ /* graphic file to open */
else if (n == 0) else if (n == 0)
jlist_append(options, option_new(OPEN_GFX_FILE, argv[i])); m_pimpl->m_options.push_back(new Option(Option::OpenSprite, argv[i]));
} }
} }
/** /**
* Shows the available options for the program * Shows the available options for the program
*/ */
static void usage(int status) void App::usage(bool show_help)
{ {
Console console; Console console;
/* show options */ ase_mode |= MODE_BATCH;
if (!status) { if (!show_help)
/* copyright */ m_pimpl->m_return_code = 1;
console.printf
("ase %s -- allegro-sprite-editor, %s\n"
COPYRIGHT "\n\n",
VERSION, _("The Ultimate Sprites Factory"));
/* usage */ // show options
if (show_help) {
// copyright
console.printf
("ase %s -- Allegro Sprite Editor, %s\n"
COPYRIGHT "\n\n",
VERSION, _("Just another tool to create sprites"));
// usage
console.printf console.printf
("%s\n %s [%s] [%s]...\n\n", ("%s\n %s [%s] [%s]...\n\n",
_("Usage:"), exe_name, _("OPTION"), _("FILE")); _("Usage:"), m_pimpl->m_exe_name, _("OPTION"), _("FILE"));
/* options */ /* options */
console.printf console.printf
@ -713,28 +705,12 @@ static void usage(int status)
/* web-site */ /* web-site */
console.printf console.printf
("%s: %s\n%s\n\n %s\n\n", ("%s: %s\n\n",
_("Find more information in the ASE's official web site at:"), WEBSITE); _("Find more information in the ASE's official web site at:"), WEBSITE);
} }
/* how to show options */ /* how to show options */
else { else {
console.printf(_("Try \"%s --help\" for more information.\n"), exe_name); console.printf(_("Try \"%s --help\" for more information.\n"),
m_pimpl->m_exe_name);
} }
exit(status);
}
static Option *option_new(int type, const char *data)
{
Option *option = new Option;
option->type = type;
option->data = jstrdup(data);
return option;
}
static void option_free(Option* option)
{
jfree(option->data);
delete option;
} }

View File

@ -21,19 +21,30 @@
#include "jinete/jbase.h" #include "jinete/jbase.h"
// enumeration of ASE events in the highest application level
enum {
APP_EXIT,
APP_PALETTE_CHANGE,
APP_EVENTS
};
class Layer; class Layer;
class Sprite; class Sprite;
class Params; class Params;
class Command; class Command;
class CommandsModule; class CommandsModule;
class AppEvent
{
public:
// enumeration of ASE events in the highest application level
enum Type {
Exit,
PaletteChange,
NumEvents
};
};
class IAppHook
{
public:
virtual ~IAppHook() { }
virtual void on_event() = 0;
};
class App class App
{ {
static App* m_instance; static App* m_instance;
@ -47,11 +58,16 @@ public:
static App* instance() { return m_instance; } static App* instance() { return m_instance; }
void run(); int run();
};
void app_add_hook(int app_event, void (*proc)(void *data), void *data); void add_hook(AppEvent::Type event, IAppHook* hook);
void app_trigger_event(int app_event); void trigger_event(AppEvent::Type event);
private:
void check_args(int argc, char *argv[]);
void usage(bool show_help);
};
void app_refresh_screen(const Sprite* sprite); void app_refresh_screen(const Sprite* sprite);

View File

@ -30,7 +30,7 @@
#include "modules/tools.h" #include "modules/tools.h"
#define DEF_MODULE(name, reqs) \ #define DEF_MODULE(name, reqs) \
{ #name, init_module_##name, exit_module_##name, (reqs), FALSE } { #name, init_module_##name, exit_module_##name, (reqs), false }
typedef struct Module typedef struct Module
{ {
@ -38,7 +38,7 @@ typedef struct Module
int (*init)(); int (*init)();
void (*exit)(); void (*exit)();
int reqs; int reqs;
int installed; bool installed;
} Module; } Module;
static Module module[] = static Module module[] =
@ -46,9 +46,9 @@ static Module module[] =
/* This sorting is very important because last modules depend of /* This sorting is very important because last modules depend of
first ones. */ first ones. */
DEF_MODULE(palette, REQUIRE_INTERFACE), DEF_MODULE(palette, 0),
DEF_MODULE(effect, REQUIRE_INTERFACE), DEF_MODULE(effect, 0),
DEF_MODULE(tools, REQUIRE_INTERFACE), DEF_MODULE(tools, 0),
DEF_MODULE(graphics, REQUIRE_INTERFACE), DEF_MODULE(graphics, REQUIRE_INTERFACE),
DEF_MODULE(gui, REQUIRE_INTERFACE), DEF_MODULE(gui, REQUIRE_INTERFACE),
DEF_MODULE(recent, REQUIRE_INTERFACE), DEF_MODULE(recent, REQUIRE_INTERFACE),
@ -61,13 +61,13 @@ static int modules = sizeof(module) / sizeof(Module);
void modules_init(int requirements) void modules_init(int requirements)
{ {
for (int c=0; c<modules; c++) for (int c=0; c<modules; c++)
if (module[c].reqs & requirements) { if ((module[c].reqs & requirements) == module[c].reqs) {
PRINTF("Installing module: %s\n", module[c].name); PRINTF("Installing module: %s\n", module[c].name);
if ((*module[c].init)() < 0) if ((*module[c].init)() < 0)
throw ase_exception(std::string("Error initializing module: ") + module[c].name); throw ase_exception(std::string("Error initializing module: ") + module[c].name);
module[c].installed = TRUE; module[c].installed = true;
} }
} }
@ -77,6 +77,6 @@ void modules_exit()
if (module[c].installed) { if (module[c].installed) {
PRINTF("Unstalling module: %s\n", module[c].name); PRINTF("Unstalling module: %s\n", module[c].name);
(*module[c].exit)(); (*module[c].exit)();
module[c].installed = FALSE; module[c].installed = false;
} }
} }

View File

@ -46,6 +46,17 @@
# define MAX_PATH 4096 /* TODO this is needed for Linux, is it correct? */ # define MAX_PATH 4096 /* TODO this is needed for Linux, is it correct? */
#endif #endif
class FreeList : public IAppHook
{
JList m_list;
public:
FreeList(JList list) : m_list(list) { }
void on_event()
{
jlist_free(m_list);
}
};
/* Variables used only to maintain the history of navigation. */ /* Variables used only to maintain the history of navigation. */
static JLink navigation_position = NULL; /* current position in the navigation history */ static JLink navigation_position = NULL; /* current position in the navigation history */
static JList navigation_history = NULL; /* set of FileItems navigated */ static JList navigation_history = NULL; /* set of FileItems navigated */
@ -89,9 +100,8 @@ jstring ase_file_selector(const jstring& message,
if (!navigation_history) { if (!navigation_history) {
navigation_history = jlist_new(); navigation_history = jlist_new();
app_add_hook(APP_EXIT, App::instance()->add_hook(AppEvent::Exit,
reinterpret_cast<void(*)(void*)>(jlist_free), new FreeList(navigation_history));
navigation_history);
} }
// we have to find where the user should begin to browse files (start_folder) // we have to find where the user should begin to browse files (start_folder)

View File

@ -52,13 +52,14 @@ public:
*/ */
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int status = 1; // 1 = error
try { try {
Allegro allegro; Allegro allegro;
try { try {
Jinete jinete; Jinete jinete;
App app(argc, argv); App app(argc, argv);
app.run(); status = app.run();
} }
catch (std::exception& e) { catch (std::exception& e) {
allegro_message(e.what()); allegro_message(e.what());
@ -70,7 +71,7 @@ int main(int argc, char *argv[])
catch (...) { catch (...) {
printf("Uncaught exception"); printf("Uncaught exception");
} }
return 0; return status;
} }
END_OF_MAIN(); END_OF_MAIN();

View File

@ -68,34 +68,32 @@ static void convert_data_to_bitmap(DATA *data, BITMAP **bmp)
} }
} }
static void gen_gfx(void *data) class GenGfx : public IAppHook
{ {
int c; public:
void on_event()
for (c=0; c<GFX_BITMAP_COUNT; c++) { {
for (int c=0; c<GFX_BITMAP_COUNT; c++) {
if (gfx_bmps[c]) if (gfx_bmps[c])
destroy_bitmap(gfx_bmps[c]); destroy_bitmap(gfx_bmps[c]);
gfx_bmps[c] = NULL; gfx_bmps[c] = NULL;
} }
} }
};
int init_module_graphics() int init_module_graphics()
{ {
int c; for (int c=0; c<GFX_BITMAP_COUNT; c++)
for (c=0; c<GFX_BITMAP_COUNT; c++)
gfx_bmps[c] = NULL; gfx_bmps[c] = NULL;
app_add_hook(APP_PALETTE_CHANGE, gen_gfx, NULL); App::instance()->add_hook(AppEvent::PaletteChange, new GenGfx);
return 0; return 0;
} }
void exit_module_graphics() void exit_module_graphics()
{ {
int c; for (int c=0; c<GFX_BITMAP_COUNT; c++)
for (c=0; c<GFX_BITMAP_COUNT; c++)
if (gfx_bmps[c]) { if (gfx_bmps[c]) {
destroy_bitmap(gfx_bmps[c]); destroy_bitmap(gfx_bmps[c]);
gfx_bmps[c] = NULL; gfx_bmps[c] = NULL;

View File

@ -149,7 +149,11 @@ static void save_gui_config();
static bool button_with_icon_msg_proc(JWidget widget, JMessage msg); static bool button_with_icon_msg_proc(JWidget widget, JMessage msg);
static bool manager_msg_proc(JWidget widget, JMessage msg); static bool manager_msg_proc(JWidget widget, JMessage msg);
static void regen_theme_and_fixup_icons(void *data); class RegenIcons : public IAppHook
{
public:
void on_event();
};
/** /**
* Used by set_display_switch_callback(SWITCH_IN, ...). * Used by set_display_switch_callback(SWITCH_IN, ...).
@ -298,7 +302,7 @@ int init_module_gui()
reload_default_font(); reload_default_font();
/* hook for palette change to regenerate the theme */ /* hook for palette change to regenerate the theme */
app_add_hook(APP_PALETTE_CHANGE, regen_theme_and_fixup_icons, NULL); App::instance()->add_hook(AppEvent::PaletteChange, new RegenIcons());
/* icon buttons */ /* icon buttons */
icon_buttons = jlist_new(); icon_buttons = jlist_new();
@ -955,9 +959,9 @@ void* get_monitor_data(Monitor* monitor)
return monitor->data; return monitor->data;
} }
/**********************************************************************/ /**
/* manager event handler */ * Manager event handler.
*/
static bool manager_msg_proc(JWidget widget, JMessage msg) static bool manager_msg_proc(JWidget widget, JMessage msg)
{ {
switch (msg->type) { switch (msg->type) {
@ -1069,10 +1073,10 @@ static bool manager_msg_proc(JWidget widget, JMessage msg)
return false; return false;
} }
/**********************************************************************/ /**
/* graphics */ * IAppHook to regenerate graphics when the App palette is changed.
*/
static void regen_theme_and_fixup_icons(void *data) void RegenIcons::on_event()
{ {
JWidget button; JWidget button;
JLink link; JLink link;

View File

@ -195,8 +195,8 @@ bool set_current_palette(Palette *_palette, bool forced)
create_rgb_table(my_rgb_map, rgbpal, NULL); create_rgb_table(my_rgb_map, rgbpal, NULL);
set_palette(rgbpal); /* change system color palette */ set_palette(rgbpal); /* change system color palette */
/* call hooks */ // call hooks
app_trigger_event(APP_PALETTE_CHANGE); App::instance()->trigger_event(AppEvent::PaletteChange);
ret = TRUE; ret = TRUE;
} }

View File

@ -137,7 +137,7 @@ static AlgoHLine inks_hline[][3] =
/* CURSOR COLOR */ /* CURSOR COLOR */
/***********************************************************/ /***********************************************************/
static void update_cursor_color(void *data) static void update_cursor_color()
{ {
if (ji_screen) if (ji_screen)
_cursor_color = get_color_for_allegro(bitmap_color_depth(ji_screen), _cursor_color = get_color_for_allegro(bitmap_color_depth(ji_screen),
@ -148,6 +148,15 @@ static void update_cursor_color(void *data)
_cursor_mask = (color_type(cursor_color) == COLOR_TYPE_MASK); _cursor_mask = (color_type(cursor_color) == COLOR_TYPE_MASK);
} }
class UpdateCursorColor : public IAppHook
{
public:
void on_event()
{
update_cursor_color();
}
};
/***********************************************************/ /***********************************************************/
/* TOOLS */ /* TOOLS */
/***********************************************************/ /***********************************************************/
@ -192,7 +201,7 @@ int init_module_tools()
air_speed = MID(1, air_speed, 100); air_speed = MID(1, air_speed, 100);
tiled_mode = (tiled_t)MID(0, (int)tiled_mode, TILED_BOTH); tiled_mode = (tiled_t)MID(0, (int)tiled_mode, TILED_BOTH);
app_add_hook(APP_PALETTE_CHANGE, update_cursor_color, NULL); App::instance()->add_hook(AppEvent::PaletteChange, new UpdateCursorColor);
return 0; return 0;
} }
@ -309,7 +318,7 @@ color_t get_cursor_color()
void set_cursor_color(color_t color) void set_cursor_color(color_t color)
{ {
cursor_color = color; cursor_color = color;
update_cursor_color(NULL); update_cursor_color();
} }
/* returns the size which use the current tool */ /* returns the size which use the current tool */

View File

@ -35,8 +35,6 @@ static std::map<gfxobj_id, GfxObj*>* objects_map; // graphics objects map
static void insert_gfxobj(GfxObj* gfxobj); static void insert_gfxobj(GfxObj* gfxobj);
static void erase_gfxobj(GfxObj* gfxobj); static void erase_gfxobj(GfxObj* gfxobj);
//////////////////////////////////////////////////////////////////////
void gfxobj_init() void gfxobj_init()
{ {
objects_map = new std::map<gfxobj_id, GfxObj*>; objects_map = new std::map<gfxobj_id, GfxObj*>;
@ -52,7 +50,7 @@ void gfxobj_exit()
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// GfxObj class // GfxObj class
GfxObj::GfxObj(int type) GfxObj::GfxObj(int type)
{ {
this->type = type; this->type = type;
@ -89,7 +87,6 @@ void GfxObj::assign_id()
} }
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
GfxObj* gfxobj_find(gfxobj_id id) GfxObj* gfxobj_find(gfxobj_id id)
{ {

View File

@ -79,7 +79,6 @@ enum {
ACTION_ROTATE_BR, ACTION_ROTATE_BR,
}; };
static void destroy_clipboard(void* data);
static void set_clipboard(Image* image, Palette* palette, bool set_system_clipboard); static void set_clipboard(Image* image, Palette* palette, bool set_system_clipboard);
static bool copy_from_sprite(const Sprite* sprite); static bool copy_from_sprite(const Sprite* sprite);
@ -106,17 +105,21 @@ static bool first_time = true;
static Palette* clipboard_palette = NULL; static Palette* clipboard_palette = NULL;
static Image* clipboard_image = NULL; static Image* clipboard_image = NULL;
static void destroy_clipboard(void* data) class DestroyClipboard : public IAppHook
{
public:
void on_event()
{ {
delete clipboard_palette; delete clipboard_palette;
delete clipboard_image; delete clipboard_image;
} }
};
static void set_clipboard(Image* image, Palette* palette, bool set_system_clipboard) static void set_clipboard(Image* image, Palette* palette, bool set_system_clipboard)
{ {
if (first_time) { if (first_time) {
first_time = false; first_time = false;
app_add_hook(APP_EXIT, destroy_clipboard, NULL); App::instance()->add_hook(AppEvent::Exit, new DestroyClipboard());
} }
delete clipboard_palette; delete clipboard_palette;