E_EVENT system is now a bit map, allowing one observer to watch MANY events, for instance: E_EVENT_BORDER_ICONIFY | E_EVENT_BORDER_UNICONIFY | E_EVENT_BORDER_NEW, etc. I also made it so that the current event is passed when notifying, so that if watching multiple events, you can do different things for each.

added an e_observer_notify_all_observees() to notify all existing observees of things, such as the creation of a border. This way, an observer can watch for E_EVENT_BORDER_NEW events and register all new borders.

Iconification! Click that iconify button. Then click the middle button on the desktop to get a menu of iconified apps to uniconify. This menu is a decent example of using the observer code to avoid polling or rebuilding more than necessary. Next, maybe instead of completely rebuilding each time something changes, maybe it should dynamically add or remove the respective menu items?


SVN revision: 5854
This commit is contained in:
rephorm 2002-01-24 08:12:12 +00:00 committed by rephorm
parent dbc39567f3
commit ffcb25ea12
11 changed files with 107 additions and 39 deletions

View File

@ -1658,7 +1658,7 @@ e_act_iconify_start (E_Object *object, E_Action *a, void *data, int x, int y, in
E_Border *b;
D_ENTER;
#if 0
#if 1
b = (E_Border*) object;
if (!b) b = e_border_current_focused();
if (!b) D_RETURN;
@ -1707,6 +1707,8 @@ e_act_max_start (E_Object *object, E_Action *a, void *data, int x, int y, int rx
b->current.requested.y = b->current.y;
b->current.requested.w = b->current.w;
b->current.requested.h = b->current.h;
e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_BORDER_UNMAXIMIZE);
}
else
{
@ -1725,6 +1727,8 @@ e_act_max_start (E_Object *object, E_Action *a, void *data, int x, int y, int rx
b->current.requested.y = b->current.y;
b->current.requested.w = b->current.w;
b->current.requested.h = b->current.h;
e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_BORDER_MAXIMIZE);
}
D_RETURN;

View File

@ -453,7 +453,7 @@ e_focus_in(Ecore_Event * ev)
e_border_focus_grab_ended();
b->current.selected = 1;
b->changed = 1;
e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_WINDOW_FOCUS_IN);
e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_BORDER_FOCUS_IN);
g = b->click_grab;
if (g)
{
@ -1619,7 +1619,7 @@ e_border_new(void)
b = NEW(E_Border, 1);
ZERO(b, E_Border, 1);
e_object_init(E_OBJECT(b), (E_Cleanup_Func) e_border_cleanup);
e_observee_init(E_OBSERVEE(b), (E_Cleanup_Func) e_border_cleanup);
e_observer_register_observee(E_OBSERVER(delayed_window_raise),
E_OBSERVEE(b));
@ -1746,6 +1746,8 @@ e_border_new(void)
e_border_attach_mouse_grabs(b);
borders = evas_list_prepend(borders, b);
e_observee_notify_all_observers(E_OBSERVEE(b), E_EVENT_BORDER_NEW);
D_RETURN_(b);
}
@ -1754,14 +1756,12 @@ void
e_border_iconify(E_Border *b)
{
D_ENTER;
D("iconfy window!\n");
b->client.iconified = 1;
b->current.requested.visible = 0;
e_icccm_state_iconified(b->win.client);
b->changed = 1;
e_border_update(b);
D("notify observers of iconification\n");
e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_WINDOW_ICONIFY);
e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_BORDER_ICONIFY);
D_RETURN;
}
@ -1771,11 +1771,12 @@ e_border_uniconify(E_Border *b)
{
b->client.iconified = 0;
b->current.requested.visible = 1;
b->client.desk = e_desktops_get_current();
e_icccm_state_mapped(b->win.client);
b->changed = 1;
e_border_update(b);
/* should be UNICONIFY */
e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_WINDOW_ICONIFY);
e_observee_notify_observers(E_OBSERVEE(b), E_EVENT_BORDER_ICONIFY);
}
void
@ -2674,7 +2675,7 @@ e_border_init(void)
ecore_event_filter_idle_handler_add(e_idle, NULL);
delayed_window_raise =
e_delayed_action_new(E_EVENT_WINDOW_FOCUS_IN,
e_delayed_action_new(E_EVENT_BORDER_FOCUS_IN,
raise_delay, e_border_raise_delayed);
ecore_add_event_timer("e_border_poll()", 1.00, e_border_poll, 0, NULL);

View File

@ -36,7 +36,7 @@ e_delayed_action_new(E_Event_Type event,
void
e_delayed_action_start(E_Observer *obs, E_Observee *obj)
e_delayed_action_start(E_Observer *obs, E_Observee *obj, E_Event_Type event)
{
char event_name[PATH_MAX];
E_Delayed_Action *eda = (E_Delayed_Action*) obs;

View File

@ -19,7 +19,7 @@ typedef struct _e_delayed_action
E_Delayed_Action *e_delayed_action_new(E_Event_Type event,
double delay, E_Delay_Func delay_func);
void e_delayed_action_start(E_Observer *obs, E_Observee *obj);
void e_delayed_action_start(E_Observer *obs, E_Observee *obj, E_Event_Type event);
void e_delayed_action_cancel(E_Delayed_Action *eda);
#endif

View File

@ -548,11 +548,11 @@ e_epplet_observer_new(FeriteScript *script, char *func_name, FeriteObject *data,
(E_Cleanup_Func)e_epplet_observer_cleanup);
#if 0
else if (!strcmp(event_type, "ICONIFY"))
e_observer_init(E_OBSERVER(obs), E_EVENT_WINDOW_ICONIFY,
e_observer_init(E_OBSERVER(obs), E_EVENT_BORDER_ICONIFY,
e_epplet_border_observer_func,
(E_Cleanup_Func)e_epplet_observer_cleanup);
else if (!strcmp(event_type, "UNICONIFY"))
e_observer_init(E_OBSERVER(obs), E_EVENT_WINDOW_UNICONIFY,
e_observer_init(E_OBSERVER(obs), E_EVENT_BORDER_UNICONIFY,
e_epplet_border_observer_func,
(E_Cleanup_Func)e_epplet_observer_cleanup);
else
@ -618,7 +618,7 @@ e_epplet_observer_register_borders(E_Epplet_Observer *obs)
#endif
void
e_epplet_desktop_observer_func(E_Observer *observer, E_Observee *observee)
e_epplet_desktop_observer_func(E_Observer *observer, E_Observee *observee, E_Event_Type event)
{
E_Epplet_Observer *obs;
E_Desktop *desk;

View File

@ -92,7 +92,7 @@ void e_epplet_timer_func(int val, void *data);
E_Epplet_Observer *e_epplet_observer_new( FeriteScript *script,
char *func_name, FeriteObject *data, char *event_type);
void e_epplet_observer_register_desktops(E_Epplet_Observer *obs);
void e_epplet_desktop_observer_func(E_Observer *observer, E_Observee *observee);
void e_epplet_desktop_observer_func(E_Observer *observer, E_Observee *observee, E_Event_Type event);
/*void e_epplet_border_observer_func(E_Observer *observer, E_Observee *observee);*/
#endif

View File

@ -564,12 +564,14 @@ static void
e_menu_item_unselect (E_Menu_Item *mi)
{
D_ENTER;
D("mi unselect\n");
if ((mi))// && (mi->menu->selected == mi))
D("mi unselect\n");
if ((mi) && (mi->menu->selected == mi))
{
D("mi && mi->menu->selected == mi\n");
mi->menu->selected = curr_selected_item = NULL;
mi->selected = 0;
D("mi && mi->menu->selected == mi\n");
mi->menu->selected = curr_selected_item = NULL;
D("after setting it NULL\n");
mi->selected = 0;
mi->menu->redo_sel = 1;
mi->menu->changed = 1;
}
@ -589,7 +591,7 @@ e_menu_item_select (E_Menu_Item *mi)
{
D_ENTER;
e_menu_item_unselect(curr_selected_item);
// e_menu_item_unselect(curr_selected_item);
if (mi)
{
mi->menu->selected = mi;

View File

@ -26,7 +26,7 @@ static void e_build_menu_gnome_apps_poll(int val, void *data);
static void e_build_menu_gnome_apps_build(E_Build_Menu *bm);
static E_Menu *e_build_menu_iconified_borders_build(E_Build_Menu *bm);
static void e_build_menu_iconified_borders_rebuild(E_Observer *observer, E_Observee *observee);
static void e_build_menu_iconified_borders_rebuild(E_Observer *observer, E_Observee *observee, E_Event_Type event);
/* ------------ various callbacks ---------------------- */
@ -524,7 +524,7 @@ e_build_menu_new_from_iconified_borders()
bm = NEW(E_Build_Menu, 1);
ZERO(bm, E_Build_Menu, 1);
e_observer_init(E_OBSERVER(bm), E_EVENT_WINDOW_ICONIFY, e_build_menu_iconified_borders_rebuild, (E_Cleanup_Func) e_build_menu_cleanup);
e_observer_init(E_OBSERVER(bm), E_EVENT_BORDER_ICONIFY | E_EVENT_BORDER_UNICONIFY | E_EVENT_BORDER_NEW, e_build_menu_iconified_borders_rebuild, (E_Cleanup_Func) e_build_menu_cleanup);
for (l = e_border_get_borders_list(); l; l = l->next)
{
@ -539,16 +539,27 @@ e_build_menu_new_from_iconified_borders()
}
static void
e_build_menu_iconified_borders_rebuild(E_Observer *observer, E_Observee *observee)
e_build_menu_iconified_borders_rebuild(E_Observer *observer, E_Observee *observee, E_Event_Type event)
{
E_Build_Menu *bm;
D_ENTER;
D("catch iconify, rebuild menu");
bm = (E_Build_Menu *)observer;
if (event & E_EVENT_BORDER_NEW)
{
D("catch new border, register it\n");
e_observer_register_observee(E_OBSERVER(observer), E_OBSERVEE(observee));
}
if (event & (E_EVENT_BORDER_ICONIFY | E_EVENT_BORDER_UNICONIFY))
{
D("catch iconify, rebuild menu\n");
bm = (E_Build_Menu *)observer;
e_build_menu_unbuild(bm);
bm->menu = e_build_menu_iconified_borders_build(bm);
e_build_menu_unbuild(bm);
bm->menu = e_build_menu_iconified_borders_build(bm);
}
D_RETURN;
}

View File

@ -3,6 +3,8 @@
#include "debug.h"
#include "observer.h"
static Evas_List observers;
void
e_observer_init(E_Observer *obs, E_Event_Type event,
E_Notify_Func notify_func,
@ -21,6 +23,8 @@ e_observer_init(E_Observer *obs, E_Event_Type event,
e_object_init(E_OBJECT(obs), cleanup_func);
observers = evas_list_append(observers, obs);
D_RETURN;
}
@ -40,6 +44,7 @@ e_observer_cleanup(E_Observer *obs)
e_observer_unregister_observee(obs, o);
}
evas_list_remove(observers, obs);
/* Call the destructor of the base class */
e_object_cleanup(E_OBJECT(obs));
@ -107,16 +112,40 @@ e_observee_notify_observers(E_Observee *o, E_Event_Type event)
{
obs = E_OBSERVER(obs_list->data);
if (obs->event == E_EVENT_MAX ||
obs->event == event)
/* check bit mask */
if (obs->event & event)
{
obs->notify_func(obs, o);
obs->notify_func(obs, o, event);
}
}
D_RETURN;
}
void
e_observee_notify_all_observers(E_Observee *o, E_Event_Type event)
{
Evas_List obs_list = NULL;
E_Observer *obs = NULL;
D_ENTER;
if (!o)
D_RETURN;
for (obs_list = observers; obs_list; obs_list = obs_list->next)
{
obs = E_OBSERVER(obs_list->data);
/* check bit mask */
if (obs->event & event)
{
obs->notify_func(obs, o, event);
}
}
D_RETURN;
}
void
e_observee_cleanup(E_Observee *obs)

View File

@ -12,18 +12,24 @@
typedef struct _e_observer E_Observer;
typedef struct _e_observee E_Observee;
typedef void(*E_Notify_Func)(E_Observer *observer, E_Observee *observee);
typedef enum _e_event_type
{
E_EVENT_WINDOW_FOCUS_IN,
E_EVENT_WINDOW_ICONIFY,
E_EVENT_WINDOW_UNICONIFY,
E_EVENT_WINDOW_MAXIMIZE,
E_EVENT_DESKTOP_SWITCH,
E_EVENT_MAX
E_EVENT_BORDER_NEW = 1 << 0,
E_EVENT_BORDER_RELEASE = 1 << 1,
E_EVENT_BORDER_FOCUS_IN = 1 << 2,
E_EVENT_BORDER_ICONIFY = 1 << 3,
E_EVENT_BORDER_UNICONIFY = 1 << 4,
E_EVENT_BORDER_MAXIMIZE = 1 << 5,
E_EVENT_BORDER_UNMAXIMIZE = 1 << 6,
E_EVENT_DESKTOP_SWITCH = 1 << 10,
E_EVENT_MAX = 0xFFFFFFFF
} E_Event_Type;
typedef void(*E_Notify_Func)(E_Observer *observer, E_Observee *observee, E_Event_Type event);
struct _e_observer
{
E_Object obj;
@ -114,4 +120,19 @@ void e_observee_cleanup(E_Observee *obs);
void e_observee_notify_observers(E_Observee *o, E_Event_Type event);
/**
* e_observee_notify_all_observers - Notify all observers of a given E event
* regardless of whether they are registered or not.
*
* @o: The observee which notifies the observers
* @event: The event by which to filter the observers
*
* This function scans ALL observers in the observee
* and calls the notify_func() of the observers that are
* responsible for the given @event. Useful for situations where the observee
* is just being created and you want to notify observers of its existence.
* If they are looking for this type of NEW event, then they can register
* it as a legitimate observee.
*/
void e_observee_notify_all_observers(E_Observee *o, E_Event_Type event);
#endif

View File

@ -432,7 +432,7 @@ e_bg_up_cb(void *_data, Evas _e, Evas_Object _o, int _b, int _x, int _y)
}
else if (_b == 2)
{
#if 0
#if 1
static E_Build_Menu *buildmenu = NULL;
if (!buildmenu)