mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-07 10:21:30 +00:00
Added IAppHook interface for a cleaner event/hook interface.
This commit is contained in:
parent
b758b113e8
commit
f2f78377ad
@ -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.
|
||||||
|
@ -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) {
|
||||||
|
@ -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 */
|
||||||
|
@ -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"));
|
||||||
|
260
src/core/app.cpp
260
src/core/app.cpp
@ -68,34 +68,44 @@
|
|||||||
#include <winalleg.h>
|
#include <winalleg.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* options */
|
class Option
|
||||||
enum {
|
|
||||||
OPEN_GFX_FILE,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Option
|
|
||||||
{
|
{
|
||||||
int type;
|
int m_type;
|
||||||
char *data;
|
jstring m_data;
|
||||||
};
|
|
||||||
|
|
||||||
struct AppHook
|
public:
|
||||||
{
|
|
||||||
void (*proc)(void *);
|
|
||||||
void *data;
|
|
||||||
|
|
||||||
AppHook(void (*proc)(void *), void *data) {
|
enum {
|
||||||
this->proc = proc;
|
OpenSprite,
|
||||||
this->data = data;
|
};
|
||||||
|
|
||||||
|
Option(int type, const char* data)
|
||||||
|
{
|
||||||
|
m_type = type;
|
||||||
|
m_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");
|
||||||
|
|
||||||
|
for (std::vector<Option*>::iterator
|
||||||
|
it = m_pimpl->m_options.begin(); it != m_pimpl->m_options.end(); ++it) {
|
||||||
|
Option* option = *it;
|
||||||
|
|
||||||
JI_LIST_FOR_EACH(options, link) {
|
switch (option->type()) {
|
||||||
option = reinterpret_cast<Option*>(link->data);
|
|
||||||
|
|
||||||
switch (option->type) {
|
case Option::OpenSprite: {
|
||||||
|
|
||||||
case OPEN_GFX_FILE: {
|
|
||||||
/* 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,63 +353,63 @@ void App::run()
|
|||||||
*/
|
*/
|
||||||
App::~App()
|
App::~App()
|
||||||
{
|
{
|
||||||
assert(m_instance == this);
|
try {
|
||||||
|
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
|
||||||
modules_exit();
|
modules_exit();
|
||||||
delete m_pimpl;
|
delete m_pimpl;
|
||||||
editor_cursor_exit();
|
editor_cursor_exit();
|
||||||
boundary_exit();
|
boundary_exit();
|
||||||
|
|
||||||
gfxobj_exit();
|
gfxobj_exit();
|
||||||
ase_config_exit();
|
ase_config_exit();
|
||||||
file_system_exit();
|
file_system_exit();
|
||||||
core_exit();
|
core_exit();
|
||||||
intl_exit();
|
intl_exit();
|
||||||
|
|
||||||
m_instance = NULL;
|
m_instance = NULL;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
allegro_message("Uncaught exception in ~App");
|
||||||
|
// no throw
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void app_add_hook(int app_event, void (*proc)(void *data), void *data)
|
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);
|
||||||
apphooks[app_event] = jlist_new();
|
|
||||||
|
|
||||||
jlist_append(apphooks[app_event], new AppHook(proc, data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void app_trigger_event(int app_event)
|
void App::trigger_event(AppEvent::Type event)
|
||||||
{
|
{
|
||||||
assert(app_event >= 0 && app_event < APP_EVENTS);
|
assert(event >= 0 && event < AppEvent::NumEvents);
|
||||||
|
|
||||||
if (apphooks[app_event] != NULL) {
|
for (std::vector<IAppHook*>::iterator
|
||||||
JList list = apphooks[app_event];
|
it = m_pimpl->m_apphooks[event].begin();
|
||||||
JLink link;
|
it != m_pimpl->m_apphooks[event].end(); ++it) {
|
||||||
|
IAppHook* apphook = *it;
|
||||||
JI_LIST_FOR_EACH(list, link) {
|
apphook->on_event();
|
||||||
AppHook *h = (AppHook *)link->data;
|
|
||||||
(h->proc)(h->data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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;
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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();
|
||||||
|
@ -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 (int c=0; c<GFX_BITMAP_COUNT; c++) {
|
||||||
|
if (gfx_bmps[c])
|
||||||
|
destroy_bitmap(gfx_bmps[c]);
|
||||||
|
|
||||||
for (c=0; c<GFX_BITMAP_COUNT; c++) {
|
gfx_bmps[c] = NULL;
|
||||||
if (gfx_bmps[c])
|
}
|
||||||
destroy_bitmap(gfx_bmps[c]);
|
|
||||||
|
|
||||||
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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 */
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
delete clipboard_palette;
|
public:
|
||||||
delete clipboard_image;
|
void on_event()
|
||||||
}
|
{
|
||||||
|
delete clipboard_palette;
|
||||||
|
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user