# Racket/gui: how to use canvas%'s init-auto-scrollbar method

**URL:** <https://racket.discourse.group/t/racket-gui-how-to-use-canvas-s-init-auto-scrollbar-method/1263>\
**Category:** Questions & Answers\
**Created:** [August 30, 2022, 5:46pm UTC](https://racket.discourse.group/t/racket-gui-how-to-use-canvas-s-init-auto-scrollbar-method/1263 "2022-08-30T17:46:20Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jjsimpso](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jjsimpso/32/602_2.png) [@jjsimpso](https://racket.discourse.group/u/jjsimpso)\
**Post date:** [August 30, 2022, 5:46pm UTC](https://racket.discourse.group/t/racket-gui-how-to-use-canvas-s-init-auto-scrollbar-method/1263/1 "2022-08-30T17:46:21Z")

</div>

I'm developing a new canvas by subclassing `canvas%`. I would like for my new canvas to manage the scrollbars automatically and am attempting to setup automatic scrollbars with `init-auto-scrollbars`.

My thought is that I need to call `init-auto-scrollbars` from my `on-paint` method after drawing, because at that point I will know the size needed for my virtual canvas. Unfortunately, `init-auto-scrollbars` is triggering another `on-paint` call, leading to an infinite loop.

How else can I set the virtual size of the canvas? Is there a better place to do this than `on-paint`? Or is the answer to just use manual scrollbars?

---

<div class="post-metadata">

**Author:** ![alexh](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/alexh/32/315_2.png) [@alexh](https://racket.discourse.group/u/alexh)\
**Post date:** [August 30, 2022, 10:45pm UTC](https://racket.discourse.group/t/racket-gui-how-to-use-canvas-s-init-auto-scrollbar-method/1263/2 "2022-08-30T22:45:00Z")

</div>

> [@jjsimpso](#):
>
> after drawing, because at that point I will know the size needed for my virtual canvas.

I am curious how is it possible to know the size only after drawing it? The `on-paint` method only receives a draw context, `dc` instance, so everything that you need to draw should already be present in the `canvas%` instance, and you could compute the size at any time, not just while drawing it.

In any case, you can use `queue-callback` as shown below, but, as you noticed, this results in another call to `on-paint`, since you changed the virtual size. This will result in your application drawing more than it is needed. You should only call it if the virtual size changes, for example inside a `when` form:

```scheme
(queue-callback
  (lambda ()
    (init-auto-scrollbars ...)))

```

Alex.

---

<div class="post-metadata">

**Author:** ![jjsimpso](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jjsimpso/32/602_2.png) [@jjsimpso](https://racket.discourse.group/u/jjsimpso)\
**Post date:** [August 31, 2022, 1:40am UTC](https://racket.discourse.group/t/racket-gui-how-to-use-canvas-s-init-auto-scrollbar-method/1263/3 "2022-08-31T01:40:55Z")

</div>

Thanks for the response. This is kind of what I expected. I am primarily rendering text snips, so I have to run through a potentially large number of snips and calculate their size. I have to do this anyway while drawing, so I was hoping there was some way to update the virtual size from `on-paint`. Of course, only calling `init-auto-scrollbars` when the virtual size actually changes is a reasonable solution, although it triggers an additional `on-paint` call.

I was a little surprised that `init-auto-scrollbars` actually triggers a full `on-paint`. I guess it is the `(send wx set-scrollbars ...)` that does it. And I suppose it makes sense because this could potentially change the viewable canvas area and not just the rendering of the scrollbars themselves(I'm making some assumptions here).
