Leadtools.MedicalViewer Namespace : MedicalViewerCustomAnnotationRequestedObject Enumeration |
public enum MedicalViewerCustomAnnotationRequestedObject : System.Enum, System.IComparable, System.IConvertible, System.IFormattable
'Declaration Public Enum MedicalViewerCustomAnnotationRequestedObject Inherits System.Enum Implements System.IComparable, System.IConvertible, System.IFormattable
'Usage Dim instance As MedicalViewerCustomAnnotationRequestedObject
public enum class MedicalViewerCustomAnnotationRequestedObject : public System.Enum, System.IComparable, System.IConvertible, System.IFormattable
Value | Member | Description |
---|---|---|
0x00000000 | EditDesigner | The request is a new instance of the custom annotation edit designer. |
0x00000001 | DrawDesigner | The request is a new instance of the custom annotation run designer. |
0x00000002 | AnnotationObject | The request is a new instance of the custom annotation object. |
The annotation as custom must be declared before registering the MedicalViewerBaseCell.CustomAnnotationDataRequested event.
For more information on how to create a custom annotation, refer to the MedicalViewerBaseCell.CustomAnnotationDataRequested event.
Imports Leadtools Imports Leadtools.Drawing Imports Leadtools.Codecs Imports Leadtools.MedicalViewer Imports Leadtools.ImageProcessing Imports Leadtools.Annotations Private Class MedicalViewerCustomAnnotationForm : Inherits Form Private _medicalViewer As MedicalViewer Private Sub MedicalViewerForm_SizeChanged(ByVal sender As Object, ByVal e As EventArgs) _medicalViewer.Size = New Size(Me.ClientRectangle.Right, Me.ClientRectangle.Bottom) End Sub Public Sub New() Dim _codecs As RasterCodecs = New RasterCodecs() Dim _image As RasterImage AddHandler SizeChanged, AddressOf MedicalViewerForm_SizeChanged ' Create the medical viewer and adjust the size and the location. _medicalViewer = New MedicalViewer(1, 2) _medicalViewer.Location = New Point(0, 0) _medicalViewer.Size = New Size(Me.ClientRectangle.Right, Me.ClientRectangle.Bottom) ' Load an image and then add it to the control. _image = _codecs.Load(Path.Combine(LEAD_VARS.ImagesDir, "xa.dcm")) Dim cell As MedicalViewerMultiCell = New MedicalViewerMultiCell(_image, True, 1, 1) ' add some actions that will be used to change the properties of the images inside the control. cell.AddAction(MedicalViewerActionType.WindowLevel) cell.AddAction(MedicalViewerActionType.Scale) cell.AddAction(MedicalViewerActionType.Offset) ' assign the added actions to a mouse button, meaning that when the user clicks and drags the mouse button, the associated action will be activated. cell.SetAction(MedicalViewerActionType.WindowLevel, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active) cell.SetAction(MedicalViewerActionType.Scale, MedicalViewerMouseButtons.Middle, MedicalViewerActionFlags.Active) cell.SetAction(MedicalViewerActionType.Offset, MedicalViewerMouseButtons.Right, MedicalViewerActionFlags.Active) _medicalViewer.Cells.Add(cell) ' adjust some properties of the cell and add some tags. _medicalViewer.Cells(0).SetTag(2, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.UserData, "EX. ID 230-36-5448") _medicalViewer.Cells(0).SetTag(4, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Frame) _medicalViewer.Cells(0).SetTag(6, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Scale) _medicalViewer.Cells(0).SetTag(2, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.WindowLevelData) _medicalViewer.Cells(0).SetTag(1, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.FieldOfView) ' Load another image and then add it to the control. _image = _codecs.Load(Path.Combine(LEAD_VARS.ImagesDir, "mr.dcm")) _medicalViewer.Cells.Add(New MedicalViewerMultiCell(_image, True, 2, 2)) ' add some actions that will be used to change the properties of the images inside the control. _medicalViewer.Cells(1).AddAction(MedicalViewerActionType.WindowLevel) _medicalViewer.Cells(1).AddAction(MedicalViewerActionType.Scale) _medicalViewer.Cells(1).AddAction(MedicalViewerActionType.Offset) ' assign the added actions to a mouse button, meaning that when the user clicks and drags the mouse button, the associated action will be activated. _medicalViewer.Cells(1).SetAction(MedicalViewerActionType.WindowLevel, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active) _medicalViewer.Cells(1).SetAction(MedicalViewerActionType.Scale, MedicalViewerMouseButtons.Middle, MedicalViewerActionFlags.Active) _medicalViewer.Cells(1).SetAction(MedicalViewerActionType.Offset, MedicalViewerMouseButtons.Right, MedicalViewerActionFlags.Active) ' adjust some properties of the cell and add some tags. _medicalViewer.Cells(1).SetTag(2, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.UserData, "EX. ID 230-36-5448") _medicalViewer.Cells(1).SetTag(4, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Frame) _medicalViewer.Cells(1).SetTag(6, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Scale) _medicalViewer.Cells(1).SetTag(2, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.WindowLevelData) _medicalViewer.Cells(1).SetTag(1, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.FieldOfView) Controls.Add(_medicalViewer) _medicalViewer.Dock = DockStyle.Fill End Sub Public ReadOnly Property Viewer() As MedicalViewer Get Return _medicalViewer End Get End Property End Class Private Function GetMedicalControlForCustomAnnotationExample() As MedicalViewerCustomAnnotationForm Return New MedicalViewerCustomAnnotationForm() End Function Public Sub MedicalViewerCustomAnnotationExample() Dim myForm As MedicalViewerCustomAnnotationForm = GetMedicalControlForCustomAnnotationExample() Dim medicalViewer As MedicalViewer = myForm.Viewer Dim cell As MedicalViewerMultiCell = CType(medicalViewer.Cells(0), MedicalViewerMultiCell) cell.AddAction(CType(101, MedicalViewerActionType)) cell.SetAction(CType(101, MedicalViewerActionType), MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active) cell.DeclareActionAsAnnotation(CType(101, MedicalViewerActionType), GetType(MyTriangleObject)) AddHandler cell.CustomAnnotationDataRequested, AddressOf cell_CustomAnnotationDataRequested myForm.ShowDialog() End Sub Private Sub cell_CustomAnnotationDataRequested(ByVal sender As Object, ByVal e As MedicalViewerCustomAnnotationArgs) Select Case e.RequestedObject Case MedicalViewerCustomAnnotationRequestedObject.AnnotationObject If e.AnnotationAction = CType(101, MedicalViewerActionType) Then Dim triangle As MyTriangleObject = New MyTriangleObject() triangle.Pen = New AnnPen(Color.Blue, New AnnLength(3, AnnUnit.Pixel)) e.AnnotationObject = triangle End If Case MedicalViewerCustomAnnotationRequestedObject.DrawDesigner If e.AnnotationAction = CType(101, MedicalViewerActionType) Then e.DrawDesigner = New MyTriangleObjectDrawDesigner() End If Case MedicalViewerCustomAnnotationRequestedObject.EditDesigner If e.AnnotationAction = CType(101, MedicalViewerActionType) Then e.EditDesigner = New MyTriangleObjectEditDesigner() End If End Select End Sub ' ' Triangle annotation object class ' This class will have a 3 points for a triangle objects that can be stroked with a pen and filled with a brush ' <Serializable()> _ Public Class MyTriangleObject : Inherits AnnObject ' must derive from AnnObject or one of its derived classes ' ' our private variables ' ' the three points that define our triangle <NonSerialized()> _ Private _firstPoint As AnnPoint <NonSerialized()> _ Private _secondPoint As AnnPoint <NonSerialized()> _ Private _thirdPoint As AnnPoint ' ' constructor ' Public Sub New() ' no, we do not require a font MyBase.New(True, True, False) ' initialize the points _firstPoint = AnnPoint.Empty _secondPoint = AnnPoint.Empty _thirdPoint = AnnPoint.Empty End Sub ' ' ISerializable implementation ' Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext) ' do not forget to call the base class version MyBase.New(info, context) ' we need to deserialize our private variables here _firstPoint = CType(info.GetValue("FirstPointName", GetType(AnnPoint)), AnnPoint) _secondPoint = CType(info.GetValue("SecondPointName", GetType(AnnPoint)), AnnPoint) _thirdPoint = CType(info.GetValue("ThirdPointName", GetType(AnnPoint)), AnnPoint) End Sub Public Overrides Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext) ' we need to serialize our private variables here ' call the base class version MyBase.GetObjectData(info, context) ' serialize the points info.AddValue("FirstPointName", _firstPoint, GetType(AnnPoint)) info.AddValue("SecondPointName", _secondPoint, GetType(AnnPoint)) info.AddValue("ThirdPointName", _thirdPoint, GetType(AnnPoint)) End Sub ' ' accessors to the points ' Public Property FirstPoint() As AnnPoint Get Return _firstPoint End Get Set(ByVal value As AnnPoint) _firstPoint = Value End Set End Property Public Property SecondPoint() As AnnPoint Get Return _secondPoint End Get Set(ByVal value As AnnPoint) _secondPoint = Value End Set End Property Public Property ThirdPoint() As AnnPoint Get Return _thirdPoint End Get Set(ByVal value As AnnPoint) _thirdPoint = Value End Set End Property ' ' AnnObject overrides ' Protected Overrides Function Create() As AnnObject ' must return a new instance of our class Return New MyTriangleObject() End Function Public Overrides Function Clone() As Object ' override the clone method ' first call the base implementation Dim obj As MyTriangleObject = TryCast(MyBase.Clone(), MyTriangleObject) ' next, copy the points obj.FirstPoint = FirstPoint obj.SecondPoint = SecondPoint obj.ThirdPoint = ThirdPoint Return obj End Function Public Overrides Function GetGraphicsPath(ByVal mode As AnnGetGraphicsPathMode) As GraphicsPath ' must a return a graphics path representation of our object ' Note: this object does not require us to override AnnObject.DrawObject since we can ' use a graphics path to represents the object completely. ' create a new graphics path Dim path As GraphicsPath = New GraphicsPath() ' add the triangle points as a series of lines ' convert the points to pixels PointF Dim pts As PointF() = {FirstPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF(), SecondPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF(), ThirdPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF()} path.AddLines(pts) path.CloseFigure() Return path End Function Public Overrides Sub ResetRotatePoints() ' Place the rotate center control point in the center of the triangle Dim CenterX As Single = (FirstPoint.X + SecondPoint.X + ThirdPoint.X) / 3 Dim CenterY As Single = (FirstPoint.Y + SecondPoint.Y + ThirdPoint.Y) / 3 RotateCenter = New AnnPoint(CenterX, CenterY) ' Place the RotateGripper along a line from the center of the triangle through a vertex Dim cx As Single = FirstPoint.X - RotateCenter.X Dim cy As Single = FirstPoint.Y - RotateCenter.Y Dim dist As Single = CSng(Math.Sqrt(cx * cx + cy * cy)) Dim fract As Single = 1 If dist <> 0 Then fract = (Math.Abs(dist) + Math.Abs(GripperDistance)) / dist End If Dim GripperX As Single = CenterX + fract * cx Dim GripperY As Single = CenterY + fract * cy RotateGripper = New AnnPoint(GripperX, GripperY) End Sub End Class ' ' MyTriangleObject draw designer ' Will require the user to click 3 times once for each point ' Public Class MyTriangleObjectDrawDesigner : Inherits AnnDrawDesigner ' must derive from AnnDrawDesigner or one of its derived classes ' ' private variables ' ' we need to keep track on next point to add Private _clickCount As Integer ' ' constructor ' Public Sub New() _clickCount = 0 End Sub ' ' AnnDrawDesigner overrides ' Public Overrides Function MouseDown(ByVal e As MouseEventArgs) As Boolean Dim handled As Boolean = False ' only process left button clicks If e.Button = MouseButtons.Left Then ' check if we have not started drawing yet, DrawObject will be null If DrawObject Is Nothing Then ' yes, create a new MyTriangleObject from ObjectTemplate Dim obj As MyTriangleObject = TryCast(ObjectTemplate.Clone(), MyTriangleObject) ' setup the points Dim pt As AnnPoint = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit) obj.FirstPoint = pt obj.SecondPoint = pt obj.ThirdPoint = pt ' start drawing this new object StartWorking(obj) handled = True ' we processed first click _clickCount += 1 Else ' an object is already being drawn, so process next click ' get our object and assign next point to it Dim obj As MyTriangleObject = TryCast(DrawObject, MyTriangleObject) Dim pt As AnnPoint = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit) If _clickCount = 1 Then ' second point obj.SecondPoint = pt _clickCount += 1 handled = True ElseIf _clickCount = 2 Then ' third point obj.ThirdPoint = pt handled = True ' we are done! EndWorking() End If End If Else ' we want to cancel the drawing if any other button has been clicked If Not DrawObject Is Nothing Then Cancel() handled = True End If End If Return handled End Function Public Overrides Function MouseMove(ByVal e As MouseEventArgs) As Boolean Dim handled As Boolean = False ' check if we are already drawing an object If Not DrawObject Is Nothing Then ' yes, get this object and assign the next point ' first, save the old invalid rectangle Dim rcOld As Rectangle = DrawObject.InvalidRectangle ' get out object and assign the point Dim obj As MyTriangleObject = TryCast(DrawObject, MyTriangleObject) Dim pt As AnnPoint = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit) If _clickCount = 1 Then obj.SecondPoint = pt ElseIf _clickCount = 2 Then obj.ThirdPoint = pt End If ' get the new invalid rectangle Dim rcNew As Rectangle = DrawObject.InvalidRectangle ' continue drawing this object Working(Rectangle.Union(rcOld, rcNew)) handled = True End If Return handled End Function Public Overrides Function MouseUp(ByVal e As MouseEventArgs) As Boolean ' we do not need to do anything special on mouse up. ' so just see if we are drawing to return true (we handled it) Dim handled As Boolean = False If DrawObject Is Nothing Then handled = True End If Return handled End Function End Class ' ' MyTriangleObject edit designer ' User can click on any of the points and move them around as well as clicking and dragging the object itself. ' Public Class MyTriangleObjectEditDesigner : Inherits AnnEditDesigner ' must derive from AnnEditDesigner or one of its derived classes ' ' constructor ' Public Sub New() End Sub ' ' AnnEditDesigner overrides ' Public Overrides ReadOnly Property ControlPointCount() As Integer Get ' return the number of control points we need ' in this case 3, one for each point in our triangle Return 3 End Get End Property Public Overrides Function GetControlPointsLocation() As AnnPoint() ' return the position of these control points ' in this case, same as the points from our object Dim obj As MyTriangleObject = TryCast(EditObject, MyTriangleObject) Return New AnnPoint() {obj.FirstPoint, obj.SecondPoint, obj.ThirdPoint} End Function Protected Overrides Sub MoveControlPoint(ByVal controlPointIndex As Integer, ByVal pt As AnnPoint) ' user has clicked and moved a point. ' based on the index, we can tell if the user dragged the first, second or third point Dim obj As MyTriangleObject = TryCast(EditObject, MyTriangleObject) Select Case controlPointIndex Case 0 ' first point obj.FirstPoint = pt.ConvertTo(Container.UnitConverter, obj.FirstPoint.Unit) Case 1 ' second point obj.SecondPoint = pt.ConvertTo(Container.UnitConverter, obj.SecondPoint.Unit) Case 2 ' third point obj.ThirdPoint = pt.ConvertTo(Container.UnitConverter, obj.ThirdPoint.Unit) End Select End Sub ' Note, we will not override Move or MoveName since the default implementation is good enough for our object End Class Public NotInheritable Class LEAD_VARS Public Const ImagesDir As String = "C:\Users\Public\Documents\LEADTOOLS Images" End Class
using Leadtools; using Leadtools.Drawing; using Leadtools.Codecs; using Leadtools.MedicalViewer; using Leadtools.ImageProcessing; using Leadtools.Annotations; class MedicalViewerCustomAnnotationForm : Form { private MedicalViewer _medicalViewer; void MedicalViewerForm_SizeChanged(object sender, EventArgs e) { _medicalViewer.Size = new Size(this.ClientRectangle.Right, this.ClientRectangle.Bottom); } public MedicalViewerCustomAnnotationForm() { RasterCodecs _codecs = new RasterCodecs(); RasterImage _image; this.SizeChanged += new EventHandler(MedicalViewerForm_SizeChanged); // Create the medical viewer and adjust the size and the location. _medicalViewer = new MedicalViewer(1, 2); _medicalViewer.Location = new Point(0, 0); _medicalViewer.Size = new Size(this.ClientRectangle.Right, this.ClientRectangle.Bottom); // Load an image and then add it to the control. _image = _codecs.Load(Path.Combine(LEAD_VARS.ImagesDir,"xa.dcm")); MedicalViewerMultiCell cell = new MedicalViewerMultiCell(_image, true, 1, 1); // add some actions that will be used to change the properties of the images inside the control. cell.AddAction(MedicalViewerActionType.WindowLevel); cell.AddAction(MedicalViewerActionType.Scale); cell.AddAction(MedicalViewerActionType.Offset); // assign the added actions to a mouse button, meaning that when the user clicks and drags the mouse button, the associated action will be activated. cell.SetAction(MedicalViewerActionType.WindowLevel, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active); cell.SetAction(MedicalViewerActionType.Scale, MedicalViewerMouseButtons.Middle, MedicalViewerActionFlags.Active); cell.SetAction(MedicalViewerActionType.Offset, MedicalViewerMouseButtons.Right, MedicalViewerActionFlags.Active); _medicalViewer.Cells.Add(cell); // adjust some properties of the cell and add some tags. _medicalViewer.Cells[0].SetTag(2, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.UserData, "EX. ID 230-36-5448"); _medicalViewer.Cells[0].SetTag(4, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Frame); _medicalViewer.Cells[0].SetTag(6, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Scale); _medicalViewer.Cells[0].SetTag(2, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.WindowLevelData); _medicalViewer.Cells[0].SetTag(1, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.FieldOfView); // Load another image and then add it to the control. _image = _codecs.Load(Path.Combine(LEAD_VARS.ImagesDir,"mr.dcm")); _medicalViewer.Cells.Add(new MedicalViewerMultiCell(_image, true, 2, 2)); // add some actions that will be used to change the properties of the images inside the control. _medicalViewer.Cells[1].AddAction(MedicalViewerActionType.WindowLevel); _medicalViewer.Cells[1].AddAction(MedicalViewerActionType.Scale); _medicalViewer.Cells[1].AddAction(MedicalViewerActionType.Offset); // assign the added actions to a mouse button, meaning that when the user clicks and drags the mouse button, the associated action will be activated. _medicalViewer.Cells[1].SetAction(MedicalViewerActionType.WindowLevel, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active); _medicalViewer.Cells[1].SetAction(MedicalViewerActionType.Scale, MedicalViewerMouseButtons.Middle, MedicalViewerActionFlags.Active); _medicalViewer.Cells[1].SetAction(MedicalViewerActionType.Offset, MedicalViewerMouseButtons.Right, MedicalViewerActionFlags.Active); // adjust some properties of the cell and add some tags. _medicalViewer.Cells[1].SetTag(2, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.UserData, "EX. ID 230-36-5448"); _medicalViewer.Cells[1].SetTag(4, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Frame); _medicalViewer.Cells[1].SetTag(6, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Scale); _medicalViewer.Cells[1].SetTag(2, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.WindowLevelData); _medicalViewer.Cells[1].SetTag(1, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.FieldOfView); Controls.Add(_medicalViewer); _medicalViewer.Dock = DockStyle.Fill; } public MedicalViewer Viewer { get { return _medicalViewer; } } } MedicalViewerCustomAnnotationForm GetMedicalControlForCustomAnnotationExample() { return new MedicalViewerCustomAnnotationForm(); } public void MedicalViewerCustomAnnotationExample() { MedicalViewerCustomAnnotationForm myForm = GetMedicalControlForCustomAnnotationExample(); MedicalViewer medicalViewer = myForm.Viewer; MedicalViewerMultiCell cell = (MedicalViewerMultiCell)(medicalViewer.Cells[0]); cell.AddAction((MedicalViewerActionType)101); cell.SetAction((MedicalViewerActionType)101, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active); cell.DeclareActionAsAnnotation((MedicalViewerActionType)101, typeof(MyTriangleObject)); cell.CustomAnnotationDataRequested += new EventHandler<MedicalViewerCustomAnnotationArgs>(cell_CustomAnnotationDataRequested); myForm.ShowDialog(); } void cell_CustomAnnotationDataRequested(object sender, MedicalViewerCustomAnnotationArgs e) { switch (e.RequestedObject) { case MedicalViewerCustomAnnotationRequestedObject.AnnotationObject: if (e.AnnotationAction == (MedicalViewerActionType)101) { MyTriangleObject triangle = new MyTriangleObject(); triangle.Pen = new AnnPen(Color.Blue, new AnnLength(3, AnnUnit.Pixel)); e.AnnotationObject = triangle; } break; case MedicalViewerCustomAnnotationRequestedObject.DrawDesigner: if (e.AnnotationAction == (MedicalViewerActionType)101) e.DrawDesigner = new MyTriangleObjectDrawDesigner(); break; case MedicalViewerCustomAnnotationRequestedObject.EditDesigner: if (e.AnnotationAction == (MedicalViewerActionType)101) e.EditDesigner = new MyTriangleObjectEditDesigner(); break; } } // // Triangle annotation object class // This class will have a 3 points for a triangle objects that can be stroked with a pen and filled with a brush // [Serializable] // our class must be serializable to play well with the annotation load/save and undo/redo features public class MyTriangleObject : AnnObject // must derive from AnnObject or one of its derived classes { // // our private variables // // the three points that define our triangle [NonSerialized()] private AnnPoint _firstPoint; [NonSerialized()] private AnnPoint _secondPoint; [NonSerialized()] private AnnPoint _thirdPoint; // // constructor // public MyTriangleObject() : base( true, // yes, we require a pen true, // yes, we require a brush false) // no, we do not require a font { // initialize the points _firstPoint = AnnPoint.Empty; _secondPoint = AnnPoint.Empty; _thirdPoint = AnnPoint.Empty; } // // ISerializable implementation // protected MyTriangleObject(SerializationInfo info, StreamingContext context) : base(info, context) // do not forget to call the base class version { // we need to deserialize our private variables here _firstPoint = (AnnPoint)info.GetValue("FirstPointName", typeof(AnnPoint)); _secondPoint = (AnnPoint)info.GetValue("SecondPointName", typeof(AnnPoint)); _thirdPoint = (AnnPoint)info.GetValue("ThirdPointName", typeof(AnnPoint)); } public override void GetObjectData(SerializationInfo info, StreamingContext context) { // we need to serialize our private variables here // call the base class version base.GetObjectData(info, context); // serialize the points info.AddValue("FirstPointName", _firstPoint, typeof(AnnPoint)); info.AddValue("SecondPointName", _secondPoint, typeof(AnnPoint)); info.AddValue("ThirdPointName", _thirdPoint, typeof(AnnPoint)); } // // accessors to the points // public AnnPoint FirstPoint { get { return _firstPoint; } set { _firstPoint = value; } } public AnnPoint SecondPoint { get { return _secondPoint; } set { _secondPoint = value; } } public AnnPoint ThirdPoint { get { return _thirdPoint; } set { _thirdPoint = value; } } // // AnnObject overrides // protected override AnnObject Create() { // must return a new instance of our class return new MyTriangleObject(); } public override object Clone() { // override the clone method // first call the base implementation MyTriangleObject obj = base.Clone() as MyTriangleObject; // next, copy the points obj.FirstPoint = FirstPoint; obj.SecondPoint = SecondPoint; obj.ThirdPoint = ThirdPoint; return obj; } public override GraphicsPath GetGraphicsPath(AnnGetGraphicsPathMode mode) { // must a return a graphics path representation of our object // Note: this object does not require us to override AnnObject.DrawObject since we can // use a graphics path to represents the object completely. // create a new graphics path GraphicsPath path = new GraphicsPath(); // add the triangle points as a series of lines // convert the points to pixels PointF PointF[] pts = { FirstPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF(), SecondPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF(), ThirdPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF() }; path.AddLines(pts); path.CloseFigure(); return path; } public override void ResetRotatePoints() { // Place the rotate center control point in the center of the triangle float CenterX = (FirstPoint.X + SecondPoint.X + ThirdPoint.X) / 3; float CenterY = (FirstPoint.Y + SecondPoint.Y + ThirdPoint.Y) / 3; RotateCenter = new AnnPoint(CenterX, CenterY); // Place the RotateGripper along a line from the center of the triangle through a vertex float cx = FirstPoint.X - RotateCenter.X; float cy = FirstPoint.Y - RotateCenter.Y; float dist = (float)Math.Sqrt(cx * cx + cy * cy); float fract = 1; if (dist != 0) fract = (Math.Abs(dist) + Math.Abs(GripperDistance)) / dist; float GripperX = CenterX + fract * cx; float GripperY = CenterY + fract * cy; RotateGripper = new AnnPoint(GripperX, GripperY); } } // // MyTriangleObject draw designer // Will require the user to click 3 times once for each point // public class MyTriangleObjectDrawDesigner : AnnDrawDesigner // must derive from AnnDrawDesigner or one of its derived classes { // // private variables // // we need to keep track on next point to add private int _clickCount; // // constructor // public MyTriangleObjectDrawDesigner() { _clickCount = 0; } // // AnnDrawDesigner overrides // public override bool MouseDown(MouseEventArgs e) { bool handled = false; // only process left button clicks if (e.Button == MouseButtons.Left) { // check if we have not started drawing yet, DrawObject will be null if (DrawObject == null) { // yes, create a new MyTriangleObject from ObjectTemplate MyTriangleObject obj = ObjectTemplate.Clone() as MyTriangleObject; // setup the points AnnPoint pt = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit); obj.FirstPoint = pt; obj.SecondPoint = pt; obj.ThirdPoint = pt; // start drawing this new object StartWorking(obj); handled = true; // we processed first click _clickCount++; } else { // an object is already being drawn, so process next click // get our object and assign next point to it MyTriangleObject obj = DrawObject as MyTriangleObject; AnnPoint pt = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit); if (_clickCount == 1) { // second point obj.SecondPoint = pt; _clickCount++; handled = true; } else if (_clickCount == 2) { // third point obj.ThirdPoint = pt; handled = true; // we are done! EndWorking(); } } } else { // we want to cancel the drawing if any other button has been clicked if (DrawObject != null) { Cancel(); handled = true; } } return handled; } public override bool MouseMove(MouseEventArgs e) { bool handled = false; // check if we are already drawing an object if (DrawObject != null) { // yes, get this object and assign the next point // first, save the old invalid rectangle Rectangle rcOld = DrawObject.InvalidRectangle; // get out object and assign the point MyTriangleObject obj = DrawObject as MyTriangleObject; AnnPoint pt = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit); if (_clickCount == 1) obj.SecondPoint = pt; else if (_clickCount == 2) obj.ThirdPoint = pt; // get the new invalid rectangle Rectangle rcNew = DrawObject.InvalidRectangle; // continue drawing this object Working(Rectangle.Union(rcOld, rcNew)); handled = true; } return handled; } public override bool MouseUp(MouseEventArgs e) { // we do not need to do anything special on mouse up. // so just see if we are drawing to return true (we handled it) bool handled = false; if (DrawObject == null) handled = true; return handled; } } // // MyTriangleObject edit designer // User can click on any of the points and move them around as well as clicking and dragging the object itself. // public class MyTriangleObjectEditDesigner : AnnEditDesigner // must derive from AnnEditDesigner or one of its derived classes { // // constructor // public MyTriangleObjectEditDesigner() { } // // AnnEditDesigner overrides // public override int ControlPointCount { get { // return the number of control points we need // in this case 3, one for each point in our triangle return 3; } } public override AnnPoint[] GetControlPointsLocation() { // return the position of these control points // in this case, same as the points from our object MyTriangleObject obj = EditObject as MyTriangleObject; return new AnnPoint[] { obj.FirstPoint, obj.SecondPoint, obj.ThirdPoint }; } protected override void MoveControlPoint(int controlPointIndex, AnnPoint pt) { // user has clicked and moved a point. // based on the index, we can tell if the user dragged the first, second or third point MyTriangleObject obj = EditObject as MyTriangleObject; switch (controlPointIndex) { case 0: // first point obj.FirstPoint = pt.ConvertTo(Container.UnitConverter, obj.FirstPoint.Unit); break; case 1: // second point obj.SecondPoint = pt.ConvertTo(Container.UnitConverter, obj.SecondPoint.Unit); break; case 2: // third point obj.ThirdPoint = pt.ConvertTo(Container.UnitConverter, obj.ThirdPoint.Unit); break; } } // Note, we will not override Move or MoveName since the default implementation is good enough for our object } static class LEAD_VARS { public const string ImagesDir = @"C:\Users\Public\Documents\LEADTOOLS Images"; }
Imports Leadtools Imports Leadtools.Drawing Imports Leadtools.Codecs Imports Leadtools.MedicalViewer Imports Leadtools.ImageProcessing Imports Leadtools.Annotations Private Class MedicalViewerCustomAnnotationForm : Inherits Form Private _medicalViewer As MedicalViewer Private Sub MedicalViewerForm_SizeChanged(ByVal sender As Object, ByVal e As EventArgs) _medicalViewer.Size = New Size(Me.ClientRectangle.Right, Me.ClientRectangle.Bottom) End Sub Public Sub New() Dim _codecs As RasterCodecs = New RasterCodecs() Dim _image As RasterImage AddHandler SizeChanged, AddressOf MedicalViewerForm_SizeChanged ' Create the medical viewer and adjust the size and the location. _medicalViewer = New MedicalViewer(1, 2) _medicalViewer.Location = New Point(0, 0) _medicalViewer.Size = New Size(Me.ClientRectangle.Right, Me.ClientRectangle.Bottom) ' Load an image and then add it to the control. _image = _codecs.Load(Path.Combine(LEAD_VARS.ImagesDir, "xa.dcm")) Dim cell As MedicalViewerMultiCell = New MedicalViewerMultiCell(_image, True, 1, 1) ' add some actions that will be used to change the properties of the images inside the control. cell.AddAction(MedicalViewerActionType.WindowLevel) cell.AddAction(MedicalViewerActionType.Scale) cell.AddAction(MedicalViewerActionType.Offset) ' assign the added actions to a mouse button, meaning that when the user clicks and drags the mouse button, the associated action will be activated. cell.SetAction(MedicalViewerActionType.WindowLevel, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active) cell.SetAction(MedicalViewerActionType.Scale, MedicalViewerMouseButtons.Middle, MedicalViewerActionFlags.Active) cell.SetAction(MedicalViewerActionType.Offset, MedicalViewerMouseButtons.Right, MedicalViewerActionFlags.Active) _medicalViewer.Cells.Add(cell) ' adjust some properties of the cell and add some tags. _medicalViewer.Cells(0).SetTag(2, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.UserData, "EX. ID 230-36-5448") _medicalViewer.Cells(0).SetTag(4, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Frame) _medicalViewer.Cells(0).SetTag(6, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Scale) _medicalViewer.Cells(0).SetTag(2, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.WindowLevelData) _medicalViewer.Cells(0).SetTag(1, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.FieldOfView) ' Load another image and then add it to the control. _image = _codecs.Load(Path.Combine(LEAD_VARS.ImagesDir, "mr.dcm")) _medicalViewer.Cells.Add(New MedicalViewerMultiCell(_image, True, 2, 2)) ' add some actions that will be used to change the properties of the images inside the control. _medicalViewer.Cells(1).AddAction(MedicalViewerActionType.WindowLevel) _medicalViewer.Cells(1).AddAction(MedicalViewerActionType.Scale) _medicalViewer.Cells(1).AddAction(MedicalViewerActionType.Offset) ' assign the added actions to a mouse button, meaning that when the user clicks and drags the mouse button, the associated action will be activated. _medicalViewer.Cells(1).SetAction(MedicalViewerActionType.WindowLevel, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active) _medicalViewer.Cells(1).SetAction(MedicalViewerActionType.Scale, MedicalViewerMouseButtons.Middle, MedicalViewerActionFlags.Active) _medicalViewer.Cells(1).SetAction(MedicalViewerActionType.Offset, MedicalViewerMouseButtons.Right, MedicalViewerActionFlags.Active) ' adjust some properties of the cell and add some tags. _medicalViewer.Cells(1).SetTag(2, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.UserData, "EX. ID 230-36-5448") _medicalViewer.Cells(1).SetTag(4, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Frame) _medicalViewer.Cells(1).SetTag(6, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Scale) _medicalViewer.Cells(1).SetTag(2, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.WindowLevelData) _medicalViewer.Cells(1).SetTag(1, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.FieldOfView) Controls.Add(_medicalViewer) _medicalViewer.Dock = DockStyle.Fill End Sub Public ReadOnly Property Viewer() As MedicalViewer Get Return _medicalViewer End Get End Property End Class Private Function GetMedicalControlForCustomAnnotationExample() As MedicalViewerCustomAnnotationForm Return New MedicalViewerCustomAnnotationForm() End Function Public Sub MedicalViewerCustomAnnotationExample() Dim myForm As MedicalViewerCustomAnnotationForm = GetMedicalControlForCustomAnnotationExample() Dim medicalViewer As MedicalViewer = myForm.Viewer Dim cell As MedicalViewerMultiCell = CType(medicalViewer.Cells(0), MedicalViewerMultiCell) cell.AddAction(CType(101, MedicalViewerActionType)) cell.SetAction(CType(101, MedicalViewerActionType), MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active) cell.DeclareActionAsAnnotation(CType(101, MedicalViewerActionType), GetType(MyTriangleObject)) AddHandler cell.CustomAnnotationDataRequested, AddressOf cell_CustomAnnotationDataRequested myForm.ShowDialog() End Sub Private Sub cell_CustomAnnotationDataRequested(ByVal sender As Object, ByVal e As MedicalViewerCustomAnnotationArgs) Select Case e.RequestedObject Case MedicalViewerCustomAnnotationRequestedObject.AnnotationObject If e.AnnotationAction = CType(101, MedicalViewerActionType) Then Dim triangle As MyTriangleObject = New MyTriangleObject() triangle.Pen = New AnnPen(Color.Blue, New AnnLength(3, AnnUnit.Pixel)) e.AnnotationObject = triangle End If Case MedicalViewerCustomAnnotationRequestedObject.DrawDesigner If e.AnnotationAction = CType(101, MedicalViewerActionType) Then e.DrawDesigner = New MyTriangleObjectDrawDesigner() End If Case MedicalViewerCustomAnnotationRequestedObject.EditDesigner If e.AnnotationAction = CType(101, MedicalViewerActionType) Then e.EditDesigner = New MyTriangleObjectEditDesigner() End If End Select End Sub ' ' Triangle annotation object class ' This class will have a 3 points for a triangle objects that can be stroked with a pen and filled with a brush ' <Serializable()> _ Public Class MyTriangleObject : Inherits AnnObject ' must derive from AnnObject or one of its derived classes ' ' our private variables ' ' the three points that define our triangle <NonSerialized()> _ Private _firstPoint As AnnPoint <NonSerialized()> _ Private _secondPoint As AnnPoint <NonSerialized()> _ Private _thirdPoint As AnnPoint ' ' constructor ' Public Sub New() ' no, we do not require a font MyBase.New(True, True, False) ' initialize the points _firstPoint = AnnPoint.Empty _secondPoint = AnnPoint.Empty _thirdPoint = AnnPoint.Empty End Sub ' ' ISerializable implementation ' Protected Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext) ' do not forget to call the base class version MyBase.New(info, context) ' we need to deserialize our private variables here _firstPoint = CType(info.GetValue("FirstPointName", GetType(AnnPoint)), AnnPoint) _secondPoint = CType(info.GetValue("SecondPointName", GetType(AnnPoint)), AnnPoint) _thirdPoint = CType(info.GetValue("ThirdPointName", GetType(AnnPoint)), AnnPoint) End Sub Public Overrides Sub GetObjectData(ByVal info As SerializationInfo, ByVal context As StreamingContext) ' we need to serialize our private variables here ' call the base class version MyBase.GetObjectData(info, context) ' serialize the points info.AddValue("FirstPointName", _firstPoint, GetType(AnnPoint)) info.AddValue("SecondPointName", _secondPoint, GetType(AnnPoint)) info.AddValue("ThirdPointName", _thirdPoint, GetType(AnnPoint)) End Sub ' ' accessors to the points ' Public Property FirstPoint() As AnnPoint Get Return _firstPoint End Get Set(ByVal value As AnnPoint) _firstPoint = Value End Set End Property Public Property SecondPoint() As AnnPoint Get Return _secondPoint End Get Set(ByVal value As AnnPoint) _secondPoint = Value End Set End Property Public Property ThirdPoint() As AnnPoint Get Return _thirdPoint End Get Set(ByVal value As AnnPoint) _thirdPoint = Value End Set End Property ' ' AnnObject overrides ' Protected Overrides Function Create() As AnnObject ' must return a new instance of our class Return New MyTriangleObject() End Function Public Overrides Function Clone() As Object ' override the clone method ' first call the base implementation Dim obj As MyTriangleObject = TryCast(MyBase.Clone(), MyTriangleObject) ' next, copy the points obj.FirstPoint = FirstPoint obj.SecondPoint = SecondPoint obj.ThirdPoint = ThirdPoint Return obj End Function Public Overrides Function GetGraphicsPath(ByVal mode As AnnGetGraphicsPathMode) As GraphicsPath ' must a return a graphics path representation of our object ' Note: this object does not require us to override AnnObject.DrawObject since we can ' use a graphics path to represents the object completely. ' create a new graphics path Dim path As GraphicsPath = New GraphicsPath() ' add the triangle points as a series of lines ' convert the points to pixels PointF Dim pts As PointF() = {FirstPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF(), SecondPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF(), ThirdPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF()} path.AddLines(pts) path.CloseFigure() Return path End Function Public Overrides Sub ResetRotatePoints() ' Place the rotate center control point in the center of the triangle Dim CenterX As Single = (FirstPoint.X + SecondPoint.X + ThirdPoint.X) / 3 Dim CenterY As Single = (FirstPoint.Y + SecondPoint.Y + ThirdPoint.Y) / 3 RotateCenter = New AnnPoint(CenterX, CenterY) ' Place the RotateGripper along a line from the center of the triangle through a vertex Dim cx As Single = FirstPoint.X - RotateCenter.X Dim cy As Single = FirstPoint.Y - RotateCenter.Y Dim dist As Single = CSng(Math.Sqrt(cx * cx + cy * cy)) Dim fract As Single = 1 If dist <> 0 Then fract = (Math.Abs(dist) + Math.Abs(GripperDistance)) / dist End If Dim GripperX As Single = CenterX + fract * cx Dim GripperY As Single = CenterY + fract * cy RotateGripper = New AnnPoint(GripperX, GripperY) End Sub End Class ' ' MyTriangleObject draw designer ' Will require the user to click 3 times once for each point ' Public Class MyTriangleObjectDrawDesigner : Inherits AnnDrawDesigner ' must derive from AnnDrawDesigner or one of its derived classes ' ' private variables ' ' we need to keep track on next point to add Private _clickCount As Integer ' ' constructor ' Public Sub New() _clickCount = 0 End Sub ' ' AnnDrawDesigner overrides ' Public Overrides Function MouseDown(ByVal e As MouseEventArgs) As Boolean Dim handled As Boolean = False ' only process left button clicks If e.Button = MouseButtons.Left Then ' check if we have not started drawing yet, DrawObject will be null If DrawObject Is Nothing Then ' yes, create a new MyTriangleObject from ObjectTemplate Dim obj As MyTriangleObject = TryCast(ObjectTemplate.Clone(), MyTriangleObject) ' setup the points Dim pt As AnnPoint = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit) obj.FirstPoint = pt obj.SecondPoint = pt obj.ThirdPoint = pt ' start drawing this new object StartWorking(obj) handled = True ' we processed first click _clickCount += 1 Else ' an object is already being drawn, so process next click ' get our object and assign next point to it Dim obj As MyTriangleObject = TryCast(DrawObject, MyTriangleObject) Dim pt As AnnPoint = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit) If _clickCount = 1 Then ' second point obj.SecondPoint = pt _clickCount += 1 handled = True ElseIf _clickCount = 2 Then ' third point obj.ThirdPoint = pt handled = True ' we are done! EndWorking() End If End If Else ' we want to cancel the drawing if any other button has been clicked If Not DrawObject Is Nothing Then Cancel() handled = True End If End If Return handled End Function Public Overrides Function MouseMove(ByVal e As MouseEventArgs) As Boolean Dim handled As Boolean = False ' check if we are already drawing an object If Not DrawObject Is Nothing Then ' yes, get this object and assign the next point ' first, save the old invalid rectangle Dim rcOld As Rectangle = DrawObject.InvalidRectangle ' get out object and assign the point Dim obj As MyTriangleObject = TryCast(DrawObject, MyTriangleObject) Dim pt As AnnPoint = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit) If _clickCount = 1 Then obj.SecondPoint = pt ElseIf _clickCount = 2 Then obj.ThirdPoint = pt End If ' get the new invalid rectangle Dim rcNew As Rectangle = DrawObject.InvalidRectangle ' continue drawing this object Working(Rectangle.Union(rcOld, rcNew)) handled = True End If Return handled End Function Public Overrides Function MouseUp(ByVal e As MouseEventArgs) As Boolean ' we do not need to do anything special on mouse up. ' so just see if we are drawing to return true (we handled it) Dim handled As Boolean = False If DrawObject Is Nothing Then handled = True End If Return handled End Function End Class ' ' MyTriangleObject edit designer ' User can click on any of the points and move them around as well as clicking and dragging the object itself. ' Public Class MyTriangleObjectEditDesigner : Inherits AnnEditDesigner ' must derive from AnnEditDesigner or one of its derived classes ' ' constructor ' Public Sub New() End Sub ' ' AnnEditDesigner overrides ' Public Overrides ReadOnly Property ControlPointCount() As Integer Get ' return the number of control points we need ' in this case 3, one for each point in our triangle Return 3 End Get End Property Public Overrides Function GetControlPointsLocation() As AnnPoint() ' return the position of these control points ' in this case, same as the points from our object Dim obj As MyTriangleObject = TryCast(EditObject, MyTriangleObject) Return New AnnPoint() {obj.FirstPoint, obj.SecondPoint, obj.ThirdPoint} End Function Protected Overrides Sub MoveControlPoint(ByVal controlPointIndex As Integer, ByVal pt As AnnPoint) ' user has clicked and moved a point. ' based on the index, we can tell if the user dragged the first, second or third point Dim obj As MyTriangleObject = TryCast(EditObject, MyTriangleObject) Select Case controlPointIndex Case 0 ' first point obj.FirstPoint = pt.ConvertTo(Container.UnitConverter, obj.FirstPoint.Unit) Case 1 ' second point obj.SecondPoint = pt.ConvertTo(Container.UnitConverter, obj.SecondPoint.Unit) Case 2 ' third point obj.ThirdPoint = pt.ConvertTo(Container.UnitConverter, obj.ThirdPoint.Unit) End Select End Sub ' Note, we will not override Move or MoveName since the default implementation is good enough for our object End Class Public NotInheritable Class LEAD_VARS Public Const ImagesDir As String = "C:\Users\Public\Documents\LEADTOOLS Images" End Class
using Leadtools; using Leadtools.Drawing; using Leadtools.Codecs; using Leadtools.MedicalViewer; using Leadtools.ImageProcessing; using Leadtools.Annotations; class MedicalViewerCustomAnnotationForm : Form { private MedicalViewer _medicalViewer; void MedicalViewerForm_SizeChanged(object sender, EventArgs e) { _medicalViewer.Size = new Size(this.ClientRectangle.Right, this.ClientRectangle.Bottom); } public MedicalViewerCustomAnnotationForm() { RasterCodecs _codecs = new RasterCodecs(); RasterImage _image; this.SizeChanged += new EventHandler(MedicalViewerForm_SizeChanged); // Create the medical viewer and adjust the size and the location. _medicalViewer = new MedicalViewer(1, 2); _medicalViewer.Location = new Point(0, 0); _medicalViewer.Size = new Size(this.ClientRectangle.Right, this.ClientRectangle.Bottom); // Load an image and then add it to the control. _image = _codecs.Load(Path.Combine(LEAD_VARS.ImagesDir,"xa.dcm")); MedicalViewerMultiCell cell = new MedicalViewerMultiCell(_image, true, 1, 1); // add some actions that will be used to change the properties of the images inside the control. cell.AddAction(MedicalViewerActionType.WindowLevel); cell.AddAction(MedicalViewerActionType.Scale); cell.AddAction(MedicalViewerActionType.Offset); // assign the added actions to a mouse button, meaning that when the user clicks and drags the mouse button, the associated action will be activated. cell.SetAction(MedicalViewerActionType.WindowLevel, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active); cell.SetAction(MedicalViewerActionType.Scale, MedicalViewerMouseButtons.Middle, MedicalViewerActionFlags.Active); cell.SetAction(MedicalViewerActionType.Offset, MedicalViewerMouseButtons.Right, MedicalViewerActionFlags.Active); _medicalViewer.Cells.Add(cell); // adjust some properties of the cell and add some tags. _medicalViewer.Cells[0].SetTag(2, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.UserData, "EX. ID 230-36-5448"); _medicalViewer.Cells[0].SetTag(4, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Frame); _medicalViewer.Cells[0].SetTag(6, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Scale); _medicalViewer.Cells[0].SetTag(2, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.WindowLevelData); _medicalViewer.Cells[0].SetTag(1, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.FieldOfView); // Load another image and then add it to the control. _image = _codecs.Load(Path.Combine(LEAD_VARS.ImagesDir,"mr.dcm")); _medicalViewer.Cells.Add(new MedicalViewerMultiCell(_image, true, 2, 2)); // add some actions that will be used to change the properties of the images inside the control. _medicalViewer.Cells[1].AddAction(MedicalViewerActionType.WindowLevel); _medicalViewer.Cells[1].AddAction(MedicalViewerActionType.Scale); _medicalViewer.Cells[1].AddAction(MedicalViewerActionType.Offset); // assign the added actions to a mouse button, meaning that when the user clicks and drags the mouse button, the associated action will be activated. _medicalViewer.Cells[1].SetAction(MedicalViewerActionType.WindowLevel, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active); _medicalViewer.Cells[1].SetAction(MedicalViewerActionType.Scale, MedicalViewerMouseButtons.Middle, MedicalViewerActionFlags.Active); _medicalViewer.Cells[1].SetAction(MedicalViewerActionType.Offset, MedicalViewerMouseButtons.Right, MedicalViewerActionFlags.Active); // adjust some properties of the cell and add some tags. _medicalViewer.Cells[1].SetTag(2, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.UserData, "EX. ID 230-36-5448"); _medicalViewer.Cells[1].SetTag(4, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Frame); _medicalViewer.Cells[1].SetTag(6, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Scale); _medicalViewer.Cells[1].SetTag(2, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.WindowLevelData); _medicalViewer.Cells[1].SetTag(1, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.FieldOfView); Controls.Add(_medicalViewer); _medicalViewer.Dock = DockStyle.Fill; } public MedicalViewer Viewer { get { return _medicalViewer; } } } MedicalViewerCustomAnnotationForm GetMedicalControlForCustomAnnotationExample() { return new MedicalViewerCustomAnnotationForm(); } public void MedicalViewerCustomAnnotationExample() { MedicalViewerCustomAnnotationForm myForm = GetMedicalControlForCustomAnnotationExample(); MedicalViewer medicalViewer = myForm.Viewer; MedicalViewerMultiCell cell = (MedicalViewerMultiCell)(medicalViewer.Cells[0]); cell.AddAction((MedicalViewerActionType)101); cell.SetAction((MedicalViewerActionType)101, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active); cell.DeclareActionAsAnnotation((MedicalViewerActionType)101, typeof(MyTriangleObject)); cell.CustomAnnotationDataRequested += new EventHandler<MedicalViewerCustomAnnotationArgs>(cell_CustomAnnotationDataRequested); myForm.ShowDialog(); } void cell_CustomAnnotationDataRequested(object sender, MedicalViewerCustomAnnotationArgs e) { switch (e.RequestedObject) { case MedicalViewerCustomAnnotationRequestedObject.AnnotationObject: if (e.AnnotationAction == (MedicalViewerActionType)101) { MyTriangleObject triangle = new MyTriangleObject(); triangle.Pen = new AnnPen(Color.Blue, new AnnLength(3, AnnUnit.Pixel)); e.AnnotationObject = triangle; } break; case MedicalViewerCustomAnnotationRequestedObject.DrawDesigner: if (e.AnnotationAction == (MedicalViewerActionType)101) e.DrawDesigner = new MyTriangleObjectDrawDesigner(); break; case MedicalViewerCustomAnnotationRequestedObject.EditDesigner: if (e.AnnotationAction == (MedicalViewerActionType)101) e.EditDesigner = new MyTriangleObjectEditDesigner(); break; } } // // Triangle annotation object class // This class will have a 3 points for a triangle objects that can be stroked with a pen and filled with a brush // [Serializable] // our class must be serializable to play well with the annotation load/save and undo/redo features public class MyTriangleObject : AnnObject // must derive from AnnObject or one of its derived classes { // // our private variables // // the three points that define our triangle [NonSerialized()] private AnnPoint _firstPoint; [NonSerialized()] private AnnPoint _secondPoint; [NonSerialized()] private AnnPoint _thirdPoint; // // constructor // public MyTriangleObject() : base( true, // yes, we require a pen true, // yes, we require a brush false) // no, we do not require a font { // initialize the points _firstPoint = AnnPoint.Empty; _secondPoint = AnnPoint.Empty; _thirdPoint = AnnPoint.Empty; } // // ISerializable implementation // protected MyTriangleObject(SerializationInfo info, StreamingContext context) : base(info, context) // do not forget to call the base class version { // we need to deserialize our private variables here _firstPoint = (AnnPoint)info.GetValue("FirstPointName", typeof(AnnPoint)); _secondPoint = (AnnPoint)info.GetValue("SecondPointName", typeof(AnnPoint)); _thirdPoint = (AnnPoint)info.GetValue("ThirdPointName", typeof(AnnPoint)); } public override void GetObjectData(SerializationInfo info, StreamingContext context) { // we need to serialize our private variables here // call the base class version base.GetObjectData(info, context); // serialize the points info.AddValue("FirstPointName", _firstPoint, typeof(AnnPoint)); info.AddValue("SecondPointName", _secondPoint, typeof(AnnPoint)); info.AddValue("ThirdPointName", _thirdPoint, typeof(AnnPoint)); } // // accessors to the points // public AnnPoint FirstPoint { get { return _firstPoint; } set { _firstPoint = value; } } public AnnPoint SecondPoint { get { return _secondPoint; } set { _secondPoint = value; } } public AnnPoint ThirdPoint { get { return _thirdPoint; } set { _thirdPoint = value; } } // // AnnObject overrides // protected override AnnObject Create() { // must return a new instance of our class return new MyTriangleObject(); } public override object Clone() { // override the clone method // first call the base implementation MyTriangleObject obj = base.Clone() as MyTriangleObject; // next, copy the points obj.FirstPoint = FirstPoint; obj.SecondPoint = SecondPoint; obj.ThirdPoint = ThirdPoint; return obj; } public override GraphicsPath GetGraphicsPath(AnnGetGraphicsPathMode mode) { // must a return a graphics path representation of our object // Note: this object does not require us to override AnnObject.DrawObject since we can // use a graphics path to represents the object completely. // create a new graphics path GraphicsPath path = new GraphicsPath(); // add the triangle points as a series of lines // convert the points to pixels PointF PointF[] pts = { FirstPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF(), SecondPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF(), ThirdPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF() }; path.AddLines(pts); path.CloseFigure(); return path; } public override void ResetRotatePoints() { // Place the rotate center control point in the center of the triangle float CenterX = (FirstPoint.X + SecondPoint.X + ThirdPoint.X) / 3; float CenterY = (FirstPoint.Y + SecondPoint.Y + ThirdPoint.Y) / 3; RotateCenter = new AnnPoint(CenterX, CenterY); // Place the RotateGripper along a line from the center of the triangle through a vertex float cx = FirstPoint.X - RotateCenter.X; float cy = FirstPoint.Y - RotateCenter.Y; float dist = (float)Math.Sqrt(cx * cx + cy * cy); float fract = 1; if (dist != 0) fract = (Math.Abs(dist) + Math.Abs(GripperDistance)) / dist; float GripperX = CenterX + fract * cx; float GripperY = CenterY + fract * cy; RotateGripper = new AnnPoint(GripperX, GripperY); } } // // MyTriangleObject draw designer // Will require the user to click 3 times once for each point // public class MyTriangleObjectDrawDesigner : AnnDrawDesigner // must derive from AnnDrawDesigner or one of its derived classes { // // private variables // // we need to keep track on next point to add private int _clickCount; // // constructor // public MyTriangleObjectDrawDesigner() { _clickCount = 0; } // // AnnDrawDesigner overrides // public override bool MouseDown(MouseEventArgs e) { bool handled = false; // only process left button clicks if (e.Button == MouseButtons.Left) { // check if we have not started drawing yet, DrawObject will be null if (DrawObject == null) { // yes, create a new MyTriangleObject from ObjectTemplate MyTriangleObject obj = ObjectTemplate.Clone() as MyTriangleObject; // setup the points AnnPoint pt = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit); obj.FirstPoint = pt; obj.SecondPoint = pt; obj.ThirdPoint = pt; // start drawing this new object StartWorking(obj); handled = true; // we processed first click _clickCount++; } else { // an object is already being drawn, so process next click // get our object and assign next point to it MyTriangleObject obj = DrawObject as MyTriangleObject; AnnPoint pt = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit); if (_clickCount == 1) { // second point obj.SecondPoint = pt; _clickCount++; handled = true; } else if (_clickCount == 2) { // third point obj.ThirdPoint = pt; handled = true; // we are done! EndWorking(); } } } else { // we want to cancel the drawing if any other button has been clicked if (DrawObject != null) { Cancel(); handled = true; } } return handled; } public override bool MouseMove(MouseEventArgs e) { bool handled = false; // check if we are already drawing an object if (DrawObject != null) { // yes, get this object and assign the next point // first, save the old invalid rectangle Rectangle rcOld = DrawObject.InvalidRectangle; // get out object and assign the point MyTriangleObject obj = DrawObject as MyTriangleObject; AnnPoint pt = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit); if (_clickCount == 1) obj.SecondPoint = pt; else if (_clickCount == 2) obj.ThirdPoint = pt; // get the new invalid rectangle Rectangle rcNew = DrawObject.InvalidRectangle; // continue drawing this object Working(Rectangle.Union(rcOld, rcNew)); handled = true; } return handled; } public override bool MouseUp(MouseEventArgs e) { // we do not need to do anything special on mouse up. // so just see if we are drawing to return true (we handled it) bool handled = false; if (DrawObject == null) handled = true; return handled; } } // // MyTriangleObject edit designer // User can click on any of the points and move them around as well as clicking and dragging the object itself. // public class MyTriangleObjectEditDesigner : AnnEditDesigner // must derive from AnnEditDesigner or one of its derived classes { // // constructor // public MyTriangleObjectEditDesigner() { } // // AnnEditDesigner overrides // public override int ControlPointCount { get { // return the number of control points we need // in this case 3, one for each point in our triangle return 3; } } public override AnnPoint[] GetControlPointsLocation() { // return the position of these control points // in this case, same as the points from our object MyTriangleObject obj = EditObject as MyTriangleObject; return new AnnPoint[] { obj.FirstPoint, obj.SecondPoint, obj.ThirdPoint }; } protected override void MoveControlPoint(int controlPointIndex, AnnPoint pt) { // user has clicked and moved a point. // based on the index, we can tell if the user dragged the first, second or third point MyTriangleObject obj = EditObject as MyTriangleObject; switch (controlPointIndex) { case 0: // first point obj.FirstPoint = pt.ConvertTo(Container.UnitConverter, obj.FirstPoint.Unit); break; case 1: // second point obj.SecondPoint = pt.ConvertTo(Container.UnitConverter, obj.SecondPoint.Unit); break; case 2: // third point obj.ThirdPoint = pt.ConvertTo(Container.UnitConverter, obj.ThirdPoint.Unit); break; } } // Note, we will not override Move or MoveName since the default implementation is good enough for our object } static class LEAD_VARS { public const string ImagesDir = @"C:\Users\Public\Documents\LEADTOOLS Images"; }
using Leadtools;
using Leadtools.Drawing;
using Leadtools.Codecs;
using Leadtools.MedicalViewer;
using Leadtools.ImageProcessing;
using Leadtools.Annotations;
class MedicalViewerCustomAnnotationForm : Form
{
private MedicalViewer _medicalViewer;
void MedicalViewerForm_SizeChanged(object sender, EventArgs e)
{
_medicalViewer.Size = new Size(this.ClientRectangle.Right, this.ClientRectangle.Bottom);
}
public MedicalViewerCustomAnnotationForm()
{
RasterCodecs _codecs = new RasterCodecs();
RasterImage _image;
this.SizeChanged += new EventHandler(MedicalViewerForm_SizeChanged);
// Create the medical viewer and adjust the size and the location.
_medicalViewer = new MedicalViewer(1, 2);
_medicalViewer.Location = new Point(0, 0);
_medicalViewer.Size = new Size(this.ClientRectangle.Right, this.ClientRectangle.Bottom);
// Load an image and then add it to the control.
_image = _codecs.Load(Path.Combine(LEAD_VARS.ImagesDir,"xa.dcm"));
MedicalViewerMultiCell cell = new MedicalViewerMultiCell(_image, true, 1, 1);
// add some actions that will be used to change the properties of the images inside the control.
cell.AddAction(MedicalViewerActionType.WindowLevel);
cell.AddAction(MedicalViewerActionType.Scale);
cell.AddAction(MedicalViewerActionType.Offset);
// assign the added actions to a mouse button, meaning that when the user clicks and drags the mouse button, the associated action will be activated.
cell.SetAction(MedicalViewerActionType.WindowLevel, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active);
cell.SetAction(MedicalViewerActionType.Scale, MedicalViewerMouseButtons.Middle, MedicalViewerActionFlags.Active);
cell.SetAction(MedicalViewerActionType.Offset, MedicalViewerMouseButtons.Right, MedicalViewerActionFlags.Active);
_medicalViewer.Cells.Add(cell);
// adjust some properties of the cell and add some tags.
_medicalViewer.Cells[0].SetTag(2, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.UserData, "EX. ID 230-36-5448");
_medicalViewer.Cells[0].SetTag(4, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Frame);
_medicalViewer.Cells[0].SetTag(6, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Scale);
_medicalViewer.Cells[0].SetTag(2, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.WindowLevelData);
_medicalViewer.Cells[0].SetTag(1, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.FieldOfView);
// Load another image and then add it to the control.
_image = _codecs.Load(Path.Combine(LEAD_VARS.ImagesDir,"mr.dcm"));
_medicalViewer.Cells.Add(new MedicalViewerMultiCell(_image, true, 2, 2));
// add some actions that will be used to change the properties of the images inside the control.
_medicalViewer.Cells[1].AddAction(MedicalViewerActionType.WindowLevel);
_medicalViewer.Cells[1].AddAction(MedicalViewerActionType.Scale);
_medicalViewer.Cells[1].AddAction(MedicalViewerActionType.Offset);
// assign the added actions to a mouse button, meaning that when the user clicks and drags the mouse button, the associated action will be activated.
_medicalViewer.Cells[1].SetAction(MedicalViewerActionType.WindowLevel, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active);
_medicalViewer.Cells[1].SetAction(MedicalViewerActionType.Scale, MedicalViewerMouseButtons.Middle, MedicalViewerActionFlags.Active);
_medicalViewer.Cells[1].SetAction(MedicalViewerActionType.Offset, MedicalViewerMouseButtons.Right, MedicalViewerActionFlags.Active);
// adjust some properties of the cell and add some tags.
_medicalViewer.Cells[1].SetTag(2, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.UserData, "EX. ID 230-36-5448");
_medicalViewer.Cells[1].SetTag(4, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Frame);
_medicalViewer.Cells[1].SetTag(6, MedicalViewerTagAlignment.TopLeft, MedicalViewerTagType.Scale);
_medicalViewer.Cells[1].SetTag(2, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.WindowLevelData);
_medicalViewer.Cells[1].SetTag(1, MedicalViewerTagAlignment.BottomLeft, MedicalViewerTagType.FieldOfView);
Controls.Add(_medicalViewer);
_medicalViewer.Dock = DockStyle.Fill;
}
public MedicalViewer Viewer
{
get { return _medicalViewer; }
}
}
MedicalViewerCustomAnnotationForm GetMedicalControlForCustomAnnotationExample()
{
return new MedicalViewerCustomAnnotationForm();
}
public void MedicalViewerCustomAnnotationExample()
{
MedicalViewerCustomAnnotationForm myForm = GetMedicalControlForCustomAnnotationExample();
MedicalViewer medicalViewer = myForm.Viewer;
MedicalViewerMultiCell cell = (MedicalViewerMultiCell)(medicalViewer.Cells[0]);
cell.AddAction((MedicalViewerActionType)101);
cell.SetAction((MedicalViewerActionType)101, MedicalViewerMouseButtons.Left, MedicalViewerActionFlags.Active);
cell.DeclareActionAsAnnotation((MedicalViewerActionType)101, typeof(MyTriangleObject));
cell.CustomAnnotationDataRequested += new EventHandler<MedicalViewerCustomAnnotationArgs>(cell_CustomAnnotationDataRequested);
myForm.ShowDialog();
}
void cell_CustomAnnotationDataRequested(object sender, MedicalViewerCustomAnnotationArgs e)
{
switch (e.RequestedObject)
{
case MedicalViewerCustomAnnotationRequestedObject.AnnotationObject:
if (e.AnnotationAction == (MedicalViewerActionType)101)
{
MyTriangleObject triangle = new MyTriangleObject();
triangle.Pen = new AnnPen(Color.Blue, new AnnLength(3, AnnUnit.Pixel));
e.AnnotationObject = triangle;
}
break;
case MedicalViewerCustomAnnotationRequestedObject.DrawDesigner:
if (e.AnnotationAction == (MedicalViewerActionType)101)
e.DrawDesigner = new MyTriangleObjectDrawDesigner();
break;
case MedicalViewerCustomAnnotationRequestedObject.EditDesigner:
if (e.AnnotationAction == (MedicalViewerActionType)101)
e.EditDesigner = new MyTriangleObjectEditDesigner();
break;
}
}
//
// Triangle annotation object class
// This class will have a 3 points for a triangle objects that can be stroked with a pen and filled with a brush
//
[Serializable] // our class must be serializable to play well with the annotation load/save and undo/redo features
public class MyTriangleObject :
AnnObject // must derive from AnnObject or one of its derived classes
{
//
// our private variables
//
// the three points that define our triangle
[NonSerialized()]
private AnnPoint _firstPoint;
[NonSerialized()]
private AnnPoint _secondPoint;
[NonSerialized()]
private AnnPoint _thirdPoint;
//
// constructor
//
public MyTriangleObject()
:
base(
true, // yes, we require a pen
true, // yes, we require a brush
false) // no, we do not require a font
{
// initialize the points
_firstPoint = AnnPoint.Empty;
_secondPoint = AnnPoint.Empty;
_thirdPoint = AnnPoint.Empty;
}
//
// ISerializable implementation
//
protected MyTriangleObject(SerializationInfo info, StreamingContext context)
:
base(info, context) // do not forget to call the base class version
{
// we need to deserialize our private variables here
_firstPoint = (AnnPoint)info.GetValue("FirstPointName", typeof(AnnPoint));
_secondPoint = (AnnPoint)info.GetValue("SecondPointName", typeof(AnnPoint));
_thirdPoint = (AnnPoint)info.GetValue("ThirdPointName", typeof(AnnPoint));
}
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
// we need to serialize our private variables here
// call the base class version
base.GetObjectData(info, context);
// serialize the points
info.AddValue("FirstPointName", _firstPoint, typeof(AnnPoint));
info.AddValue("SecondPointName", _secondPoint, typeof(AnnPoint));
info.AddValue("ThirdPointName", _thirdPoint, typeof(AnnPoint));
}
//
// accessors to the points
//
public AnnPoint FirstPoint
{
get
{
return _firstPoint;
}
set
{
_firstPoint = value;
}
}
public AnnPoint SecondPoint
{
get
{
return _secondPoint;
}
set
{
_secondPoint = value;
}
}
public AnnPoint ThirdPoint
{
get
{
return _thirdPoint;
}
set
{
_thirdPoint = value;
}
}
//
// AnnObject overrides
//
protected override AnnObject Create()
{
// must return a new instance of our class
return new MyTriangleObject();
}
public override object Clone()
{
// override the clone method
// first call the base implementation
MyTriangleObject obj = base.Clone() as MyTriangleObject;
// next, copy the points
obj.FirstPoint = FirstPoint;
obj.SecondPoint = SecondPoint;
obj.ThirdPoint = ThirdPoint;
return obj;
}
public override GraphicsPath GetGraphicsPath(AnnGetGraphicsPathMode mode)
{
// must a return a graphics path representation of our object
// Note: this object does not require us to override AnnObject.DrawObject since we can
// use a graphics path to represents the object completely.
// create a new graphics path
GraphicsPath path = new GraphicsPath();
// add the triangle points as a series of lines
// convert the points to pixels PointF
PointF[] pts =
{
FirstPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF(),
SecondPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF(),
ThirdPoint.ConvertTo(UnitConverter, AnnUnit.Pixel).ToPointF()
};
path.AddLines(pts);
path.CloseFigure();
return path;
}
public override void ResetRotatePoints()
{
// Place the rotate center control point in the center of the triangle
float CenterX = (FirstPoint.X + SecondPoint.X + ThirdPoint.X) / 3;
float CenterY = (FirstPoint.Y + SecondPoint.Y + ThirdPoint.Y) / 3;
RotateCenter = new AnnPoint(CenterX, CenterY);
// Place the RotateGripper along a line from the center of the triangle through a vertex
float cx = FirstPoint.X - RotateCenter.X;
float cy = FirstPoint.Y - RotateCenter.Y;
float dist = (float)Math.Sqrt(cx * cx + cy * cy);
float fract = 1;
if (dist != 0)
fract = (Math.Abs(dist) + Math.Abs(GripperDistance)) / dist;
float GripperX = CenterX + fract * cx;
float GripperY = CenterY + fract * cy;
RotateGripper = new AnnPoint(GripperX, GripperY);
}
}
//
// MyTriangleObject draw designer
// Will require the user to click 3 times once for each point
//
public class MyTriangleObjectDrawDesigner :
AnnDrawDesigner // must derive from AnnDrawDesigner or one of its derived classes
{
//
// private variables
//
// we need to keep track on next point to add
private int _clickCount;
//
// constructor
//
public MyTriangleObjectDrawDesigner()
{
_clickCount = 0;
}
//
// AnnDrawDesigner overrides
//
public override bool MouseDown(MouseEventArgs e)
{
bool handled = false;
// only process left button clicks
if (e.Button == MouseButtons.Left)
{
// check if we have not started drawing yet, DrawObject will be null
if (DrawObject == null)
{
// yes, create a new MyTriangleObject from ObjectTemplate
MyTriangleObject obj = ObjectTemplate.Clone() as MyTriangleObject;
// setup the points
AnnPoint pt = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit);
obj.FirstPoint = pt;
obj.SecondPoint = pt;
obj.ThirdPoint = pt;
// start drawing this new object
StartWorking(obj);
handled = true;
// we processed first click
_clickCount++;
}
else
{
// an object is already being drawn, so process next click
// get our object and assign next point to it
MyTriangleObject obj = DrawObject as MyTriangleObject;
AnnPoint pt = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit);
if (_clickCount == 1)
{
// second point
obj.SecondPoint = pt;
_clickCount++;
handled = true;
}
else if (_clickCount == 2)
{
// third point
obj.ThirdPoint = pt;
handled = true;
// we are done!
EndWorking();
}
}
}
else
{
// we want to cancel the drawing if any other button has been clicked
if (DrawObject != null)
{
Cancel();
handled = true;
}
}
return handled;
}
public override bool MouseMove(MouseEventArgs e)
{
bool handled = false;
// check if we are already drawing an object
if (DrawObject != null)
{
// yes, get this object and assign the next point
// first, save the old invalid rectangle
Rectangle rcOld = DrawObject.InvalidRectangle;
// get out object and assign the point
MyTriangleObject obj = DrawObject as MyTriangleObject;
AnnPoint pt = GetLogicalAnnPoint(e.X, e.Y, obj.FirstPoint.Unit);
if (_clickCount == 1)
obj.SecondPoint = pt;
else if (_clickCount == 2)
obj.ThirdPoint = pt;
// get the new invalid rectangle
Rectangle rcNew = DrawObject.InvalidRectangle;
// continue drawing this object
Working(Rectangle.Union(rcOld, rcNew));
handled = true;
}
return handled;
}
public override bool MouseUp(MouseEventArgs e)
{
// we do not need to do anything special on mouse up.
// so just see if we are drawing to return true (we handled it)
bool handled = false;
if (DrawObject == null)
handled = true;
return handled;
}
}
//
// MyTriangleObject edit designer
// User can click on any of the points and move them around as well as clicking and dragging the object itself.
//
public class MyTriangleObjectEditDesigner :
AnnEditDesigner // must derive from AnnEditDesigner or one of its derived classes
{
//
// constructor
//
public MyTriangleObjectEditDesigner()
{
}
//
// AnnEditDesigner overrides
//
public override int ControlPointCount
{
get
{
// return the number of control points we need
// in this case 3, one for each point in our triangle
return 3;
}
}
public override AnnPoint[] GetControlPointsLocation()
{
// return the position of these control points
// in this case, same as the points from our object
MyTriangleObject obj = EditObject as MyTriangleObject;
return new AnnPoint[]
{
obj.FirstPoint,
obj.SecondPoint,
obj.ThirdPoint
};
}
protected override void MoveControlPoint(int controlPointIndex, AnnPoint pt)
{
// user has clicked and moved a point.
// based on the index, we can tell if the user dragged the first, second or third point
MyTriangleObject obj = EditObject as MyTriangleObject;
switch (controlPointIndex)
{
case 0:
// first point
obj.FirstPoint = pt.ConvertTo(Container.UnitConverter, obj.FirstPoint.Unit);
break;
case 1:
// second point
obj.SecondPoint = pt.ConvertTo(Container.UnitConverter, obj.SecondPoint.Unit);
break;
case 2:
// third point
obj.ThirdPoint = pt.ConvertTo(Container.UnitConverter, obj.ThirdPoint.Unit);
break;
}
}
// Note, we will not override Move or MoveName since the default implementation is good enough for our object
}
static class LEAD_VARS
{
public const string ImagesDir = @"C:\Users\Public\Documents\LEADTOOLS Images";
}
System.Object
System.ValueType
System.Enum
Leadtools.MedicalViewer.MedicalViewerCustomAnnotationRequestedObject