Mercurial > MadButterfly
diff src/redraw_man.c @ 73:9ab15ebc9061
Observer for mouse events
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Mon, 18 Aug 2008 01:59:26 +0800 |
parents | 1ca417f741f1 |
children | 23bc382d9683 |
line wrap: on
line diff
--- a/src/redraw_man.c Wed Aug 13 09:25:57 2008 +0800 +++ b/src/redraw_man.c Mon Aug 18 01:59:26 2008 +0800 @@ -6,6 +6,8 @@ #include "shapes.h" #include "tools.h" #include "redraw_man.h" +#include "observer.h" + /* NOTE: bounding box should also consider width of stroke. */ @@ -13,7 +15,6 @@ #define OK 0 #define ERR -1 -#define OFFSET(type, field) ((void *)&((type *)NULL)->field - (void *)NULL) #define SWAP(a, b, t) do { t c; c = a; a = b; b = c; } while(0) #ifdef UNITTEST @@ -23,6 +24,14 @@ extern void sh_dummy_fill(shape_t *, cairo_t *); #endif /* UNITTEST */ +static subject_t *ob_subject_alloc(ob_factory_t *factory); +static void ob_subject_free(ob_factory_t *factory, subject_t *subject); +static observer_t *ob_observer_alloc(ob_factory_t *factory); +static void ob_observer_free(ob_factory_t *factory, observer_t *observer); +static subject_t *ob_get_parent_subject(ob_factory_t *factory, + subject_t *cur_subject); + + /*! \brief Sort a list of element by a unsigned integer. * * The result is in ascend order. The unsigned integers is @@ -123,11 +132,37 @@ return ERR; } + rdman->observer_pool = elmpool_new(sizeof(observer_t), 16); + if(rdman->observer_pool == NULL) { + elmpool_free(rdman->geo_pool); + elmpool_free(rdman->coord_pool); + elmpool_free(rdman->shnode_pool); + return ERR; + } + + rdman->subject_pool = elmpool_new(sizeof(subject_t), 16); + if(rdman->subject_pool == NULL) { + elmpool_free(rdman->geo_pool); + elmpool_free(rdman->coord_pool); + elmpool_free(rdman->shnode_pool); + elmpool_free(rdman->observer_pool); + return ERR; + } + + rdman->ob_factory.subject_alloc = ob_subject_alloc; + rdman->ob_factory.subject_free = ob_subject_free; + rdman->ob_factory.observer_alloc = ob_observer_alloc; + rdman->ob_factory.observer_free = ob_observer_free; + rdman->ob_factory.get_parent_subject = ob_get_parent_subject; + rdman->root_coord = elmpool_elm_alloc(rdman->coord_pool); if(rdman->root_coord == NULL) redraw_man_destroy(rdman); rdman->n_coords = 1; coord_init(rdman->root_coord, NULL); + rdman->root_coord->mouse_event = subject_new(&rdman->ob_factory, + rdman->root_coord, + OBJT_COORD); rdman->cr = cr; rdman->backend = backend; @@ -139,6 +174,8 @@ elmpool_free(rdman->coord_pool); elmpool_free(rdman->geo_pool); elmpool_free(rdman->shnode_pool); + elmpool_free(rdman->observer_pool); + elmpool_free(rdman->subject_pool); if(rdman->dirty_coords) free(rdman->dirty_coords); if(rdman->dirty_geos) @@ -226,6 +263,7 @@ return ERR; geo_init(geo); + geo->mouse_event = subject_new(&rdman->ob_factory, geo, OBJT_GEO); sh_attach_geo(shape, geo); STAILQ_INS_TAIL(rdman->all_geos, geo_t, next, geo); @@ -261,6 +299,7 @@ */ int rdman_remove_shape(redraw_man_t *rdman, shape_t *shape) { STAILQ_REMOVE(rdman->all_geos, geo_t, next, shape->geo); + subject_free(&rdman->ob_factory, shape->geo->mouse_event); elmpool_elm_free(rdman->geo_pool, shape->geo); sh_detach_geo(shape); rdman->n_geos--; @@ -277,6 +316,9 @@ return NULL; coord_init(coord, parent); + coord->mouse_event = subject_new(&rdman->ob_factory, + coord, + OBJT_COORD); rdman->n_coords++; coord->order = ++rdman->next_coord_order; @@ -313,6 +355,7 @@ return ERR; STAILQ_REMOVE(parent->children, coord_t, sibling, coord); + subject_free(&rdman->ob_factory, coord->mouse_event); elmpool_elm_free(rdman->coord_pool, coord); rdman->n_coords--; @@ -857,7 +900,71 @@ * - redraw changed */ +/* Implment factory and strategy functions for observers and subjects. + */ +static subject_t *ob_subject_alloc(ob_factory_t *factory) { + redraw_man_t *rdman; + subject_t *subject; + + rdman = MEM2OBJ(factory, redraw_man_t, ob_factory); + subject = elmpool_elm_alloc(rdman->subject_pool); + + return subject; +} + +static void ob_subject_free(ob_factory_t *factory, subject_t *subject) { + redraw_man_t *rdman; + + rdman = MEM2OBJ(factory, redraw_man_t, ob_factory); + elmpool_elm_free(rdman->subject_pool, subject); +} + +static observer_t *ob_observer_alloc(ob_factory_t *factory) { + redraw_man_t *rdman; + observer_t *observer; + + rdman = MEM2OBJ(factory, redraw_man_t, ob_factory); + observer = elmpool_elm_alloc(rdman->observer_pool); + + return observer; +} + +static void ob_observer_free(ob_factory_t *factory, observer_t *observer) { + redraw_man_t *rdman; + + rdman = MEM2OBJ(factory, redraw_man_t, ob_factory); + elmpool_elm_free(rdman->observer_pool, observer); +} + +static subject_t *ob_get_parent_subject(ob_factory_t *factory, + subject_t *cur_subject) { + redraw_man_t *rdman; + coord_t *coord; + geo_t *geo; + subject_t *parent; + + rdman = MEM2OBJ(factory, redraw_man_t, ob_factory); + switch(cur_subject->obj_type) { + case OBJT_GEO: + geo = (geo_t *)cur_subject->obj; + coord = geo->shape->coord; + parent = coord->mouse_event; + break; + case OBJT_COORD: + coord = (coord_t *)cur_subject->obj; + coord = coord->parent; + parent = coord->mouse_event; + break; + default: + parent = NULL; + break; + } + + return parent; +} + #ifdef UNITTEST +/* Test cases */ #include <CUnit/Basic.h> #include "paint.h"