www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

draw-plain.rkt (5217B)


      1 #lang racket ;scheme/gui
      2 (provide lang-pict string->color)
      3 
      4 (require scheme/runtime-path
      5          slideshow/pict
      6          racket/draw)
      7 
      8 (define-runtime-path lang.plain "lang.plain")
      9 
     10 (define (parse-file)
     11   (call-with-input-file lang.plain
     12     (λ (port)
     13       (for ([l (in-lines port)]) 
     14         (parse-line l)))))
     15 
     16 ;; nodes : hash[string -o> node]
     17 (define nodes (make-hash))
     18 (define-struct node (x y w h type color) #:transparent)
     19 
     20 ;; parents : hash[string -o> string]
     21 (define parents (make-hash))
     22 
     23 (define graph-width 0)
     24 (define graph-height 0)
     25 
     26 (define (parse-line line)
     27   (cond
     28     [(regexp-match #rx"^node \"([^\"]*)\" +([0-9.]*) +([0-9.]*) +([0-9.]*) +([0-9.]*) +\"([^\"]*)\" +([^ ]*) +([^ ]*) +([^ ]*) +([^ ]*)"
     29                    line)
     30      =>
     31      (λ (m)
     32        (let-values ([(id x y w h label type1 type2 color1 color2)
     33                      (apply values (cdr m))])
     34          (hash-set! nodes id (make-node (string->number y)
     35                                         (string->number x)
     36                                         (string->number w)
     37                                         (string->number h)
     38                                         (string->symbol type2)
     39                                         (string->color color1)))))]
     40     [(regexp-match #rx"^edge \"([^\"]*)\" +\"([^\"]*)\""
     41                    line)
     42      =>
     43      (λ (m) 
     44        (let-values ([(src dest) (apply values (cdr m))])
     45          (hash-set! parents dest src)))]
     46     [(regexp-match #rx"^graph ([0-9.]*) ([0-9.]*) ([0-9.]*)" line) 
     47      =>
     48      (λ (m) 
     49        (let-values ([(scale w h) (apply values (cdr m))])
     50          (set! graph-width (string->number w))
     51          (set! graph-height (string->number h))))]
     52     [(regexp-match #rx"^stop" line) (void)]
     53     [else 
     54      (error 'parse-line "unknown line ~s\n" line)]))
     55 
     56 (define (string->color str)
     57   (cond
     58     [(regexp-match
     59       #rx"#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])"
     60       str)
     61      =>
     62      (λ (m)
     63        (let-values ([(r g b) (apply values (cdr m))])
     64          (make-object color% 
     65            (string->number r 16)
     66            (string->number g 16)
     67            (string->number b 16))))]
     68     [else
     69      (let ([c (send the-color-database find-color str)])
     70        (unless c
     71          (error 'string->color "unknown color ~s" str))
     72        c)]))
     73 
     74 (define (draw-graph dc dx dy w h color?)
     75   (let ([scale (min (/ w graph-width)
     76                     (/ h graph-height))])
     77     (define (draw-node name node)
     78       (case (node-type node)
     79         [(circle)
     80          (let-values ([(nx ny) (node->xy node)]
     81                       [(px py) (node->xy (hash-ref nodes (hash-ref parents name)))])
     82            (let ([nw (* 1.8 (node-w node))]
     83                  [nh (* 1.8 (node-h node))])
     84              (cond
     85                [color?
     86                 (send dc set-pen "black" 1 'transparent)
     87                 (send dc set-brush (node-color node) 'solid)]
     88                [else
     89                 (send dc set-pen "SlateGray" 1 'solid)
     90                 (send dc set-brush "LightSlateGray" 'solid)])
     91              (send dc draw-ellipse 
     92                    (+ dx (- nx (* scale (/ nw 2))))
     93                    (+ dy (- ny (* scale (/ nh 2))))
     94                    (* scale nw)
     95                    (* scale nh))))]
     96         [else (void)]))
     97     (define (draw-edge src dest)
     98       (send dc set-pen "gray" 1 'solid)
     99       (send dc set-brush "black" 'transparent) 
    100       (let-values ([(sx sy) (node->xy (hash-ref nodes src))]
    101                    [(tx ty) (node->xy (hash-ref nodes dest))])
    102         (send dc draw-line
    103               (+ dx sx)
    104               (+ dy sy)
    105               (+ dx tx)
    106               (+ dy ty))))
    107     
    108     (define (node->xy node)
    109       (values (* scale (node-x node))
    110               (- h (* scale (node-y node)))))
    111     (let ([smoothing (send dc get-smoothing)]
    112           [pen (send dc get-pen)]
    113           [brush (send dc get-brush)])
    114       (send dc set-smoothing 'aligned)
    115       (hash-for-each
    116        parents
    117        (λ (dest src)
    118          (draw-edge src dest)))
    119       (for-each
    120        (λ (name-node)
    121          (draw-node (car name-node)
    122                     (cadr name-node)))
    123        (sort (hash-map nodes list)
    124              (compare-name-node-list w h)))
    125       (send dc set-smoothing smoothing)
    126       (send dc set-pen pen)
    127       (send dc set-brush brush))))
    128 
    129 (define ((compare-name-node-list w h) name-node1 name-node2)
    130   (let* ([c (make-rectangular (/ w 2) (/ h 2))]
    131          [x (make-rectangular (node-x (cadr name-node1))
    132                               (node-x (cadr name-node2)))]
    133          [y (make-rectangular (node-y (cadr name-node1)) 
    134                               (node-y (cadr name-node2)))]
    135          [ax (angle (- x c))]
    136          [ay (angle (- y c))])
    137     (cond
    138       [(= ax ay)
    139        (< (magnitude x) (magnitude y))]
    140       [else
    141        (< ax ay)])))
    142 
    143 (parse-file)
    144 
    145 #;
    146 (begin
    147   (define f (new frame% [label ""]))
    148   (define c (new canvas% 
    149                  [parent f] 
    150                  [paint-callback
    151                   (λ (c dc) 
    152                     (let-values ([(w h) (send c get-client-size)])
    153                       (draw-graph dc 0 0 w h)))]))
    154   (send f show #t))
    155 
    156 (define (lang-pict size color?)
    157   (dc (λ (dc dx dy) (draw-graph dc dx dy size size color?))
    158       size size))