[racket] how to add text-field-style behavior to rectangles drawn on a canvas

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Thu Oct 6 07:31:34 EDT 2011

At Thu, 06 Oct 2011 12:40:18 +0200, Marijn wrote:
> - - The display (a grid in my case) should create an editor-admin% which
> in turn should have a field to refer back to its display. When an
> editor becomes available to the display, the display will notify the
> editor of the editor-admin% instance through which it should direct
> its requests.


> - - The editor-admin% get-dc method is used to determine the upper left
> corner of the area in the drawing context into which the editor should
> draw itself. If I read the source correctly the docs are wrong here in
> that "The x box is filled with the x-origin of the DC in editor
> coordinates, unless x is #f." really should be something like "Unless
> x is #f, the x box is filled with the x-coordinate of the upper left
> corner of the area in the drawing context into which the editor should
> draw itself."

No, I think the docs are right. Roughly, the `x' and `y' boxes are
filled with the negative of the number you suggest. If an editor should
draw at 20 pixels down from the top of a canvas, then `y' should be
filled with -20.

> - - The get-view method determines the area of the editor which should
> be drawn into the dc returned by get-dc at the dc coordinates returned
> in the box arguments of get-dc. 

Yes. That is, the result of `get-view' is in editor coordinates, which
you shift by the numbers from `get-dc' to get to DC coordinates.

> The full? argument is #t in case of an
> embedded editor.

The `full?' argument value is meant to change the admin's result only
in the case a nested editor, so I think you can ignore that argument.

> - - The get-max-view method is not used to determine a bounding box of
> all displays of this editor in display coordinates (which doesn't even
> make sense). 

Indeed, it would make no sense if it were in display coordinates. Like
`get-view', the result is in editor coordinates.

> Instead it is used to determine the union of all regions
> in the editor which are viewed in some display. But how does get-view
> know which of the displayed regions if there are multiple to return?
> And how does get-dc then know of which display to return the dc and
> upper left corner?

Hopefully these questions are answered by the result being in editor

> - - The grab-caret method is specified in the docs to call the editor's
> own-caret method. Well, maybe it doesn't claim that it will be called
> directly, but as I understand it now, it really will defer to the
> display by calling its set-focus method. I didn't check whether the
> set-focus method does or doesn't call the editor's own-caret method.

For a display that has a window, then `focus' is indeed the right way
to get focus to the display. In that case, the admin is responsible for
calling `own-caret' in response to `on-focus' calls for the `window<%>'.

> - - The modified method is used to determine whether content in an
> editor is different from that same content stored on disk. Or?

It's a notification from the editor that it is modified, in case that
information is useful, but the admin can ignore the notification. For
example, an admin might respond to a `modified' call by adding or
removing an asterisk in the title of the frame that contains the
editor, or it might not care whether the editor has transitioned
between "unmodified" and "modified".

> - - The needs-update method is specified in the docs to call the
> editor's refresh method, but in the code it calls methods (repaint,
> redraw) of the display instead.

The `needs-update' method should eventually call the editor's `refresh'
method, but the right way to refresh depends on the display. In a
canvas, for example, it's probably better to call the canvas `refresh'
method and let the windowing system schedule a refresh, in which case
the `on-paint' method of the `canvas' will call `refresh' for the

(The conflicting meanings of "refresh" at the canvas and editor levels
is unfortunate. At the canvas level, `refresh' asks the window manager
to eventually call `on-paint', and the `on-paint' method actually
paints. At the editor level, `refresh' actually paints, so it should
have been called `on-paint', etc.)

Posted on the users mailing list.