This project is read-only.

Getting a handle on shapes (literally and figuratively)

Sep 21, 2010 at 4:18 AM

I am trying to add to the ShapeEditor tool by adding the ability to edit loaded shapes (rotate, slide, stretch/shrink, etc).

Something I have been struggling with all night is how to get a handle on the currently selected shape (I'll worry about groups of shapes later). I have F11'ed my way thru the entire chain of events that happen after the 'dotted box' used by the selection tool is released and have come away without realizing how a shape is marked as selected.

So I ask...  how can I tell if a shape is marked as selected in something like Maps.MapPolygonLayer.BuildPaths()? 

Thank you for your time,



Sep 23, 2010 at 5:37 PM

After staring at the code some more I figured it out...  in Maps.MapPolygonLayer.BuildPaths(). DrawnStates is a list of the drawing state of each shape. Not only the shape's Selected state, but also its Visibility state and the symbolic category of the shape.


Sep 23, 2010 at 6:44 PM

Yep.  Also, watch out.  FeatureSets can exist in two modes.  In index mode, it uses the FastDrawnState array.  This is a simple array, and works since each index value should match up precisely with the index of the shape, so it's easier.  If you are not in index mode, however, it assumes that you are in an editing mode where you could potentially be moving around the order of the Features in the FeatureSet.Features list.  In this case it gets more complicated because it tracks the DrawnState by using the "IFeature" object itself.  So just be aware that if you update the code that works with indices, but then you create a new FeatureSet from scratch by adding new Features to the Features list, any potential optimizations you are considering will not be invoked because I think in that case it calls based on the Feature instead.  It still uses an updated vertex array for drawing, but lets say you color shape number 5 red.  In the Index mode, if you removed shape 4, the fifth shape in the list would still be the one being colored red.  If not in IndexMode, however, if you remove shape 4, it would simply use the lookup based on IFeature and skip the old DrawnState for shape 4 and continue to draw the old shape5 red, even though it is now fourth in the list of features.



Sep 24, 2010 at 5:10 AM

Before I start working on what I have in mind, can you tell me if code already exists to put those corner handles and mid-segment handles on shapes so that the user can grab them for stretch/shrink?

If not, is there a 'usual' way to do that? Can big fat points be put on a polygon layer? If not, what is the move? To make a multipoint layer that doesn't show in the legend and put the handles on that?

Thank you for your time,


Sep 24, 2010 at 5:43 PM

Have we walked you through creating your own MapFunction yet, or is that still a strange concept?

I will assume you are working in the context of a MapFunction that is designed for editing.  Inherit from MapFunction to get started.  You can use a point layer added to the MapFrame.DrawingLayer to show points that are cached as coordinates.  You could alternately simply draw the point locations yourself by overriding the OnDraw method in the MapFunction, and taking advantage of the Map.ProjToPixel method to figure out where to draw.  To make them responsive to mouse clicking, however, you would probably want to track a list of rectangles.  That way, you can easily do a hit-test with the current mouse coordinates during mouse-move, mouse-down and mouse-up events in your MapFunction.

The OnDraw method could also handle your shape stretching desires.  I would recommend drawing the glyphs that let you stretch the shape using the OnDraw method of the map function, but only after the user has "selected" the shape first.  Once you click on the shape, then the extent of that shape shows up.  So that's effectively two functions you are wrangling.  First a "click on the shape" function and then the second function is a "Stretch shape" function.  You could draw the cute, clickable stretch icons by using the OnDraw method and this time using the Map.ProjtoPixel with regards to the extent of the shape you are working with.  I would leave the original shape visible and have your stretched version be drawn as a transparent polygon on top of the original.  That way, they could get it back to it's original size pretty easily if they grab the wrong one.