Mercurial > MadButterfly
diff include/mb_redraw_man.h @ 186:530bb7728546 include_mb_test
Move header files to $(top_srcdir)/include/ and prefixed with 'mb_'.
This is the solution that I dicussed with FourDollars, last night.
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Wed, 05 Nov 2008 15:24:01 +0800 |
parents | include/mb/redraw_man.h@c7e5b8779bb5 |
children | 29e1b2bffe4c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/mb_redraw_man.h Wed Nov 05 15:24:01 2008 +0800 @@ -0,0 +1,160 @@ +#ifndef __REDRAW_MAN_H_ +#define __REDRAW_MAN_H_ + +#include <cairo.h> +#include "mb_tools.h" +#include "mb_types.h" +#include "mb_observer.h" + +typedef struct _redraw_man redraw_man_t; + +typedef void (*free_func_t)(redraw_man_t *rdman, void *obj); +struct _free_obj { + void *obj; + free_func_t free_func; +}; +typedef struct _free_obj free_obj_t; +struct _free_objs { + int num, max; + free_obj_t *objs; +}; +typedef struct _free_objs free_objs_t; + +DARRAY(coords, coord_t *); +DARRAY(geos, geo_t *); +DARRAY(areas, area_t *); + +/*! \brief Manage redrawing of shapes (graphic elements). + * + * Every coord_t and geo_t object is assigned with a unique + * incremental order. The order is a unsigned integer. + * Every time a new coord_t or geo_t object is added, it is + * assigned with a order number that 1 bigger than last one + * until reaching maximum of unsigned integer. + * When a maximum is meet, all coord_t or geo_t objects + * are reasigned with a new order number from 1. It means + * order numbers that have been assigned and then removed + * later are recycled. + * + * Dirty flag is clear when the transformation matrix of a coord + * object been recomputed or when a geo_t objects been redrawed. + */ +struct _redraw_man { + unsigned int next_coord_order; + int n_coords; + coord_t *root_coord; + + elmpool_t *geo_pool; + elmpool_t *coord_pool; + elmpool_t *shnode_pool; + elmpool_t *observer_pool; + elmpool_t *subject_pool; + elmpool_t *paint_color_pool; + + coords_t dirty_coords; + geos_t dirty_geos; + areas_t dirty_areas; + + geos_t gen_geos; + + STAILQ(shape_t) shapes; /*!< \brief All managed shapes. */ + STAILQ(paint_t) paints; /*!< \brief All managed paints. */ + + free_objs_t free_objs; + + cairo_t *cr; + cairo_t *backend; + + ob_factory_t ob_factory; + + subject_t *redraw; /*!< \brief Notified after redrawing. */ +}; + +extern int redraw_man_init(redraw_man_t *rdman, cairo_t *cr, + cairo_t *backend); +extern void redraw_man_destroy(redraw_man_t *rdman); +extern int rdman_find_overlaid_shapes(redraw_man_t *rdman, + geo_t *geo, + geo_t ***overlays); +extern int rdman_add_shape(redraw_man_t *rdman, + shape_t *shape, coord_t *coord); +/*! \brief Make a shape been managed by a redraw manager. */ +#define rdman_shape_man(rdman, shape) \ + STAILQ_INS_TAIL(rdman->shapes, shape_t, sh_next, shape) +extern int rdman_shape_free(redraw_man_t *rdman, shape_t *shape); + +#define rdman_paint_man(rdman, paint) \ + STAILQ_INS_TAIL(rdman->paints, paint_t, pnt_next, shape) +extern int rdman_paint_free(redraw_man_t *rdman, paint_t *paint); + +extern coord_t *rdman_coord_new(redraw_man_t *rdman, coord_t *parent); +extern int rdman_coord_free(redraw_man_t *rdman, coord_t *coord); +extern int rdman_coord_subtree_free(redraw_man_t *rdman, coord_t *subtree); +extern int rdman_coord_changed(redraw_man_t *rdman, coord_t *coord); +extern int rdman_shape_changed(redraw_man_t *rdman, shape_t *shape); +extern int rdman_redraw_changed(redraw_man_t *rdman); +extern int rdman_redraw_all(redraw_man_t *rdman); +extern int rdman_redraw_area(redraw_man_t *rdman, co_aix x, co_aix y, + co_aix w, co_aix h); +extern geo_t *rdman_geos(redraw_man_t *rdman, geo_t *last); +extern int rdman_force_clean(redraw_man_t *rdman); +extern shnode_t *shnode_new(redraw_man_t *rdman, shape_t *shape); +#define shnode_free(rdman, node) elmpool_elm_free((rdman)->shnode_pool, node) +#define shnode_list_free(rdman, q) \ + do { \ + shnode_t *__node, *__last; \ + __last = STAILQ_HEAD(q); \ + if(__last == NULL) break; \ + for(__node = STAILQ_NEXT(shnode_t, next, __last); \ + __node != NULL; \ + __node = STAILQ_NEXT(shnode_t, next, __node)) { \ + shnode_free(rdman, __last); \ + __last = __node; \ + } \ + shnode_free(rdman, __last); \ + } while(0) +#define _rdman_paint_child(rdman, paint, shape) \ + do { \ + shnode_t *__node; \ + if((shape)->fill != (paint) && \ + (shape)->stroke != (paint)) { \ + __node = shnode_new(rdman, shape); \ + STAILQ_INS_TAIL((paint)->members, \ + shnode_t, next, __node); \ + } \ + } while(0) +extern void _rdman_paint_real_remove_child(redraw_man_t *rdman, + paint_t *paint, + shape_t *shape); +#define _rdman_paint_remove_child(rdman, paint, shape) \ + do { \ + if((shape)->fill == (shape)->stroke && \ + (shape)->stroke == paint) \ + break; \ + _rdman_paint_real_remove_child(rdman, paint, shape); \ + } while(0) +#define rdman_paint_fill(rdman, paint, shape) \ + do { \ + if((shape)->fill == paint) \ + break; \ + _rdman_paint_remove_child(rdman, paint, shape); \ + _rdman_paint_child(rdman, paint, shape); \ + (shape)->fill = paint; \ + } while(0) +#define rdman_paint_stroke(rdman, paint, shape) \ + do { \ + if((shape)->stroke == paint) \ + break; \ + _rdman_paint_remove_child(rdman, paint, shape); \ + _rdman_paint_child(rdman, paint, shape); \ + (shape)->stroke = paint; \ + } while(0) +extern int rdman_paint_changed(redraw_man_t *rdman, paint_t *paint); + +extern shape_t *find_shape_at_pos(redraw_man_t *rdman, + co_aix x, co_aix y, int *in_stroke); +#define rdman_get_ob_factory(rdman) (&(rdman)->ob_factory) +#define rdman_get_redraw_subject(rdman) ((rdman)->redraw) + + +#endif /* __REDRAW_MAN_H_ */