/*============================================================================= Project: SharpImage Module: siSeedSelector.cs Language: C# Author: Dan Mueller Date: $Date: 2007-07-06 10:57:00 +1000 (Fri, 06 Jul 2007) $ Revision: $Revision: 2 $ Copyright (c) Queensland University of Technology (QUT) 2007. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =============================================================================*/ using System; using System.Collections.Generic; using System.Text; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Windows.Forms; using System.Diagnostics; using SharpImage.Main; using SharpImage.Properties; namespace SharpImage.Rendering { public class siSeedSelector : siActor { #region Instance Variables //===================================================================== //========================================================================= #endregion #region Construction and Disposal //===================================================================== /// /// Public constuctor. /// /// The Renderer to which this Actor is attached. public siSeedSelector(siRenderer renderer) : base(renderer) { } //===================================================================== #endregion #region Properties //===================================================================== #region Seeds //===================================================================== private List m_Seeds = new List(); /// /// Gets the list of seeds. /// public List Seeds { get { return this.m_Seeds; } } //===================================================================== #endregion //===================================================================== #endregion #region Events //===================================================================== public delegate void siSeedHandler(siSeedSelector sender, itk.itkIndex seed); private siSeedHandler m_EventStorage_SeedAdded; private siSeedHandler m_EventStorage_SeedSelected; /// /// An event raised when the user adds a seed. /// public event siSeedHandler SeedAdded { add { this.m_EventStorage_SeedAdded += value; } remove { this.m_EventStorage_SeedAdded -= value; } } /// /// An event raised when the user selects an existing seed. /// public event siSeedHandler SeedSelected { add { this.m_EventStorage_SeedSelected += value; } remove { this.m_EventStorage_SeedSelected -= value; } } /// /// Raises the SeedAdded event. /// /// private void RaiseSeedAdded(itk.itkIndex seed) { if (this.m_EventStorage_SeedAdded != null) { this.m_EventStorage_SeedAdded(this, seed); this.RaiseModified(); } } /// /// Raises the SeedSelected event. /// /// private void RaiseSeedSelected(itk.itkIndex seed) { if (this.m_EventStorage_SeedSelected != null) { this.m_EventStorage_SeedSelected(this, seed); this.RaiseModified(); } } //===================================================================== #endregion #region Public Methods //===================================================================== /// /// Changes the currently selected seed. /// The seed value can be null to unselect all seeds. /// /// public void SelectSeed(itk.itkIndex seed) { this.Metadata["SelectedSeed"] = seed; this.RaiseModified(); } /// /// Removes the given seed from the list. /// /// public void RemoveSeed(itk.itkIndex seed) { this.Seeds.Remove(seed); this.RaiseModified(); } /// /// Removes all the seeds from the list /// public void ClearSeeds() { this.Seeds.Clear(); this.RaiseModified(); } //===================================================================== #endregion #region Actor Methods //===================================================================== /// /// Allows the actor to render itself. /// /// protected override void OnPaint(PaintEventArgs e) { // Check the Renderer has all the required Metadata variables if (!this.Parent.ContainsMetadata("CurrentSlice", "ImageScreenRectangle")) return; // Set to draw smooth Graphics g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; // Setup for rendering the seed location siGdiSliceRenderer rendererGDI = this.Parent as siGdiSliceRenderer; Pen pen = new Pen(new SolidBrush(Color.Red), 1.0F); const float width = 9.0F; const float widthHalf = width / 2.0F; float crossLength = (widthHalf / (float)Math.Cos(Math.PI / 4.0)) / 2.0F; // Enumerate the seed list foreach (itk.itkIndex seed in this.Seeds) { // Check the seed is visible at the moment (assumes the GdiSliceRenderer) if ( seed.Dimension == 2 || (seed.Dimension == 3 && (int)this.Parent.Metadata["CurrentSlice"] == seed[2])) { // Get info for drawing seed RectangleF rectImageScreen = (RectangleF)this.Parent.Metadata["ImageScreenRectangle"]; PointF pointScreen = rendererGDI.TransformImageIndexToScreenPoint(seed, rectImageScreen); // Check if the seed is selected if (this.Metadata.ContainsKey("SelectedSeed") && (this.Metadata["SelectedSeed"] as itk.itkIndex) == seed) { // Draw larger circle around selected seed RectangleF rectSelected = new RectangleF(pointScreen.X - widthHalf - 2.0F, pointScreen.Y - widthHalf - 2.0F, width + 4.0F, width + 4.0F); g.DrawArc(pen, rectSelected, 0.0F, 360.0F); } // Draw RectangleF rect = new RectangleF(pointScreen.X - widthHalf, pointScreen.Y - widthHalf, width, width); g.DrawArc(pen, rect, 0.0F, 360.0F); g.DrawLine(pen, pointScreen.X - crossLength, pointScreen.Y - crossLength, pointScreen.X + crossLength, pointScreen.Y + crossLength); g.DrawLine(pen, pointScreen.X - crossLength, pointScreen.Y + crossLength, pointScreen.X + crossLength, pointScreen.Y - crossLength); } }//end enumerate seeds } /// /// Allows the actor to consume the MouseDown event. /// /// protected override bool OnMouseDown(MouseEventArgs e) { // Only consume if a left button click if (e.Button != MouseButtons.Left) return false; // Check the Renderer has all the required Metadata variables if (!this.Parent.ContainsMetadata("IsMouseInsideImageSpace", "LastImageIndexMouseDown")) return false; // Add the seed if ((bool)this.Parent.Metadata["IsMouseInsideImageSpace"]) { // Get the index itk.itkIndex seed = (itk.itkIndex)this.Parent.Metadata["LastImageIndexMouseDown"]; // Check the seed is not already added to the list foreach (itk.itkIndex seedAlreadyInList in this.Seeds) { if (seedAlreadyInList == seed) { // Select this seed this.Metadata["SelectedSeed"] = seed; this.RaiseSeedSelected(seed); return true; } } // Add the seed to the list, it is unique this.Seeds.Add(seed); this.Metadata["SelectedSeed"] = seed; this.RaiseSeedAdded(seed); return true; } return false; } //===================================================================== #endregion } }