[kepler-dev] Kepler specific Director and ComponentEntity classes and _addIcon()

Matthew Brooke brooke at nceas.ucsb.edu
Tue Apr 18 21:17:10 PDT 2006


Christopher:

Given the non-trivial issues and potential changes involved, and given 
the imminent deadlines for Kepler Beta 1 and 1.0 releases, I'm soundly 
of the opinion that we should probably not make any attempt to actually 
do any of this until after 1.0; what do you think?


 > it seems like we don't really need a Kepler specific EditorIcon
 > since
 >   ComponentEntityConfig.addSVGIconTo(context);
 > basically adds attributes to the NamedObj context (I think).

Yes - that's exactly right - it just adds 2 attributes.


 > I suspect this might just work, though there is a custom
 > version of XMLIcon to deal with which could cause problems.

It would probably be useful for us to talk in more depth about what's 
going on (are you going to the SEEK all-hands meeting in Albuquerque in 
a couple of weeks' time?). In particular, I think I should maybe explain 
XMLIcon in more detail, since this is pretty key to the whole 
proceedings for Kepler. It strives for backward compatibility by still 
being ptii/diva friendly, while also dealing with SVG icons using Batik, 
where necessary.

If I understand you correctly, you guys are saying we should use the 
*Icon.xml system - is that right? If so, I don't think that's going to 
work for Kepler; basically, we have about 130 (and counting) icons 
already defined as standard SVG files - do you mean we'd need to write a 
*Icon.xml file (which is not SVG, but is ptii-specific) for each one? 
I'm not entirely sure I'm understanding you correctly, so let me know if 
I'm on the wrong track...
(keeping up the "train wreck" theme ;-)

Yours befuddledly

m



---------------------------------------------
Matthew Brooke, Ph.D.
Marine Sciences Research Building, Room #3407
University of California
Santa Barbara, CA  93106-6150
ph: (805) 893-7108   fx: 805-893-8062
brooke at nceas.ucsb.edu
---------------------------------------------

Christopher Brooks wrote:
> Edward writes:
> 
>> A simple workaround that would not require having the icon
>> information in each model's moml file would be to create
>> a moml class somewhere, and instantiate that in the library.
> 
> I'm not sure I understand what you mean here.
> What would the MoML class look like?
> 
>> A better alternative would be to make the current icon
>> mechanism smarter.  Currently, vergil looks for a particular
>> file named FooIcon.xml in the same directory as actor and/or
>> director, and if it finds it, uses that to define the icon.
>> We could make where to look for this icon something controlled
>> by the configuration. Then kepler could simply put its
>> icon definitions, each of which instantiates a subclass
>> of EditorIcon, in some other directory tree.  Your subclass
>> of EditorIcon could look wherever you want for the icon
>> definition, including in a centralized system.
> 
> Below is my random train (wreck) of thoughts.
> 
> It looks like this private method in MoMLParser is what looks
> for the FooIcon.xml:
> 
>     /** Look for a MoML file associated with the specified class
>      *  name, and if it exists, parse it in the context of the
>      *  specified instance. The file name is constructed from
>      *  the class name by replacing periods with file separators
>      *  ("/") and appending "Icon.xml".  So, for example, for
>      *  the class name "ptolemy.actor.lib.Ramp", if there is a
>      *  file "ptolemy/actor/lib/RampIcon.xml" in the classpath
>      *  then that file be read.
>      *  @param className The class name.
>      *  @param context The context into which to load the file.
>      *  @return True if a file was found.
>      *  @exception Exception If the file exists but cannot be read
>      *   for some reason.
>      */
>     private boolean _loadIconForClass(String className, NamedObj context)
>             throws Exception {
>         String fileName = className.replace('.', '/') + "Icon.xml";
>         return _loadFileInContext(fileName, context);
>     }
> 
> For example, BooleanSwitchIcon.xml contains:
> <property name="BooleanSwitchIcon" class="ptolemy.vergil.icon.EditorIcon">
>     <property name="rectangle" class="ptolemy.vergil.kernel.attributes.RectangleAttribute">
> ...
> So when we call _loadIconForClass(), we create an EditorIcon
> named BooleanSwitchIcon. 
> 
> There are lots of places where we iterate over EditorIcon, but
> it seems like we don't really need a Kepler specific EditorIcon
> since
>   ComponentEntityConfig.addSVGIconTo(context);
> basically adds attributes to the NamedObj context (I think).
> I suspect this might just work, though there is a custom
> version of XMLIcon to deal with which could cause problems.
> 
> Unfortunately, MoMLParser does not know about the configuration, so we
> would have to add something here to MoMLParser so that we can tell
> MoMLParser to invoke our Kepler specific loader.  We could use my
> Iconable interface which would have a method that loads the icon.  We
> would then call MoMLParser.setIconable() which would refer to our
> loader.
> 
> I'll see what I can do about this.
> 
>> This would deal with the legacy model problem and the problem
>> of bloating the moml files.
> 
> Seems doable!
> 
> _Christopher
> 
>> Edward
>>
>> At 09:47 AM 4/18/2006, Matthew Brooke wrote:
>>
>>> Hi Christopher/Edward -
>>>
>>> A couple of thoughts and some additional info:
>>>
>>>
>>>
>>>> Also, this means that every Director and ComponentEntity would
>>>> have to have a BatikEditorIcon attribute in the MoML file.
>>> We are specifically trying not to include icon descriptions or 
>>> assignments in the MOML files (or in *Icon.xml files, or hard-coded 
>>> in java), since it presents a maintenance problem for us (if/when 
>>> icon assignments change, older models will still show the old 
>>> assignments). This obviously becomes a larger and larger problem as 
>>> models proliferate.
>>>
>>> We therefore have all our icon assignments in 2 text files - one has 
>>> icons assigned by classname, and the other assigned by LSID. When 
>>> Director or ComponentEntity make the call to:
>>>
>>>  ComponentEntityConfig.addSVGIconTo(this);
>>>
>>> the method does a lookup to try to match the specific subclass (ie 
>>> the actor or director) by LSID, and then by classname. It then sets 
>>> a ConfigurableAttribute (called "_svgIcon") on the actor/director, 
>>> which is subsequently used by the Batik rendering system. (We don't 
>>> change the existing "_iconDescription" attributes, so these are 
>>> still present as a"fallback" in case anything goes wrong with the assignments.
>>     )
>>> Having this centralized system is important to us, because it 
>>> provides a level of decoupling between the models and their visual 
>>> representations - we can make changes to icon assignments, and even 
>>> completely change out *all* the icons at once if needed, and thus 
>>> "re-skin" workflows entirely.
>>>
>>>
>>>> 4) My previous idea, where we have some code that sets the Iconable
>>>> class that gets called.  This results in one method being
>>>> added to Directory and ComponentEntity.
>>> Cool idea, but we'd still need to introduce an "Iconable" interface 
>>> into ptii (maybe I'm just missing the point ;-).  To be completely 
>>> Kepler agnostic, we'd have to use your reflection solution, I think?
>>>
>>>
>>> Just some extra stuff to add to the mix...
>>>
>>> m
>>>
>>>
>>>
>>> ---------------------------------------------
>>> Matthew Brooke, Ph.D.
>>> Marine Sciences Research Building, Room #3407
>>> University of California
>>> Santa Barbara, CA  93106-6150
>>> ph: (805) 893-7108   fx: 805-893-8062
>>> brooke at nceas.ucsb.edu
>>> ---------------------------------------------
>>>
>>>
>>> Christopher Brooks wrote:
>>>> Interesting idea.  We could create a subclass of EditorIcon called
>>>> BatikEditorIcon that would do this.
>>>> However, how would we handle changing the icons of preexisting models?
>>>> I suppose we could use the MoMLFilter.  This would slow down the Kepler
>>>> a little, but would not be noticable.
>>>> Also, this means that every Director and ComponentEntity would have to
>>>> have a BatikEditorIcon attribute in the MoML file. This will increase
>>>> model file size a certain amount, say 10%?
>>>> Besides my proposal below, an alternative that is more in keeping with
>>>> _iconDescription would be to either modify _iconDescription so it
>>>> calls the addSVGIcon method or add a static text valued attribute that
>>>> named the class that was to be called.  I think this would be
>>>> definitely pollute Director and ComponentEntity with more UI code, but
>>>> it would also be more lightweight (smaller MoML files).
>>>> We really need to do something, having separate copies of these files
>>>> is not maintainable.  I keep fixing problems in Ptolemy and then
>>>> I or someone else has to update the copies in Kepler.
>>>> To recap, I see several solutions
>>>> 1) Do nothing - we keep updating these files by hand
>>>> This is not maintainable.
>>>> 2) Hack in Kepler specific code that calls ComponentEntityConfig
>>>> I have this implemented in my tree, there is a static initializer
>>>> that uses reflection to see if ComponentEntityConfig exists and if 
>>>> it does then each _addIcon() method calls
>>>> ComponentEntityConfig.addSVGIconTo(this);
>>>> The problem here is that it is somewhat hardwired and ugly.
>>>> 3) My new idea, which would be to somehow modify _iconDescription so
>>>> that we can invoke a method that creates the icon.  We could either
>>>> have another attribute, say _iconFactory or we could add a field It
>>>> would be nice to be able to change the icon once for all Directors and
>>>> once for all ComponentEntities, so I'd like to create a static method
>>>> that allows the user to override what text _addIcon attaches.  Perhaps
>>>> we could attach the BatikEditorIcon here?  Or, _iconDescription could
>>>> take a class name and method name to be invoked somehow.  This has the
>>>> advantage of being done once each for Director and ComponentEntity.
>>>> 4) My previous idea, where we have some code that sets the Iconable
>>>> class that gets called.  This results in one method being
>>>> added to Directory and ComponentEntity.
>>>> 5) Your idea of using EditorIcon here.
>>>> This would bulk up the Kepler models a little, say 10%?
>>>> Also, current models would need a filter.
>>>> I'm still feeling that I'd prefer to see #4, adding setIcon().
>>>> What do you think?  I agree that #4 is not perfect but it seems like
>>>> less work and not much uglification of the UI.  At least I'm staying
>>>> out of NamedObj :-)
>>>> My goal here is to help the Kepler folks with some UI problems.  In my
>>>> mind, it should not be necessary to override Ptolemy classes, it 
>>>> should be possible to extend classes or use attributes like
>>>> EditorIcon.
>>>> A good example of this is that for the DBConnectionToken class it was
>>>> not necessary to override ptolemy.data.type.BaseType, instead I 
>>>> used an inner class like what we do for
>>>> ptolemy.actor.lib.security.KeyToken.
>>>> If a Ptolemy class is being overridden with a copy of a class, it is
>>>> either a bug in Ptolemy or a bug in Kepler and it should be fixed
>>>> so as to avoid problems.
>>>> _Christopher
>>>> --------
>>>>
>>>>     There is no need to modify any Java class to change the icon...
>>>>     Any attribute (including directors) that contains an instance of
>>>>     EditorIcon or any subclass of EditorIcon will defer to that class
>>>>     to render the icon.
>>>>
>>>>     So why can't the Kepler configuration just include such an
>>>>     attribute in every director in the director library?
>>>>
>>>>     We have tried to keep the support in the kernel for visual rendering
>>>>     to an absolute minimum... At most some text-valued attributes,
>>>>     like _iconDescription. In retrospect, even this was probably a
>>>>     mistake.  Icons should be controlled by attributes contained
>>>>     by the object being represented by the icon.
>>>>
>>>>     Edward
>>>>
>>>>
>>>>     At 09:21 PM 4/17/2006, Christopher Brooks wrote:
>>>>     >Hi Edward,
>>>>     >
>>>>     >I'm looking at folding in the Kepler copies of Director
>>>>     >and ComponentEntity.  The reason to fold these in is
>>>>     >to avoid code duplication and reduce maintenance.
>>>>     >
>>>>     >Both of these classes have _addIcon methods like:
>>>>     >
>>>>     >     private void _addIcon() {
>>>>     >
>>>>     >       //simple Icon:
>>>>     >       _attachText("_iconDescription", "<svg>\n"
>>>>     >                   + "<rect x=\"-30\" y=\"-20\" width=\"60\" "
>>>>     >                   + "height=\"40\" style=\"fill:white\"/>\n"
>>>>     >                   + "<polygon points=\"-20,-10 20,0 -20,10\" "
>>>>     >                   + "style=\"fill:blue\"/>\n" + "</svg>\n");
>>>>     >
>>>>     >       try {
>>>>     >         ComponentEntityConfig.addSVGIconTo(this);
>>>>     >       } catch (Exception ex) {
>>>>     >         //ignore exceptions - they just mean that the
>>>>     >         //default icon will be used, as defined above
>>>>     >       }
>>>>     >     }
>>>>     >
>>>>     >In this case,
>>>>     >         ComponentEntityConfig.addSVGIconTo(this);
>>>>     >is a Kepler static method that takes a NamedObj as an argument
>>>>     >and adds an SVG icon.  So, we need some way for Kepler
>>>>     >to override the icons without subclassing Director.  We
>>>>     >can't subclass Director here because SDFDirector etc all
>>>>     >extend Director and they would not extend our new class that
>>>>     >had the custom Kepler icons.
>>>>     >
>>>>     >I could hack some Kepler specific hack that used reflection to look
>>>>     >for a specific class that added the icon, but I think it would be
>>>>     >better to add methods that named a class that on which we invoked a
>>>>     >method that would add the Icon.
>>>>     >
>>>>     >Unfortunately, it looks like this would go in NamedObj and thus would
>>>>     >be present for all NamedObjs.  I think it would be better for Director
>>>>     >and ComponentEntity to have a setter that sets a class on which we can
>>>>     >call an addIcon().  Yes, this is a little bit of code duplication, but
>>>>     >it is not horrible.  Perhaps we could have Director and
>>>>     >ComponentEntity implement a IconableFactory(?) interface that just has
>>>>     >the setIconable method.
>>>>     >
>>>>     >
>>>>     >Director and ComponentEntity would both get
>>>>     >     setIconable(Iconable iconable) {
>>>>     >         _iconable = iconable
>>>>     >     }
>>>>     >     private static Iconable _iconable;
>>>>     >
>>>>     >     private void _addIcon() {
>>>>     >         _attachText("...");
>>>>     >         if (_iconable != null) {
>>>>     >             try {
>>>>     >                 _iconable.addIcon(this)
>>>>     >             } catch (Exception ex) {
>>>>     >                 //ignore exceptions - they just mean that the
>>>>     >                 //default icon will be used, as defined above
>>>>     >             }
>>>>     >     }
>>>>     >
>>>>     >ComponentEntityConfig would implement Iconable and have
>>>>     >     public static addIcon(NamedObj) {
>>>>     >         ....
>>>>     >     }
>>>>     >The KeplerInitiailizer would call setIconable() for
>>>>     >Director and ComponentEntity and set it to ComponentEntityConfig.
>>>>     >
>>>>     >Whattya think?  Do you have any ideas?
>>>>     >
>>>>     >Director and ComponentEntity should not really have icon specific code
>>>>     >in them, but they already have _attachText() calls.
>>>>     >
>>>>     >_Christopher
>>>>
>>>>     ------------
>>>>     Edward A. Lee
>>>>     Professor, Chair of the EE Division, Associate Chair of EECS
>>>>     231 Cory Hall, UC Berkeley, Berkeley, CA 94720-1770
>>>>     phone: 510-642-0253 or 510-642-0455, fax: 510-642-2845
>>>>     eal at eecs.Berkeley.EDU, http://ptolemy.eecs.berkeley.edu/~eal
>>>> --------
>>>> _______________________________________________
>>>> Kepler-dev mailing list
>>>> Kepler-dev at ecoinformatics.org
>>>> http://mercury.nceas.ucsb.edu/ecoinformatics/mailman/listinfo/kepler-dev
>>> ------------
>>> Edward A. Lee
>>> Professor, Chair of the EE Division, Associate Chair of EECS
>>> 231 Cory Hall, UC Berkeley, Berkeley, CA 94720-1770
>>> phone: 510-642-0253 or 510-642-0455, fax: 510-642-2845
>>> eal at eecs.Berkeley.EDU, http://ptolemy.eecs.berkeley.edu/~eal
> _______________________________________________
> Kepler-dev mailing list
> Kepler-dev at ecoinformatics.org
> http://mercury.nceas.ucsb.edu/ecoinformatics/mailman/listinfo/kepler-dev


More information about the Kepler-dev mailing list