[racket] Newbie question: creating a custom canvas

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Fri Aug 24 09:42:59 EDT 2012

Let me spell out Richard's comment in some detail. The docs for on-paint in get-dc say that the function is called on no arguments (other than this) and produce no values. So this demands 

 (define/override (on-paint) ...)

because other methods in the superclass call this method like this (on-paint) whenever there are certain events. 

This leaves you with the question where to get the drawing context into which to draw the grid. Well, you know how to get the current width and height of the canvas. If you look at the same page where you got those methods, you find get-dc, which the docs explains retrieves the dc. 

So this is the code, edited for our style guide: 

;; -> Void 
;; set up and draw the Sudoku grid
(define (sudoku)
  (define WIDTH 300)
  (define HEIGHT 300)
  (define frame (new frame% [label "Sudoku"] [width WIDTH] [height HEIGHT]))
  (define the-grid (new grid-canvas% [parent frame] [min-width WIDTH] [min-height HEIGHT]))
  (send frame show #t))

;; a class for graphically rendering a grid on any canvas 
(define grid-canvas%
  (class canvas%
    (inherit get-dc get-width get-height)
    (define/override (on-paint)
      (define dc (get-dc))
      (define w (get-width))
      (define h (get-height))
      (send dc set-pen "black" 3 'solid)
      (for ([i (in-range 3)])
        (send dc draw-line 0 (* i (/ h 3)) w (* i (/ h 3)))
        (send dc draw-line (* i (/ w 3)) 0 (* i (/ w 3)) h))
      (send dc set-pen "black" 1 'solid)
      (for ([i (in-range 9)])
        (send dc draw-line 0 (* i (/ h 9)) w (* i (/ h 9))))
      (for ([i (in-range 9)])
        (send dc draw-line (* i (/ w 9)) 0 (* i (/ w 9)) h)))
    (super-new)))




On Aug 23, 2012, at 8:29 PM, Gregory Woodhouse wrote:

> I apologize in advance for the elementary nature of this question, and for the amount of code included below. I'm having a tough time following the documentation for racket/gui and racket/draw. My first attempt to create a Sudoku grid follows the example in the documentation rather slavishly and works fine
> 
> 
> (define frame (new frame% [label "Sudoku"]
>                   [width 300]
>                   [height 300]))
> 
> (define grid-canvas (new canvas% [parent frame]
>                                 [min-width 300]
>                                 [min-height 300]
>                                 [paint-callback
>                 (lambda (canvas dc)
>                   (let
>                       ([w (send canvas get-width)]
>                        [h (send canvas get-height)])
>                     (send dc set-pen "black" 3 'solid)
>                     (for ([i (in-range 3)])
>                       (send dc draw-line 0 (* i (/ h 3)) w (* i (/ h 3)))
>                       (send dc draw-line (* i (/ w 3)) 0 (* i (/ w 3)) h))
>                     (send dc set-pen "black" 1 'solid)
>                     (for ([i (in-range 9)])
>                           (send dc draw-line 0 (* i (/ h 9)) w (* i (/ h 9))))
>                     (for ([i (in-range 9)])
>                       (send dc draw-line (* i (/ w 9)) 0 (* i (/ w 9)) h))))]))
> 
> ; Show the frame by calling its show method
> (send frame show #t)
> 
> 
> But this does not work
> 
> (define frame (new frame% [label "Sudoku"]
>                   [width 300]
>                   [height 300]))
> 
> (define grid-canvas%
>  (class canvas%
>    (define/override (on-paint dc)
>      (let
>          ([w (send this get-width)]
>           [h (send this get-height)])
>        (send dc set-pen "black" 3 'solid)
>                     (for ([i (in-range 3)])
>                       (send dc draw-line 0 (* i (/ h 3)) w (* i (/ h 3)))
>                       (send dc draw-line (* i (/ w 3)) 0 (* i (/ w 3)) h))
>                     (send dc set-pen "black" 1 'solid)
>                     (for ([i (in-range 9)])
>                           (send dc draw-line 0 (* i (/ h 9)) w (* i (/ h 9))))
>                     (for ([i (in-range 9)])
>                       (send dc draw-line (* i (/ w 9)) 0 (* i (/ w 9)) h))))
>    (super-new)))
> 
> (define the-grid (new grid-canvas% [parent frame]
>                                   [min-width 300]
>                                   [min-height 300]))
> 
> 
> I get an arity mismatch in on-paint.
> 
> The reason for not wanting in to pass in the paint-callback is that I want to be able to augment it somewhat in grid-canvas% (specifically, I need to draw in the digits based on the contents of the grid!) It's not clear (to me) how to do this, or if I should be taking an entirely different approach.
> ____________________
>  Racket Users list:
>  http://lists.racket-lang.org/users

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4373 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20120824/a1268929/attachment.p7s>

Posted on the users mailing list.