/// <summary> Initialize a new instance of the <see cref="Controller"/> class. /// </summary> /// <param name="model"></param> public Controller(Renderer model) { _model = model; _startPoint = new EuclidianVector(); _endPoint = new EuclidianVector(); _clickPoint = new ScreenVector(); }
/// <summary> /// Constructor. /// </summary> /// <param name="model">The tree model to draw.</param> /// <param name="view">The view using this drawing model.</param> public Renderer(Model model, IView view) { // initialize mapping _nodeViewMap = new Dictionary <INode, NodeView>(); _view = view; _model = model; _screenPlaneOrigin = new ScreenVector(); _screenPlaneMaxPoint = new ScreenVector(); _ray = new double[4]; _ray[0] = model.Length; for (int i = 1; i < _ray.Length; i++) { _ray[i] = (_ray[0] + _ray[i - 1]) / (1 + (_ray[0] * _ray[i - 1])); } NodeModel __rootNodeModel = model.Root; if (__rootNodeModel.IsLeaf) { _rootNodeView = new NodeView(null, __rootNodeModel, this); } else { _rootNodeView = new CompositeNodeView(null, (CompositeNodeModel)__rootNodeModel, this); } this.Background = new LinearGradientBrush(Colors.Black, Colors.DarkBlue, 90); CompositionTarget.Rendering += UpdatePosition; }
/// <summary> Returns the minimal distance between this node /// and his father and his brother. /// </summary> /// <returns>The minimal distance.</returns> public virtual int GetSpace() { int __dF = -1; int __dB = -1; if (_parentNode != null) { ScreenVector __zF = _parentNode.ScreenCoordinates; __dF = _screenCoordinates.GetDistance(__zF); } if (_brother != null) { ScreenVector __zB = _brother.ScreenCoordinates; __dB = _screenCoordinates.GetDistance(__zB); } // this means that the node is a standalone node if ((__dF == -1) && (__dB == -1)) { return(int.MaxValue); } else if (__dF == -1) { return(__dB); } else if (__dB == -1) { return(__dF); } else { return(Math.Min(__dF, __dB)); } }
/// <summary> Called when the user moves the mouse over the hyperbolic tree. /// Used to signal the tree translation when the left button has been pressed over a node. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void MouseMoveHandler(object sender, MouseEventArgs e) { ScreenVector __p = this.GetPosition(sender, e); if (__p != null) { if (sender is Renderer) { Renderer __htDraw = ((Renderer)sender); __htDraw.ForEachNode(__p, delegate(NodeView node) { node.RenderIsMouseOver = true; }, delegate(NodeView node) { node.RenderIsMouseOver = false; } ); if (_statusButtonDown == true) { if (_startPoint.IsValid) { _endPoint.ProjectionStoE(__p.X, __p.Y, _model.SOrigin, _model.SMax); if (_endPoint.IsValid) { __htDraw.Translate(_startPoint, _endPoint); } } } } } }
private IView _view = null; // the view using this drawing model #endregion Fields #region Constructors /// <summary> /// Constructor. /// </summary> /// <param name="model">The tree model to draw.</param> /// <param name="view">The view using this drawing model.</param> public Renderer(Model model, IView view) { // initialize mapping _nodeViewMap = new Dictionary<INode, NodeView>(); _view = view; _model = model; _screenPlaneOrigin = new ScreenVector(); _screenPlaneMaxPoint = new ScreenVector(); _ray = new double[4]; _ray[0] = model.Length; for (int i = 1; i < _ray.Length; i++) { _ray[i] = (_ray[0] + _ray[i - 1]) / (1 + (_ray[0] * _ray[i - 1])); } NodeModel __rootNodeModel = model.Root; if (__rootNodeModel.IsLeaf) { _rootNodeView = new NodeView(null, __rootNodeModel, this); } else { _rootNodeView = new CompositeNodeView(null, (CompositeNodeModel)__rootNodeModel, this); } this.Background = new LinearGradientBrush(Colors.Black, Colors.DarkBlue, 90); CompositionTarget.Rendering += UpdatePosition; }
/// <summary> Performs the specified action on each child node of this node. /// </summary> /// <param name="zs">The given screen coordinate.</param> /// <param name="action">The <see cref="System.Action<T>"></see> delegate to perform on the node whose screen coordinates' zone contains thoses given in parameters.</param> /// <param name="actionElse">The <see cref="System.Action<T>"></see> delegate to perform on the node whose screen coordinates' zone do not contains thoses given in parameters.</param> public override void ForEach(ScreenVector zs, Action <NodeView> action, Action <NodeView> actionElse) { base.ForEach(zs, action, actionElse); foreach (NodeView child in _childNodes) { child.ForEach(zs, action, actionElse); } }
/// <summary> Returns the node (if any) whose screen coordinates' zone contains thoses given in parameters. /// </summary> /// <param name="zs">The given screen coordinate.</param> /// <returns>the searched <see cref="NodeView"/> if found; <code>null</code> otherwise.</returns> public virtual NodeView FindNode(ScreenVector zs) { if (this.Contains(zs)) { return(this); } else { return(null); } }
/// <summary> Performs the specified action on this node. /// </summary> /// <param name="zs">The given screen coordinate.</param> /// <param name="action">The <see cref="System.Action<T>"></see> delegate to perform on the node whose screen coordinates' zone contains thoses given in parameters.</param> /// <param name="actionElse">The <see cref="System.Action<T>"></see> delegate to perform on the node whose screen coordinates' zone do not contains thoses given in parameters.</param> public virtual void ForEach(ScreenVector zs, Action <NodeView> action, Action <NodeView> actionElse) { if (this.Contains(zs)) { action(this); } else { actionElse(this); } }
private ScreenVector _c = null; // control point (on the screen) #endregion #region Constructor /// <summary> Constructor. /// </summary> /// <param name="za">The first point.</param> /// <param name="zb">The second point.</param> public Geodesic(EuclidianVector za, EuclidianVector zb) { _za = za; _zb = zb; _zc = new EuclidianVector(); _zo = new EuclidianVector(); _a = new ScreenVector(); _b = new ScreenVector(); _c = new ScreenVector(); this.Rebuild(); }
private EuclidianVector _zo = null; // center of the geodesic; #endregion Fields #region Constructors /// <summary> Constructor. /// </summary> /// <param name="za">The first point.</param> /// <param name="zb">The second point.</param> public Geodesic(EuclidianVector za, EuclidianVector zb) { _za = za; _zb = zb; _zc = new EuclidianVector(); _zo = new EuclidianVector(); _a = new ScreenVector(); _b = new ScreenVector(); _c = new ScreenVector(); this.Rebuild(); }
/// <summary> Refresh the screen coordinates of this node and recurse on children. /// </summary> /// <param name="origin">The origin of the screen plane.</param> /// <param name="max">The (xMax, yMax) point in the screen plane.</param> public override void RefreshScreenCoordinates(ScreenVector origin, ScreenVector max) { base.RefreshScreenCoordinates(origin, max); foreach (NodeView child in _childNodes) { child.RefreshScreenCoordinates(origin, max); Geodesic geod = _geodesics[child]; if (geod != null) { geod.RefreshScreenCoordinates(origin, max); } } }
private bool _active = false; // should be drawed ? #endregion #region Constructor /// <summary> Constructor. /// </summary> /// <param name="parentNode">The father of this node.</param> /// <param name="nodeModel">The encapsulated <see cref="NodeModel"/>.</param> /// <param name="renderer">The drawing model.</param> public NodeView(CompositeNodeView parentNode, NodeModel nodeModel, Renderer renderer) { _parentNode = parentNode; _nodeModel = nodeModel; _renderer = renderer; this.Opacity = 0.9; this.Child = new NodeLabel(this); _ze = new EuclidianVector(nodeModel.OriginalCoordinates); _oldZe = new EuclidianVector(_ze); _screenCoordinates = new ScreenVector(); // store this object in INode -> NodeView mapping renderer.MapNode(nodeModel.Node, this); renderer.Children.Add(this); }
private EuclidianVector _ze = null; // current euclidian coordinates #endregion Fields #region Constructors /// <summary> Constructor. /// </summary> /// <param name="parentNode">The father of this node.</param> /// <param name="nodeModel">The encapsulated <see cref="NodeModel"/>.</param> /// <param name="renderer">The drawing model.</param> public NodeView(CompositeNodeView parentNode, NodeModel nodeModel, Renderer renderer) { _parentNode = parentNode; _nodeModel = nodeModel; _renderer = renderer; this.Opacity = 0.9; this.Child = new NodeLabel(this); _ze = new EuclidianVector(nodeModel.OriginalCoordinates); _oldZe = new EuclidianVector(_ze); _screenCoordinates = new ScreenVector(); // store this object in INode -> NodeView mapping renderer.MapNode(nodeModel.Node, this); renderer.Children.Add(this); }
/// <summary> Is the given <see cref="ScreenVector"/> within this control ? /// </summary> /// <param name="zs">The given point.</param> /// <returns><code>true</code> if it is, <code>false</code> otherwise.</returns> public bool Contains(ScreenVector zs) { if (_active) { if ((zs.X >= Canvas.GetLeft(this)) && (zs.X <= (Canvas.GetLeft(this) + this.Width)) && (zs.Y >= Canvas.GetTop(this)) && (zs.Y <= (Canvas.GetTop(this) + this.Height))) { return(true); } else { return(false); } } else { return(this.ScreenCoordinates.Contains(zs)); } }
/// <summary> Called when a user pressed the mouse button on the hyperbolic tree. /// Used to get the starting point of the drag. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void MouseDownHandler(object sender, MouseButtonEventArgs e) { if (e.OriginalSource is System.Windows.Controls.TextBlock) { ScreenVector __p = GetPosition(sender, e); if (__p != null) { if (sender is Renderer) { Renderer __htDraw = ((Renderer)sender); NodeView __node = __htDraw.FindNode(__p); if (__node != null) { __node.RenderIsPressed = true; } else { foreach (NodeView __n in __htDraw.Children) { __n.RenderIsPressed = false; } } } _startPoint.ProjectionStoE(__p.X, __p.Y, _model.SOrigin, _model.SMax); _clickPoint.X = __p.X; _clickPoint.Y = __p.Y; if (e.ClickCount > 1) { _statusButtonDown = false; MouseClicked(sender, e); } else { _statusButtonDown = true; } } } }
/// <summary> Draw this node. /// Adjust size and position accordingly to the font metrics. /// </summary> /// <param name="dc">The graphic canvas.</param> public virtual void DrawNodes(DrawingContext dc) { //get the font metrics FontFamily __font = new FontFamily("Arial"); FormattedText __formattedText = new FormattedText( this.NodeName, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface( __font, FontStyles.Normal, FontWeights.Light, FontStretches.Normal), 10, Brushes.Black ); int __height = (int)__formattedText.Height; int __width = (int)__formattedText.Width; this.Height = __height + 2 * this.Size; this.Width = __width + 10 + 2 * this.Size; ScreenVector __zs = this.ScreenCoordinates; double __x = __zs.X - (this.Width / 2) - this.Size; double __y = __zs.Y - (this.Height / 2) - this.Size; int __space = this.GetSpace(); if (__space >= __height) { _active = true; this.Visibility = Visibility.Visible; Canvas.SetLeft(this, __x); Canvas.SetTop(this, __y); } else { _active = false; this.Visibility = Visibility.Collapsed; } }
/// <summary> Returns the node (if any) whose screen coordinates's zone contains thoses given in parameters. /// </summary> /// <param name="zs">The given screen coordinate.</param> /// <returns>The searched <see cref="NodeView"/> if found; <code>null</code> otherwise.</returns> public override NodeView FindNode(ScreenVector zs) { NodeView __result = base.FindNode(zs); if (__result != null) { return(__result); } else { foreach (NodeView child in _childNodes) { __result = child.FindNode(zs); if (__result != null) { return(__result); } } return(null); } }
/// <summary> Called when a user release the mouse button on the hyperbolic tree. /// Used to signal the end of the translation. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void MouseUpHandler(object sender, MouseButtonEventArgs e) { ScreenVector __p = GetPosition(sender, e); if (__p != null) { if (sender is Renderer) { Renderer __htDraw = ((Renderer)sender); NodeView __node = __htDraw.FindNode(__p); if (__node != null) { __node.RenderIsPressed = false; } else { foreach (NodeView __n in __htDraw.Children) { __n.RenderIsPressed = false; } } __htDraw.EndTranslation(); //uncomment this to allow translate on simple node click if (_statusButtonDown) { if (__p.X - _clickPoint.X < 5 && __p.Y - _clickPoint.Y < 5) { this.MouseClicked(sender, e); } } } _statusButtonDown = false; } }
/// <summary> Returns the minimal distance between this node and his father and his brother. /// </summary> /// <returns>The minimal distance.</returns> public override int GetSpace() { int __space = base.GetSpace(); if (_childNodes.Count > 0) { NodeView __child = _childNodes[0]; ScreenVector __zC = __child.ScreenCoordinates; int __dC = this.ScreenCoordinates.GetDistance(__zC); if (__space == -1) { return(__dC); } else { return(Math.Min(__space, __dC)); } } else { return(__space); } }
/// <summary> Constructor copying the given screen point. /// </summary> /// <param name="z">The screen point to copy.</param> public ScreenVector(ScreenVector z) { _x = z._x; _y = z._y; }
/// <summary> Projects the given Euclidian point on the screen plane. /// </summary> /// <param name="ze">The euclidian point.</param> /// <param name="sOrigin">The origin of the screen plane.</param> /// <param name="sMax">The (xMax, yMax) point in the screen plane.</param> public void ProjectionEtoS(EuclidianVector ze, ScreenVector sOrigin, ScreenVector sMax) { _x = (int)Math.Round(ze.X * sMax._x) + sOrigin._x; _y = -(int)Math.Round(ze.Y * sMax._y) + sOrigin._y; }
/// <summary> Refresh the screen coordinates of this node. /// </summary> /// <param name="origin">The origin of the screen plane.</param> /// <param name="max">The (xMax, yMax) point in the screen plane.</param> public virtual void RefreshScreenCoordinates(ScreenVector origin, ScreenVector max) { _screenCoordinates.ProjectionEtoS(_ze, origin, max); }
/// <summary> Performs the specified action on this node. /// </summary> /// <param name="zs">The given screen coordinate.</param> /// <param name="action">The <see cref="System.Action<T>"></see> delegate to perform on the node whose screen coordinates' zone contains thoses given in parameters.</param> /// <param name="actionElse">The <see cref="System.Action<T>"></see> delegate to perform on the node whose screen coordinates' zone do not contains thoses given in parameters.</param> public virtual void ForEach(ScreenVector zs, Action<NodeView> action, Action<NodeView> actionElse) { if (this.Contains(zs)) { action(this); } else { actionElse(this); } }
/// <summary> Returns the node (if any) whose screen coordinates' zone contains thoses given in parameters. /// </summary> /// <param name="zs">The given screen coordinate.</param> /// <returns>the searched <see cref="NodeView"/> if found; <code>null</code> otherwise.</returns> public virtual NodeView FindNode(ScreenVector zs) { if (this.Contains(zs)) { return this; } else { return null; } }
/// <summary> Is the given <see cref="ScreenVector"/> within this control ? /// </summary> /// <param name="zs">The given point.</param> /// <returns><code>true</code> if it is, <code>false</code> otherwise.</returns> public bool Contains(ScreenVector zs) { if (_active) { if ((zs.X >= Canvas.GetLeft(this)) && (zs.X <= (Canvas.GetLeft(this) + this.Width)) && (zs.Y >= Canvas.GetTop(this)) && (zs.Y <= (Canvas.GetTop(this) + this.Height))) { return true; } else { return false; } } else { return this.ScreenCoordinates.Contains(zs); } }
/// <summary> Performs the specified action on each child node of the node with the specified coordinates. /// </summary> /// <param name="zs">The given screen coordinate.</param> /// <param name="action">The <see cref="System.Action<T>"></see> delegate to perform on each node.</param> public void ForEachNode(ScreenVector zs, Action <NodeView> action, Action <NodeView> actionElse) { _rootNodeView.ForEach(zs, action, actionElse); }
/// <summary> Returns the node (if any) whose screen coordinates' zone /// contains thoses given in parameters. /// </summary> /// <param name="zs">The given screen coordinate.</param> /// <returns>The searched <see cref="HtDrawNode"/> if found; /// <code>null</code> otherwise</returns> public NodeView FindNode(ScreenVector zs) { return _rootNodeView.FindNode(zs); }
/// <summary> Returns the distance between this point and the given point. /// </summary> /// <param name="z">The given point.</param> /// <returns>The distance.</returns> public int GetDistance(ScreenVector z) { int __d2 = (z._x - _x) * (z._x - _x) + (z._y - _y) * (z._y - _y); return((int)Math.Round(Math.Sqrt(__d2))); }
/// <summary> Refresh the screen coordinates of this node. /// </summary> /// <param name="origin">The origin of the screen plane.</param> /// <param name="max">The (xMax, yMax) point in the screen plane.</param> public void RefreshScreenCoordinates(ScreenVector origin, ScreenVector max) { _a.ProjectionEtoS(_za, origin, max); _b.ProjectionEtoS(_zb, origin, max); _c.ProjectionEtoS(_zc, origin, max); }
/// <summary> Performs the specified action on each child node of the node with the specified coordinates. /// </summary> /// <param name="zs">The given screen coordinate.</param> /// <param name="action">The <see cref="System.Action<T>"></see> delegate to perform on each node.</param> public void ForEachNode(ScreenVector zs, Action<NodeView> action, Action<NodeView> actionElse) { _rootNodeView.ForEach(zs, action, actionElse); }
/// <summary> Is the given HtCoordS within the zone length of this HtCoordS ? /// </summary> /// <param name="zs"></param> /// <returns>true if it is, false otherwise</returns> public bool Contains(ScreenVector zs) { int __length = this.GetDistance(zs); return(__length <= ZONE_LENGTH); }
/// <summary> Projects from Screen to Euclidian. /// </summary> /// <param name="x">The x screen coordinate.</param> /// <param name="y">The y screen coordinate.</param> /// <param name="origin">The origin of the screen plane.</param> /// <param name="max">The (xMax, yMax) point in the screen plane.</param> public void ProjectionStoE(int x, int y, ScreenVector origin, ScreenVector max) { _x = (double)(x - origin.X) / (double)max.X; _y = -((double)(y - origin.Y) / (double)max.Y); }
/// <summary> Returns the node (if any) whose screen coordinates' zone /// contains thoses given in parameters. /// </summary> /// <param name="zs">The given screen coordinate.</param> /// <returns>The searched <see cref="HtDrawNode"/> if found; /// <code>null</code> otherwise</returns> public NodeView FindNode(ScreenVector zs) { return(_rootNodeView.FindNode(zs)); }
/// <summary> Is the given HtCoordS within the zone length of this HtCoordS ? /// </summary> /// <param name="zs"></param> /// <returns>true if it is, false otherwise</returns> public bool Contains(ScreenVector zs) { int __length = this.GetDistance(zs); return __length <= ZONE_LENGTH; }
/// <summary> Returns the distance between this point and the given point. /// </summary> /// <param name="z">The given point.</param> /// <returns>The distance.</returns> public int GetDistance(ScreenVector z) { int __d2 = (z._x - _x) * (z._x - _x) + (z._y - _y) * (z._y - _y); return (int)Math.Round(Math.Sqrt(__d2)); }