Grasshopper

algorithmic modeling for Rhino

Hi David, others,

 

Is there an event that is typically raised when a user toggles the preview of a component? I'm drawing some things on the viewport only as tags using Rhino.Display.CustomDisplay but I don't need that stuff to be coming out through one of the output parameters -- just like what you do with the pointList or textTag components.

 

I wanted to use this event to Enable/Dispose my CustomDisplay. I was looking at OnAttributesChanged, but couldn't make much sense of it.

 

Many Thanks,

 

Suryansh.

Views: 769

Replies to This Discussion

Hi Suryansh,

 

the Hidden property of a GH_Component will tell you whether you should draw stuff or not. The ObjectChanged event will be raised whenever the Hidden state is modified. The type of ObjectChange event will be GH_ObjectEventType.Preview

 

--

David Rutten

david@mcneel.com

Poprad, Slovakia

Hi David,

 

Thanks for the prompt reply. I've tried to implement this, but I'm a bit confused. Here's what I came up with:

 

Protected Overrides Sub SolveInstance(ByVal DA As Grasshopper.Kernel.IGH_DataAccess)       

draw = Me.Hidden

AddHandler Me.ObjectChanged, AddressOf stuffChanged
DA.SetData(0, draw.ToString)

DA.SetData(1, New Point3d(0, 0, 0))

End Sub

 

Private Shared draw As Boolean

 

Private Sub stuffChanged(ByVal sender As IGH_DocumentObject, ByVal e As GH_ObjectChangedEventArgs)

RemoveHandler Me.ObjectChanged, AddressOf stuffChanged

If e.Type = GH_ObjectEventType.Preview Then draw = Not draw

End Sub

 

Obviously this ain't working. What I'm confused about is that GH_ObjectChangedEventArgs contains a whole range of ObjectChanged scenarios, not just the Preview toggle. So if I need something to react only to Preview being toggled, I came up with the condition

 

If e.Type = GH_ObjectEventType.Preview Then

 

which is something I've never seen anywhere else, so I guessed that's where the problem was. I tried another version where the stuffChanged sub only removed the handler and flipped the boolean, no conditional statements, but that ain't working either.

 

What do you think I'm doing wrong?

Thanks a bunch!

 

Suryansh.

Hi Suryansh,

 

The basic problem you have is that you need to synch your CustomDisplay object with your component. It doesn't matter how often you synch it, you just need to make sure it happens when the Hidden flag changes.

 

Let's assume your CustomDisplay is a private member of your GH_Component class:

 

Private m_display As CustomDisplay

 

then you'll need a function that synchs it:

 

Private Sub SynchDisplay()

  If (m_display IsNot Nothing) Then m_display.Enabled = Not Me.Hidden

End Sub

 

Next up you'll need an event handler for ObjectChanged:

 

Private Sub LocalObjectChanged( _

    ByVal sender As Object, _

    ByVal e As GH_ObjectChangedEventArgs)

  If (e.Type = GH_ObjectEventType.Preview) Then

    SynchDisplay()

  End If

End Sub

 

You'll also need to attach this handler to the event. Best place would be in the component constructor:

 

Public Sub New()
  MyBase.New("Blah", "Blah", "Yadayadayada", "Tab", "Panel")

  AddHandler Me.ObjectChanged, AddressOf LocalObjectChanged
End Sub

 

Inside your SolveInstance method you'll need to create a new CustomDisplay class every time and then synch it:

 

Protected Overrides Sub SolveInstance(ByVal DA As IGH_DataAccess)

  If (DA.Iteration = 0) Then

    If (m_display Is Nothing) Then m_display = New CustomDisplay(Not Me.Hidden)

    'TODO: fill up the m_display class

    SynchDisplay()

  End If

End Sub

 

--

David Rutten

david@mcneel.com

Poprad, Slovakia

The reason for having a single event that can handle a lot of different types of messages is three-fold. First, it means less typing for the implementer as you can get away with handling just one event. Two, it means that future types of changes can be send through the same conduit, limiting changes to the SDK and three, it allows for changes of unknown origin to be handled as well. That is why there is a GH_ObjectEventType.Custom field and the possibility to add user data to the event arguments. This way the event is extendable by 3rd party implementers.

 

--

David Rutten

david@mcneel.com

Poprad, Slovakia

Thanks for the reply David, it works. And now it all makes sense.

 

In the earlier code I posted, I was trying to get only a boolean value that would flip every time the preview was toggled, which I would later use to control my CustomDisplay. I wasn't using it now only because I was just trying to extract the value of the hidden switch first.

 

I understand that SolveInstance isn't recalled for preview toggles, so whatever I do inside it will not reflect the change, and DA.SetData() is not called either. So even though the Boolean 'draw' that I was using might be changing, it wouldn't reflect in the outputs - so that was my problem.

 

It certainly makes a lot of sense to have multiple events handled by the same Event, just that I hadn't come across a case where the 'sender' or the 'e' were being put to any constructive use inside the EventHandler Sub. But now I know better.

 

Thanks a lot!

Hi!, I've read and analyze the code exposed in this post a lot but I can't figure out how to use GH_ComponentParamServer.ParameterChanged event to run a piece of code inside one of my components.

I've tried to create an event handler to one of my components but I'm not be able to solve some problems with the code :S

 

I've begun trying to simply add "1" to a variable every time and input param is changed. This is the code I've written:

 

Dim a As Integer = 0

'Sub
Private Sub Addition()
a += 1
End Sub

'EvetHandler
Private Sub InputChanged(ByVal sender As Object, _
ByVal e As GH_ObjectChangedEventArgs)
Addition()

End Sub


Protected Overrides Sub RegisterInputParams(ByVal pManager As GH_Component.GH_InputParamManager)

pManager.Register_IntegerParam("I", "I", "Registered input")
AddHandler Me.Params.ParameterChanged, AddressOf InputChanged
End Sub

 

VS show this error:

"Error 2 Method 'Private Sub InputChanged(sender As Object, e As Grasshopper.Kernel.GH_ObjectChangedEventArgs)' does not have a signature compatible with delegate 'Delegate Sub ParameterChangedEventHandler(sender As Object, e As Grasshopper.Kernel.GH_ParamServerEventArgs)'. (...)"

 

I hope that someone could help me a little bit with this.

GH_ObjectChangedEventArgs is not the same as  GH_ParamServerEventArgs

 

That's what the error claims basically. It says that you're trying to attach a handler to an event which does not have the correct signature.

 

--

David Rutten

david@mcneel.com

Poprad, Slovakia

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