Adorners in Silverlight - Move, Size, Rotate, Custom Mouse Cursor
Dec 13, 2009
This adorner took me few days to get right!
Edit Dec, 15: Andrej Tozon created an updated source supporting Behaviours (and drag-drop without code in Blend). Here's a link to his version. Thanks Andrej!
This is work in progress, but the base functionality is there and stable!
The adorner currently has the following features:
- Shows custom mouse cursors that get rotated and aligned to the object being rotated/sized in realtime. The cursors are Path elements, so this makes the cursor rotation possible. To see the effect in action, try rotating a window and then sizing: the size cursor is always perpendicular to the sizing edges.
- Move. It also does click detection on activation - so that you can click a non-adorned object and immediately start dragging.
- Two resize modes: center-preserving and edge-preserving (currently set via private bool property).
- Rotate: hover outside any corner with the mouse to see the rotating adorner
- Extension panel: allows to add additional adorner controls (e.g. "send backwards" icon on top of adorner). This is currently private, but will become properly exposed in later versions
- The element being adorned can choose any algorithm to rotate/move itself (e.g. use TranslateTransform vs Canvas.Left and Canvas.Top). The functionality with the element being adorned is loosely coupled with the adorner through a simple IAdornedOject interface.
- Nice glass border (from http://www.sixin.nl/antoni-dol-blog/09-11-15/Silverlight_Style_GlassBorderStyle.aspx)
Turns out, properly doing rotation, translation and all those adorner-specific things, wasn't easy for me...in fact it took me quite a bit of time! I'm glad it's done for now! :)
Here is a quick extract of the source and how to use the interfaces:
[code:c#]
public interface IAdornedObject
{
double Angle { get; set; }
double X { get; set; }
double Y { get; set; }
double Width { get; set; }
double Height { get; set; }
}
[/code]
Usage is straight-forward:
[code:c#]
Adorner adorner = new Adorner();
AdornedObject item = new AdornedObject(testImage);
adorner.SetAdornedObject(item);
panelDisplay.Children.Add(adorner);
[/code]
To avoid hassles with Thumbs moving around, the core of the move/size/rotate code is in thumb_MouseMove() - giving it nice absolute mouse coordinates!
What do you think this adorner?