gui widgets over canvas

156 views
Skip to first unread message

Neil Van Dyke

unread,
Aug 5, 2019, 7:28:17 AM8/5/19
to Racket-Users List
For a million-rows spreadsheet GUI widget that's based on a canvas, and
wants to overlay a single normal widget like a `text-field%` at a time,
over the canvas, for cell value editing... what's the best way to get
that overlay to happen in Racket `gui`?

One idea: in the implementation of `panel%`, looks like I can force it
to be implemented as a canvas (`wx-vertical-canvas-panel%`).  If I could
draw the spreadsheet viewport to that same canvas, as well as parent
overlaid widgets to it, I suppose I could use panes to position and size
the editing widget.  I don't know whether that would work at all, on all
platforms, and in future Racket releases.

Or is there a better way?

Alex Harsanyi

unread,
Aug 5, 2019, 8:49:33 PM8/5/19
to Racket Users
I can think of two options which only use the functionality that is currently
available in the racket GUI library:

One option is to use a `pasteboard%` instead of the `canvas%` and use an
`editor-snip%` for the text input, with the snip being moved where you need
it.  This solution will be limited to the text input widget only, unless you
want to write additional widgets, which will have to be implemented as `snip%`
instances.

Another option is to write your own panel widget by deriving from `panel%` and
overriding `container-size` and `place-children` -- this will give full
control over the placement of child items inside the panel: e.g. the canvas
could be placed at 0,0 and fill the entire client area, while the text input
will be placed on top of the canvas at the correct position.  This solution
allows placing arbitrary controls on the canvas.  For scrolling, I would
suggest making the canvas itself scrollable and have the panel update the
position of the text input: a scrollable panel works, but the canvas will not
know its viewing area and will have to draw all the rows and let the
underlying draw routines clip them -- this might be a performance issue for
very large number of rows.

Good luck with your project,
Alex.

Neil Van Dyke

unread,
Aug 6, 2019, 2:03:18 AM8/6/19
to Alex Harsanyi, Racket Users
Thank you, Alex.  I'll take another look at using `panel%` that way.  (I
wasn't sure that would work well on all platforms, because its own
implementation has special-cases for its stock subclasses, which
conceivably might be necessary on some platforms.)

Regarding scrollbars, I might end up abusing the native ones, to look
still native but make scrolling less jumpy on all platforms when there's
a million rows.  We'll see how well it works without tweaking on various
platforms in practice, and then what the priority is.

Regarding `pasteboard%`, that was the first promising-sounding thing,
but I want native editing widgets if possible for this (`text-field% is
just one example, there will also at least be some kind of
select/combobox).  Also didn't want to pull in the Framework, if I
didn't have to.

(BTW, I appreciate that cross-platform GUI toolkits that use the native
look&feel toolkits (as opposed to its own look&feel, or emulating the
native look&feel) are always going to have some restrictions, and lots
of subtleties in their implementation, so I'm not expecting this to be
nearly as easy as targeting a single native toolkit.  I like that Racket
went this route.)

Hendrik Boom

unread,
Aug 6, 2019, 4:03:14 PM8/6/19
to Racket Users
On Tue, Aug 06, 2019 at 02:03:14AM -0400, Neil Van Dyke wrote:
> Thank you, Alex.  I'll take another look at using `panel%` that way.  (I
> wasn't sure that would work well on all platforms, because its own
> implementation has special-cases for its stock subclasses, which conceivably
> might be necessary on some platforms.)
>
> Regarding scrollbars, I might end up abusing the native ones, to look still
> native but make scrolling less jumpy on all platforms when there's a million
> rows.  We'll see how well it works without tweaking on various platforms in
> practice, and then what the priority is.

A long long time ago I had a scroll region in a gtk app. However, it
turned out that the scroll region was limited to something like 32K or
64K pixels. Evidently it was limiting pixel counts to 16-bit words.
I could not find this limit in any user documentation.

I have since asked about such limits in newer versions of gtk. I have
never received a reply.

Be careful. You might hit such limits, and your interfaces might
behave in dangerous ways.

-- hendrik

Neil Van Dyke

unread,
Aug 6, 2019, 4:35:46 PM8/6/19
to Racket Users
Hendrik Boom wrote on 8/6/19 4:03 PM:
> Be careful. You might hit such limits, and your interfaces might behave in dangerous ways.

Thanks for the warning.  I've seen a lot of such limits in various GUI
toolkits, and, when you have a cross-platform layer over it, you have to
do a combination of both anticipating limits, and then testing on all
the platforms to see if you missed anything.  That's in addition to
testing for various non-limit quirks of the platform, which over time
the cross-platform layer has gotten tweaked for, but you can still run
into things that haven't already been exercised through the layer.

(Other ones most immediately in mind are any kind of large
list/table/tree widget -- even if the layer offers some kind of
model-view linking that looks like it can page in data from the model
on-demand, the way the layer uses the underlying widget might just be to
load the entire model into storage controlled by the native widget.  I'm
also suspicious of letting every native toolkit do a large scrolling
canvas on its own, and I expect some to have small limits there, and for
it to also do things like buffering very large pixmaps for the entire
coordinate system or bounding box, so I'd prefer it just gave me a
viewport and drawing&scrolling callbacks.  And, of course, perhaps most
toolkits don't scale well to millions of widgets in a spreadsheet, even
though there's no reason you couldn't make one that does scale, it was
almost never a requirement.  We can guess what a lot of the things to
test will be, and try to avoid them, but still have to test whatever we
do write, on everything.)

Reply all
Reply to author
Forward
0 new messages