Lisp HUG Maillist Archive

Creating your own radio group?

Hello,

I have an interface which displays several instances of one data model
object. It is very convenient to represent this layout by extending a
CAPI grid class, and having multiple instances of this layout. That
works fine.

Now I wanted to create radio buttons to select which of the objects is
active, and store the active button boolean value inside each object.
Thus, I have several boolean variables that need to be updated through
radio buttons, and the buttons need to be logically grouped together
like for regular radio button panel, but displayed manually.

I tried but it seems that displaying buttons from CAPI radio button
panel in separate layouts does not work. So I need my own radio group
which can be laid out anywhere. I decided to use capi:choice as base.

The solution below seems to work otherwise, but for some reason the
old radio button does not seem to get disabled. The actual data
boolean gets updated correctly, however. I tried this both with and
without capi:apply-in-current-pane-process, that does not seem to
change anything. Even stranger is that if I update the button manually
with

    (setf (capi:button-selected radio1) t)

(or nil) the button image gets updated.

Am I doing something wrong?

I am running LW5.11 on OSX.

Best regards,

Mikko Ahonen

--

(defvar *foo* nil)
(defvar *bar* t)
(defvar *foobar* nil)

(defmacro with-gensyms (syms &body body)
  `(let ,(mapcar #'(lambda (s)
                     `(,s (gensym)))
                 syms)
    ,@body))

(defun radio-group-reset-other-buttons (group other-than-pane)
  (loop for item across (capi:collection-items group)
        do (unless (eq other-than-pane item)
             (format t "unselect ~A~%" item)
             (funcall (capi:callbacks-retract-callback item) item)
             (setf (capi:button-selected item) nil))))

(defmacro radio (name txt var group)
  (with-gensyms (selected rb)
    `(let ((,rb (make-instance 'capi:radio-button
                               :selection-callback #'(lambda (pane)
                                                       (format t "~A
selection callback~%" pane)
                                                       (setf ,var t)
                                                       (setf
(capi:choice-selected-item ,group) pane)

(radio-group-reset-other-buttons ,group pane))
                               :retract-callback #'(lambda (pane)
                                                     (format t "~A
retract callback~%" pane)
                                                     (setf ,var nil))
                               :callback-type '(:item)
                               :text ,txt
                               :selected ,var)))
           (capi:append-items ,group (list ,rb))
           (when ,var
             (setf (capi:choice-selected-item ,group) ,rb))
           ,rb)))

(defmacro radio-group (&rest args)
    `(make-instance 'capi:choice
                    :interaction :single-selection
                    :items '()
                    ,@args))

(setf g (radio-group))

(setf radio1 (radio :foo "Foo" *foo* g))

(setf radio2 (radio :bar "Bar" *bar* g))

(setf radio3 (radio :foobar "Foobar" *foobar* g))

(capi:contain (make-instance 'capi:column-layout :description (list
radio1 radio2 radio3)))

(list *foo* *bar* *foobar*)


Re: Creating your own radio group?

Unable to parse email body. Email id is 9100

Re: Creating your own radio group?

Hello,

Thanks a lot for your example.

It seems going through all panes in the interface gets quite slow when
the interface is deep, i.e. I have several levels of layouts inside
each other. In my interface your example was perceptibly slow for
human eye.

Perhaps I should try to avoid deep interfaces? It is just very useful
way to develop things as components, which can be easily tested
separately and located as groups in containers.

But your example helped me to realize that using capi:layout for what
I was doing was not such a good idea. I used my own class and it seems
to work well.

Btw, thanks for the excellent product! I have been programming with LW
(and Lisp) for perhaps 8 months now, and more I get used to it, more I
like it. It seems that libraries are very well thought out. The
learning curve for Lisp beginners is quite steep, though, but well
worth it.

Best regards,

Mikko Ahonen

On Mon, Mar 30, 2009 at 8:15 PM,  <davef@lispworks.com> wrote:
>
> Try this:
>
> ----------------------------------------------------------------------
> (defun button (i &optional selected)
>  (make-instance 'capi:radio-button :data i :text (format nil "r~D" i)
>                 :selected selected
>                 :selection-callback 'callback
>                 :callback-type :data-interface))
>
> (defun text (i &optional enabled)
>  (make-instance 'capi:text-input-pane :title (format nil "t~D" i) :enabled enabled))
>
> (capi:define-interface buttons-and-text ()
>  ((radio-buttons :initarg :radio-buttons)
>   (text-panes :initarg :text-panes))
>  (:layouts
>   (grid
>    capi:grid-layout
>    (append radio-buttons text-panes)
>    :columns 2
>    :y-gap 20
>    :accessor grid)))
>
> (defun callback (data interface)
>  (loop for pane in (capi:layout-description (grid interface))
>        do
>        (etypecase pane
>          (capi:radio-button
>           (unless (eq (capi:item-data pane) data)
>             (setf (capi:button-selected pane) nil)))
>          (capi:text-input-pane
>           (setf (capi:text-input-pane-enabled pane)
>                 (string= (capi:titled-pane-title pane) (format nil "t~D" data)))))))
>
> (let* ((r1 (button 1))
>       (r2 (button 2 t))
>       (r3 (button 3))
>       (r4 (button 4))
>       (t1 (text 1))
>       (t2 (text 2 t))
>       (t3 (text 3))
>       (t4 (text 4))
>       (grid (make-instance
>              'buttons-and-text
>              :radio-buttons (list r1 r2 r3 r4)
>              :text-panes (list t1 t2 t3 t4))))
>    (capi:display grid))
> ----------------------------------------------------------------------
>
> The enabled/disabled state of the text panes is the "boolean"
> controlled by each corresponding radio button.
>
> Hopefully this example will help you to implement the layout and
> interaction you actually want.
>
> --
> Dave Fox
> LispWorks Ltd
> St John's Innovation Centre, Cowley Road
> Cambridge CB4 0WS
> England
> http://www.lispworks.com/
>
> LispWorks Ltd is registered in England, company number 5114963.  The
> company's registered address is c/o Streets Whitmarsh Sterland LLP,
> 62 Hills Road, Cambridge CB2 1LA (but customers and suppliers should
> write to our office address above).  LispWorks Ltd is registered for
> VAT with EC VAT ID: GB 833329531
>
>
>
>  > Hello,
>  >
>  > I have an interface which displays several instances of one data model
>  > object. It is very convenient to represent this layout by extending a
>  > CAPI grid class, and having multiple instances of this layout. That
>  > works fine.
>  >
>  > Now I wanted to create radio buttons to select which of the objects is
>  > active, and store the active button boolean value inside each object..
>  > Thus, I have several boolean variables that need to be updated through
>  > radio buttons, and the buttons need to be logically grouped together
>  > like for regular radio button panel, but displayed manually.
>  >
>  > I tried but it seems that displaying buttons from CAPI radio button
>  > panel in separate layouts does not work. So I need my own radio group
>  > which can be laid out anywhere. I decided to use capi:choice as base..
>  >
>  > The solution below seems to work otherwise, but for some reason the
>  > old radio button does not seem to get disabled. The actual data
>  > boolean gets updated correctly, however. I tried this both with and
>  > without capi:apply-in-current-pane-process, that does not seem to
>  > change anything. Even stranger is that if I update the button manually
>  > with
>  >
>  >     (setf (capi:button-selected radio1) t)
>  >
>  > (or nil) the button image gets updated.
>  >
>  > Am I doing something wrong?
>  >
>  > I am running LW5.11 on OSX.
>  >
>  > Best regards,
>  >
>  > Mikko Ahonen
>  >
>  > --
>  >
>  > (defvar *foo* nil)
>  > (defvar *bar* t)
>  > (defvar *foobar* nil)
>  >
>  > (defmacro with-gensyms (syms &body body)
>  >   `(let ,(mapcar #'(lambda (s)
>  >                      `(,s (gensym)))
>  >                  syms)
>  >     ,@body))
>  >
>  > (defun radio-group-reset-other-buttons (group other-than-pane)
>  >   (loop for item across (capi:collection-items group)
>  >         do (unless (eq other-than-pane item)
>  >              (format t "unselect ~A~%" item)
>  >              (funcall (capi:callbacks-retract-callback item) item)
>  >              (setf (capi:button-selected item) nil))))
>  >
>  > (defmacro radio (name txt var group)
>  >   (with-gensyms (selected rb)
>  >     `(let ((,rb (make-instance 'capi:radio-button
>  >                                :selection-callback #'(lambda (pane)
>  >                                                        (format t "~A
>  > selection callback~%" pane)
>  >                                                        (setf ,var t)
>  >                                                        (setf
>  > (capi:choice-selected-item ,group) pane)
>  >
>  > (radio-group-reset-other-buttons ,group pane))
>  >                                :retract-callback #'(lambda (pane)
>  >                                                      (format t "~A
>  > retract callback~%" pane)
>  >                                                      (setf ,var nil))
>  >                                :callback-type '(:item)
>  >                                :text ,txt
>  >                                :selected ,var)))
>  >            (capi:append-items ,group (list ,rb))
>  >            (when ,var
>  >              (setf (capi:choice-selected-item ,group) ,rb))
>  >            ,rb)))
>  >
>  > (defmacro radio-group (&rest args)
>  >     `(make-instance 'capi:choice
>  >                     :interaction :single-selection
>  >                     :items '()
>  >                     ,@args))
>  >
>  > (setf g (radio-group))
>  >
>  > (setf radio1 (radio :foo "Foo" *foo* g))
>  >
>  > (setf radio2 (radio :bar "Bar" *bar* g))
>  >
>  > (setf radio3 (radio :foobar "Foobar" *foobar* g))
>  >
>  > (capi:contain (make-instance 'capi:column-layout :description (list
>  > radio1 radio2 radio3)))
>  >
>  > (list *foo* *bar* *foobar*)
>  >
>


Re: Creating your own radio group?

Hi Mikko,

Do you mean that it is slow to display on the screen, slow to resize or
something else?

Regards,

Martin Simmons
LispWorks Ltd
http://www.lispworks.com/


>>>>> On Tue, 31 Mar 2009 04:07:29 +0300, Mikko Ahonen said:
> 
> Hello,
> 
> Thanks a lot for your example.
> 
> It seems going through all panes in the interface gets quite slow when
> the interface is deep, i.e. I have several levels of layouts inside
> each other. In my interface your example was perceptibly slow for
> human eye.
> 
> Perhaps I should try to avoid deep interfaces? It is just very useful
> way to develop things as components, which can be easily tested
> separately and located as groups in containers.
> 
> But your example helped me to realize that using capi:layout for what
> I was doing was not such a good idea. I used my own class and it seems
> to work well.
> 
> Btw, thanks for the excellent product! I have been programming with LW
> (and Lisp) for perhaps 8 months now, and more I get used to it, more I
> like it. It seems that libraries are very well thought out. The
> learning curve for Lisp beginners is quite steep, though, but well
> worth it.
> 
> Best regards,
> 
> Mikko Ahonen
> 
> On Mon, Mar 30, 2009 at 8:15 PM,  <davef@lispworks.com> wrote:
> >
> > Try this:
> >
> > ----------------------------------------------------------------------
> > (defun button (i &optional selected)
> >  (make-instance 'capi:radio-button :data i :text (format nil "r~D" i)
> >                 :selected selected
> >                 :selection-callback 'callback
> >                 :callback-type :data-interface))
> >
> > (defun text (i &optional enabled)
> >  (make-instance 'capi:text-input-pane :title (format nil "t~D" i) :enabled enabled))
> >
> > (capi:define-interface buttons-and-text ()
> >  ((radio-buttons :initarg :radio-buttons)
> >   (text-panes :initarg :text-panes))
> >  (:layouts
> >   (grid
> >    capi:grid-layout
> >    (append radio-buttons text-panes)
> >    :columns 2
> >    :y-gap 20
> >    :accessor grid)))
> >
> > (defun callback (data interface)
> >  (loop for pane in (capi:layout-description (grid interface))
> >        do
> >        (etypecase pane
> >          (capi:radio-button
> >           (unless (eq (capi:item-data pane) data)
> >             (setf (capi:button-selected pane) nil)))
> >          (capi:text-input-pane
> >           (setf (capi:text-input-pane-enabled pane)
> >                 (string= (capi:titled-pane-title pane) (format nil "t~D" data)))))))
> >
> > (let* ((r1 (button 1))
> >       (r2 (button 2 t))
> >       (r3 (button 3))
> >       (r4 (button 4))
> >       (t1 (text 1))
> >       (t2 (text 2 t))
> >       (t3 (text 3))
> >       (t4 (text 4))
> >       (grid (make-instance
> >              'buttons-and-text
> >              :radio-buttons (list r1 r2 r3 r4)
> >              :text-panes (list t1 t2 t3 t4))))
> >    (capi:display grid))
> > ----------------------------------------------------------------------
> >
> > The enabled/disabled state of the text panes is the "boolean"
> > controlled by each corresponding radio button.
> >
> > Hopefully this example will help you to implement the layout and
> > interaction you actually want.
> >
> > --
> > Dave Fox
> > LispWorks Ltd
> > St John's Innovation Centre, Cowley Road
> > Cambridge CB4 0WS
> > England
> > http://www.lispworks.com/
> >
> > LispWorks Ltd is registered in England, company number 5114963.  The
> > company's registered address is c/o Streets Whitmarsh Sterland LLP,
> > 62 Hills Road, Cambridge CB2 1LA (but customers and suppliers should
> > write to our office address above).  LispWorks Ltd is registered for
> > VAT with EC VAT ID: GB 833329531
> >
> >
> >
> >  > Hello,
> >  >
> >  > I have an interface which displays several instances of one data model
> >  > object. It is very convenient to represent this layout by extending a
> >  > CAPI grid class, and having multiple instances of this layout. That
> >  > works fine.
> >  >
> >  > Now I wanted to create radio buttons to select which of the objects is
> >  > active, and store the active button boolean value inside each object.
> >  > Thus, I have several boolean variables that need to be updated through
> >  > radio buttons, and the buttons need to be logically grouped together
> >  > like for regular radio button panel, but displayed manually.
> >  >
> >  > I tried but it seems that displaying buttons from CAPI radio button
> >  > panel in separate layouts does not work. So I need my own radio group
> >  > which can be laid out anywhere. I decided to use capi:choice as base.
> >  >
> >  > The solution below seems to work otherwise, but for some reason the
> >  > old radio button does not seem to get disabled. The actual data
> >  > boolean gets updated correctly, however. I tried this both with and
> >  > without capi:apply-in-current-pane-process, that does not seem to
> >  > change anything. Even stranger is that if I update the button manually
> >  > with
> >  >
> >  >     (setf (capi:button-selected radio1) t)
> >  >
> >  > (or nil) the button image gets updated.
> >  >
> >  > Am I doing something wrong?
> >  >
> >  > I am running LW5.11 on OSX.
> >  >
> >  > Best regards,
> >  >
> >  > Mikko Ahonen
> >  >
> >  > --
> >  >
> >  > (defvar *foo* nil)
> >  > (defvar *bar* t)
> >  > (defvar *foobar* nil)
> >  >
> >  > (defmacro with-gensyms (syms &body body)
> >  >   `(let ,(mapcar #'(lambda (s)
> >  >                      `(,s (gensym)))
> >  >                  syms)
> >  >     ,@body))
> >  >
> >  > (defun radio-group-reset-other-buttons (group other-than-pane)
> >  >   (loop for item across (capi:collection-items group)
> >  >         do (unless (eq other-than-pane item)
> >  >              (format t "unselect ~A~%" item)
> >  >              (funcall (capi:callbacks-retract-callback item) item)
> >  >              (setf (capi:button-selected item) nil))))
> >  >
> >  > (defmacro radio (name txt var group)
> >  >   (with-gensyms (selected rb)
> >  >     `(let ((,rb (make-instance 'capi:radio-button
> >  >                                :selection-callback #'(lambda (pane)
> >  >                                                        (format t "~A
> >  > selection callback~%" pane)
> >  >                                                        (setf ,var t)
> >  >                                                        (setf
> >  > (capi:choice-selected-item ,group) pane)
> >  >
> >  > (radio-group-reset-other-buttons ,group pane))
> >  >                                :retract-callback #'(lambda (pane)
> >  >                                                      (format t "~A
> >  > retract callback~%" pane)
> >  >                                                      (setf ,var nil))
> >  >                                :callback-type '(:item)
> >  >                                :text ,txt
> >  >                                :selected ,var)))
> >  >            (capi:append-items ,group (list ,rb))
> >  >            (when ,var
> >  >              (setf (capi:choice-selected-item ,group) ,rb))
> >  >            ,rb)))
> >  >
> >  > (defmacro radio-group (&rest args)
> >  >     `(make-instance 'capi:choice
> >  >                     :interaction :single-selection
> >  >                     :items '()
> >  >                     ,@args))
> >  >
> >  > (setf g (radio-group))
> >  >
> >  > (setf radio1 (radio :foo "Foo" *foo* g))
> >  >
> >  > (setf radio2 (radio :bar "Bar" *bar* g))
> >  >
> >  > (setf radio3 (radio :foobar "Foobar" *foobar* g))
> >  >
> >  > (capi:contain (make-instance 'capi:column-layout :description (list
> >  > radio1 radio2 radio3)))
> >  >
> >  > (list *foo* *bar* *foobar*)
> >  >
> >
> 

Re: Creating your own radio group?

Hello,

Slow to display on screen. Of course slow is relative, but what I mean
is that I can see that all changes do not happen at the same time.

I found the with-atomic-redisplay which would probably help.

But for me it does not make sense to loop through items in perhaps
over a hundred layout-descriptions just to update a few known panes.
(I am for example using simple-layouts to remove extra border pixels
from around text input panes to fit more of them nicely on screen).

Mikko

On Tue, Mar 31, 2009 at 8:37 PM, Martin Simmons <martin@lispworks.com> wrote:
>
> Hi Mikko,
>
> Do you mean that it is slow to display on the screen, slow to resize or
> something else?
>
> Regards,
>
> Martin Simmons
> LispWorks Ltd
> http://www.lispworks.com/
>
>
>>>>>> On Tue, 31 Mar 2009 04:07:29 +0300, Mikko Ahonen said:
>>
>> Hello,
>>
>> Thanks a lot for your example.
>>
>> It seems going through all panes in the interface gets quite slow when
>> the interface is deep, i.e. I have several levels of layouts inside
>> each other. In my interface your example was perceptibly slow for
>> human eye.
>>
>> Perhaps I should try to avoid deep interfaces? It is just very useful
>> way to develop things as components, which can be easily tested
>> separately and located as groups in containers.
>>
>> But your example helped me to realize that using capi:layout for what
>> I was doing was not such a good idea. I used my own class and it seems
>> to work well.
>>
>> Btw, thanks for the excellent product! I have been programming with LW
>> (and Lisp) for perhaps 8 months now, and more I get used to it, more I
>> like it. It seems that libraries are very well thought out. The
>> learning curve for Lisp beginners is quite steep, though, but well
>> worth it.
>>
>> Best regards,
>>
>> Mikko Ahonen
>>
>> On Mon, Mar 30, 2009 at 8:15 PM,  <davef@lispworks.com> wrote:
>> >
>> > Try this:
>> >
>> > ----------------------------------------------------------------------
>> > (defun button (i &optional selected)
>> >  (make-instance 'capi:radio-button :data i :text (format nil "r~D" i)
>> >                 :selected selected
>> >                 :selection-callback 'callback
>> >                 :callback-type :data-interface))
>> >
>> > (defun text (i &optional enabled)
>> >  (make-instance 'capi:text-input-pane :title (format nil "t~D" i) :enabled enabled))
>> >
>> > (capi:define-interface buttons-and-text ()
>> >  ((radio-buttons :initarg :radio-buttons)
>> >   (text-panes :initarg :text-panes))
>> >  (:layouts
>> >   (grid
>> >    capi:grid-layout
>> >    (append radio-buttons text-panes)
>> >    :columns 2
>> >    :y-gap 20
>> >    :accessor grid)))
>> >
>> > (defun callback (data interface)
>> >  (loop for pane in (capi:layout-description (grid interface))
>> >        do
>> >        (etypecase pane
>> >          (capi:radio-button
>> >           (unless (eq (capi:item-data pane) data)
>> >             (setf (capi:button-selected pane) nil)))
>> >          (capi:text-input-pane
>> >           (setf (capi:text-input-pane-enabled pane)
>> >                 (string= (capi:titled-pane-title pane) (format nil "t~D" data)))))))
>> >
>> > (let* ((r1 (button 1))
>> >       (r2 (button 2 t))
>> >       (r3 (button 3))
>> >       (r4 (button 4))
>> >       (t1 (text 1))
>> >       (t2 (text 2 t))
>> >       (t3 (text 3))
>> >       (t4 (text 4))
>> >       (grid (make-instance
>> >              'buttons-and-text
>> >              :radio-buttons (list r1 r2 r3 r4)
>> >              :text-panes (list t1 t2 t3 t4))))
>> >    (capi:display grid))
>> > ----------------------------------------------------------------------
>> >
>> > The enabled/disabled state of the text panes is the "boolean"
>> > controlled by each corresponding radio button.
>> >
>> > Hopefully this example will help you to implement the layout and
>> > interaction you actually want.
>> >
>> > --
>> > Dave Fox
>> > LispWorks Ltd
>> > St John's Innovation Centre, Cowley Road
>> > Cambridge CB4 0WS
>> > England
>> > http://www.lispworks.com/
>> >
>> > LispWorks Ltd is registered in England, company number 5114963.  The
>> > company's registered address is c/o Streets Whitmarsh Sterland LLP,
>> > 62 Hills Road, Cambridge CB2 1LA (but customers and suppliers should
>> > write to our office address above).  LispWorks Ltd is registered for
>> > VAT with EC VAT ID: GB 833329531
>> >
>> >
>> >
>> >  > Hello,
>> >  >
>> >  > I have an interface which displays several instances of one data model
>> >  > object. It is very convenient to represent this layout by extending a
>> >  > CAPI grid class, and having multiple instances of this layout. That
>> >  > works fine.
>> >  >
>> >  > Now I wanted to create radio buttons to select which of the objects is
>> >  > active, and store the active button boolean value inside each object.
>> >  > Thus, I have several boolean variables that need to be updated through
>> >  > radio buttons, and the buttons need to be logically grouped together
>> >  > like for regular radio button panel, but displayed manually.
>> >  >
>> >  > I tried but it seems that displaying buttons from CAPI radio button
>> >  > panel in separate layouts does not work. So I need my own radio group
>> >  > which can be laid out anywhere. I decided to use capi:choice as base.
>> >  >
>> >  > The solution below seems to work otherwise, but for some reason the
>> >  > old radio button does not seem to get disabled. The actual data
>> >  > boolean gets updated correctly, however. I tried this both with and
>> >  > without capi:apply-in-current-pane-process, that does not seem to
>> >  > change anything. Even stranger is that if I update the button manually
>> >  > with
>> >  >
>> >  >     (setf (capi:button-selected radio1) t)
>> >  >
>> >  > (or nil) the button image gets updated.
>> >  >
>> >  > Am I doing something wrong?
>> >  >
>> >  > I am running LW5.11 on OSX.
>> >  >
>> >  > Best regards,
>> >  >
>> >  > Mikko Ahonen
>> >  >
>> >  > --
>> >  >
>> >  > (defvar *foo* nil)
>> >  > (defvar *bar* t)
>> >  > (defvar *foobar* nil)
>> >  >
>> >  > (defmacro with-gensyms (syms &body body)
>> >  >   `(let ,(mapcar #'(lambda (s)
>> >  >                      `(,s (gensym)))
>> >  >                  syms)
>> >  >     ,@body))
>> >  >
>> >  > (defun radio-group-reset-other-buttons (group other-than-pane)
>> >  >   (loop for item across (capi:collection-items group)
>> >  >         do (unless (eq other-than-pane item)
>> >  >              (format t "unselect ~A~%" item)
>> >  >              (funcall (capi:callbacks-retract-callback item) item)
>> >  >              (setf (capi:button-selected item) nil))))
>> >  >
>> >  > (defmacro radio (name txt var group)
>> >  >   (with-gensyms (selected rb)
>> >  >     `(let ((,rb (make-instance 'capi:radio-button
>> >  >                                :selection-callback #'(lambda (pane)
>> >  >                                                        (format t "~A
>> >  > selection callback~%" pane)
>> >  >                                                        (setf ,var t)
>> >  >                                                        (setf
>> >  > (capi:choice-selected-item ,group) pane)
>> >  >
>> >  > (radio-group-reset-other-buttons ,group pane))
>> >  >                                :retract-callback #'(lambda (pane)
>> >  >                                                      (format t "~A
>> >  > retract callback~%" pane)
>> >  >                                                      (setf ,var nil))
>> >  >                                :callback-type '(:item)
>> >  >                                :text ,txt
>> >  >                                :selected ,var)))
>> >  >            (capi:append-items ,group (list ,rb))
>> >  >            (when ,var
>> >  >              (setf (capi:choice-selected-item ,group) ,rb))
>> >  >            ,rb)))
>> >  >
>> >  > (defmacro radio-group (&rest args)
>> >  >     `(make-instance 'capi:choice
>> >  >                     :interaction :single-selection
>> >  >                     :items '()
>> >  >                     ,@args))
>> >  >
>> >  > (setf g (radio-group))
>> >  >
>> >  > (setf radio1 (radio :foo "Foo" *foo* g))
>> >  >
>> >  > (setf radio2 (radio :bar "Bar" *bar* g))
>> >  >
>> >  > (setf radio3 (radio :foobar "Foobar" *foobar* g))
>> >  >
>> >  > (capi:contain (make-instance 'capi:column-layout :description (list
>> >  > radio1 radio2 radio3)))
>> >  >
>> >  > (list *foo* *bar* *foobar*)
>> >  >
>> >
>>
>
>


Updated at: 2020-12-10 08:41 UTC