Hello,
I've tried to get with-output-as-gadget working but I was not successful. The problem being that I have not understood recording and several further parts of CLIM, yet. In this mail I want to present my observation about the problem, in the hope that someone with more experience and knowledge might see a solution. I would really like to have it working for a file selector that I need for several projects.
Christophe reported the problem already in July: http://common-lisp.net/pipermail/mcclim-devel/2005-July/004100.html You might want to read that mail first.
Basically the panes of the whole gadget are only adopted to the stream's sheet (stream being the stream that is given as an argument to the call of WITH-OUTPUT-AS-GADGET) when the output-record of the sheet is replayed (or what is the right term?). The adoption happens via note-output-record-got-sheet method calls that are made when output-records about "parent/child-relationships" are processed; there is specialization on (record gadget-output-record) for that method, in which the adoption takes place.
The problem is that the output methods of the clx-backend (window-clear-area (called from window-clear), medium-draw-text* (called from write-string), .. ) try to access the native-transformation (and later native-region) of the gadget's panes quite early, and that does not work if the panes are not yet adopted.
Either the adoption has to happen earlier, or the clx output method have to be delayed via output-records as well. I suspect that the clx backend needs an general overhaul to make it be (more) "output-recording aware". But perhaps a single, deliberately inserted line would work a miracle..
Consider Christophe's example:
(clim:with-output-as-gadget (*standard-output*) (clim:with-look-and-feel-realization ((clim:frame-manager clim:*application-frame*) clim:*application-frame*) (clim:labelling (:label "Hello") (clim:make-pane 'clim:text-field :activate-callback (lambda (g) (princ (clim:gadget-value g)))))))
The flow to the error NO-APPLICABLE-METHOD on sheet-native-transformation when called with an argument of NIL is:
In WITH-OUTPUT-AS-GADGET a instance of 'GADGET-OUTPUT-TYPE is created (with the evaluated body of the call as its :child argument).
There is a initialize-instance :after method for instances of this class, in which ALLOCATE-SPACE for the child (the label-pane) is called.
ALLOCATE-SPACE calls MOVE-SHEET for the first child of the label-pane (the text-field-pane).
MOVE-SHEET SETFs the SHEET-TRANSFORMATION of the text-field-pane.
There is a method (setf sheet-transformation) :after (transformation (sheet basic-sheet)). It calls (note-sheet-transformation-changed sheet), which calls UPDATE-MIRROR-GEOMETRY.
Inside UPDATE-MIRROR-GEOMETRY (sheet-native-transformation (sheet-parent sheet)) is called, but as the sheet is not adopted yet, that gives nil and sheet-native-transformation is not defined for nil.
=> NO-APPLICABLE-METHOD on sheet-native-transformation when called with an argument of NIL
It is quite the same for simpler examples where the WRITE-STRING is called with a pane of the gadget as output stream. There it is: WRITE-STRING -> %WRITE-STRING -> .. -> MEDIUM-DRAW-TEXT* -> (sheet-native-transformation (medium-sheet medium)) Inside sheet-native-transformation the same function is called again for the sheet-parent. As the sheet is not adopted yet, that gives nil and sheet-native-transformation is not defined for nil.
Naively, I tried something like:
(let ((my-stream (find-pane-named *application-frame* 'clim-listener::interactor))) (replay (STREAM-CURRENT-OUTPUT-RECORD my-stream) my-stream))
right after WITH-OUTPUT-AS-GADGET and before the WRITE-STRING, in the hope that this would force recorded adoption records to take place earlier. Is this completely wrong, should it have been replay-output-record instead? Well, it would only be an ugly workaround at it doesn't help against the problems with labelling and scrolling.
I could confirm my assumption that the delayed adoption is the problem as with neatly placed calls to SHEET-ADOPT-CHILD and SHEET-DISOWN-CHILD I got my file-selector kind of running (only the first ACCEPTING-VALUES iteration draws correctly and there is no scrolling for the embedded pane: http://bl0rg.net/~mgr/flux/file-selector-dialog.png
(In the end it should become a accept method for pathname presentations in gadget-dialog-view.)
There are additional problem when the stream for WITH-OUTPUT-AS-GADGET is an ACCEPTING-VALUES-STREAM:
When attempting to read the slot's value (slot-value), the slot CLIM-INTERNALS::HEIGHT is missing from the object #<CLIM-INTERNALS::ACCEPTING-VALUES-STREAM {92BF441}>. [Condition of type SIMPLE-ERROR]
It would be especially nice to get this running as well..
Regards, Max