Modified the way that GUI manager (jmanager) controls the message-loop.

This commit is contained in:
David Capello 2008-01-07 11:45:02 +00:00
parent 6fcea92d7b
commit 7fe8991db2
28 changed files with 349 additions and 375 deletions

View File

@ -1,5 +1,19 @@
2008-01-06 David A. Capello <dacap@users.sourceforge.net>
* src/jinete/jwidget.c (jwidget_free_deferred): Added.
* src/jinete/jmanager.c: Replaced 'jmanager_poll' with
'jmanager_generate_messages' and
'jmanager_dispatch_messages'. This fixed a lot of bugs when mix up
two foreground windows.
* src/jinete/jfilesel.c (generate_extensions): Fixed a bug that
leaves 'extensions=NULL' when it's should be 'extensions=a empty
list'.
* src/modules/gui.c (load_widget): Fixed the most stupid code I
ever write (double loading of the widget from the .jid files).
* src/modules/rootmenu.c (load_menu_by_id): Added to fix a problem
with popup-menus of the new jmenu.c implementation.

View File

@ -1,6 +1,7 @@
High priority work
------------------
- the user_data of hook_signal should be void*.
- search for TODO;
- Problems:
- 100% CPU

View File

@ -1,5 +1,5 @@
<!-- ASE - Allegro Sprite Editor -->
<!-- Copyright (C) 2001-2005, 2007 by David A. Capello -->
<!-- Copyright (C) 2001-2005, 2007, 2008 by David A. Capello -->
<!-- Read "LEGAL.txt" for more information. -->
@ -16,12 +16,16 @@
<entry maxsize=32 name="frame" />
<entry maxsize=32 name="xpos" />
<entry maxsize=32 name="ypos" />
<slider min=0 max=255 name="opacity" />
<slider min=0 max=255 name="opacity" minwidth="180" />
</box>
</box>
<box horizontal homogeneous>
<button text="&OK" name="ok" magnetic />
<button text="&Cancel" />
<box horizontal>
<box horizontal expansive />
<box horizontal homogeneous>
<button text="&OK" name="ok" magnetic width="60" />
<button text="&Cancel" />
</box>
</box>
</box>
</window>

View File

@ -1,5 +1,5 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2007 David A. Capello
* Copyright (C) 2007, 2008 David A. Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -77,13 +77,13 @@ static void cmd_configure_tools_execute(const char *argument)
/* if the window is opened, close it */
if (window) {
jwindow_close (window, NULL);
jwindow_close(window, NULL);
return;
}
/* if the window is closed, open it */
window = load_widget ("toolconf.jid", "configure_tool");
window = load_widget("toolconf.jid", "configure_tool");
if (!window)
return;

View File

@ -110,7 +110,7 @@ static void preview_sprite(int flags)
/* print a informative text */
status_bar_set_text(app_get_status_bar(), 1, _("Rendering..."));
jwidget_flush_redraw(app_get_status_bar());
jmanager_dispatch_messages();
jmanager_dispatch_messages(ji_get_default_manager());
jmouse_set_cursor(JI_CURSOR_NULL);
jmouse_set_position(JI_SCREEN_W/2, JI_SCREEN_H/2);

View File

@ -180,7 +180,7 @@ void do_progress(int progress)
status_bar_do_progress(status_bar, progress);
jwidget_flush_redraw(status_bar);
jmanager_dispatch_messages();
jmanager_dispatch_messages(ji_get_default_manager());
gui_feedback();
}
}

View File

@ -177,7 +177,7 @@ void switch_between_film_and_sprite_editor(void)
update_screen_for_sprite(sprite);
}
/***********************************************************************
LayerBox
***********************************************************************/
@ -457,7 +457,7 @@ static bool layer_box_msg_proc(JWidget widget, JMessage msg)
return FALSE;
}
/***********************************************************************
CelBox
***********************************************************************/
@ -800,7 +800,7 @@ static bool cel_box_msg_proc(JWidget widget, JMessage msg)
return FALSE;
}
/***********************************************************************
Extra Routines
***********************************************************************/

View File

@ -1,5 +1,6 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2005, 2007 David A. Capello
* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007,
* 2008 David A. Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -20,16 +21,10 @@
#ifndef USE_PRECOMPILED_HEADER
#include <assert.h>
#include <stdio.h>
#include "jinete/jbox.h"
#include "jinete/jbutton.h"
#include "jinete/jhook.h"
#include "jinete/jlist.h"
#include "jinete/jrect.h"
#include "jinete/jsystem.h"
#include "jinete/jwidget.h"
#include "jinete/jwindow.h"
#include "jinete/jinete.h"
#include "modules/color.h"
#include "modules/gui.h"
@ -39,28 +34,27 @@
#endif
static int paledit_change_signal (JWidget widget, int user_data);
static int window_resize_signal (JWidget widget, int user_data);
static int paledit_change_signal(JWidget widget, int user_data);
static bool window_hook(JWidget widget, JMessage msg);
void ji_minipal_new (JWidget color_bar, int x, int y)
void ji_minipal_new(JWidget color_bar, int x, int y)
{
JWidget window, paledit;
window = jwindow_new ("MiniPal");
paledit = palette_editor_new (current_palette, FALSE, 3);
window = jwindow_new("MiniPal");
paledit = palette_editor_new(current_palette, FALSE, 3);
HOOK (paledit, SIGNAL_PALETTE_EDITOR_CHANGE, paledit_change_signal, color_bar);
HOOK (window, JI_SIGNAL_WINDOW_RESIZE, window_resize_signal, paledit);
HOOK(paledit, SIGNAL_PALETTE_EDITOR_CHANGE, paledit_change_signal, color_bar);
jwidget_add_hook(window, JI_USER_WIDGET, window_hook, paledit);
jwidget_expansive (paledit, TRUE);
jwidget_expansive(paledit, TRUE);
jwidget_add_child(window, paledit);
jwidget_add_child (window, paledit);
jwindow_position (window, x, y);
jwindow_open_bg (window);
jwindow_position(window, x, y);
jwindow_open_bg(window);
}
static int paledit_change_signal (JWidget widget, int user_data)
static int paledit_change_signal(JWidget widget, int user_data)
{
if (jmouse_b(0)) {
PaletteEditor *paledit = palette_editor_data (widget);
@ -98,23 +92,36 @@ static int paledit_change_signal (JWidget widget, int user_data)
return FALSE;
}
static int window_resize_signal (JWidget widget, int user_data)
static bool window_hook(JWidget widget, JMessage msg)
{
JWidget paledit = (JWidget)user_data;
int cols, box = 3;
switch (msg->type) {
do {
box++;
palette_editor_data(paledit)->boxsize = box;
cols = (jrect_w(paledit->rc)-1) / (box+1);
palette_editor_set_columns(paledit, cols);
} while (((jrect_h(paledit->rc)-1) / (box+1))*cols > 256);
case JM_SIGNAL: {
if (msg->signal.num == JI_SIGNAL_WINDOW_RESIZE) {
JWidget paledit = jwidget_get_data(widget, JI_USER_WIDGET);
int cols, box = 3;
box--;
palette_editor_data(paledit)->boxsize = box;
cols = (jrect_w(paledit->rc)-1) / (box+1);
palette_editor_set_columns(paledit, cols);
do {
box++;
palette_editor_data(paledit)->boxsize = box;
cols = (jrect_w(paledit->rc)-1) / (box+1);
palette_editor_set_columns(paledit, cols);
} while (((jrect_h(paledit->rc)-1) / (box+1))*cols > 256);
box--;
palette_editor_data(paledit)->boxsize = box;
cols = (jrect_w(paledit->rc)-1) / (box+1);
palette_editor_set_columns(paledit, cols);
jwidget_dirty(paledit);
}
else if (msg->signal.num == JI_SIGNAL_WINDOW_CLOSE) {
jwidget_free_deferred(widget);
}
break;
}
}
jwidget_dirty(paledit);
return FALSE;
}

View File

@ -110,9 +110,8 @@ struct jwidget;
#define JI_MAGNETIC 0x000100 /* attract the focus */
#define JI_EXPANSIVE 0x000200 /* is expansive (want more space) */
#define JI_DECORATIVE 0x000400 /* to decorate windows */
#define JI_AUTODESTROY 0x000800 /* destroyed by the manager */
#define JI_HARDCAPTURE 0x001000 /* only windows use hard capture */
#define JI_INITIALIZED 0x002000 /* the widget was already initialized by a theme */
#define JI_HARDCAPTURE 0x000800 /* only windows use hard capture */
#define JI_INITIALIZED 0x001000 /* the widget was already initialized by a theme */
/* widget types */
enum {
@ -162,6 +161,7 @@ enum {
JM_SETPOS, /* set position */
JM_WINMOVE, /* window movement */
JM_DRAWRGN, /* redraw region */
JM_DEFERREDFREE, /* deferred jwidget_free call */
JM_DIRTYCHILDREN, /* dirty children */
JM_QUEUEPROCESSING, /* only sent to manager which indicate
the last message in the queue */

View File

@ -349,7 +349,7 @@ static bool button_msg_proc(JWidget widget, JMessage msg)
/* dispatch focus movement messages (because the buttons
process them) */
jmanager_dispatch_messages();
jmanager_dispatch_messages(ji_get_default_manager());
jwidget_select(widget);
return TRUE;

View File

@ -29,6 +29,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include <allegro.h>
#include <allegro/internal/aintern.h>
#include <errno.h>
@ -87,7 +88,7 @@ static int filesel_type(void)
{
static int type = 0;
if (!type)
type = ji_register_widget_type ();
type = ji_register_widget_type();
return type;
}
@ -593,6 +594,7 @@ static void generate_extensions(const char *exts)
if (ext->size == 1) {
jfree(ext);
free_extensions(); /* all extensions */
extensions = jlist_new(); /* empty */
break;
}
else {
@ -618,6 +620,8 @@ static bool check_extension(const char *filename_ext)
JLink link;
int len;
assert(extensions != NULL);
if (jlist_empty(extensions))
return TRUE; /* all extensions */
@ -664,6 +668,7 @@ static void free_extensions(void)
}
jlist_free(extensions);
extensions = NULL;
}
static void fixup_filename(char *buf, char *from, const char *filename)
@ -804,7 +809,7 @@ static int my_ustrfilecmp (const char *s1, const char *s2)
/* ustrnicmp:
* Unicode-aware version of the DJGPP strnicmp() function.
*/
static int my_ustrnicmp (AL_CONST char *s1, AL_CONST char *s2, int n)
static int my_ustrnicmp(AL_CONST char *s1, AL_CONST char *s2, int n)
{
int c1, c2;
/* ASSERT(s1); */

View File

@ -80,8 +80,7 @@ bool _jwindow_is_moving(void);
/* jmanager.c */
void _jmanager_open_window(JWidget manager, JWidget window);
void _jmanager_close_window(JWidget manager, JWidget window,
bool sendtokill, bool redraw_background);
void _jmanager_close_window(JWidget manager, JWidget window, bool redraw_background);
/**********************************************************************/
/* jtheme.c */

View File

@ -92,7 +92,6 @@ static Timer **timers; /* registered timers */
static int n_timers; /* number of timers */
static JList new_windows; /* windows that we should show */
static JList old_windows; /* windows that we should destroy */
static JList proc_windows_list; /* current window's list in process */
static JList msg_queue; /* messages queue */
static JList msg_filters[NFILTERS]; /* filters for every enqueued message */
@ -107,18 +106,14 @@ static bool first_time_poll; /* TRUE when we don't enter in poll yet */
static char old_readed_key[KEY_MAX]; /* keyboard status of previous
poll */
/* all messages are enqueue before this 'link' (or in the end of the
queue if it's NULL) */
static JLink enqueue_messages_before_this = NULL;
/* manager widget */
static bool manager_msg_proc(JWidget widget, JMessage msg);
static void manager_request_size(JWidget widget, int *w, int *h);
static void manager_set_position(JWidget widget, JRect rect);
static void dispatch_messages(JWidget widget);
static void manager_redraw_region(JWidget widget, JRegion region);
/* auxiliary */
static void destroy_window(JWidget window);
static void remove_msgs_for(JWidget widget, JMessage msg);
static void generate_proc_windows_list(void);
static void generate_proc_windows_list2(JWidget manager);
@ -169,7 +164,6 @@ JWidget jmanager_new(void)
/* empty lists */
msg_queue = jlist_new();
new_windows = jlist_new();
old_windows = jlist_new();
proc_windows_list = jlist_new();
for (c=0; c<NFILTERS; ++c)
@ -215,7 +209,7 @@ void jmanager_free(JWidget widget)
assert_valid_widget(widget);
/* there are some messages in queue? */
jmanager_dispatch_messages();
jmanager_dispatch_messages(widget);
/* finish with main manager */
if (default_manager == widget) {
@ -224,7 +218,6 @@ void jmanager_free(JWidget widget)
/* TODO destroy the AUTODESTROY windows in these lists */
jlist_free(new_windows);
jlist_free(old_windows);
/* destroy filters */
for (c=0; c<NFILTERS; ++c) {
@ -268,21 +261,29 @@ void jmanager_free(JWidget widget)
void jmanager_run(JWidget widget)
{
do {
} while (jmanager_poll(widget, TRUE));
while (!jlist_empty(widget->children)) {
if (jmanager_generate_messages(widget))
jmanager_dispatch_messages(widget);
}
}
bool jmanager_poll(JWidget manager, bool all_windows)
/**
* @return TRUE if there are messages in the queue to be distpatched
* through jmanager_dispatch_messages().
*/
bool jmanager_generate_messages(JWidget manager)
{
/* JList old_proc_windows_list; */
JWidget widget;
JWidget window;
bool ret = TRUE;
int mousemove;
JMessage msg;
JLink link;
int c;
/* make some OSes happy */
yield_timeslice();
rest(1);
/* poll keyboard */
poll_keyboard();
@ -323,10 +324,6 @@ bool jmanager_poll(JWidget manager, bool all_windows)
generate_proc_windows_list();
}
/* create the window's list in process */
/* old_proc_windows_list = proc_windows_list; */
/* proc_windows_list = NULL; */
/* generate_proc_windows_list (manager); */
if (jlist_empty(proc_windows_list))
generate_proc_windows_list();
@ -545,56 +542,22 @@ bool jmanager_poll(JWidget manager, bool all_windows)
}
}
/* process messages queue */
if (!jlist_empty(msg_queue)) {
/* clean the queue of messages */
jmanager_dispatch_messages();
return !jlist_empty(msg_queue);
}
/* redraw dirty widgets */
jwidget_flush_redraw(manager);
jmanager_dispatch_messages();
void jmanager_dispatch_messages(JWidget manager)
{
JMessage msg;
/* add the "Queue Processing" message for the manager */
msg = new_mouse_msg(JM_QUEUEPROCESSING);
jmessage_add_dest(msg, manager);
jmanager_enqueue_message(msg);
/* redraw dirty widgets */
jwidget_flush_redraw(manager);
/* add the "Queue Processing" message for the manager */
msg = new_mouse_msg(JM_QUEUEPROCESSING);
jmessage_add_dest(msg, manager);
jmanager_enqueue_message(msg);
jmanager_dispatch_messages();
}
/* make some OSes happy */
yield_timeslice();
rest(1);
/* old windows to close? */
if (!jlist_empty(old_windows)) {
bool final_close = FALSE;
bool break_loop = FALSE;
JI_LIST_FOR_EACH(old_windows, link) {
window = link->data;
if (jwindow_is_desktop(window))
final_close = TRUE;
if (jwindow_is_foreground(window))
break_loop = TRUE;
destroy_window(window);
}
jlist_clear(old_windows);
if ((!all_windows) && (break_loop))
ret = FALSE;
}
/* destroy the window's list in process */
/* jlist_free (proc_windows_list); */
/* proc_windows_list = old_proc_windows_list; */
/* return */
return ret;
dispatch_messages(manager);
}
/**
@ -684,153 +647,9 @@ void jmanager_enqueue_message(JMessage msg)
}
}
/* jlist_insert_before(msg_queue, */
/* enqueue_messages_before_this, msg); */
jlist_append(msg_queue, msg);
}
void jmanager_dispatch_messages(void)
{
JMessage msg, first_msg;
JLink link, link2, next;
JWidget widget;
bool done;
#ifdef LIMIT_DISPATCH_TIME
int t = ji_clock;
#endif
assert(msg_queue != NULL);
link = jlist_first(msg_queue);
while (link != msg_queue->end) {
msg = link->data;
#ifdef LIMIT_DISPATCH_TIME
if (ji_clock-t > 250)
break;
#endif
/* go to next message */
if (msg->any.used) {
link = link->next;
continue;
}
enqueue_messages_before_this = link->next;
/* this message is in use */
msg->any.used = TRUE;
first_msg = msg;
done = FALSE;
do {
JI_LIST_FOR_EACH(msg->any.widgets, link2) {
widget = link2->data;
#ifdef REPORT_EVENTS
{
static char *msg_name[] = {
"Open",
"Close",
"Destroy",
"Draw",
"Idle",
"Signal",
"Timer",
"ReqSize",
"SetPos",
"WinMove",
"DrawRgn",
"DirtyChildren",
"QueueProcessing",
"Char",
"KeyPressed",
"KeyReleased",
"FocusEnter",
"FocusLeave",
"ButtonPressed",
"ButtonReleased",
"DoubleClick",
"LostClick",
"MouseEnter",
"MouseLeave",
"Motion",
"Wheel",
};
const char *string =
(msg->type >= JM_OPEN &&
msg->type <= JM_WHEEL) ? msg_name[msg->type]:
"Unknown";
printf("Event: %s (%d)\n", string, widget->id);
fflush(stdout);
}
#endif
/* draw message? */
if (msg->type == JM_DRAW) {
/* hidden? */
if (widget->flags & JI_HIDDEN)
continue;
jmouse_hide();
acquire_bitmap(ji_screen);
/* set clip */
set_clip(ji_screen,
msg->draw.rect.x1, msg->draw.rect.y1,
msg->draw.rect.x2-1, msg->draw.rect.y2-1);
#ifdef REPORT_EVENTS
printf("set_clip(%d, %d, %d, %d)\n",
msg->draw.rect.x1, msg->draw.rect.y1,
msg->draw.rect.x2-1, msg->draw.rect.y2-1);
fflush(stdout);
#endif
/* rectfill(ji_screen, 0, 0, JI_SCREEN_W-1, JI_SCREEN_H-1, makecol(255, 0, 0)); */
/* vsync(); vsync(); vsync(); vsync(); */
}
/* call message handler */
done = jwidget_send_message(widget, msg);
/* restore clip */
if (msg->type == JM_DRAW) {
set_clip(ji_screen, 0, 0, JI_SCREEN_W-1, JI_SCREEN_H-1);
/* dirty rectangles */
if (ji_dirty_region)
ji_add_dirty_rect(&msg->draw.rect);
release_bitmap(ji_screen);
jmouse_show();
}
if (done)
break;
}
/* done? */
if (done)
/* don't go to sub-msg */
msg = NULL;
else
/* use sub-msg */
msg = msg->any.sub_msg;
} while (msg);
/* remove the message from the msg_queue */
next = link->next;
jlist_delete_link(msg_queue, link);
link = next;
/* destroy the message */
jmessage_free(first_msg);
}
enqueue_messages_before_this = NULL;
}
JWidget jmanager_get_focus(void)
{
return focus_widget;
@ -1114,8 +933,7 @@ void _jmanager_open_window(JWidget manager, JWidget window)
jlist_append(new_windows, window);
}
void _jmanager_close_window(JWidget manager, JWidget window,
bool sendtokill, bool redraw_background)
void _jmanager_close_window(JWidget manager, JWidget window, bool redraw_background)
{
JMessage msg;
JRegion reg1;
@ -1128,10 +946,6 @@ void _jmanager_close_window(JWidget manager, JWidget window,
else
reg1 = NULL;
/* jmanager_dispatch_messages (); /\* TODO WARNING!!! *\/ */
/* printf (" %d CLOSED BY MANAGER\n", window_id); */
/* close all windows to this desktop */
if (jwindow_is_desktop(window)) {
JLink link, next;
@ -1144,31 +958,31 @@ void _jmanager_close_window(JWidget manager, JWidget window,
jregion_union(reg1, reg1, reg2);
jregion_free(reg2);
_jmanager_close_window(manager, link->data, sendtokill, FALSE);
_jmanager_close_window(manager, link->data, FALSE);
}
}
}
/* free all widgets of special states */
#if 0
jmanager_free_capture();
jmanager_free_mouse();
jmanager_set_focus(manager);
/* jmanager_free_focus(); */
#else
jmanager_free_capture();
jmanager_free_mouse();
jmanager_free_focus();
#endif
/* hide window */
jwidget_hide(window);
/* jmanager_dispatch_messages(); /\* TODO WARNING!!! *\/ */
/* close message */
msg = jmessage_new(JM_CLOSE);
jmessage_broadcast_to_children(msg, window);
jmanager_enqueue_message(msg);
/* TODO this was uncommented */
/* jmanager_dispatch_messages(); /\* TODO WARNING!!! *\/ */
/* update manager list stuff */
jlist_remove(manager->children, window);
window->parent = NULL;
@ -1183,11 +997,8 @@ void _jmanager_close_window(JWidget manager, JWidget window,
jregion_free(reg1);
}
/* update the list of windows to close */
if (sendtokill) {
jlist_remove(new_windows, window); /* maybe the window is in the "new_windows" list */
jlist_append(old_windows, window);
}
/* maybe the window is in the "new_windows" list */
jlist_remove(new_windows, window);
}
/**********************************************************************
@ -1198,6 +1009,13 @@ static bool manager_msg_proc(JWidget widget, JMessage msg)
{
switch (msg->type) {
case JM_DEFERREDFREE:
assert_valid_widget(msg->deffree.widget_to_free);
assert(msg->deffree.widget_to_free != widget);
jwidget_free(msg->deffree.widget_to_free);
return TRUE;
case JM_REQSIZE:
manager_request_size(widget, &msg->reqsize.w, &msg->reqsize.h);
return TRUE;
@ -1285,6 +1103,145 @@ static void manager_set_position(JWidget widget, JRect rect)
jrect_free(old_pos);
}
static void dispatch_messages(JWidget widget_manager)
{
JMessage msg, first_msg;
JLink link, link2, next;
JWidget widget;
bool done;
#ifdef LIMIT_DISPATCH_TIME
int t = ji_clock;
#endif
/* TODO get the msg_queue from 'widget_manager' */
assert(msg_queue != NULL);
link = jlist_first(msg_queue);
while (link != msg_queue->end) {
msg = link->data;
#ifdef LIMIT_DISPATCH_TIME
if (ji_clock-t > 250)
break;
#endif
/* go to next message */
if (msg->any.used) {
link = link->next;
continue;
}
/* this message is in use */
msg->any.used = TRUE;
first_msg = msg;
done = FALSE;
do {
JI_LIST_FOR_EACH(msg->any.widgets, link2) {
widget = link2->data;
#ifdef REPORT_EVENTS
{
static char *msg_name[] = {
"Open",
"Close",
"Destroy",
"Draw",
"Signal",
"Timer",
"ReqSize",
"SetPos",
"WinMove",
"DrawRgn",
"DeferredFree",
"DirtyChildren",
"QueueProcessing",
"Char",
"KeyPressed",
"KeyReleased",
"FocusEnter",
"FocusLeave",
"ButtonPressed",
"ButtonReleased",
"DoubleClick",
"MouseEnter",
"MouseLeave",
"Motion",
"Wheel",
};
const char *string =
(msg->type >= JM_OPEN &&
msg->type <= JM_WHEEL) ? msg_name[msg->type]:
"Unknown";
printf("Event: %s (%d)\n", string, widget->id);
fflush(stdout);
}
#endif
/* draw message? */
if (msg->type == JM_DRAW) {
/* hidden? */
if (widget->flags & JI_HIDDEN)
continue;
jmouse_hide();
acquire_bitmap(ji_screen);
/* set clip */
set_clip(ji_screen,
msg->draw.rect.x1, msg->draw.rect.y1,
msg->draw.rect.x2-1, msg->draw.rect.y2-1);
#ifdef REPORT_EVENTS
printf("set_clip(%d, %d, %d, %d)\n",
msg->draw.rect.x1, msg->draw.rect.y1,
msg->draw.rect.x2-1, msg->draw.rect.y2-1);
fflush(stdout);
#endif
/* rectfill(ji_screen, 0, 0, JI_SCREEN_W-1, JI_SCREEN_H-1, makecol(255, 0, 0)); */
/* vsync(); vsync(); vsync(); vsync(); */
}
/* call message handler */
done = jwidget_send_message(widget, msg);
/* restore clip */
if (msg->type == JM_DRAW) {
set_clip(ji_screen, 0, 0, JI_SCREEN_W-1, JI_SCREEN_H-1);
/* dirty rectangles */
if (ji_dirty_region)
ji_add_dirty_rect(&msg->draw.rect);
release_bitmap(ji_screen);
jmouse_show();
}
if (done)
break;
}
/* done? */
if (done)
/* don't go to sub-msg */
msg = NULL;
else
/* use sub-msg */
msg = msg->any.sub_msg;
} while (msg);
/* remove the message from the msg_queue */
next = link->next;
jlist_delete_link(msg_queue, link);
link = next;
/* destroy the message */
jmessage_free(first_msg);
}
}
static void manager_redraw_region(JWidget widget, JRegion region)
{
JWidget window;
@ -1330,15 +1287,6 @@ static void manager_redraw_region(JWidget widget, JRegion region)
Internal routines
**********************************************************************/
static void destroy_window(JWidget window)
{
/* printf (" %d DESTROYED BY MANAGER\n", window->id); */
/* delete the window */
if (jwidget_is_autodestroy(window))
jwidget_free(window);
}
static void remove_msgs_for(JWidget widget, JMessage msg)
{
JLink link, next;

View File

@ -42,7 +42,8 @@ JWidget jmanager_new(void);
void jmanager_free(JWidget manager);
void jmanager_run(JWidget manager);
bool jmanager_poll(JWidget manager, bool all_windows);
bool jmanager_generate_messages(JWidget manager);
void jmanager_dispatch_messages(JWidget manager);
/* timers */
@ -54,7 +55,6 @@ void jmanager_stop_timer(int timer_id);
/* routines that uses the ji_get_default_manager() */
void jmanager_enqueue_message(JMessage msg);
void jmanager_dispatch_messages(void);
JWidget jmanager_get_focus(void);
JWidget jmanager_get_mouse(void);

View File

@ -309,7 +309,6 @@ int jmenuitem_is_highlight(JWidget widget)
return MITEM(widget)->highlight;
}
/* TODO complete this routine */
void jmenu_popup(JWidget menu, int x, int y)
{
JWidget window, menubox;
@ -755,7 +754,8 @@ static bool menubox_msg_proc(JWidget widget, JMessage msg)
default:
if (msg->type == JM_CLOSE_POPUP) {
jwindow_close(jwidget_get_window(widget), NULL);
_jmanager_close_window(jwidget_get_manager(widget),
jwidget_get_window(widget), TRUE);
}
break;

View File

@ -56,6 +56,12 @@ struct jmessage_any
int shifts; /* key shifts pressed when message was created */
};
struct jmessage_deffree /* deferred jwidget_free call */
{
struct jmessage_any any;
JWidget widget_to_free;
};
struct jmessage_key
{
struct jmessage_any any;
@ -122,6 +128,7 @@ union jmessage
{
int type;
struct jmessage_any any;
struct jmessage_deffree deffree;
struct jmessage_key key;
struct jmessage_draw draw;
struct jmessage_mouse mouse;

View File

@ -128,11 +128,8 @@ void jwidget_free(JWidget widget)
jwidget_remove_child(widget->parent, widget);
/* remove children */
JI_LIST_FOR_EACH_SAFE(widget->children, link, next) {
/* TODO the autodestroy flag is only useful for windows */
/* if (jwidget_is_autodestroy (link->data)) */
jwidget_free(link->data);
}
JI_LIST_FOR_EACH_SAFE(widget->children, link, next)
jwidget_free(link->data);
jlist_free(widget->children);
/* destroy the update region */
@ -157,7 +154,20 @@ void jwidget_free(JWidget widget)
jlist_free(widget->hooks);
/* low level free */
_ji_free_widget (widget);
_ji_free_widget(widget);
}
void jwidget_free_deferred(JWidget widget)
{
JMessage msg;
assert_valid_widget(widget);
msg = jmessage_new(JM_DEFERREDFREE);
msg->deffree.widget_to_free = widget;
/* TODO use the manager of 'widget' */
jmessage_add_dest(msg, ji_get_default_manager());
jmanager_enqueue_message(msg);
}
void jwidget_init_theme(JWidget widget)
@ -382,21 +392,6 @@ void jwidget_decorative(JWidget widget, bool state)
widget->flags &= ~JI_DECORATIVE;
}
void jwidget_autodestroy(JWidget widget, bool state)
{
JLink link;
assert_valid_widget(widget);
if (state)
widget->flags |= JI_AUTODESTROY;
else
widget->flags &= ~JI_AUTODESTROY;
JI_LIST_FOR_EACH(widget->children, link)
jwidget_autodestroy(link->data, state);
}
void jwidget_focusrest(JWidget widget, bool state)
{
assert_valid_widget(widget);
@ -428,13 +423,6 @@ bool jwidget_is_decorative(JWidget widget)
return (widget->flags & JI_DECORATIVE) ? TRUE: FALSE;
}
bool jwidget_is_autodestroy(JWidget widget)
{
assert_valid_widget(widget);
return (widget->flags & JI_AUTODESTROY) ? TRUE: FALSE;
}
bool jwidget_is_focusrest(JWidget widget)
{
assert_valid_widget(widget);

View File

@ -102,6 +102,7 @@ int ji_register_widget_type(void);
JWidget jwidget_new(int type);
void jwidget_free(JWidget widget);
void jwidget_free_deferred(JWidget widget);
void jwidget_init_theme(JWidget widget);
@ -130,13 +131,11 @@ void jwidget_set_font(JWidget widget, struct FONT *font);
void jwidget_magnetic(JWidget widget, bool state);
void jwidget_expansive(JWidget widget, bool state);
void jwidget_decorative(JWidget widget, bool state);
void jwidget_autodestroy(JWidget widget, bool state);
void jwidget_focusrest(JWidget widget, bool state);
bool jwidget_is_magnetic(JWidget widget);
bool jwidget_is_expansive(JWidget widget);
bool jwidget_is_decorative(JWidget widget);
bool jwidget_is_autodestroy(JWidget widget);
bool jwidget_is_focusrest(JWidget widget);
/* status properties */

View File

@ -197,15 +197,16 @@ void jwindow_open_fg(JWidget widget)
window->is_foreground = TRUE;
do {
} while (jmanager_poll(manager, FALSE));
while (!(widget->flags & JI_HIDDEN)) {
if (jmanager_generate_messages(manager))
jmanager_dispatch_messages(manager);
}
window->is_foreground = FALSE;
}
void jwindow_open_bg(JWidget widget)
{
widget->flags |= JI_AUTODESTROY; /* TODO */
jwindow_open(widget);
}
@ -215,7 +216,7 @@ void jwindow_close(JWidget widget, JWidget killer)
window->killer = killer;
_jmanager_close_window(jwidget_get_manager(widget), widget, TRUE, TRUE);
_jmanager_close_window(jwidget_get_manager(widget), widget, TRUE);
}
bool jwindow_is_toplevel(JWidget widget)
@ -279,8 +280,7 @@ static bool window_msg_proc(JWidget widget, JMessage msg)
switch (msg->type) {
case JM_DESTROY:
_jmanager_close_window(jwidget_get_manager(widget), widget,
FALSE, FALSE);
_jmanager_close_window(jwidget_get_manager(widget), widget, FALSE);
jfree(window);
break;

View File

@ -517,19 +517,15 @@ JWidget load_widget(const char *filename, const char *name)
dirs_free(dirs);
if (found)
widget = ji_load_widget(buf, name);
else
widget = NULL;
if (!found) {
console_printf(_("File not found: \"%s\"\n"), filename);
return NULL;
}
widget = ji_load_widget (buf, name);
widget = ji_load_widget(buf, name);
if (!widget)
console_printf(_("Error loading widget: \"%s\"\n"), name);
return widget;
}
@ -565,30 +561,30 @@ void rebuild_recent_list(void)
typedef struct HookData {
int signal_num;
int (*signal_handler) (JWidget widget, int user_data);
int (*signal_handler)(JWidget widget, int user_data);
int user_data;
} HookData;
static int hook_type (void)
static int hook_type(void)
{
static int type = 0;
if (!type)
type = ji_register_widget_type ();
type = ji_register_widget_type();
return type;
}
static bool hook_handler (JWidget widget, JMessage msg)
static bool hook_handler(JWidget widget, JMessage msg)
{
switch (msg->type) {
case JM_DESTROY:
jfree (jwidget_get_data (widget, hook_type ()));
jfree(jwidget_get_data(widget, hook_type()));
break;
case JM_SIGNAL: {
HookData *hook_data = jwidget_get_data (widget, hook_type ());
HookData *hook_data = jwidget_get_data(widget, hook_type());
if (hook_data->signal_num == msg->signal.num)
return (*hook_data->signal_handler) (widget, hook_data->user_data);
return (*hook_data->signal_handler)(widget, hook_data->user_data);
break;
}
}
@ -596,18 +592,21 @@ static bool hook_handler (JWidget widget, JMessage msg)
return FALSE;
}
/**
* @warning You can't use this function for the same widget two times.
*/
void hook_signal(JWidget widget,
int signal_num,
int (*signal_handler) (JWidget widget, int user_data),
int (*signal_handler)(JWidget widget, int user_data),
int user_data)
{
HookData *hook_data = jnew (HookData, 1);
HookData *hook_data = jnew(HookData, 1);
hook_data->signal_num = signal_num;
hook_data->signal_handler = signal_handler;
hook_data->user_data = user_data;
jwidget_add_hook (widget, hook_type (), hook_handler, hook_data);
jwidget_add_hook(widget, hook_type(), hook_handler, hook_data);
}
/**

View File

@ -1,5 +1,5 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2005, 2007 David A. Capello
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -22,7 +22,7 @@
#include "jinete/jbase.h"
#define HOOK(widget, signal, signal_handler, user_data) \
hook_signal ((widget), (signal), (signal_handler), (int)(user_data))
hook_signal((widget), (signal), (signal_handler), (int)(user_data))
struct Sprite;
@ -53,7 +53,7 @@ void rebuild_recent_list(void);
void hook_signal(JWidget widget,
int signal_num,
int(*signal_handler) (JWidget widget, int user_data),
int (*signal_handler)(JWidget widget, int user_data),
int user_data);
bool get_widgets(JWidget window, ...);

View File

@ -1073,7 +1073,7 @@ void control_tool(JWidget widget, Tool *tool, const char *_color)
}
jwidget_flush_redraw(status_bar);
jmanager_dispatch_messages();
jmanager_dispatch_messages(ji_get_default_manager());
}
release_bitmap(ji_screen);

View File

@ -1,5 +1,5 @@
/* Jinete - a GUI library
* Copyright (c) 2003, 2004, 2005, 2007, David A. Capello
* Copyright (c) 2003, 2004, 2005, 2007, 2008, David A. Capello
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -51,25 +51,25 @@ int main (int argc, char *argv[])
install_keyboard ();
install_mouse ();
manager = jmanager_new ();
ji_set_standard_theme ();
manager = jmanager_new();
ji_set_standard_theme();
show_file_select ("Select 'bmp,pcx'", "bmp,pcx");
show_file_select ("Select '*t'", "*t");
show_file_select ("Select 't*'", "t*");
show_file_select ("Select '*'", "*");
show_file_select("Select 'bmp,pcx'", "bmp,pcx");
show_file_select("Select '*t'", "*t");
show_file_select("Select 't*'", "t*");
show_file_select("Select '*'", "*");
jmanager_free (manager);
jmanager_free(manager);
return 0;
}
END_OF_MAIN();
static void show_file_select (const char *title, const char *exts)
static void show_file_select(const char *title, const char *exts)
{
char *filename = ji_file_select (title, "", exts);
char *filename = ji_file_select(title, "", exts);
if (filename) {
jalert ("Test<<You select the file:<<\"%s\"||&OK", filename);
jfree (filename);
jalert("Test<<You select the file:<<\"%s\"||&OK", filename);
jfree(filename);
}
}

View File

@ -1,5 +1,5 @@
/* Jinete - a GUI library
* Copyright (c) 2003, 2004, 2005, 2007, David A. Capello
* Copyright (c) 2003, 2004, 2005, 2007, 2008, David A. Capello
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -126,7 +126,10 @@ void shutdown_gui(void)
bool update_gui(void)
{
return !jmanager_poll(manager, TRUE);
if (jmanager_generate_messages(manager))
jmanager_dispatch_messages(manager);
return jwidget_is_visible(window);
}
void draw_gui()

View File

@ -1,5 +1,5 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2005, 2007 David A. Capello
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -246,7 +246,7 @@ static bool interactive_transform(JWidget widget,
jmouse_hide(); \
old_screen = ji_screen; \
ji_screen = bmp1; \
jmanager_dispatch_messages(); \
jmanager_dispatch_messages(ji_get_default_manager()); \
ji_screen = old_screen; \
REDRAW(); \
jmouse_show();
@ -822,5 +822,5 @@ static void update_status_bar(JWidget editor, Image *image,
iangle);
jwidget_flush_redraw(app_get_status_bar());
jmanager_dispatch_messages();
jmanager_dispatch_messages(ji_get_default_manager());
}

View File

@ -1,5 +1,5 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2005, 2007 David A. Capello
* Copyright (C) 2001-2005, 2007, 2008 David A. Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -318,7 +318,7 @@ int interactive_move_layer(int mode, int use_undo, int (*callback)(void))
/* redraw dirty widgets */
jwidget_flush_redraw(ji_get_default_manager());
jmanager_dispatch_messages();
jmanager_dispatch_messages(ji_get_default_manager());
gui_feedback();
} while (editor_click(editor, &new_x, &new_y, &update, NULL));

View File

@ -247,7 +247,7 @@ void editor_set_scroll(JWidget widget, int x, int y, int use_refresh_region)
/* refresh the update_region */
jwidget_flush_redraw(widget);
jmanager_dispatch_messages();
jmanager_dispatch_messages(ji_get_default_manager());
jregion_free(reg2);
}
@ -873,7 +873,7 @@ void editor_refresh_region(JWidget widget)
/* editor->refresh_region); */
/* jwidget_redraw_region (widget, editor->refresh_region); */
jwidget_flush_redraw(widget);
jmanager_dispatch_messages();
jmanager_dispatch_messages(ji_get_default_manager());
/* if (editor->refresh_region) { */
/* jregion_free (editor->refresh_region); */

View File

@ -192,7 +192,7 @@ void status_bar_del_progress(JWidget widget)
if (status_bar->nprogress == 1) {
status_bar->progress[0].pos = status_bar->progress[0].max;
jwidget_flush_redraw(widget);
jmanager_dispatch_messages();
jmanager_dispatch_messages(ji_get_default_manager());
rest(5);
jwidget_dirty(widget);