|
3 | 3 | racket/list
|
4 | 4 | racket/math
|
5 | 5 | racket/gui/base
|
6 |
| - (for-syntax racket/base) |
| 6 | + racket/match |
| 7 | + (for-syntax racket/base) |
7 | 8 | racket/contract)
|
8 | 9 |
|
9 | 10 | (provide graph-snip<%>
|
|
401 | 402 | ;; invalidate-to-children/parents : snip dc -> void
|
402 | 403 | ;; invalidates the region containing this snip and
|
403 | 404 | ;; all of its children and parents.
|
404 |
| - (inherit invalidate-bitmap-cache) |
405 | 405 | (define/private (invalidate-to-children/parents snip dc)
|
406 | 406 | (when (is-a? snip graph-snip<%>)
|
| 407 | + (unless (eq? last-dc dc) |
| 408 | + (define-values (w h a s) (send dc get-text-extent "Label" #f #f 0)) |
| 409 | + (set! last-dc dc) |
| 410 | + (set! text-height h)) |
407 | 411 | (let* ([parents-and-children (append (get-all-parents snip)
|
408 | 412 | (get-all-children snip))]
|
409 |
| - [rects (eliminate-redundancies (get-rectangles snip parents-and-children))] |
| 413 | + [rects (get-rectangles snip parents-and-children)] |
410 | 414 | [or/c (or/c-rects rects)]
|
411 |
| - [text-height (call-with-values |
412 |
| - (λ () (send dc get-text-extent "Label" #f #f 0)) |
413 |
| - (λ (w h a s) h))] |
414 | 415 | [invalidate-rect
|
415 | 416 | (lambda (rect)
|
416 |
| - (invalidate-bitmap-cache (- (rect-left rect) text-height) |
417 |
| - (- (rect-top rect) text-height) |
418 |
| - (+ (- (rect-right rect) |
419 |
| - (rect-left rect)) |
420 |
| - text-height) |
421 |
| - (+ (- (rect-bottom rect) |
422 |
| - (rect-top rect)) |
423 |
| - text-height)))]) |
| 417 | + (save-rectangle-to-invalidate |
| 418 | + (- (rect-left rect) text-height) |
| 419 | + (- (rect-top rect) text-height) |
| 420 | + (+ (- (rect-right rect) |
| 421 | + (rect-left rect)) |
| 422 | + text-height) |
| 423 | + (+ (- (rect-bottom rect) |
| 424 | + (rect-top rect)) |
| 425 | + text-height)))]) |
424 | 426 | (cond
|
425 | 427 | [(< (rect-area or/c)
|
426 | 428 | (apply + (map (lambda (x) (rect-area x)) rects)))
|
427 | 429 | (invalidate-rect or/c)]
|
428 | 430 | [else
|
429 | 431 | (for-each invalidate-rect rects)]))))
|
430 |
| - |
431 |
| - ;; (listof rect) -> (listof rect) |
432 |
| - (define/private (eliminate-redundancies rects) |
433 |
| - (let loop ([rects rects] |
434 |
| - [acc null]) |
435 |
| - (cond |
436 |
| - [(null? rects) acc] |
437 |
| - [else (let ([r (car rects)]) |
438 |
| - (cond |
439 |
| - [(or (ormap (lambda (other-rect) (rect-included-in? r other-rect)) |
440 |
| - (cdr rects)) |
441 |
| - (ormap (lambda (other-rect) (rect-included-in? r other-rect)) |
442 |
| - acc)) |
443 |
| - (loop (cdr rects) |
444 |
| - acc)] |
445 |
| - [else |
446 |
| - (loop (cdr rects) |
447 |
| - (cons r acc))]))]))) |
448 |
| - |
449 |
| - ;; rect-included-in? : rect rect -> boolean |
450 |
| - (define/private (rect-included-in? r1 r2) |
451 |
| - (and ((rect-left r1) . >= . (rect-left r2)) |
452 |
| - ((rect-top r1) . >= . (rect-top r2)) |
453 |
| - ((rect-right r1) . <= . (rect-right r2)) |
454 |
| - ((rect-bottom r1) . <= . (rect-bottom r2)))) |
| 432 | + (inherit invalidate-bitmap-cache) |
| 433 | + (define text-height #f) |
| 434 | + (define last-dc #f) |
| 435 | + |
| 436 | + (define pending-invalidate-rectangle #f) |
| 437 | + (define pending-invalidate-rectangle-timer #f) |
| 438 | + (define/private (run-pending-invalidate-rectangle) |
| 439 | + (define the-pending-invalidate-rectangle pending-invalidate-rectangle) |
| 440 | + (set! pending-invalidate-rectangle #f) |
| 441 | + (invalidate-bitmap-cache . the-pending-invalidate-rectangle)) |
| 442 | + |
| 443 | + (define/private (save-rectangle-to-invalidate l t r b) |
| 444 | + (unless pending-invalidate-rectangle-timer |
| 445 | + (set! pending-invalidate-rectangle-timer |
| 446 | + (new timer% [notify-callback |
| 447 | + (λ () (run-pending-invalidate-rectangle))]))) |
| 448 | + (cond |
| 449 | + [pending-invalidate-rectangle |
| 450 | + (match pending-invalidate-rectangle |
| 451 | + [(list l2 t2 r2 b2) |
| 452 | + (set! pending-invalidate-rectangle |
| 453 | + (list (min l l2) (min t t2) (max r r2) (max b b2)))])] |
| 454 | + [else |
| 455 | + (set! pending-invalidate-rectangle (list l t r b))]) |
| 456 | + (send pending-invalidate-rectangle-timer start 20 #t)) |
455 | 457 |
|
456 | 458 | ;; get-rectangles : snip (listof snip) -> rect
|
457 | 459 | ;; computes the rectangles that need to be invalidated for connecting
|
|
519 | 521 | (let ([old-font (send dc get-font)])
|
520 | 522 | (when edge-label-font
|
521 | 523 | (send dc set-font edge-label-font))
|
522 |
| - (draw-edges dc left top right bottom dx dy) |
| 524 | + (unless pending-invalidate-rectangle (draw-edges dc left top right bottom dx dy)) |
523 | 525 | (when edge-label-font
|
524 | 526 | (send dc set-font old-font))))
|
525 | 527 | (super on-paint before? dc left top right bottom dx dy draw-caret))
|
|
0 commit comments