Grasshopper

algorithmic modeling for Rhino

Dear all, dear David,

I would like to know if it is currently possible/if any of you managed to add custom settings menus to the interface like this: 

or in the preferences panel...

This could be extremely useful to manage global settings that affect several custom components (ex: tolerance), but I did not managed to get it working... so any idea is welcome!

Thank you,

T.

Views: 965

Replies to This Discussion

Yes. It is fairly easy to add sections to the Preference window, it was designed to be extendable. Adding items into the Grasshopper main window menu is also possible but requires a bit more hacky code. For one you'll have to wait with adding those items until the window actually exists, which is not the case yet during GHA loading. Also the MainMenu control has Friend (internal in C#) access which means you have to access it via reflection, you cannot simply call methods and properties on it. This is something I can make a proper SDK for in the future if needed.

To add a custom section to the Preferences window, do the following:

  • Create a public class with an empty constructor which implements the IGH_SettingFrontend interface. The Category and Name properties are important, Keywords are not (yet) used. You must also return a valid winforms control via the SettingsUI() method. This is the control that will end up in the Preferences window. This control must handle all events to keep itself up to date.
  • If you also want to add your own settings category, create a public class with an empty constructor which implements IGH_SettingsCategory (or which derives from the abstract GH_SettingsCategory class).

That's all there's to it.

What sort of items are you planning to add to the menu?

--

David Rutten

david@mcneel.com

Poprad, Slovakia

Thank you David, I will try to test it this evening then.

Some documentation in the SDK on this part (well, globally on all the GUI aspects in fact) will always be very good I think, since it's not super easy to get through those things at the moment (but there is a few tips here and there on the forum topics of course).

I am planning to add different items to manage a few global variables in HAL (ex: number of digits to be considered for the post-processing depending on the controller types, the display size and colors of several elements a bit like plane and point objects, size of typo, more intuitive license management, etc.). So in other words, plenty of little details that would be much easier to manage in the preferences window with a new category for the plugin instead of having options in right click menus everywhere.

I will update the topic when I will have checked the method you are mentioning above.

Thank you again!

T.

Yep, sounds like the Preferences are the right spot for that. IGH_SettingsCategory and IGH_SettingsFrontEnd have xml comments of course and there really isn't much to tell other than; "implement this interface and you're done". Please post a screenshot of your settings when it works, I'd love to see it.

--

David Rutten

david@mcneel.com

Poprad, Slovakia

OK, no problem, but it wll maybe take some time, plenty of things to learn, I never worked with this kind of things before :).

Anyway, I did what you said and it worked (I have my new category with a test control).

If I understand correctly, now if I want to add several controls in the same window I have to create one big custom UserControl embedding all those things so that I end up with only one UserControl to return in SettingsUI() (seems not possible to return a list, is it?).

By the way, if I want the settings to be saved when I close the document, is there something special I need to do (equivalent to overriding the read and write functions in the components), or is it stored automaticaly already?

If you want multiple settings you can either put them all on a single control, or you can create multiple controls. The sort order of controls is alphabetical though, so if you want to have a specific order, put them on a single System.Windows.Forms.Panel or System.Windows.Forms.UserControl or something.

All the current settings are changed (and updated) in realtime. They are not saved when the Preferences window closes. Whenever someone changes a setting, make sure it takes immediate effect.

Also note that there no custom settings on a GH_Document. You can add your own settings to the Instances.Settings type (several data primitive data types are supported and I take care of all the saving/loading).

Alternatively you can have settings in your own GHA library and do the saving/loading yourself. A middle ground would be to use the Kernel.GH_SettingsServer type to create a custom xml file which is stored in the GH settings folder but you won't have to share it with anyone else.

As an example, take a look at the following code which is the code inside the control that exposes the Align Widget Visibility setting:

Public Class GH_AlignWidgetFrontEnd

  Private Sub GH_AlignWidgetFrontEnd_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load

    AlignVisibleChanged()
    AddHandler GH_AlignWidget.WidgetVisibleChanged,  AddressOf AlignVisibleChanged
  End Sub
  Private Sub GH_AlignWidgetFrontEnd_HandleDestroyed(ByVal sender As Object, ByVal e As EventArgs) Handles Me.HandleDestroyed
    RemoveHandler GH_AlignWidget.WidgetVisibleChanged, AddressOf AlignVisibleChanged
  End Sub

  Private Sub AlignVisibleChanged()
    checkShow.Checked = GH_AlignWidget.SharedVisible
  End Sub

  Private Sub checkShow_CheckedChanged(ByVal sender As Object, ByVal e As EventArgs) Handles checkShow.CheckedChanged
    GH_AlignWidget.SharedVisible = checkShow.Checked
    Instances.RedrawCanvas()
  End Sub
End Class

You'll notice that there is a central property that is used to get or set the visibility of the Align Widget. This property is called GH_AlignWidget.SharedVisible. Furthermore this property raises an event whenever it changes called GH_AlignWidget.WidgetVisibleChanged. Bottlenecking this kind of stuff is important.

Then there's an event handler which responds to the actual winforms checkbox being toggled and another event handler which responds to the shared event being triggered. This way the UI is kept in sync. The event handler for the shared event is registered in the Load event and unregistered in the HandleDestroyed event.

I'm afraid it's not as simple as adding a few checkboxes to a control, you really are in charge of making sure everything is up-to-date and properly registered/unregistered when the time comes.

--

David Rutten

david@mcneel.com

Poprad, Slovakia

Thank you for all these details and the example David,

It seems that the logic of the syncing is quite similar to what I have done in the OSC interface I wrote for the plugin, so at least I will not have to start from 0 on this point. I will take a look at the SettingsServer, it seems to be what I need.

Thank you again!

T.

RSS

About

Translate

Search

Photos

  • Add Photos
  • View All

Videos

  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service