In the rest of this article, I will discuss the event mechanism of the MadButterfly and provide a design of event API.
First thing go first. We will start from the most important event - mouse evnets.
In this way, we can decouple the components which send the events and the components which need the events. For example, if we implement the X and GTK backend, both of them will call subject_notify when it receive the mouse events from the X or GTK. The observers don't care whether the notification coming from X or GTK. The X and GTK backend are responsible to translate the X or GTK mouse events into the mouse subject.
Therefore, we can use the subject as the astraction layer between MadButterfly clients and the backend.
To be more specific, in the current X backend. When it receive a MotionNotify mouse event from the X server, it will send an mouse event to the mouse event subject ob type OBJT_GEO.
mouse_event.event.type = etype; mouse_event.x = x; mouse_event.y = y; mouse_event.but_state = state; mouse_event.button = button; subject = sh_get_mouse_event_subject(shape); factory = rdman_get_ob_factory(rdman); subject_notify(factory, subject, (event_t *)&mouse_event);
The shape above is determined by the mouse position and the etype is determined the shape under the mouse and the last shape which receive mouse event.
mevt = (XMotionEvent *)&evt; x = mevt->x; y = mevt->y; state = get_button_state(mevt->state); shape = find_shape_at_pos(rdman, x, y, &in_stroke); if(shape != NULL) { if(rt->last != shape) { if(rt->last) notify_shapes(rdman, rt->last, x, y, EVT_MOUSE_OUT, state, 0); notify_shapes(rdman, shape, x, y, EVT_MOUSE_OVER, state, 0); rt->last = shape; } else notify_shapes(rdman, shape, x, y, EVT_MOUSE_MOVE, state, 0); } else { if(rt->last) { notify_shapes(rdman, rt->last, x, y, EVT_MOUSE_OUT, state, 0); rt->last = NULL; } }
Please remember that the subject will relay the the events to all of its parents.
PS. Currently, the MadButterfly does not have mechanism to stop propogation based on the result of the observer.