Overriding Paint(), and selection bounds

Problem summary:

I’m overriding GoTextNode. I’m trying to supply an alternate rendering of the text by overriding the Paint() and ComputeBounds() methods. However, this seems to break the selection tool.


This is the code for a node which overrides GoTextNode. There’s a
custom Paint() function, and a custom ComputeBounds() function. Paint
happily paints the big red square created in the ctor. ComputeBounds
happily gives it enough space to be drawn. But the selection tool does
not allow you to select the red square; it seems to use the underlying
mybase.ComputeBounds function, or something close…

Imports Northwoods.Go

Public Class GoBadSelectionNode

Inherits GoTextNode

Dim _picture As Image

Sub New()

’ Set some node text

Me.Text = “short”

’ create a big red square

_picture = New Bitmap(100, 100)

Dim g As Graphics = Graphics.FromImage(_picture)


’ invalidate the bounds to force a recalc

Me.InvalidBounds = True

End Sub

Public Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal view As Northwoods.Go.GoView)

g.DrawImage(_pic ture, Me.Bounds.Left, Me.Bounds.Top, Me.Bounds.Width,

End Sub

Protected Overrides Function ComputeBounds() As System.Drawing.RectangleF

Dim baseRect As RectangleF = MyBase.ComputeBounds()

If _picture Is Nothing Then

     &nbs p;  '

this is necessary because ComputeBounds is called on mybase.New(),
before _picture has been set.

Return baseRect


Return New RectangleF(baseRect.X, baseRect.Y, _picture.Width,

End If

End Function

End Class

I’m adding one such node to a GoView with the call

GoView1.Document.Add(New GoBadSelectionNode)


Have I missed something? Is there something I have to do to get the selection tool to select within it’s new bounds?

Thanks for any light you might be able to shed on it…


Could you explain what you really want?
To comment on your code here, I think it might make more sense to create a GoRectangle that was not Selectable, had a Brush that was Brushes.Red, had no Pen, and was added to the node by calling InsertBefore.
Overriding Paint isn’t done very often except for defining new GoShapes or for adding a little bit of decoration to an object; the latter case wouldn’t be expected to change the “picking” behavior. With your code it isn’t clear to me how it could possibly work unless you also called the base Paint method.

Yeah, sure. Thanks for replying :)

I’ve been developing an app that until now has used a fairly simple
override of GoTextNode - I’ve just overridden a few things to get the
ports to appear in a certain way, to limit behaviours, etc.

I've distributed the app, and people have said to me, "this is great, but... it'd be better if we could have something prettier." (It's a classic story ;) )

So, I have decided to replace the simple text rendering of GoTextNode with something a bit sexier. What the users'll be getting is a node with a rectangular node containing a thumbnail, some text, some icons,and if I'm feeling really adventurous, some gradients.

So, I figured the easiest and quickest way to put this together would be to create an image of the node I wanted using the .NET System.Drawing.Bitmap and .Graphics classes. Then, override Paint() and ComputeBounds() so that the image was painted rather than the base Paint() method. Voila! The node would work exactly the same as it had, except that it has the new, sexy rendering.

At least, that was the idea. But I got the selection problems I mentioned before.

Would I be understanding you right if I were to say that selection is based on, what, the rectangle that contains all the GoObjects used in the node? Something like that? And that by adding a GoObject that displays the image (eg, a GoImage) it would naturally expand the node so that selection etc works?

[QUOTE=walter]To comment on your code here, I think it might make more sense to create a GoRectangle [and add it] to the node by calling InsertBefore.[/quote]

I don't have InsertBefore - is that something only available in Professional?

OK. Then the most natural thing to do would be to create and draw a Bitmap, create a GoImage that uses that Bitmap, and assign the GoTextNode.Background to be that GoImage.
If you want to share those bitmaps amongst copies of the nodes, I would create an ImageList, add the Bitmap, and set the static/shared variable GoImage.DefaultImageList to refer to this ImageList. Then all you would need to do to initialize the GoImage would be to assign the GoImage.Index property to refer to the appropriate bitmap in the ImageList.
Now GoTextNode always resizes the Background object to fit around the Label (a GoText object) with some margins. If you set GoTextNode.AutoResizes to false, the Label will be resized to fit inside the Background object, i.e., your GoImage. I don’t know which behavior you want.
Yes, GoDiagram Express doesn’t have general support for groups, which is why there’s no InsertBefore method.

That sounds great. I’ll try it out tonight!

Works like a charm. Thanks!