comparison src/redraw_man.c @ 224:29e1b2bffe4c

X backend only sent EVT_MOUSE_MOVE_RAW to MadButterfly. - backend does not interpret mouse events (over/out/move), now. - redraw manager, now, interpret mouse events to make it backend independent. - The task (interpret mouse events) should be moved to somewhere in futhure. - backend only sent MotionNotify as EVT_MOUSE_MOVE_RAW. - EVT_MOUSE_MOVE_RAW is interpreted by backend independent code.
author Thinker K.F. Li <thinker@branda.to>
date Mon, 15 Dec 2008 10:13:03 +0800
parents c234ee745ceb
children 2637519e2bd7
comparison
equal deleted inserted replaced
223:8be36a0d4239 224:29e1b2bffe4c
5 #include "mb_types.h" 5 #include "mb_types.h"
6 #include "mb_shapes.h" 6 #include "mb_shapes.h"
7 #include "mb_tools.h" 7 #include "mb_tools.h"
8 #include "mb_redraw_man.h" 8 #include "mb_redraw_man.h"
9 #include "mb_observer.h" 9 #include "mb_observer.h"
10 10 #include "mb_prop.h"
11
12 #ifndef ASSERT
13 #define ASSERT(x)
14 #endif
11 15
12 /* NOTE: bounding box should also consider width of stroke. 16 /* NOTE: bounding box should also consider width of stroke.
13 */ 17 */
14 18
15 #define sh_attach_geo(sh, g) \ 19 #define sh_attach_geo(sh, g) \
233 237
234 RM_MEMBER(coord, geo); 238 RM_MEMBER(coord, geo);
235 coord->num_members--; 239 coord->num_members--;
236 } 240 }
237 241
242 static void mouse_event_root_dummy(event_t *evt, void *arg) {
243 }
244
245 static void mouse_event_interpreter(event_t *evt, void *arg) {
246 mouse_event_t *mevt = (mouse_event_t *)evt;
247 redraw_man_t *rdman = (redraw_man_t *)arg;
248 mb_obj_t *obj;
249 mouse_event_t new_evt;
250 coord_t *coord;
251 shape_t *shape;
252
253 ASSERT(evt->type == EVT_MOUSE_MOVE_RAW);
254
255 obj = (mb_obj_t *)subject_get_object(evt->cur_tgt);
256 if(rdman->last_mouse_over == obj) {
257 evt->type = EVT_MOUSE_MOVE;
258 return;
259 }
260
261 new_evt.x = mevt->x;
262 new_evt.y = mevt->y;
263 new_evt.but_state = mevt->but_state;
264 new_evt.button = mevt->button;
265
266 if(rdman->last_mouse_over != NULL) {
267 new_evt.event.type = EVT_MOUSE_OUT;
268 if(IS_MBO_COORD(rdman->last_mouse_over)) {
269 coord = (coord_t *)rdman->last_mouse_over;
270 subject_notify(coord->mouse_event, (event_t *)&new_evt);
271 } else if(IS_MBO_SHAPES(rdman->last_mouse_over)) {
272 shape = (shape_t *)rdman->last_mouse_over;
273 ASSERT(shape->geo != NULL);
274 subject_notify(shape->geo->mouse_event, (event_t *)&new_evt);
275 }
276 }
277
278 new_evt.event.type = EVT_MOUSE_OVER;
279 subject_notify(evt->cur_tgt, (event_t *)&new_evt);
280 rdman->last_mouse_over = obj;
281
282 evt->flags |= EVTF_STOP_NOTIFY;
283 }
284
285 static void addrm_monitor_hdlr(event_t *evt, void *arg) {
286 monitor_event_t *mevt;
287 redraw_man_t *rdman;
288 mb_obj_t *obj;
289 mb_prop_store_t *props;
290 observer_t *observer;
291 int cnt = 0;
292
293 mevt = (monitor_event_t *)evt;
294 rdman = (redraw_man_t *)evt->tgt;
295 obj = (mb_obj_t *)subject_get_object(mevt->subject);
296 props = mb_obj_prop_store(obj);
297
298 switch(evt->type) {
299 case EVT_MONITOR_ADD:
300 if(!mb_prop_has(props, PROP_MEVT_OB_CNT))
301 cnt = 0;
302 else
303 cnt = (int)mb_prop_get(props, PROP_MEVT_OB_CNT);
304
305 cnt++;
306 mb_prop_set(props, PROP_MEVT_OB_CNT, (void *)cnt);
307 if(cnt == 1) {
308 observer =
309 subject_add_event_observer_head(mevt->subject,
310 EVT_MOUSE_MOVE_RAW,
311 mouse_event_interpreter,
312 rdman);
313 ASSERT(observer != NULL);
314 mb_prop_set(props, PROP_MEVT_OBSERVER, observer);
315 }
316 break;
317
318 case EVT_MONITOR_REMOVE:
319 cnt = (int)mb_prop_get(props, PROP_MEVT_OB_CNT);
320 cnt--;
321 mb_prop_set(props, PROP_MEVT_OB_CNT, (void *)cnt);
322 if(cnt == 1) {
323 observer = (observer_t *)mb_prop_get(props, PROP_MEVT_OBSERVER);
324 subject_remove_observer(mevt->subject, observer);
325 mb_prop_del(props, PROP_MEVT_OBSERVER);
326 }
327 break;
328
329 case EVT_MONITOR_FREE:
330 break;
331 }
332 }
333
238 int redraw_man_init(redraw_man_t *rdman, cairo_t *cr, cairo_t *backend) { 334 int redraw_man_init(redraw_man_t *rdman, cairo_t *cr, cairo_t *backend) {
239 extern void redraw_man_destroy(redraw_man_t *rdman); 335 extern void redraw_man_destroy(redraw_man_t *rdman);
240 extern int _paint_color_size; 336 extern int _paint_color_size;
337 observer_t *addrm_ob;
241 338
242 memset(rdman, 0, sizeof(redraw_man_t)); 339 memset(rdman, 0, sizeof(redraw_man_t));
243 340
244 rdman->geo_pool = elmpool_new(sizeof(geo_t), 128); 341 rdman->geo_pool = elmpool_new(sizeof(geo_t), 128);
245 if(rdman->geo_pool == NULL)
246 return ERR;
247
248 rdman->coord_pool = elmpool_new(sizeof(coord_t), 16); 342 rdman->coord_pool = elmpool_new(sizeof(coord_t), 16);
249 if(rdman->coord_pool == NULL) {
250 elmpool_free(rdman->geo_pool);
251 return ERR;
252 }
253
254 rdman->shnode_pool = elmpool_new(sizeof(shnode_t), 16); 343 rdman->shnode_pool = elmpool_new(sizeof(shnode_t), 16);
255 if(rdman->shnode_pool == NULL) {
256 elmpool_free(rdman->geo_pool);
257 elmpool_free(rdman->coord_pool);
258 return ERR;
259 }
260
261 rdman->observer_pool = elmpool_new(sizeof(observer_t), 32); 344 rdman->observer_pool = elmpool_new(sizeof(observer_t), 32);
262 if(rdman->observer_pool == NULL) {
263 elmpool_free(rdman->geo_pool);
264 elmpool_free(rdman->coord_pool);
265 elmpool_free(rdman->shnode_pool);
266 return ERR;
267 }
268
269 rdman->subject_pool = elmpool_new(sizeof(subject_t), 32); 345 rdman->subject_pool = elmpool_new(sizeof(subject_t), 32);
270 if(rdman->subject_pool == NULL) {
271 elmpool_free(rdman->geo_pool);
272 elmpool_free(rdman->coord_pool);
273 elmpool_free(rdman->shnode_pool);
274 elmpool_free(rdman->observer_pool);
275 return ERR;
276 }
277
278 rdman->paint_color_pool = elmpool_new(_paint_color_size, 64); 346 rdman->paint_color_pool = elmpool_new(_paint_color_size, 64);
279 if(rdman->subject_pool == NULL) { 347 rdman->pent_pool = elmpool_new(sizeof(mb_prop_entry_t), 128);
280 elmpool_free(rdman->geo_pool); 348 if(!(rdman->geo_pool && rdman->coord_pool && rdman->shnode_pool &&
281 elmpool_free(rdman->coord_pool); 349 rdman->observer_pool && rdman->subject_pool &&
282 elmpool_free(rdman->shnode_pool); 350 rdman->paint_color_pool))
283 elmpool_free(rdman->observer_pool); 351 goto err;
284 elmpool_free(rdman->subject_pool);
285 return ERR;
286 }
287 352
288 rdman->ob_factory.subject_alloc = ob_subject_alloc; 353 rdman->ob_factory.subject_alloc = ob_subject_alloc;
289 rdman->ob_factory.subject_free = ob_subject_free; 354 rdman->ob_factory.subject_free = ob_subject_free;
290 rdman->ob_factory.observer_alloc = ob_observer_alloc; 355 rdman->ob_factory.observer_alloc = ob_observer_alloc;
291 rdman->ob_factory.observer_free = ob_observer_free; 356 rdman->ob_factory.observer_free = ob_observer_free;
292 rdman->ob_factory.get_parent_subject = ob_get_parent_subject; 357 rdman->ob_factory.get_parent_subject = ob_get_parent_subject;
293 358
294 rdman->redraw = 359 rdman->redraw =
295 subject_new(&rdman->ob_factory, rdman, OBJT_RDMAN); 360 subject_new(&rdman->ob_factory, rdman, OBJT_RDMAN);
361 rdman->addrm_monitor =
362 subject_new(&rdman->ob_factory, rdman, OBJT_RDMAN);
363 if(!(rdman->redraw && rdman->addrm_monitor))
364 goto err;
365
366 addrm_ob = subject_add_observer(rdman->addrm_monitor,
367 addrm_monitor_hdlr, NULL);
368 if(addrm_ob == NULL)
369 goto err;
370
371 rdman->last_mouse_over = NULL;
296 372
297 rdman->root_coord = elmpool_elm_alloc(rdman->coord_pool); 373 rdman->root_coord = elmpool_elm_alloc(rdman->coord_pool);
298 if(rdman->root_coord == NULL) 374 if(rdman->root_coord == NULL)
299 redraw_man_destroy(rdman); 375 redraw_man_destroy(rdman);
300 rdman->n_coords = 1; 376 rdman->n_coords = 1;
301 coord_init(rdman->root_coord, NULL); 377 coord_init(rdman->root_coord, NULL);
378 mb_prop_store_init(&rdman->root_coord->obj.props, rdman->pent_pool);
302 rdman->root_coord->mouse_event = subject_new(&rdman->ob_factory, 379 rdman->root_coord->mouse_event = subject_new(&rdman->ob_factory,
303 rdman->root_coord, 380 rdman->root_coord,
304 OBJT_COORD); 381 OBJT_COORD);
305 rdman->root_coord->flags |= COF_OWN_CANVAS; 382 rdman->root_coord->flags |= COF_OWN_CANVAS;
306 rdman->root_coord->canvas = cr; 383 rdman->root_coord->canvas = cr;
309 rdman->cr = cr; 386 rdman->cr = cr;
310 rdman->backend = backend; 387 rdman->backend = backend;
311 388
312 STAILQ_INIT(rdman->shapes); 389 STAILQ_INIT(rdman->shapes);
313 STAILQ_INIT(rdman->paints); 390 STAILQ_INIT(rdman->paints);
391
392 /* \note To make root coord always have at leat one observer.
393 * It triggers mouse interpreter to be installed on root.
394 */
395 subject_set_monitor(rdman->root_coord->mouse_event,
396 rdman->addrm_monitor);
397 subject_add_observer(rdman->root_coord->mouse_event,
398 mouse_event_root_dummy, NULL);
314 399
315 return OK; 400 return OK;
401
402 err:
403 if(rdman->geo_pool)
404 elmpool_free(rdman->geo_pool);
405 if(rdman->coord_pool)
406 elmpool_free(rdman->coord_pool);
407 if(rdman->shnode_pool)
408 elmpool_free(rdman->shnode_pool);
409 if(rdman->observer_pool)
410 elmpool_free(rdman->observer_pool);
411 if(rdman->subject_pool)
412 elmpool_free(rdman->subject_pool);
413 if(rdman->paint_color_pool)
414 elmpool_free(rdman->paint_color_pool);
415 if(rdman->pent_pool)
416 elmpool_free(rdman->pent_pool);
417 return ERR;
316 } 418 }
317 419
318 void redraw_man_destroy(redraw_man_t *rdman) { 420 void redraw_man_destroy(redraw_man_t *rdman) {
319 coord_t *coord, *saved_coord; 421 coord_t *coord, *saved_coord;
320 shape_t *shape, *saved_shape; 422 shape_t *shape, *saved_shape;
330 FORMEMBERS(saved_coord, member) { 432 FORMEMBERS(saved_coord, member) {
331 rdman_shape_free(rdman, member->shape); 433 rdman_shape_free(rdman, member->shape);
332 } 434 }
333 rdman_coord_free(rdman, saved_coord); 435 rdman_coord_free(rdman, saved_coord);
334 } 436 }
437 #if 0
335 FORMEMBERS(saved_coord, member) { 438 FORMEMBERS(saved_coord, member) {
336 rdman_shape_free(rdman, member->shape); 439 rdman_shape_free(rdman, member->shape);
337 } 440 }
441 #endif
338 /* Resources of root_coord is free by elmpool_free() or 442 /* Resources of root_coord is free by elmpool_free() or
339 * caller; for canvas 443 * caller; for canvas
340 */ 444 */
341 445
342 shape = saved_shape = STAILQ_HEAD(rdman->shapes); 446 shape = saved_shape = STAILQ_HEAD(rdman->shapes);
354 elmpool_free(rdman->geo_pool); 458 elmpool_free(rdman->geo_pool);
355 elmpool_free(rdman->shnode_pool); 459 elmpool_free(rdman->shnode_pool);
356 elmpool_free(rdman->observer_pool); 460 elmpool_free(rdman->observer_pool);
357 elmpool_free(rdman->subject_pool); 461 elmpool_free(rdman->subject_pool);
358 elmpool_free(rdman->paint_color_pool); 462 elmpool_free(rdman->paint_color_pool);
463 elmpool_free(rdman->pent_pool);
359 464
360 DARRAY_DESTROY(&rdman->dirty_coords); 465 DARRAY_DESTROY(&rdman->dirty_coords);
361 DARRAY_DESTROY(&rdman->dirty_geos); 466 DARRAY_DESTROY(&rdman->dirty_geos);
362 DARRAY_DESTROY(&rdman->dirty_areas); 467 DARRAY_DESTROY(&rdman->dirty_areas);
363 DARRAY_DESTROY(&rdman->gen_geos); 468 DARRAY_DESTROY(&rdman->gen_geos);
395 if(geo == NULL) 500 if(geo == NULL)
396 return ERR; 501 return ERR;
397 502
398 geo_init(geo); 503 geo_init(geo);
399 geo->mouse_event = subject_new(&rdman->ob_factory, geo, OBJT_GEO); 504 geo->mouse_event = subject_new(&rdman->ob_factory, geo, OBJT_GEO);
505 subject_set_monitor(geo->mouse_event, rdman->addrm_monitor);
400 506
401 geo_attach_coord(geo, coord); 507 geo_attach_coord(geo, coord);
402 508
403 /* New one should be dirty to recompute it when drawing. */ 509 /* New one should be dirty to recompute it when drawing. */
404 r = add_dirty_geo(rdman, geo); 510 r = add_dirty_geo(rdman, geo);
440 return ERR; 546 return ERR;
441 return OK; 547 return OK;
442 } 548 }
443 549
444 if(geo != NULL) { 550 if(geo != NULL) {
551 subject_free(geo->mouse_event);
445 geo_detach_coord(geo, shape->coord); 552 geo_detach_coord(geo, shape->coord);
446 sh_detach_coord(shape); 553 sh_detach_coord(shape);
447 sh_detach_geo(shape); 554 sh_detach_geo(shape);
448 subject_free(geo->mouse_event);
449 elmpool_elm_free(rdman->geo_pool, geo); 555 elmpool_elm_free(rdman->geo_pool, geo);
450 } 556 }
451 STAILQ_REMOVE(rdman->shapes, shape_t, sh_next, shape); 557 STAILQ_REMOVE(rdman->shapes, shape_t, sh_next, shape);
452 shape->free(shape); 558 shape->free(shape);
559
560 if(rdman->last_mouse_over == (mb_obj_t *)shape)
561 rdman->last_mouse_over = NULL;
562
453 return OK; 563 return OK;
454 } 564 }
455 565
456 shnode_t *shnode_new(redraw_man_t *rdman, shape_t *shape) { 566 shnode_t *shnode_new(redraw_man_t *rdman, shape_t *shape) {
457 shnode_t *node; 567 shnode_t *node;
515 coord = elmpool_elm_alloc(rdman->coord_pool); 625 coord = elmpool_elm_alloc(rdman->coord_pool);
516 if(coord == NULL) 626 if(coord == NULL)
517 return NULL; 627 return NULL;
518 628
519 coord_init(coord, parent); 629 coord_init(coord, parent);
630 mb_prop_store_init(&coord->obj.props, rdman->pent_pool);
520 coord->mouse_event = subject_new(&rdman->ob_factory, 631 coord->mouse_event = subject_new(&rdman->ob_factory,
521 coord, 632 coord,
522 OBJT_COORD); 633 OBJT_COORD);
634 subject_set_monitor(coord->mouse_event, rdman->addrm_monitor);
523 /*! \note default opacity == 1 */ 635 /*! \note default opacity == 1 */
524 coord->opacity = 1; 636 coord->opacity = 1;
525 if(parent) 637 if(parent)
526 coord->canvas = parent->canvas; 638 coord->canvas = parent->canvas;
527 rdman->n_coords++; 639 rdman->n_coords++;
611 rdman->n_coords--; 723 rdman->n_coords--;
612 724
613 return OK; 725 return OK;
614 } 726 }
615 727
616 static _rdman_coord_free_members(redraw_man_t *rdman, coord_t *coord) { 728 static int _rdman_coord_free_members(redraw_man_t *rdman, coord_t *coord) {
617 geo_t *member; 729 geo_t *member;
618 shape_t *shape; 730 shape_t *shape;
619 int r; 731 int r;
620 732
621 FORMEMBERS(coord, member) { 733 FORMEMBERS(coord, member) {
1466 dummy->w = w; 1578 dummy->w = w;
1467 dummy->h = h; 1579 dummy->h = h;
1468 dummy->trans_cnt = 0; 1580 dummy->trans_cnt = 0;
1469 dummy->draw_cnt = 0; 1581 dummy->draw_cnt = 0;
1470 dummy->shape.free = sh_dummy_free; 1582 dummy->shape.free = sh_dummy_free;
1471 1583
1472 rdman_shape_man(rdman, (shape_t *)dummy); 1584 rdman_shape_man(rdman, (shape_t *)dummy);
1473 1585
1474 return (shape_t *)dummy; 1586 return (shape_t *)dummy;
1475 } 1587 }
1476 1588