Dear GH folks, dear David,
I’ve implemented a couple of custom component attributes to have sliders, buttons and other controls on top of Grasshopper components.
With my dropdown I’m running into trouble if the profiler widget is activated and the expanded dropdown exceeds the component bounds at the bottom.
Afaik the profiler boxes are not drawn by the components but by the profiler widget. The widgets are pretty far to the end of the drawing pipeline so the profiler boxes will always be on top of the components.
I have two ideas:
Grasshopper.GUI.Widgets.GH_ProfilerWidget and redo it’s render method so it will not render the profiler box for components that have some special flag set (e.g.
false if they have a dropdown and it is expanded,
true otherwise). However, how can I tell GH to load my modified profiler widget instead of the original one?
- Expand the bounds of my component to include the expanded dropdown. This has to be done after its own
Render method was called because otherwise I’m messing up my component capsule. This feels pretty hacky but might be the way to go if the other way does not work…
Are there any other ways to tackle this problem? Which is more doable / elegant?
Thanks in advance!
Expand you “drop down” box upwards? ( “Raise up” box that is. )
Excellent idea, this really didn’t come to my mind. Thanks
However, I’d like to keep that as a last resort and see if hiding the profiler is possible…
@DavidRutten do you have any further hints on where to look / which path to go?
ProcessorTime property on your component and return a zero timespan. It’s not ideal, but if your component never takes long to complete anyway it shouldn’t mess too much with the bookkeeping.
Nice example of the Custom component.
Have you used any guide for creating it? I only recall a guide with extending of the ContextMenu of the component.
The Grasshopper SDK docs contain an example for extending the attributes of objects, although note that it is much harder to do it for aggregate objects like Components than it is for individual objects like floating parameters. Almost all custom attribute objects in Grasshopper core are individual parameters, with the only exceptions being Gradient, Legend, Data Dam, Expression, Make2D, and Galapagos.
ProcessorTime property seems to be read-only. At least that’s the error I get for
ProcessorTime = TimeSpan.Zero;
Is there a way around this? In principle I like the idea and it would be easy to implement…
I’ve based this on the instruction you can find here:
In principle all of it is in there…
Ah, now I get it, you wrote override.
In my component I’m doing this:
public override TimeSpan ProcessorTime
HideProfiler is a
bool that I set if one of the dropdowns is expanded and extends over the bounds of the component.
Thanks for the help
@PaulBomke, are you adding all elements (Buttons, Combos, Dropdowns) inside Render Sub?
Edit: Ok, yes. I found it out.
Very neat, I figured you’d always return zero, but this is a much nicer solution.
In the overridden
Render Sub I am calling
RenderIncomingWires(canvas.Painter, Owner.Sources, Owner.WireDisplay), however its says that Sources and WireDisplay are not the members of my GH component.
Others properties from below work fine.
Where can be the problem?
@Dmitriy If you only want to paint stuff on top of your component it might be much easier to expand its Bounds in your Layout override to make it a little bigger and then simply call this in your Render override:
// Draw the component. This is a convenience function that draws all of the
// specified items at once.
// Set the flags to omit drawing specific items:
// drawComponentBaseBox, drawComponentNameBox, drawJaggedEdges, drawParameterGrips, drawParameterNames, drawZuiElements
base.RenderComponentCapsule(canvas, graphics, true, false, false, true, true, true);
This will draw the larger component with all the incoming wires, name box and so on and you can then paint some custom stuff in top of it within the free space you have…
I found the problem: it was related to the inheritance of wrong type.
As for my goal - I need sometimes extend functionality of my Custom components with elements such as drop-downs, Combos, Checkboxes and others.
I as learned - all this needs to be added manually: graphics + event handling, but seems not a big issue in comparison to the additional functionality it can provide.
Hello @DavidRutten, @PaulBomke and others.
I have a small question: I am changing layout content of the custom component (adding extra button) inside
RespondToMouseDown function but seems that
Render sub is not called automatically.
Only after zooming in/out component view is updated as I need it.
How to handle it? Should I extra call
Render sub within
Thanks in advance,
I think that
GH_Component_Extended comp = Owner as GH_Component_Extended;
should do it. (
GH_Component_Extended is the name of you component class)
You can also do
I managed to get call of
I also resizing component in
Layout sub. But seems
Layout is not being called unless I drag component.
Any way to make
Layout sub called?
ExpireLayout() on the attributes. That should trigger a call to
Layout() during the next canvas paint operation.