Lisp HUG Maillist Archive

Continuing grief with editor-pane in LWM

Hi,

I've attached a bit of code that does the following:
-- creates a new interface called 'toy' that has a list and an editor  
pane
-- the list has a call back that changes the text in the editor
-- exports a function called play:toy that runs the interface

There is a function called 'toy-redisplay' that redisplays the editor  
in its own thread using the technique from  
<http://www1.xanalys.com/support/lisp/kbase.nsf/ 
51fe6e1cdfe748a180256639005a2ba9/12e133730edbe13980256ea9004e2448? 
OpenDocument>

There is a function called 'add-text' that adds an item to the list,  
selects it and sets the editor text.

There is a function called 'play' that adds four items and displays  
everything.

When I run it (i.e. (toy:play) selecting items in the card list will  
update the text in the editor-pane. This is how I expect it to work.

HOWEVER...

If you uncomment the resize-callback for the editor, recompile and run,  
it stops working, but in a very strange way: The editor pane is not  
updated but the underlying buffer *is* updated (change tabs in the  
IDE's editor and select the toy buffer and watch it change as you click  
in the list). NOTE the resize callback has not been called, though if  
you do resize the window it will be.

Any help would be appreciated. What happens on other platforms?

Cheers,
Bob


(defpackage toy
   (:add-use-defaults t)
   (:use
    common-lisp
    capi)
   (:export
    #:play))

(in-package toy)

(defun toy-redisplay (ed)
   (format t "redisplay ~A~%" ed)
   (when ed
     (let ((window (editor-window ed)))
       (if window
           (editor:process-character `(editor:redisplay ,ed) window)
         (format t "no window for editor")))))

(define-interface toy ()
   ()
   (:panes
    (texts list-panel
           :accessor texts
           :items nil
           :visible-min-height '(character 10)
           :print-function #'(lambda (data) (string-capitalize (car  
data)))
           :selection-callback #'(lambda (data interface)
                                   (let ((ed (editor interface))
                                         (text (cadr data)))
                                         ;(modify-editor-pane-buffer ed  
:contents text)
                                     ;(setf (editor-pane-text ed) text)
                                     (setf (editor-pane-text ed) (coerce  
text 'simple-text-string))
                                     (toy-redisplay ed))))
   (editor editor-pane
            :accessor editor
            :buffer-name "the-toy-buffer"
            :font (gp:find-best-font (capi:convert-to-screen)
                                     (gp:make-font-description :family  
"Monaco"
                                                               :size 14))
            :text "Resizable"
            :visible-min-height '(:character 10)
            :visible-min-width '(:character 10)
#|
            ; if this is uncommented the toy will break
            :resize-callback #'(lambda (ed x y w h)
                                 (declare (ignore x) (ignore y) (ignore  
w) (ignore h))
                                 #+nil(let* ((fw (system::ed-font-width  
ed))
                                        (pw (system::ed-pane-width ed))
                                        (cw (truncate (/ pw fw)))
                                        (ff (- cw 2))
                                        (text (editor-pane-text ed)))
                                   (format t "#chars wide: ~A, text  
length: ~A ~%"
                                           ff (length text))))
|#
   ))
   (:layouts
    (the-layout row-layout '(texts editor)
                :reader the-layout
                :ratios '(1 4)))
   (:default-initargs
    :title "toy"
    :layout 'the-layout
    :best-width 600
    :best-height 400))

(defun add-text (name text toy)
   (format t "add-text name: ~A, text ~A ~%" name text)
   (let* ((texts-list (texts toy))
          (texts (collection-items texts-list))
          (new-index (length texts))
          (new-texts (adjust-array texts (+ 1 new-index)))
          (item (list name text))
          (ed (editor toy)))
     (setf (aref new-texts new-index) item)
     (setf (collection-items texts-list) new-texts)
     (setf (choice-selected-item texts-list) item)
     (modify-editor-pane-buffer ed :contents text)))

(defun play ()
   (let ((toy (make-instance 'toy)))
     (add-text "one" "one one one" toy)
     (add-text "two" "two two two" toy)
     (add-text "three" "three three three" toy)
     (add-text "four" "four four four" toy)
     (display toy)))


Re: Continuing grief with editor-pane in LWM

On Dec 2, 2004, at 10:43 AM, Bob Hutchison wrote:

> If you uncomment the resize-callback for the editor, recompile and 
> run, it stops working, but in a very strange way: The editor pane is 
> not updated but the underlying buffer *is* updated (change tabs in the 
> IDE's editor and select the toy buffer and watch it change as you 
> click in the list). NOTE the resize callback has not been called, 
> though if you do resize the window it will be.

It seems like a bug to me. I tried a few things and could not find a 
way to make it work. It would not even work if you use :resize-callback 
nil.

Also, it seems like a bug to me if you have to call editor:redisplay 
after using (setf editor-pane-text).

Best,

John DeSoi, Ph.D.


Re: Continuing grief with editor-pane in LWM [SOLVED]

Hi,

I reported this as a bug, and Martin Simmons of LispWorks support got  
back to me with the cause of the problem: the editor-pane has a default  
resize-callback that must be called. I tried defining an  
INITIALIZE-INSTANCE method on my interface, but this seems to be too  
early for this to work (the editor pane slot was not defined yet). As  
it happens, I use a single function to create the interface, so I added  
the following code there, and it works.


(let ((default-resize-callback (output-pane-resize-callback (editor  
window))))
       (labels ((extended-editor-resize (ed x y w h)
                  (apply default-resize-callback (list ed x y w h))
                  (let* ((fw (system::ed-font-width ed))
                         (pw (system::ed-pane-width ed))
                         (cw (truncate (/ pw fw)))
                         (ff (- cw 2))
                         #+nil(text (editor-pane-text ed)))
                    (setf (editor-pane-fixed-fill ed) ff))))
         (setf (output-pane-resize-callback (editor window))
               #'extended-editor-resize)))

So that's solved.

Now. What this bit of code does is calculate how many characters fit on  
a line in the editor and set the fixed-fill accordingly. It works. It  
does seem to me that there should be an easier way to do this though.

Cheers,
Bob


On Dec 2, 2004, at 10:43 AM, Bob Hutchison wrote:

> Hi,
>
> I've attached a bit of code that does the following:
> -- creates a new interface called 'toy' that has a list and an editor  
> pane
> -- the list has a call back that changes the text in the editor
> -- exports a function called play:toy that runs the interface
>
> There is a function called 'toy-redisplay' that redisplays the editor  
> in its own thread using the technique from  
> <http://www1.xanalys.com/support/lisp/kbase.nsf/ 
> 51fe6e1cdfe748a180256639005a2ba9/12e133730edbe13980256ea9004e2448? 
> OpenDocument>
>
> There is a function called 'add-text' that adds an item to the list,  
> selects it and sets the editor text.
>
> There is a function called 'play' that adds four items and displays  
> everything.
>
> When I run it (i.e. (toy:play) selecting items in the card list will  
> update the text in the editor-pane. This is how I expect it to work.
>
> HOWEVER...
>
> If you uncomment the resize-callback for the editor, recompile and  
> run, it stops working, but in a very strange way: The editor pane is  
> not updated but the underlying buffer *is* updated (change tabs in the  
> IDE's editor and select the toy buffer and watch it change as you  
> click in the list). NOTE the resize callback has not been called,  
> though if you do resize the window it will be.
>
> Any help would be appreciated. What happens on other platforms?
>
> Cheers,
> Bob
>
>
> (defpackage toy
>   (:add-use-defaults t)
>   (:use
>    common-lisp
>    capi)
>   (:export
>    #:play))
>
> (in-package toy)
>
> (defun toy-redisplay (ed)
>   (format t "redisplay ~A~%" ed)
>   (when ed
>     (let ((window (editor-window ed)))
>       (if window
>           (editor:process-character `(editor:redisplay ,ed) window)
>         (format t "no window for editor")))))
>
> (define-interface toy ()
>   ()
>   (:panes
>    (texts list-panel
>           :accessor texts
>           :items nil
>           :visible-min-height '(character 10)
>           :print-function #'(lambda (data) (string-capitalize (car  
> data)))
>           :selection-callback #'(lambda (data interface)
>                                   (let ((ed (editor interface))
>                                         (text (cadr data)))
>                                         ;(modify-editor-pane-buffer ed  
> :contents text)
>                                     ;(setf (editor-pane-text ed) text)
>                                     (setf (editor-pane-text ed)  
> (coerce text 'simple-text-string))
>                                     (toy-redisplay ed))))
>   (editor editor-pane
>            :accessor editor
>            :buffer-name "the-toy-buffer"
>            :font (gp:find-best-font (capi:convert-to-screen)
>                                     (gp:make-font-description :family  
> "Monaco"
>                                                               :size  
> 14))
>            :text "Resizable"
>            :visible-min-height '(:character 10)
>            :visible-min-width '(:character 10)
> #|
>            ; if this is uncommented the toy will break
>            :resize-callback #'(lambda (ed x y w h)
>                                 (declare (ignore x) (ignore y) (ignore  
> w) (ignore h))
>                                 #+nil(let* ((fw (system::ed-font-width  
> ed))
>                                        (pw (system::ed-pane-width ed))
>                                        (cw (truncate (/ pw fw)))
>                                        (ff (- cw 2))
>                                        (text (editor-pane-text ed)))
>                                   (format t "#chars wide: ~A, text  
> length: ~A ~%"
>                                           ff (length text))))
> |#
>   ))
>   (:layouts
>    (the-layout row-layout '(texts editor)
>                :reader the-layout
>                :ratios '(1 4)))
>   (:default-initargs
>    :title "toy"
>    :layout 'the-layout
>    :best-width 600
>    :best-height 400))
>
> (defun add-text (name text toy)
>   (format t "add-text name: ~A, text ~A ~%" name text)
>   (let* ((texts-list (texts toy))
>          (texts (collection-items texts-list))
>          (new-index (length texts))
>          (new-texts (adjust-array texts (+ 1 new-index)))
>          (item (list name text))
>          (ed (editor toy)))
>     (setf (aref new-texts new-index) item)
>     (setf (collection-items texts-list) new-texts)
>     (setf (choice-selected-item texts-list) item)
>     (modify-editor-pane-buffer ed :contents text)))
>
> (defun play ()
>   (let ((toy (make-instance 'toy)))
>     (add-text "one" "one one one" toy)
>     (add-text "two" "two two two" toy)
>     (add-text "three" "three three three" toy)
>     (add-text "four" "four four four" toy)
>     (display toy)))
>
>
----
Bob Hutchison          -- blogs at <http://www.recursive.ca/hutch/>
Recursive Design Inc.  -- <http://www.recursive.ca/>


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