[racket] choice% - replace all choices

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Sat Jan 4 17:47:52 EST 2014

On Jan 4, 2014, at 1:30 PM, lothar atheling wrote:

> hello,
> 
> is there a way to replace all the choices at one whack?
> 
> i have choice lists several hundred items long, which to reset with
> choice% methods clear, append will be tedious  
> 
> the only way i can see is to work on a parent area-container% with
> change-children, but that also looks tedious.
> 
> it were best to subclass choice%, but there seems to be no way to access
> the choices field.

Here is how I would do it. It's basically a small library. -- Matthias



#lang racket/gui

(define (main)
  (define f (new frame% [label "testing choice replacement"][width 100][height 200]))
  ;; String [List-of String] String [-> (instance-of Choice%)] -> (instance-of Choice%)
  ;; add a choice% object to f with selections los and special switch entry s at bottom 
  ;; if this special choice is made, switch to (next) 
  (define (choice lbl los s next)
    (new choice% 
         [label lbl]
         [choices (append los (list "" s))]
         [parent f]
         [callback (lambda (c e)
                     (define chosen (send c get-string-selection))
                     (cond
                       [(string=? s chosen)
                        (send f begin-container-sequence)
                        (send f change-children (all-but (next)))
                        (send f end-container-sequence)]
                       [else 
                        (displayln chosen)]))]))
  
  ;; --- some instances of choice%
  (define c
    (choice "choose character"
            `("darth vadar" "luke skywalker" "princess leia" "han solo" "chuwaka")
            "chose tea instead"
            (thunk d)))
  
  (define d 
    (choice "chose teas"
            `("green" "black" "vanilla")
            "chose character instead"
            (thunk c)))
  
  ;; --- set up f now and show 
  
  (send f change-children (all-but c))
  (send f show #t))

;; X -> [List-of X] -> (cons X [List-of X])
;; create a function that adds c to a given list and removes all others
;; NOTE: this is more complex than needed here to show how this could be generalized. 
(define (all-but c)
  (lambda (children)
    (define x (filter (lambda (d) (eq? c d)) children))
    (if (member c x) x (cons c x))))

(main)



Posted on the users mailing list.