Another minor update, which I’m mostly using to publish a useful patch. I’ve forgotten to mention that I’ve already created a custom settings page for my Visual TorqueScript projects. Yesterday night (before going to bed) I decided to add a configuration dependent page, too. As you’ll see it’s very Torsion-esque, which is intentional and I plan to support .torsion files directly (as project files) later-on.

The main reason is that Torsion rocks and there is no reason to have yet another project file format for TorqueScript projects.

I hope that it will also be an incentive for people to give my plugin a try (if I ever release it).

A few notes (programatically so to speak :D):

  • Again the managed project framework is awesome and once you figure out where to look for things you’ll certainly find eternal bliss, too..

  • I generally derive from SettingsPage directly, because I don’t want any of the regular faff in my project.

  • Don’t forget to publish your pages via ProvideObject(or ProvideClass from my previous post)

  • You don’t need to create your own GUIDs for everything. Classses are automatically provided with a unique GUID - try it and access typeof(SomeClassWithoutGuidAttribute).GUID and it’ll still work.

    (If I said something wrong, please correct me..)

  • SettingsPage has an IsDirty property which you have to set, when a property is changed (to update the Apply button state). It results in pretty ugly copy’n’paste code, because you can’t use default property accessors anymore. To fix this I spent an hour or two and I’ve come up with an elegant (in my opinion) patch to fix the issue:

    Index: ProjectBase/SettingsPage.cs
    ===================================================================
    --- ProjectBase/SettingsPage.cs (revision 10)
    +++ ProjectBase/SettingsPage.cs (working copy)
    @@ -27,7 +27,26 @@
    
     namespace Microsoft.VisualStudio.Package
     {
    +    // Added to make it easier to edit pages [9/10/2008 Andreas]
    
    +    class SettingsPagePropertyDescriptor : DesignPropertyDescriptor
    +    {
    +        public SettingsPagePropertyDescriptor(PropertyDescriptor prop)
    +            : base(prop)
    +        {
    +        }
    +
    +        public override void SetValue(object component, object value)
    +        {
    +            if (component is SettingsPage)
    +            {
    +                SettingsPage page = (SettingsPage)component;
    +                page.IsDirty = true;
    +            }
    +            base.SetValue(component, value);
    +        }
    +    }
    +
         /// <summary>
         /// The base class for property pages.
         /// </summary>
    @@ -78,7 +97,7 @@
                 get { return this.grid; }
             }
    
    -        protected bool IsDirty
    +        protected internal bool IsDirty
             {
                 get
                 {
    @@ -203,6 +222,13 @@
    
             #endregion
    
    +        #region overriden methods.
    +        public override DesignPropertyDescriptor CreateDesignPropertyDescriptor(PropertyDescriptor propertyDescriptor)
    +        {
    +            return new SettingsPagePropertyDescriptor(propertyDescriptor);
    +        }
    +        #endregion
    +
             #region IPropertyPage methods.
             public virtual void Activate(IntPtr parent, RECT[] pRect, int bModal)
             {
    @@ -410,6 +436,8 @@
                     try
                     {
                         Marshal.WriteIntPtr(ppUnk, p);
    +                    // Reset IsDirty before rebinding all properties [9/10/2008 Andreas]
    +                    IsDirty = false;
                         this.BindProperties();
                         // BUGBUG -- this is really bad casting a pointer to "int"...
                         this.grid.SetSelectedObjects(1, ppUnk.ToInt32());

It also contains a one-line fix to reset IsDirty when reloading the page or switching configurations (ie. any time the properties are reset to their old value).

Cheers,
Black