[racket] gui issue > frame updating control thread painter > questions about how to resolve the problem, attain eventual reactive semantics

From: Patrick Mahoney (paddy.mahoney at gmail.com)
Date: Fri Apr 20 15:16:20 EDT 2012

> #lang racket
> (require racket/gui/base)
>
> #|Hello all,
>  Patrick here-
> First, my apologies for posting a non-working example-I hope I didn't
> waste anyone's time. Secondly, thanks to Matthias and Robby for the
> corrections-I will certainly refer to these when I use eventspaces again.
>
> I found the issue I had seen, and it had nothing to do with eventspaces-it
> occurred even without the call-with-eventspace machinery.  Rather, the
> message% used truncated all text whose length exceeded that of the original
> init field [Label]. I think there is either a docs bug or a bug in the
> Windows implementation. |#
>
> #|Problem: I have a message% control called x-pos parented by a frame%
> called parent1. I have a canvas% subclass called canvas parented under
> frame% parent2. I would like x-pos to always show the current x coordinate
> of the mouse position over canvas, and for this to be kept up to date as
> the mouse moves.|#
>
> #|Setting up the first frame and parent.|#
>
> (define parent1 (new frame%
>                               [label "Parent1"]
>                               [width 200]
>                               [height 200]
>                               [enabled #t]))
>
> #|Upon further investigation, I found that the label was indeed showing
> the first digit of the number, and truncating the remaining. This was of
> course dependent on the length of the label set on message% init. message%
> does not resize automatically, and I needed to set the auto-resize field to
> #t. It also didn't show in my original test-sort of a heisenbug because I
> used a really long initial label in my test scenario.
>
>
> From
> http://docs.racket-lang.org/gui/message_.html
> "If auto-resize is not #f, then automatic resizing is initially enanbled
> (see auto-resize), and the message% object’s graphical minimum size is as
> small as possible." -> this doesn't appear to be the case here. Windows XP,
> Racket 5.1
>
> I don't have a linux box to test atm, but I wonder if the default for the
> auto-size field is #t there. If so, either the docs are incorrect, or the
> windows implementation. If not, docs need to be updated. I'd be glad to
> help in any way possible.|#
>
> (define x-pos (new message%
>                    [parent parent1]
>                    [label "0"]))
>
> #|This variant of x-pos works, resizing with new set-label requests and
> thus avoiding the truncation. |#
> #;(define x-pos (new message%
>                    [parent parent1]
>                    [label "0"]#|Setting the label to say, "Long label!"
> avoids the behavior.|#
>                    [auto-resize #t]))
>
> (send parent1 show #t)
>
> #|The second frame*pos combo-|#
>
> (define parent2 (new frame%
>                               [label "Parent2"]
>                               [width 200]
>                               [height 200]
>                               [enabled #t]))
>
> #|Here comes the canvas subclass-I'm looking to override on-event method
> to grab the x-component of the mouse pos, and I want to have that
> constantly updating the x-pos message%. I really want reactive behavior,
> but I ran into some issues with the frtime-namely, differences in bindings
> due to the mzscheme bindings. the require spec (prefix-in ..) doesn't
> appear to be in the language. I'm probably doing something wrong. |#
> (define my-canvas% (class canvas%
>
>     (inherit get-dc)
>
>     (define/override (on-event mouse-event)
>       (define x (send mouse-event get-x))
>       (send  x-pos set-label (number->string x)))
>     (super-new)))
>
> (define canvas (new my-canvas% [parent parent2]
>                     [label "Nothing yet."]))
>
> (send parent2 show #t)
>
>
> #|There you have it kids-message% objects don't auto-resize, and will
> truncate the text that is longer than the [label] that they are init-ed
> with. Sorry for the noise. |#
>
>
>
> On 20 April 2012 10:34, Matthias Felleisen <matthias at ccs.neu.edu> wrote:
>
>>
>> Here is a solution in the DrRacket beginner language:
>>
>> (require 2htdp/universe)
>> (require 2htdp/image)
>>
>> (define (bundle x) (make-bundle x '() '()))
>>
>> (launch-many-worlds
>>  (universe 'n/a (on-new (λ (u nw) (bundle u))) (on-msg (λ (u w m) (bundle
>> m))) (state #t))
>>  (big-bang 'n/a (to-draw (λ (w) (empty-scene 200 200)))
>>           (register LOCALHOST)
>>           (on-mouse (λ (w x y ke) (make-package w x)))))
>>
>> Here is a solution in Racket derived from yours:
>>
>> #lang racket
>>
>> (require racket/gui/base)
>>
>> (define show-x
>>  (new frame%
>>       [label "frame for displaying the current x coordinate"]
>>        [width 200]
>>       [height 200]
>>       [enabled #t]))
>>
>> (define x-pos
>>  (new message%
>>        [parent show-x]
>>        [label "No x-pos yet."]))
>>
>> (define discover-x
>>  (new frame%
>>       [label "frame for noticing mouse evets and their current x
>> coordinates"]
>>        [width 200]
>>       [height 200]
>>       [enabled #t]))
>>
>> (define y-pos
>>  (new (class canvas%
>>         (inherit get-dc)
>>         (super-new)
>>         (define/override (on-event mouse-event)
>>            (define x-pos (send mouse-event get-x))
>>           (define y-pos (send mouse-event get-y))
>>            (set! *x x-pos)
>>           (refresh)))
>>       [parent discover-x]))
>>
>> ;; for communicating between the two frams
>> (define *x 'n/a)
>>
>> (define (refresh)
>>  (send x-pos set-label (format "~a" *x)))
>>
>> ;; run program run
>> (send show-x show #t)
>> (send discover-x show #t)
>>
>> ;; you were creating way too many event spaces. No need for that.
>>
>>
>>
>>
>> On Apr 19, 2012, at 2:32 PM, Patrick Mahoney wrote:
>>
>> > #lang racket
>> > #|Hello all, I'm  PMah. |#
>> > (require racket/gui/base)
>> >
>> > #|Problem: I have a message% control called x-pos parented by a frame%
>> called parent1. I have a canvas% called canvas parented under frame%
>> parent2. I would like x-pos to always show the current x coordinate of the
>> mouse position over canvas, and for this to be kept up to date as the mouse
>> moves. Ultimately I'd love to move to a reactive semantics. |#
>> >
>> >
>> > #|Setting up the first frame and parent. I'm also going to grab the
>> eventspace for this frame while I'm at it.|#
>> > (define parent1 (new frame%
>> >                               [label "Parent1"]
>> >                               [width 200]
>> >                               [height 200]
>> >                               [enabled #t]))
>> >
>> > (define x-pos (new message%
>> >                    [parent parent1]
>> >                    [label "No x-pos yet."]))
>> >
>> > (send parent1 show #t)
>> >
>> > (define eventspace1 (send parent1 get-eventspace))
>> >
>> >
>> > #|The second eventspace*frame*pos combo-|#
>> > (define parent2 (new frame%
>> >                               [label "Parent2"]
>> >                               [width 200]
>> >                               [height 200]
>> >                               [enabled #t]))
>> >
>> >
>> > #|Here comes the canvas subclass-I'm looking to override on-event
>> method to grab the x-component of the mouse pos, and I want to have that
>> constantly updating the x-pos message%. I really want reactive behavior,
>> but I ran into some issues with the frtime-namely, differences in bindings
>> due to the mzscheme bindings. the require spec (prefix-in ..) doesn't
>> appear to be in the language. I'm probably doing something wrong. |#
>> > (define y-pos (class canvas%
>> >
>> >     (inherit get-dc)
>> > #|My notion of scope in objects is not precise. With those defines
>> within the scope of the on-event bindings, do the defines recalculate each
>> time on-event receives a message? lo, I wish I had some sort of channel
>> protocol to pass messages between threads, along with control.
>> > The mushrooms kick in now.
>> > PFFFT MIND
>> > |#
>> >     (define/override (on-event mouse-event)
>> >       (define min-x (dc:min-x (get-dc)))
>> >       (define max-x (dc:max-x (get-dc)))
>> >       (define min-y (dc:min-y (get-dc)))
>> >       (define max-y (dc:max-y (get-dc)))
>> >       (define x-pos (send mouse-event get-x))
>> >       (define y-pos (send mouse-event get-y))
>> >       (call-in-other-eventspace (make-eventspace) (draw-diagnostics
>> max-x max-y x-pos y-pos)))
>> >
>> >     (super-new)))
>> >
>> > (define
>> > (send parent2 show #t)
>> >
>> >
>> > #|I have tried some of the examples on
>> http://groups.google.com/group/plt-scheme/browse_thread/thread/28af25a01200bc3c/7937bb0314cc231e?lnk=raot
>> > Basically, one using a channel, probably incorrectly and the second
>> without. Now what I believe I've done is to add the thunk to the queue in
>> the frame% parent1's eventspace, but I haven't transferred control. The
>> other eventspace's thread still has control. Kind of?
>> > |#
>> > (define (call-in-other-eventspace e thunk)
>> >    (let ([ch (make-channel)])
>> >      (parameterize ([current-eventspace e])
>> >        (queue-callback (lambda ()
>> >                          (channel-put ch (thunk)))))
>> >      (channel-get ch)))
>> >   #|This blocks both frames updating in some way-im not able to
>> transfer control smoothly to the thread in the message% message1 workspace,
>> and so the x-pos label updates only sporadically when the other eventspace
>> thread yields? |#
>> > (define (call-in-other-eventspace e thunk)
>> >    (parameterize ([current-eventspace e])
>> >        (queue-callback thunk)))
>> >
>> >
>> > #|How can I get x-pos to update automatically on each on-event send
>> here? (draw-diagnostics max-x max-y x-pos y-pos) appears to terminate here
>> in all cases. Part 2: how can I apply frtime to make the update
>> relationship I want between canvas mouse position and message text  (or
>> other racket reactive work if it exists.). I really would like to
>> understand this idiom and get it in my toolchest for gui programming.
>> Thanks all! Racket is an impressive contribution to computer science. |#
>> >
>> >
>> >
>> > ____________________
>> >  Racket Users list:
>> >  http://lists.racket-lang.org/users
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20120420/85e53e2d/attachment-0001.html>

Posted on the users mailing list.