Re: problem with :active slots

From: Erick Gallesio <eg_at_unice.fr>
Date: Tue, 28 Jul 1998 18:22:24 +0200 (CEST)

Andrew Dorrell writes:

> I need to be able to set the fraction slot on a <Paned> composite.
> But setting this slot doesn't update the widget - you need to call
> place-grip to do that. As the new module system hides this method
> I thought I'd try and get it going using an active slot.

That's a great idea. I should probably rewrite a lot of the composite
widget with active slots now that we have this allocation scheme..

> So I
> modified Paned.stklos:
>
>
> > (fraction :init-keyword :fraction)
>
> < (fraction :init-keyword :fraction
> < :allocation :active
> < :after-slot-set! (lambda(o v) (place-grip o)))
>
> which is similar to how the new <gauge> widget is set up. It doesn't
> work for me however:


The problem is that you need to specify that your class has a
meta-class which knows how to deal with the :active scheme allocation.
You need to use a :metaclass. The problem here (and which is different
from the Gauge widget is that you need :active slots *AND* :propagated
slots. Since such a Metaclass does not exists by itself you need to
create such a metaclass. For instance, you can define:

    (define-class <Tk-active-and-propagated-metaclass>
      (<Tk-active-metaclass> <Tk-composite-metaclass>)
      ())
        
and uses this meta-class in the HPaned> and <VPaned> classes.

THE PROBLEM IS THAT IT DOESN'T WORK.
In fact, the linearization
algorithm which is used for this meta-class provides the following
class-precedence list:

     stklos+tk> (map class-name (class-precedence-list
                                <Tk-active-and-propagated-metaclass>))
     (<tk-active-and-propagated-metaclass>
      <tk-active-metaclass>
      <tk-composite-metaclass>
      <tk-metaclass>
      <active-metaclass>
      <with-tk-virtual-slots-metaclass>
      <class>
      <composite-metaclass>
      <object>
      <top>)
      stklos+tk>

As you can see, <composite-metaclass> is after <class>. That means
that when the meta-class is initialised, the initialize method will be
for <class> will be executed before the <composite-metaclass>. So, you
will have a message which say that it doesn't know how to manage the
:propagated slots.

One way to solve this problem consists in helping the linearization
algorithm by providing it (suggesting it?) a class precedence
list. You can do:

(define-class <Tk-active-and-propagated-metaclass>
  (<Tk-active-metaclass>
   <Tk-composite-metaclass>
   <Tk-metaclass>
   <active-metaclass>
   <with-tk-virtual-slots-metaclass>
   <composite-metaclass>
   <class>)
  ())

I agree that this is not very pleasant, but this tayloring the class
precedence list is a general rule which always works.

Hopefully we can do better here, because in fact the code of STklos
is written in the idea that <class> is always initialized last (but
before <object> and <top> of course). This is obviously wrong and the
patch provided just after allows you to avoid this "gymnastic".

Hope it helps

                -- Erick



--- stklos.stk.old Sun May 31 13:11:06 1998
+++ stklos.stk Tue Jul 28 18:12:32 1998
_at_@ -16,7 +16,7 @@
 ;;;;
 ;;;; Author: Erick Gallesio [eg_at_unice.fr]
 ;;;; Creation date: 20-Feb-1994 21:09
-;;;; Last file update: 31-May-1998 13:11
+;;;; Last file update: 28-Jul-1998 10:19
 
 (when (provided? "stklos")
   (error "STklos already initialized."))
_at_@ -698,7 +698,10 @@
                   (error "You must supply a :slot-ref and a :slot-set! in ~A" s))
                (list (make-closure get env)
                      (make-closure set env))))
- (else (error "Allocation \"~S\" is unknown"(slot-definition-allocation s)))))
+ (else (next-method))))
+
+(define-method compute-get-n-set ((o <object>) s)
+ (error "Allocation \"~S\" is unknown" (slot-definition-allocation s)))
 
 ;=============================================================================
 ;
Received on Tue Jul 28 1998 - 18:42:00 CEST

This archive was generated by hypermail 2.3.0 : Mon Jul 21 2014 - 19:38:59 CEST