How do I change the color of multiple lines of text in a Racket GUI app?
Asked Answered
L

2

5

I'm experimenting with Racket's GUI Toolkit and am trying to get a cool color-changing effect going on with ASCII art on the screen. I have a callback which does the color-changing, but I can't seem to figure out how to call it to get the appropriate result.

At first I tried to use the message control to draw the text, and would then change the text color from there, but as far as I can tell there is no way to change the text color of messages. So I moved on to using the canvas subwindow, but I can't seem to draw multiple lines of text at once; newlines just get removed and the ascii art appears as one long line of text. Furthermore, the on-paint callback I was using to change the color only seems to be called whenever the window is resized or otherwise changed, so the colors don't change if the user is sitting and watching.

If I could find a way to get a callback going on each frame with the canvas, I could loop over a list of text strings and draw each one to the screen, separated vertically as to give the appearance of a newline, but I don't know if such an "on-frame" call exists with canvas.

Any ideas on how to get this working?

Lorianne answered 20/8, 2012 at 21:59 Comment(0)
C
7

Probably the easiest widget to use here is the text% class (you'll need an editor-canvas% for it too). Look at change-style and related methods to see how to change the styling of a particular piece of text.

Example:

#lang racket/gui

(define frame (new frame% [label "Test"] [width 300] 
                                         [height 300]))
(define text (new text%))
(define canvas (new editor-canvas% [parent frame] 
                                   [editor text]))

(define style-delta (make-object style-delta% 
                                 'change-normal-color))

;; do some red
(send style-delta set-delta-foreground "red")
(send text change-style style-delta)
(send text insert "Hello world in red\n")

;; do some blue
(send style-delta set-delta-foreground "blue")
(send text change-style style-delta)
(send text insert "Now available in blue")

(send frame show #t)
Countrified answered 21/8, 2012 at 2:57 Comment(1)
Beautiful, it worked! I used a timer that I created to call the color-changing callback on every few ticks, and used that to change the style-delta of the ASCII art. Thanks so much!Lorianne
E
0

You don't have to specify the change-command.

Simpler one:

#lang racket/gui

(define frame (new frame% [label "Test"] [width 300] 
                                         [height 300]))
(define text (new text%))
(define canvas (new editor-canvas% [parent frame] 
                                   [editor text]))

(define style-delta (make-object style-delta%))

;; do some red
(send style-delta set-delta-foreground "red")
(send text change-style style-delta)
(send text insert "Hello world in red\n")

;; do some blue
(send style-delta set-delta-foreground "blue")
(send text change-style style-delta)
(send text insert "Now available in blue\n")

;; do some modern
(send style-delta set-delta-foreground "black")
(send style-delta set-family 'modern)
(send text change-style style-delta)
(send text insert "Now available in modern\n(fixed width)")

(send frame show #t)
Eufemiaeugen answered 14/1, 2015 at 1:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.