Lisp HUG Maillist Archive

Chicken and egg, or am I just too dumb?

I'm trying to dynamically create an interface which will contain a
pinboard layout.  The pinboard layout in turn will consist of drawn
pinboard objects which show text snippets.  The sizes and the
locations of these objects are to be computed based on the extent of
the text snippets.  Finally, the size of the pinboard layout is
determined by its objects.  It is supposed to fit exactly, i.e. no
empty space around it, no scrolling.

Now, my problem is that in order to compute the text extents with
GP:GET-STRING-EXTENT I seemingly already need to have the interface
and it even has to be displayed.  But when the interface is already
displayed, then it's too late to compute its size as described above.

I can think of a workaround where I put some dummy with an estimated
size into the interface and then, once the interface has been created
and displayed, compute the real size constraints and replace the dummy
with the real thing.  But that doesn't seem right to me.  Is there a
better solution?

Thanks,
Edi.


Re: Chicken and egg, or am I just too dumb?

Edi Weitz <edi@agharta.de> writes:

> I can think of a workaround where I put some dummy with an estimated
> size into the interface and then, once the interface has been created
> and displayed, compute the real size constraints and replace the dummy
> with the real thing.  But that doesn't seem right to me.  Is there a
> better solution?

I haven't found any better solution, I display the interfaces with
mostly empty pinboards, and then do all the math.
-- 
  (espen)


Re: Chicken and egg, or am I just too dumb?

At 09:02 23/01/2006, Espen Vestre wrote:

>Edi Weitz <edi@agharta.de> writes:
>
> > I can think of a workaround where I put some dummy with an estimated
> > size into the interface and then, once the interface has been created
> > and displayed, compute the real size constraints and replace the dummy
> > with the real thing.  But that doesn't seem right to me.  Is there a
> > better solution?
>
>I haven't found any better solution, I display the interfaces with
>mostly empty pinboards, and then do all the math.
>--
>   (espen)


I had a similar problem with getting string extents for a layout into an 
output-pane. I am not sure the issue is with interfaces exactly - 
get-string-extent needs a 'realized' graphics-port-mixin. At least that was 
my problem. I moved the layout code into the display-callback of the 
output-pane and arranged for it to be called once only - at the first 
display. IIRC this advice came from the Lispworks team.

Anyway as pinboard-layout is a subclass of output-pane this approach might 
work for you. Change the display-callback  of the pinboard-layout to create 
the items and set the size then call capi::pinboard-pane-display.

Hopefully the code below illustrates the approach.

cheers

paulm


(in-package "CL-USER")

(capi:define-interface string-extent-test ()
   ((the-string-y :initform 0)
    (the-string :initarg :the-string)
    (the-string-pane :initform nil))
   (:panes )
   (:layouts
    (pinboard
     capi:pinboard-layout
     '()
     :display-callback 'display-string-extent-test
     :background :white
     :vertical-scroll nil
     :horizontal-scroll nil
     :visible-border nil))
   (:default-initargs
    :layout 'pinboard
    :title "string-extent-test"))

(defun display-string-extent-test (pinboard  x y width height)
   (let ((interface (capi:top-level-interface pinboard)))
     (with-slots (the-string the-string-pane the-string-y) interface
       (unless the-string-pane
         (setf the-string-pane
               (make-instance 'capi:drawn-pinboard-object
                              :display-callback 'draw-the-string)
               (capi:layout-description pinboard)
               (list the-string-pane))
         (multiple-value-bind (left top right bottom)
             (gp:get-string-extent pinboard the-string)
           (capi:set-hint-table pinboard  (list :visible-min-width (- right 
left)
                                                :visible-max-width t
                                                :visible-min-height (- 
bottom top)
                                                :visible-max-height t))
           (setf the-string-y (abs top))))
       (capi::pinboard-pane-display pinboard x y width height))))

(defun draw-the-string (pane object x y width height)
   (declare (ignore x y width height))
   (let ((interface (capi:element-interface
                     (capi:pinboard-object-pinboard object))))
     (with-slots (the-string the-string-y) interface
         (gp:draw-string pane the-string 0 the-string-y))))

(defun string-extent-test (the-string)
   (capi:display (make-instance 'string-extent-test
                                :the-string the-string)))



Re: Chicken and egg, or am I just too dumb?


On Jan 22, 2006, at 11:22 AM, Edi Weitz wrote:

> I can think of a workaround where I put some dummy with an estimated
> size into the interface and then, once the interface has been created
> and displayed, compute the real size constraints and replace the dummy
> with the real thing.  But that doesn't seem right to me.  Is there a
> better solution?

Have you tried using the interface :create-callback initarg? It is  
still basically the same solution, but at least this is the  
documented way to perform initialization after the interface is  
created but before it is displayed on the screen.

John




John DeSoi, Ph.D.
http://pgedit.com/
Power Tools for PostgreSQL


Re: Chicken and egg, or am I just too dumb?

Unable to parse email body. Email id is 5243

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