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*)
>> > >
>> >
>>
>
>