[MonoDevelop] Larger set of stetic patches

Lluis Sanchez lluis at ximian.com
Thu Jun 29 11:57:14 EDT 2006


Ok, so right now Stetic gets the information about widgets from an
objects.xml file embedded in the library. What you are proposing is to
read that information, or at least part of it, from the widget classes
using reflection. That's an important change in the model, so it needs
some thinking.

There are at least two scenarios in which an xml description is
necessary and can't be replaced by reflection:

      * When we can't modify the widget library to add attributes.
        That's the case of gtk#.
      * When building a dll which implements both widgets and windows
        that contain instances of those widgets. The problem in this
        case is that we need to have the widget description before
        compiling, but we don't have a dll to reflect.

So we still need to support the xml model, and I'm not sure it is a good
idea to provide another model for describing widgets. In any case I
don't think that mixing both models is good. A library should describe a
widget either using xml or reflection, but not a mix of both.

> 
> These patches include: 
> 
> 1. ToolboxItem kind of specifying of widgets (but you still have to
> specify export widget in project options)
> 
> [ToolboxItem (true)]
> [Category ("widgetgroup")]
> [Description ("Description as posed as label to icon"]
> public class SomeWidget
> {
> ...
> }

If widgets still have to be specified in the export widget option panel,
what's the point of using [ToolboxItem]?

> 
> 
> 
> 2. Adding new groups to stetic from code on loading library
> (ToolboxItem(false) and abstract are conditions here). Original .Net
> does not provide groups, stetic requires them
> 
> [ToolboxItem (false), Category ("widgetgroup"), Description ("Group
> Label"]
> public abstract class SomeClass { /* dummy abstract class */ }

This is really ugly. If a widget library needs to define new categories,
it should do it in the objects.xml file.

> 
> 
> 
> 3. Correction to objects.xml for SpinButton, second itemgroup "Spin
> Button Properties" was not inheritable because it didn't provide name

Ok.

> 
> 
> 
> 4. Real loading when specifying -lib:<somelibrary>, previous code was
> missing actual loading

Ok.

> 
> 
> 
> 5. Added possibility for control to specify CreateWrappedInstance
> method, without this wrapped controls couldn't work without being
> referenced to stetic. This enables stetic to use base wrapper and use
> re
> classed widget. It basically enables for widgets to be fully
> functional
> without being referenced to stetic.

Can you give an example in which is this needed?

More comments inline...

> 
> 
> 
> m.
> 
> 
> 
> 
> 
> 
> 
> fitxer adjunt
> differences
> between files
> (toolboxitem_groups_few_errors.patch)
> 

> (snip)

> stetic.clean/libstetic/ClassDescriptor.cs
> --- stetic/libstetic/ClassDescriptor.cs 2006-06-09 22:59:49.000000000
> +0200
> +++ stetic.clean/libstetic/ClassDescriptor.cs   2006-06-24
> 20:46:00.000000000 +0200
> @@ -9,6 +9,20 @@
>         
>         public abstract class ClassDescriptor
>         {
> +               public struct ToolboxItemDefinitions
> +               {
> +                       public string Name;
> +                       public string Category;
> +                       public string Description;
> +                       
> +                       public ToolboxItemDefinitions (string aName,
> string aCategory, string aDescription)
> +                       {
> +                               Name = aName;
> +                               Category = aCategory;
> +                               Description = aDescription;
> +                       }
> +               }

Why do you need this struct? class descriptors need a name, category and
description, doesn't matter if they have been described using attributes
or xml.

> (snip)

> diff -ruN stetic/libstetic/Registry.cs
> stetic.clean/libstetic/Registry.cs
> --- stetic/libstetic/Registry.cs        2006-03-15 16:40:40.000000000
> +0100
> +++ stetic.clean/libstetic/Registry.cs  2006-06-26 04:43:16.000000000
> +0200
> @@ -1,5 +1,6 @@
>  using System;
>  using System.Collections;
> +using System.ComponentModel;
>  using System.Reflection;
>  using System.Xml;
>  using System.Xml.Xsl;
> @@ -7,15 +8,41 @@
>  namespace Stetic {
>         public static class Registry {
>  
> +               public delegate void PaletteGroupsChanged();
> +
> +               public class ControlGroup {
> +                       public string Name;
> +                       public string DisplayName;
> +                       public int Ref;
> +                       
> +                       public ControlGroup (string name, string
> displayname)
> +                       {
> +                               Name = name;
> +                               DisplayName = displayname;
> +                               Ref = 1;
> +                       }
> +               }

If the class is public, please use properties, not public fields.

> +               
> +               public static void DoRegisterWidgetLibrary
> (WidgetLibrary library, bool register)
> +               {
> +                       if (library is AssemblyWidgetLibrary) {
> +                               AssemblyWidgetLibrary asm =
> (AssemblyWidgetLibrary) library;
> +                               bool onlygroup, group = false;
> +                               bool ctrl, cat, desc = false;
> +                               string name, category, description =
> "";
> +                               foreach (System.Type type in
> asm.Asm.GetExportedTypes()) {
> +                                       Attribute[] attrs =
> Attribute.GetCustomAttributes (type);
> +                                       onlygroup = ((type.IsAbstract
> == true) || (type.IsNotPublic == true));
> +                                       
> +                                       ctrl = false; cat = false;
> desc = false; group = false;
> +                                       name = ""; category = "";
> description = "";
> +                                       foreach (Attribute attr in
> attrs) {
> +                                               if (attr is
> ToolboxItemAttribute) {
> +                                                       name =
> type.Name;
> +                                                       if
> (attr.Equals(ToolboxItemAttribute.Default) == true) {
> +                                                               ctrl =
> true;
> +                                                               if
> ((type.IsAbstract == true) || (type.IsNotPublic == true))
> +                                                                       continue;
> +                                                       }
> +                                                       else
> +                                                               //
> Group specifiying class has to be abstract
> +                                                               if
> ((attr.Equals(ToolboxItemAttribute.None) == true) && (type.IsAbstract
> == true)) {
> +                                                                       group = true;
> +                                                                       ctrl = true;
> +                                                               }
> +                                                       if ((ctrl ==
> false) && (group == false))
> +                                                               continue;
> +                                               }
> +                                               if (attr is
> CategoryAttribute) {
> +                                                       cat = true;
> +                                                       category =
> (attr as CategoryAttribute).Category;
> +                                               }
> +                                               if (attr is
> DescriptionAttribute) {
> +                                                       desc = true;
> +                                                       description =
> (attr as DescriptionAttribute).Description;
> +                                               }
> +                                       }
> +
> +                                       if (ctrl == true)
> +                                               if (group == true) {
> +                                                       if
> (description == "")
> +                                                               description = category;
> +                                                       if (register
> == true)
> +                                                               AddControlGroup (category, description);
> +                                                       else
> +                                                               RemoveControlGroup (category);
> +                                               }
> +                                               else
> +                                                       if
> (ControlGroupExists(category) == false) {
> +                                                               category = "unsorted";
> +                                                               if
> (ControlGroupExists("unsorted") == false)
> +                                                                       AddControlGroup ("unsorted", "[Unsorted]");
> +                                                       }
> +                               }
> +                       }
> +               }

All the previous method is specific to AssemblyWidgetLibrary, so it
should be moved to that class.

And please, instead of "if (group==true)..." or "if (group==false)..."
use either "if (group)..." or "if (!group)...".

Lluis.



More information about the Monodevelop-list mailing list