/release 0.1.1/Designer/Editors/MindMap/MindMapNeuron.cs
C# | 429 lines | 283 code | 45 blank | 101 comment | 34 complexity | 7ad86ecf01c0bdf7fdf0c975ed7f5bdd MD5 | raw file
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Windows;
- using System.Windows.Documents;
- using System.Windows.Media;
- using System.Windows.Shapes;
- using System.Xml;
- using System.Xml.Serialization;
- namespace NeuralNetworkDesigne.HAB.Designer
- {
- /// <summary>
- /// An item that can be displayed on a <see cref="MindMap"/> and that represents a <see cref="Neuron"/>.
- /// </summary>
- public class MindMapNeuron : PositionedMindMapItem, INeuronInfo, INeuronWrapper
- {
- #region fields
- Neuron fItem;
- NeuronData fItemData;
- int fChildCount;
- Shape fShape; //stores the shape that represents the neuron, required for drawing links.
- List<EdgePoint> fEdgePoints; //stores the edgepoints calculated on the shape.
- #endregion
- #region ctor
- /// <summary>
- /// Initializes a new instance of the <see cref="MindMapNeuron"/> class.
- /// </summary>
- /// <remarks>
- /// This is a private function so that the Create function needs to be used.
- /// </remarks>
- internal MindMapNeuron(Neuron item)
- {
- Item = item;
- }
- /// <summary>
- /// Initializes a new instance of the <see cref="MindMapNeuron"/> class.
- /// </summary>
- /// <remarks>
- /// This constructor is provided for streaming, should be fixed later on
- /// </remarks>
- public MindMapNeuron()
- {
- }
- public static MindMapNeuron CreateFor(Neuron item)
- {
- if (item is NeuronCluster)
- return new MindMapCluster((NeuronCluster)item);
- else
- return new MindMapNeuron(item);
- }
- #endregion
- #region prop
- #region NeuronInfo
- /// <summary>
- /// Gets the extra info stored about the <see cref="MindMapNeuron.Item"/>.
- /// </summary>
- [XmlIgnore]
- public NeuronData NeuronInfo
- {
- get
- {
- if (fItemData == null && Brain.Current != null && fItem != null)
- {
- fItemData = BrainData.Current.NeuronInfo[fItem.ID];
- if (fItemData != null)
- fItemData.PropertyChanged += new PropertyChangedEventHandler(ItemData_PropertyChanged);
- }
- return fItemData;
- }
- internal set { fItemData = value; }
- }
- #endregion
- #region Item
- /// <summary>
- /// Gets/sets the neuron that this mind map item represents.
- /// </summary>
- [XmlIgnore]
- public virtual Neuron Item
- {
- get
- {
- return fItem;
- }
- set
- {
- if (fItemData != null)
- fItemData.PropertyChanged -= new PropertyChangedEventHandler(ItemData_PropertyChanged);
- OnPropertyChanging("Item", fItem, value);
- fItem = value;
- fItemData = null;
- OnPropertyChanged("Item");
- OnPropertyChanged("Description"); //whenever ItemData changes, these 2 props are also triggered, cause we use the global data.
- OnPropertyChanged("DescriptionTitle");
- }
- }
- /// <summary>
- /// need to pass along the prop change, cause this is where we get the values for titel and
- /// description.
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- void ItemData_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
- {
- OnPropertyChanged(e.PropertyName);
- }
- #endregion
- #region ItemId
- /// <summary>
- /// Gets/sets the id of the neuron that this item represents.
- /// </summary>
- /// <remarks>
- /// This is primarely provided so we can easely stream this info.
- /// </remarks>
- [XmlElement("Neuron")]
- public ulong ItemID
- {
- get
- {
- if (fItem != null)
- return fItem.ID;
- else
- return Neuron.EmptyId;
- }
- set
- {
- if (value == Neuron.EmptyId)
- Item = null;
- else
- Item = Brain.Current[value];
- }
- }
- #endregion
- #region Shape
- /// <summary>
- /// Gets/sets the Shape that draws this neuron. This is used to calculate the edge for placing links.
- /// </summary>
- /// <remarks>
- /// We need the shape, not just the geometry, cause if we retrieve this, it is a snapshot and doesn't get
- /// updated.
- /// </remarks>
- [XmlIgnore]
- public Shape Shape
- {
- get
- {
- return fShape;
- }
- set
- {
- if (fShape != value)
- {
- fShape = value;
- fEdgePoints = null; //we must make certain that edgepoints are recalculated.
- OnPropertyChanged("Shape");
- }
- }
- }
- #endregion
- #region EdgePoints
- /// <summary>
- /// Gets the list of all the edgepoints for this object.
- /// </summary>
- [XmlIgnore]
- public List<EdgePoint> EdgePoints
- {
- get
- {
- if (fEdgePoints == null)
- {
- fEdgePoints = new List<EdgePoint>(360);
- PathGeometry iPath = Shape.RenderedGeometry.GetOutlinedPathGeometry(1, ToleranceType.Absolute); //need the outline of the object.
- TransformGroup iTransform = new TransformGroup(); //need to scale it a bit (bigger) for the margin.
- ScaleTransform iScale = new ScaleTransform(1 + (MindMapLink.Margin / iPath.Bounds.Width), 1 + (MindMapLink.Margin / iPath.Bounds.Height)); //margin is expressed in absolute values, so we need to convert it to relative to the width/height of the item
- iScale.CenterX = iPath.Bounds.Width / 2;
- iScale.CenterY = iPath.Bounds.Height / 2;
- iTransform.Children.Add(iScale);
- iTransform.Children.Add(new TranslateTransform(X, Y));
- iPath.Transform = iTransform;
- Point iTangent;
- Point iFound;
- Point iCenter = new Point(X + (Width / 2), Y + (Height / 2));
- for (int i = 0; i < 360; i++)
- {
- EdgePoint iEdge = new EdgePoint();
- fEdgePoints.Add(iEdge);
- iPath.GetPointAtFractionLength(i / 360.0, out iFound, out iTangent);
- iEdge.Point = iFound;
- iEdge.Angle = Helper.GetAnlge(iCenter, iEdge.Point);
- }
- }
- return fEdgePoints;
- }
- }
- #endregion
- #region Description
- /// <summary>
- /// We always use the global description data for neurons, so we don't store it and get the data from the braindata.
- /// </summary>
- [XmlIgnore]
- public override FlowDocument Description
- {
- get
- {
- if (NeuronInfo != null)
- return NeuronInfo.Description;
- else return null;
- }
- set
- {
- if (NeuronInfo != null)
- NeuronInfo.Description = value;
- }
- }
- #endregion
- #region DescriptionTitle
- /// <summary>
- /// used as the header of the description editor frame.
- /// </summary>
- public override string DescriptionTitle
- {
- get
- {
- if (NeuronInfo != null && string.IsNullOrEmpty(NeuronInfo.DisplayTitle) == false)
- return NeuronInfo.DisplayTitle;
- else if (fItem != null)
- return fItem.ToString();
- return null;
- }
- }
- #endregion
- #region ChildCount
- /// <summary>
- /// Gets the nr of times this neuron is a child of a cluster.
- /// </summary>
- /// <remarks>
- /// This property is automatically managed by the <see cref="MindMapCluster"/> objects.
- /// It can be used in the UI to indicate if an item is directly on the design surface or not.
- /// </remarks>
- [XmlIgnore]
- public int ChildCount
- {
- get
- {
- return fChildCount;
- }
- internal set
- {
- fChildCount = value;
- OnPropertyChanged("ChildCount");
- }
- }
- #endregion
- /// <summary>
- /// Gets/sets the height of the item.
- /// </summary>
- /// <value></value>
- /// <remarks>
- /// virtual so that <see cref="MindMapCluster"/> can check and change val as desired, depending on children.
- /// need to reset the edgepoints
- /// </remarks>
- public override double Height
- {
- get
- {
- return base.Height;
- }
- set
- {
- fEdgePoints = null; //we must make certain that edgepoints are recalculated.
- base.Height = value;
- }
- }
- /// <summary>
- /// Gets/sets the width of the item.
- /// </summary>
- /// <value>The width.</value>
- /// <remarks>
- /// virtual so that <see cref="MindMapCluster"/> can check and change val as desired, depending on children.
- /// need to reset the edgepoints
- /// </remarks>
- public override double Width
- {
- get
- {
- return base.Width;
- }
- set
- {
- fEdgePoints = null; //we must make certain that edgepoints are recalculated.
- base.Width = value;
- }
- }
- /// <summary>
- /// Gets/sets the horizontal offset of the item on the graph.
- /// </summary>
- /// <value></value>
- /// <remarks>
- /// virtual so that <see cref="MindMapCluster"/> can check and change val as desired, depending on children.
- /// need to reset the edgepoints
- /// </remarks>
- public override double X
- {
- get
- {
- return base.X;
- }
- set
- {
- fEdgePoints = null; //we must make certain that edgepoints are recalculated.
- base.X = value;
- }
- }
- /// <summary>
- /// Gets/sets the vertical offset of the item on the graph.
- /// </summary>
- /// <value></value>
- /// <remarks>
- /// virtual so that <see cref="MindMapCluster"/> can check and change val as desired, depending on children.
- /// need to reset the edgepoints
- /// </remarks>
- public override double Y
- {
- get
- {
- return base.Y;
- }
- set
- {
- fEdgePoints = null; //we must make certain that edgepoints are recalculated.
- base.Y = value;
- }
- }
- #region INeuronWrapper Members
- /// <summary>
- /// Gets the item.
- /// </summary>
- /// <value>The item.</value>
- Neuron INeuronWrapper.Item
- {
- get { return Item; }
- }
- #endregion
- #endregion
- #region Functions
- /// <returns>A deep copy of this object.</returns>
- public override MindMapItem Duplicate()
- {
- MindMapNeuron iRes = (MindMapNeuron)base.Duplicate();
- iRes.fItem = fItem;
- return iRes;
- }
- /// <summary>
- /// Copies the field values.
- /// </summary>
- /// <param name="from">from where to copy the data.</param>
- internal void CopyValues(MindMapNeuron from)
- {
- X = from.X;
- Y = from.Y;
- Width = from.Width;
- Height = from.Height;
- ZIndex = from.ZIndex;
- ChildCount = from.ChildCount;
- }
- /// <summary>
- /// Assigns this neuron to all the mindmap clusters in the list.
- /// </summary>
- /// <param name="clusters">The clusters.</param>
- internal void AssignToClusters(IEnumerable<MindMapCluster> clusters)
- {
- foreach (MindMapCluster i in clusters)
- {
- using (ChildrenAccessor iList = i.Cluster.Children)
- {
- if (iList.Contains(Item) == true)
- {
- i.MonditorChild(this);
- i.Children.Add(this);
- }
- }
- }
- }
- #endregion
- }
- }