[plt-scheme] dual-editor snip

From: Jordan Johnson (jmj at fellowhuman.com)
Date: Sat Apr 11 02:40:12 EDT 2009

Hi all,

I'm trying to implement a snip similar to DrScheme's comment and XML  
boxes, but containing two distinct text boxes rather than one.   
Before I invest more time searching for the right way -- I've put in  
enough time that my this-*must*-be-easier alarm bells are going off  
-- I need to ask which classes/methods are the ones I'm after, or, at  
very least, if there's a relevant tutorial out there.

Here's what I want to accomplish:
	1) When both parts are visible, the user should be able to click  
into either one to edit its text; the contents will be independent,  
but the boxes should remain stacked (i.e., one should display above  
the other, in fixed order).
	2) When the snip does not have focus, only one of the two text boxes  
should be visible.
	3) Ultimately I want to hook into DrScheme and be able to create  
these snips by highlighting text in another editor and selecting a  
menu item, much like "Comment Out with a Box", to populate one of the  
snip's two fields with the selection.

Currently I'm just trying a simple precursor to (1):  getting  
DrScheme to draw the snip with both areas visible.  Code is below; it  
does not successfully draw the snip.

What is an appropriate way to manage the two editors the snip contains?


=== code ===
#lang scheme/gui

(define PAD 4)

(define my-snip%
   (class snip%
     (init-field [has-focus? #f]
                 [area1-text (new editor-snip%
                                 [editor (new text%)]
                                 [min-width 20]
                                 [max-width 600])]
                 [area2-text (new editor-snip%
                                  [editor (new text%)]
                                  [min-width 20]
                                  [max-width 600])])

     (define/override get-extent
       (lambda (dc x y w h descent space lspace rspace)
         (when (box? w)
           (let ([area2-w (box #f)]
                 [area1-w (box #f)]
                 [area1-h (box #f)])
             (send area1-text get-extent dc x y area1-w area1-h)
             (send area2-text get-extent dc x (+ y area1-h PAD) area2-w)
             (set-box! w (max (unbox area2-w area1-w)))))
         (when (box? h)
           (let ([area2-h (box #f)]
                 [area1-h (box #f)])
             (send area1-text get-extent dc x y #f area1-h)
             (send area2-text get-extent dc x (+ y area1-h PAD) #f  
             (set-box! h (+ area2-h area1-h PAD))))

     (define/override (draw dc x y left top right bottom
                            dx dy draw-caret?)
       (let ([area1-bottom (box #f)])
         (send area1-text get-extent dc x y #f area1-bottom)
         (send area1-text draw dc
               x y left top right area1-bottom
               dx dy draw-caret?)
         (send area2-text draw dc
               x (+ area1-bottom PAD)
               left (+ area1-bottom PAD)
               dx dy draw-caret?)))

(define s (new my-snip%))  ;; s doesn't render.

Posted on the users mailing list.