# Set input text box scroll position? (gui-easy)

**URL:** <https://racket.discourse.group/t/set-input-text-box-scroll-position-gui-easy/1638>\
**Category:** Questions & Answers\
**Tags:** gui\
**Created:** [January 14, 2023, 4:01pm UTC](https://racket.discourse.group/t/set-input-text-box-scroll-position-gui-easy/1638 "2023-01-14T16:01:59Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![joeld](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/joeld/32/38_2.png) [@joeld](https://racket.discourse.group/u/joeld)\
**Post date:** [January 14, 2023, 4:01pm UTC](https://racket.discourse.group/t/set-input-text-box-scroll-position-gui-easy/1638/1 "2023-01-14T16:01:59Z")

</div>

I’m creating my first GUI app, and I want to use `input` (from `gui-easy`) to display the output of a long-running command in "real time" (i.e. not waiting until the command is finished). When the output has more lines than can be displayed, I would like to set the text box’s vertical scroll position to the bottom as the output is updated. How does one update the scroll position of an `input`? (@bogdan or anyone)

---

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [January 14, 2023, 5:03pm UTC](https://racket.discourse.group/t/set-input-text-box-scroll-position-gui-easy/1638/2 "2023-01-14T17:03:12Z")

</div>

Why use an input for output? You might want to embed some kind of editor-canvas (make it read-only), or use the `text` control which is, aesthetically, more like a "label" than a "text box."

A more-complex-than-you-need example of the former is [https://github.com/benknoble/frosthaven-manager/blob/main/gui/markdown.rkt](https://github.com/benknoble/frosthaven-manager/blob/main/gui/markdown.rkt); you might also be able to use any of the procedures in [https://docs.racket-lang.org/gui-easy/index.html#%28part._.Canvases_\_\_.Snips%29](https://docs.racket-lang.org/gui-easy/index.html#%28part._.Canvases___.Snips%29). I forget which procedure does it, but you can also embed arbitrary racket/gui objects in gui-easy IIUC.

---

<div class="post-metadata">

**Author:** ![joeld](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/joeld/32/38_2.png) [@joeld](https://racket.discourse.group/u/joeld)\
**Post date:** [January 14, 2023, 5:17pm UTC](https://racket.discourse.group/t/set-input-text-box-scroll-position-gui-easy/1638/3 "2023-01-14T17:17:49Z")

</div>

> [@benknoble](#):
>
> Why use an input for output?

I’m not opinionated about using `input`, though I’m not sure what the objection is to using it for output (isn’t a read-only “editor” just as oxymoronic?). It just needs to support scrolling, and I need to know how to tell it to scroll to the bottom when its contents are updated. Something like what DrRacket its “Package Manager” dialog when running package management operations. I’ll take a look at your links, thanks.

---

<div class="post-metadata">

**Author:** ![bogdan](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/bogdan/32/8_2.png) [@bogdan](https://racket.discourse.group/u/bogdan)\
**Post date:** [January 14, 2023, 6:57pm UTC](https://racket.discourse.group/t/set-input-text-box-scroll-position-gui-easy/1638/4 "2023-01-14T18:57:24Z")

</div>

The `input` view in gui-easy takes a `#:mixin` argument that would normally allow you to change the scroll position by overriding its `set-value` method and operating on its internal editor. However, that seems to interact badly with some of the logic in that view that tries to preserve the cursor position when the input text changes. So, that's one reason to avoid using `input` for this. I could add another keyword argument to disable that functionality, but I'd like to avoid that for now.

The only other option right now is to roll your own view. [Here](https://gist.github.com/Bogdanp/4afd76f1e96ce4cad126a989e4e1512b) are two examples, the 2nd being just a more efficient variation on the first.

---

<div class="post-metadata">

**Author:** ![joeld](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/joeld/32/38_2.png) [@joeld](https://racket.discourse.group/u/joeld)\
**Post date:** [January 16, 2023, 3:16pm UTC](https://racket.discourse.group/t/set-input-text-box-scroll-position-gui-easy/1638/5 "2023-01-16T15:16:34Z")

</div>

Thanks so much for these! They are very instructive, and I'm studying them to understand how they work. I understand how consing to a buffer list, managing the buffer size and updating the editor (vs complete erase/replace on every update) all make the second example more efficient. This also helps me better understand custom views, and the underlying text/editor-canvas model. I am still digesting why `context-mixin` is needed in the second example, and what exactly it does. Obviously it is not a documented part of gui-easy so I know I'd never have gotten there on my own.

---

<div class="post-metadata">

**Author:** ![bogdan](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/bogdan/32/8_2.png) [@bogdan](https://racket.discourse.group/u/bogdan)\
**Post date:** [January 16, 2023, 4:39pm UTC](https://racket.discourse.group/t/set-input-text-box-scroll-position-gui-easy/1638/6 "2023-01-16T16:39:52Z")

</div>

You're welcome!

I've just pushed a change to make `context-mixin` public, which I had been intending to for a while but never got around to it. I've also added some docs for it. The gist of it is that a `view<%>` may be used to create multiple separate GUI widgets ([here's a contrived example](https://gist.github.com/Bogdanp/7668c1f4c9729a1cf4be7f7d967a6413#file-console-reuse-rkt-L100-L116)), so `view<%>` implementations should themselves be stateless. But, in most cases, you need to keep track of some additional state (like the buffer in the 2nd example) for every widget. The `context-mixin` wraps any class to add methods for associating arbitrary key-value pairs with its instances.
