Grasshopper

algorithmic modeling for Rhino

I'm interested in creating a resizable component, and deriving my own attributes class from GH_ResizableAttributes seems like the best solution. However, I can't seem to get it to include input and output parameters.

 

Besides adding resizing functionality, I'm interested in changing the default color. I've done this for other components by deriving from GH_ComponentAttributes, and creating a capsule of the appropriate shade, then calling base.RenderComponentCapsule(canvas, graphics, false, true, true, true, true, true). I'd also like to draw vector shapes, and I'm assuming I would just call 'graphics.DrawXYZ' during the appropriate channel.

Below is the current Render method in my GH_ResizableAttributes<GH_Component> class. It will draw a component, with grip circles, but the parameters aren't included with my component, so no wires can be attached.

What am I missing in my derived class?

protected override void Render(GH_Canvas canvas, System.Drawing.Graphics graphics, GH_CanvasChannel channel)
{
    if (channel == GH_CanvasChannel.Objects)
    {
        GH_Palette palette = GH_Palette.Normal;

        // Adjust palette based on the Owner's worst case messaging level.
        switch (Owner.RuntimeMessageLevel)
        {
            case GH_RuntimeMessageLevel.Warning:
               palette = GH_Palette.Warning;
               break;

            case GH_RuntimeMessageLevel.Error:
               palette = GH_Palette.Error;
               break;
         }

         RectangleF capsuleBox =
            new RectangleF(this.Bounds.Location, this.Bounds.Size);
         GH_Capsule capsule = GH_Capsule.CreateCapsule(capsuleBox, palette);
         float inputGripSeparation = this.Bounds.Height / Owner.Params.Input.Count;
         float outputGripSeparation = this.Bounds.Height / Owner.Params.Output.Count;

         float inputOffset = inputGripSeparation / 2;
         float outputOffset = outputGripSeparation / 2;

         for (int i = 0; i < Owner.Params.Input.Count; ++i)
         {

            float y = i * inputGripSeparation + inputOffset;
            capsule.AddInputGrip(this.Bounds.Y + y);
         }
         for (int i = 0; i < Owner.Params.Output.Count; ++i)
         {

            float y = i * outputGripSeparation + outputOffset;
            capsule.AddOutputGrip(this.Bounds.Y + y);
         }

         if (Owner.RuntimeMessageLevel == GH_RuntimeMessageLevel.Error ||
             Owner.RuntimeMessageLevel == GH_RuntimeMessageLevel.Warning)
         {
            capsule.Render(graphics, this.Selected, Owner.Locked, true);
         }
         else
         {

            capsule.Render(graphics, Color.FromArgb(188, 157, 202));
         }

         capsule.Dispose();
         base.Render(canvas, graphics, channel);
     }
     else
     {

         base.Render(canvas, graphics, channel);
     }
}

Views: 1309

Replies to This Discussion

So the issue doesn't appear to be rendering. It just seems that input/output parameters aren't inherently included with the GH_ResizableAttributes<GH_Component> derived class. I think the component I'm trying to create is most similar to the "Legend" component (Params>Utils). It's not clear to me that the available virtual/abstract members in GH_ResizableAttributes solve my issue.

Hi Stephen,

making your own component attributes is no walk in the park. When you create the attributes capsule you'll have to add all the grips for all the parameters so they show up. You'll also have to layout all the input and output parameters inside the component Layout method. 

There are utility functions for this in GH_ComponentAttributes. The thing to decide is whether you should derive from GH_ComponentAttributes and add logic for resizing or derive for GH_ResizableAttributes and add logic for components. I'm afraid either will be a lot of finicky work.

If you want you can have a look at the Gradient object code using a disassembler (I hereby officially grant you permission to disassemble the Grasshopper.Kernel.Special.GH_GradientControlAttributes class to see how it works. It derives from resizable attributes and adds all the required logic to make it work for components.

--

David Rutten

david@mcneel.com

Tirol, Austria

Thanks for the tips. It certainly does look tricky but I have been able to make some good progress.

Hello Stephen and David,

i have the same problem, i try to render a GH_Component that carries my custom i/o parameters which have custom attributes.

My custom prm attributes work as they should work when i use my param individually but...

I would like if possible to change the place where my custom prms attributes are drawn by my Component "or" at least change the location of my prms i/oGrips and draw the rest of my params graphics inside my Component Attrs render function.

Is that possible?

I already managed to place my params where i would like them to appear (I override my Comp Layout() func and pass it's pivot to create new atts for my params whenever my comp layouts) but although i can draw incoming wires, these cant be attached to my params input grips.

Thanks.

EDIT.. overriding AppendToAttributeTree(List/font>IGH_Attributes> attributes) solved it.

 

 

RSS

About

Translate

Search

Videos

  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service