Example #1
0
 //public virtual int GetLengthBefore(TikzParseItem tpi)
 //{
 //    return ToString().Length; //
 //}
 /// <summary>
 /// This method triggers a TextChanged event in the root of the parse tree.
 /// </summary>
 /// <param name="sender">The node whose text was changed.</param>
 /// <param name="oldtext">the text of the node before the change.</param>
 public virtual void RaiseTextChanged(TikzParseItem sender, string oldtext)
 {
     if (parent != null)
         parent.RaiseTextChanged(sender, oldtext);
 }
Example #2
0
        /// <summary>
        /// Adjusts the current coordinates (seen as coordinates of relto)
        /// such that relto sits at p in absolute coordinates.
        /// The extra parameter is needed since this method is called by Tikz_Node, which
        /// contains a Tikz_Coord object. (In that case relto will be the Tikz_Node)
        /// relto is used to query, e.g., the current position in the Tikz Path.
        /// (Which is a parent of relto, but not of the current coordinate.)
        /// </summary>
        /// <param name="p">The new absolute (cartesian) coordinates, in cm</param>
        /// <param name="relto">Object with respect to which the coordinate transformation is determined</param>
        public void SetAbsPos(Point p, TikzParseItem relto)
        {
            if (IsBroken || type == Tikz_CoordType.Named)
            {
                // cannot change coord
            }
            else
            {
                Point relp; // will hold the new coordinates, in the current coordinate system
                TikzMatrix MM;
                if (!relto.parent.GetCurrentTransformAt(relto, out MM))
                    return; // broken coord trafo -> do nothing
                MM = MM.Inverse();

                if (deco == "+" || deco == "++")
                {
                    Point offset;
                    if (relto.parent is Tikz_Controls)
                    {
                        Tikz_Controls par = relto.parent as Tikz_Controls;
                        Tikz_XYItem offc = null;
                        if (relto == par.FirstCP)
                            offc = par.CoordBefore;
                        else if (relto == par.LastCP)
                            offc = par.CoordAfter;
                        if (offc == null || !offc.GetAbsPos(out offset))
                            return;
                        relp = new Point(p.X - offset.X, p.Y - offset.Y);   // the desired shift, in absolute coordinates
                        relp = MM.Transform(relp, true);
                    }
                    else if ((relto.parent as Tikz_Path).GetAbsOffset(out offset, relto))
                    {
                        relp = new Point(p.X - offset.X, p.Y - offset.Y);   // the desired shift, in absolute coordinates
                        relp = MM.Transform(relp, true);
                    }
                    else
                    {
                        // error in determining offset -> cannot set coordinate
                        return;
                    }
                }
                else
                {
                    relp = MM.Transform(new Point(p.X, p.Y));   // this is the target point in current coordinate system
                }

                if (type == Tikz_CoordType.Polar)
                {
                    relp = Helper.CartToPolTC(relp);

                }
                uX.SetInCM(relp.X);
                uY.SetInCM(relp.Y);
            }
        }
Example #3
0
        /// <summary>
        /// Get the last item that changes the "current position" in a tikz path.
        /// This implememntation is not yet entirely accurate at present.... for example  ... edge (v) .. does not change the current position.
        /// </summary>
        /// <param name="before">The item before which we should search.</param>
        /// <param name="ret">The last item that changed the current position.</param>
        /// <param name="VeryCurrent">Whether to return the last item changing the "very current" position (see GetAbsOffset).</param>
        /// <returns></returns>
        bool GetLastDrawnItem(TikzParseItem before, out Tikz_XYItem ret, bool VeryCurrent )
        {
            int ind;
            if (before == null)
                ind = Children.Count;
            else
                ind = Children.IndexOf(before);

            //CoordTrafoInBetween = new TikzMatrix();
            for (int i = ind - 1; i >= 0; i--)
            {
                if (Children[i] is Tikz_Coord)
                {
                    Tikz_Coord tc = Children[i] as Tikz_Coord;

                    if (tc.type == Tikz_CoordType.Named || tc.deco != "+" || VeryCurrent)  
                    {
                        ret = tc;
                        return true;
                    }
                }
                else if (Children[i] is Tikz_Arc)
                {
                    ret = Children[i] as Tikz_Arc;
                    return true;
                }
                //else if (Children[i] is Tikz_Options)
                //{
                //    CoordTrafoInBetween = (Children[i] as Tikz_Options).GetTransform() * CoordTrafoInBetween;
                //}
                else if (Children[i] is Tikz_Path)
                {
                    Tikz_Path tp = (Children[i] as Tikz_Path);
                    Tikz_XYItem tpi;
                    //TikzMatrix M; // not used here
                    bool lret = tp.GetLastDrawnItem(null, out tpi, VeryCurrent);
                    if (lret)
                    {
                        ret = tpi;
                        return true;
                    }
                }
            }

            // nothing found -> look in parent
            if (this.parent is Tikz_Path)
            {
                Tikz_Path tparent = parent as Tikz_Path;
                Tikz_XYItem tpi;
                if (tparent.GetLastDrawnItem(this, out tpi, VeryCurrent))
                {
                    ret = tpi;
                    return true;
                }
            }

            // if we come here, nothing has been found...
            ret = null;
            return false;
        }
Example #4
0
 public bool IsChildOfOrSelf(TikzParseItem tpi)
 {
     return (this == tpi) || Ancestors.Contains(tpi);
 }
Example #5
0
 public override void RaiseTextChanged(TikzParseItem sender, string oldtext)
 {
     if (TextChanged != null)
         TextChanged(this, new ParseTreeTextChangedEventArgs() { ChangedItem=sender, OldText=oldtext });
     //base.RaiseTextChanged(sender, oldtext);
 }
Example #6
0
        /// <summary>
        /// Gets the offset, i.e., the current drawing position at some
        /// position along the path. (in absolute Cartesian coordinates)
        /// This is used to determine the absolute position of items specified with relative 
        /// coordinates like +(1,1).
        /// 
        /// Note that in Tikz two offsets are relevant:
        /// Example:
        /// \draw (0,0) +(1,1) node {1} +(3,3) -- (5,5);
        /// Node 1 is placed at +(1,1), the "very current" position.
        /// The coordinate +(3,3) is taken relative to the "current position", i.e., (0,0).
        /// </summary>
        /// <param name="tpi">The item just before which the current drawing position is to be determined.</param>
        /// <param name="VeryCurrent">Whether to "very current" position.</param>
        /// <returns>True, if offset could be determined, false otherwise.</returns>
        public bool GetAbsOffset(out Point ret, TikzParseItem tpi, bool VeryCurrent = false)
        {
            Tikz_XYItem tcret;
            if (GetLastDrawnItem(tpi, out tcret, VeryCurrent))
            {
                // last drawn item exists
                TikzMatrix M2, M1;
                if (!GetCurrentTransformAt(tpi, out M2) || !tcret.parent.GetCurrentTransformAt(tcret, out M1))
                {
                    ret = new Point(0, 0);
                    return false;
                }
                Point p1;
                if (tcret.GetAbsPos(out p1))
                {
                    // p1 = M2 * orig point; offset = M1 * orig point (I guess) => offset = M1 * I(M2) * p1
                    ret = (M2 * (M1.Inverse())).Transform(p1);
                    return true;
                }
                else
                {
                    ret = new Point(0, 0);
                    return false;
                }
            }
            else
            {
                // no item was drawn before.... take origin (...after coord transform)
                TikzMatrix M;
                if (!GetCurrentTransformAt(tpi, out M))
                {
                    ret = new Point(0, 0);
                    return false;
                }
                ret = M.Transform(new Point(0, 0));
                return true;
            }
            /*int ind = Children.IndexOf(tpi);
                        Tikz_Coord previous = null;
                        for (int i = ind - 1; i >= 0; i--)
                        {
                            if (Children[i] is Tikz_Coord)
                            {
                                Tikz_Coord tc = Children[i] as Tikz_Coord;

                                if (tc.type == Tikz_CoordType.Named || tc.deco != "+")
                                {
                                    previous = tc;
                                    break;
                                }
                            }
                        }
                        if (previous == null)
                            return GetCurrentTransformAt(tpi).Transform(new Point(0,0));
                        else 
                            return previous.GetAbsPos(); */
        }
Example #7
0
      /*  public TikzMatrix GetCurrentTransform()
        {
            TikzMatrix M;
            //M = Tikz_Options.GetTransform(this);
            if (options != null)
                M = options.GetTransform();
            else
                M = new TikzMatrix();
            if (parent != null)
                M = parent.GetCurrentTransform() * M;
            return M;
        } */
        /// <summary>
        /// Determines the coordinate transformation at object childtpi,
        /// or at the end of the container in case childtpi is null.
        /// </summary>
        /// <param name="childtpi">The object to determine coordinate trsf. at.</param>
        /// <returns>The coordinate transformation.</returns>
        public bool GetCurrentTransformAt(TikzParseItem childtpi, out TikzMatrix M)
        {
            if (parent != null)
            {
                if (!parent.GetCurrentTransformAt(this, out M))
                    return false;
            }
            else
                M = new TikzMatrix(); // identity matrix

            foreach (TikzParseItem tpi in Children)
            {
                if (tpi == childtpi && childtpi != null)
                {
                    break;
                }
                else if (tpi is Tikz_Options)
                {
                    TikzMatrix MM;
                    if ((tpi as Tikz_Options).GetTransform(out MM))
                        M = M * MM;
                    else
                        return false;
                }
            }
            return true;
        }
Example #8
0
        public void SetCorrectRaster(TikzParseItem tpi, bool IsParent = false)
        {
            if (ParseTree == null)
                return;
            if (tpi == null)
            {
                Tikz_Picture tp = ParseTree.GetTikzPicture();
                if (tp != null)
                {
                    TikzMatrix M;
                    if (!tp.GetCurrentTransformAt(null, out M))
                        Rasterizer.View.CoordinateTransform = new TikzMatrix();   // if the program gets here, the global coord. transformation could not be understood->ovelay should display nothing
                    else
                        Rasterizer.View.CoordinateTransform = M;
                    //rasterizer.RasterOrigin = M.Transform(new Point(0, 0));
                    //rasterizer.RasterScale = M.m[1, 1];
                    Rasterizer.View.IsCartesian = !UsePolarCoordinates;
                }
            }
            else if (tpi is Tikz_Scope)
            {
                Tikz_Scope ts = tpi as Tikz_Scope;
                TikzMatrix M;
                if (IsParent)
                {
                    if (!ts.GetCurrentTransformAt(null, out M))  // todo
                        M = new TikzMatrix(); // broken coords-> take unity as backup
                }
                else
                {
                    //if (!ts.parent.GetCurrentTransformAt(ts, out M))
                    //    M = new TikzMatrix();
                    if (!ts.GetRasterTransform(out M))
                        M = new TikzMatrix();
                }
                Rasterizer.View.CoordinateTransform = M;
                //rasterizer.RasterOrigin = M.Transform(new Point(0, 0));
                //rasterizer.RasterScale = M.m[1, 1];
                Rasterizer.View.IsCartesian = !IsParent || !UsePolarCoordinates;
            }
            else if (tpi is Tikz_XYItem)
            {
                Tikz_XYItem t = tpi as Tikz_XYItem;
                Point offset;
                if (t.GetAbsPos(out offset, true))
                {
                    TikzMatrix M;
                    if (!t.parent.GetCurrentTransformAt(t, out M)) //.CloneIt();
                        M = new TikzMatrix();

                    M.m[0, 2] = offset.X;
                    M.m[1, 2] = offset.Y;
                    //rasterizer.RasterScale = M.m[1, 1];
                    Rasterizer.View.CoordinateTransform = M;
                    Rasterizer.View.IsCartesian = !(t.IsPolar());
                }
                else throw new Exception("In PdfOverlay: Encountered drawn item without valid coordinates");
            }
            else if (tpi is Tikz_Path)
            {
                Tikz_Path ts = tpi as Tikz_Path;
                TikzMatrix M;
                if (IsParent)
                {
                    Point curPointAtEnd;
                    if (!ts.GetCurrentTransformAt(null, out M))  // todo
                        M = new TikzMatrix(); // broken coords-> take unity as backup
                    if (ts.GetAbsOffset(out curPointAtEnd, null))
                    {
                        M.m[0, 2] = curPointAtEnd.X;
                        M.m[1, 2] = curPointAtEnd.Y;
                    }
                }
                else
                {
                    if (!ts.parent.GetCurrentTransformAt(ts, out M))
                        M = new TikzMatrix();
                    //if (!ts.GetRasterTransform(out M))
                    //    M = new TikzMatrix();
                }
                Rasterizer.View.CoordinateTransform = M;
                //rasterizer.RasterOrigin = M.Transform(new Point(0, 0));
                //rasterizer.RasterScale = M.m[1, 1];
                Rasterizer.View.IsCartesian = !IsParent || !UsePolarCoordinates;
            }
            else
                Debug.WriteLine("Error in SetCorrectRaster: unsupported type");//Rasterizer.IsCartesian = true;  // should not get here
        }
Example #9
0
 public void InsertChildAt(TikzParseItem tpi, int position)
 {
     tpi.parent = this;
     Children.Insert(position, tpi);
     // raise event
     RaiseTextChanged(tpi, "");
     RaiseParseTreeModified(new ParseTreeModifiedEventArgs() { AffectedItem = tpi, Type = ParseTreeModifiedType.Insert });
 }
Example #10
0
        /// <summary>
        /// Removes a child
        /// </summary>
        /// <param name="tpi"></param>
        /// <param name="InsertAsFirst"></param>
        public void RemoveChild(TikzParseItem tpi)
        {

            int startpos = tpi.StartPosition();
            string oldtext = tpi.ToString();
            tpi.parent = null;
            Children.Remove(tpi);

            // raise event
            RaiseTextChanged(new DummyTikzParseItem(startpos), oldtext);
            RaiseParseTreeModified(new ParseTreeModifiedEventArgs() { AffectedItem = tpi, Type = ParseTreeModifiedType.Remove });
        }
Example #11
0
 /// <summary>
 /// This should be called instead of adding nodes to Children directly
 /// </summary>
 /// <param name="tpi"></param>
 public void AddChild(TikzParseItem tpi, bool InsertAsFirst=false)
 {
     tpi.parent = this;
     if (InsertAsFirst)
         Children.Insert(0, tpi);
     else
         Children.Add(tpi);
     // raise event
     RaiseTextChanged(tpi, "");
     RaiseParseTreeModified(new ParseTreeModifiedEventArgs() { AffectedItem = tpi, Type = ParseTreeModifiedType.Insert });
 }
Example #12
0
        IEnumerable<OverlayShapeVM> CreateOverlayShapesFromItem(TikzParseItem tpi)
        {

            var ret = new List<OverlayShapeVM>();
            if (tpi is Tikz_Scope)
            {
                OverlayScope os = new OverlayScope();
                //os.pol = this;
                os.tikzitem = tpi as Tikz_Scope;

                // add child shapes
                os.children.AddRange( (tpi as TikzContainerParseItem).Children.SelectMany( child => CreateOverlayShapesFromItem(child) ) );

                //foreach (TikzParseItem t in (tpi as TikzContainerParseItem).Children)
                //    DrawObject(t, os.children);

                // don't draw scopes with no drawable children
                // (we don't know where to render them)
                if (os.children.Count > 0)
                {
                    ret.Add(os);
                    os.AdjustPosition(TikzToScreen);
                    
                }
            }
            else if (tpi is TikzContainerParseItem)
            {
                ret.AddRange( (tpi as TikzContainerParseItem).Children.SelectMany( child => CreateOverlayShapesFromItem(child) ) );
            }
            else if (tpi is Tikz_XYItem)
            {
                if ((tpi as Tikz_XYItem).HasEditableCoordinate())
                {
                    OverlayNode el;
                    if (tpi.parent is Tikz_Controls)
                        el = new OverlayControlPoint();     // control points for Bezier curves
                    else
                        el = new OverlayNode();
                    //el.pol = this;
                    el.tikzitem = tpi as Tikz_XYItem;

                    el.AdjustPosition(TikzToScreen);

                    // add tooltip
                    if (ParseTree != null)
                    {
                        Tikz_Node nref = TikzParseTreeHelper.GetReferenceableNode(tpi as Tikz_XYItem, ParseTree.GetTikzPicture());
                        if (nref != null && !String.IsNullOrWhiteSpace(nref.name))
                        {
                            el.ToolTip = nref.name;
                        }
                    }
                    ////canvas1.Children.Add(el);
                    ret.Add(el);

                    //bbg.Add(new Rect(Canvas.GetLeft(el), Canvas.GetTop(el), el.Width, el.Height));
                }
            }
            else if (tpi is Tikz_Path)
            {
            }

            return ret;
        }
Example #13
0
 /// <summary>
 /// Adds a single parseitem to the display tree and redraws.
 /// This is called by tools adding something to the parsetree to refresh the overlay
 /// without redrawing it completely.
 /// </summary>
 /// <param name="tpi">The parseitem to add.</param>
 public void AddToDisplayTree(TikzParseItem tpi)
 {
     List<OverlayShape> l = new List<OverlayShape>();
     DrawObject(tpi, l);
     if (CurEditing == null)
     {
         //do not redraw if there is nothing to show.
         if (TopLevelItems == null)
             RedrawObjects();
         TopLevelItems.AddRange(l);
     }
     else
     {
         CurEditing.children.AddRange(l);
     }
     AdjustPositions();
     BindControlPointsToOrigins();
 }
Example #14
0
        /// <summary>
        /// Gets the absolute position. For the significance of relto, see SetAbsPos()
        /// </summary>
        /// <param name="relto"></param>
        /// <param name="OnlyOffset">Only the coordinate offset is returned. (This is used to determine the raster offset.)</param>
        /// <returns>The position in the coordinates of the ancestral Tikz_Picture, or (0,0) in case of failure.</returns>
        public bool GetAbsPos(out Point ret, TikzParseItem relto, bool OnlyOffset=false)
        {
            if (IsBroken || type == Tikz_CoordType.Invalid)   // cannot determine coordinates
            {
                ret = new Point(0,0);
                return false;
            }

            Point offset = new Point(0, 0);
            if (type == Tikz_CoordType.Named)
            {
                if (relto.parent == null)
                {
                    // node name not find in node list (either error or not parsed)
                    ret = new Point(0, 0);
                    return false;
                }

                // try to get referenced node...
                if (nameref == "") // empty reference means that we reference the current position (treat as +(0,0))
                {
                    // determine current position
                    if (relto.parent is Tikz_Path)
                    {
                        if (!(relto.parent as Tikz_Path).GetAbsOffset(out ret, relto))
                        {
                            // error in determining offset -> cannot determine coordinates
                            ret = new Point(0, 0);
                            return false;
                        }
                        else
                            return true; // success
                    }
                    else
                    {
                        // couldn't get offset, because the parent is some container I don't know -> fail
                        ret = new Point(0, 0);
                        return false;
                    }
                }

                Tikz_Node t = relto.parent.GetNodeByName(nameref);
                if (t == null)
                {
                    ret = new Point(0, 0);
                    return false;
                }
                else
                {
                    // Tikz allows decorations (+, ++) in front of named coordinates, but not nodes (!!!)
                    // so we have to take care of this case separately
                    /*if ( (deco == "+" || deco == "++") && t.parent.starttag.Trim() == "\\coordinate")
                    {
                        if (relto.parent is Tikz_Path)
                        {
                            if (!(relto.parent as Tikz_Path).GetAbsOffset(out offset, relto))
                            {
                                // error in determining offset -> cannot determine coordinates
                                ret = new Point(0, 0);
                                return false;
                            }
                        }
                        if (t.GetAbsPos(out ret))
                        {
                            ret = new Point(ret.X + offset.X, ret.Y + offset.Y);
                        }
                        else
                            return false;
                    }
                    else*/
                        return t.GetAbsPos(out ret);
                }
            }
            else if (type == Tikz_CoordType.Cartesian || type == Tikz_CoordType.Polar)
            {

                // determine offset if there is a decoration...
                // for this we have to ask the parent Tikz Path what the current position is
                if (deco == "+" || deco == "++")
                {
                    // determine offset
                    if (relto.parent is Tikz_Path)
                    {
                        if (!(relto.parent as Tikz_Path).GetAbsOffset(out offset, relto))
                        {
                            // error in determining offset -> cannot determine coordinates
                            ret = new Point(0, 0);
                            return false;
                        }
                    }
                    else if (relto.parent is Tikz_Controls)
                    {
                        Tikz_Controls par = relto.parent as Tikz_Controls;
                        Tikz_XYItem offc = null;
                        if (relto == par.FirstCP)
                            offc = par.CoordBefore;
                        else if (relto == par.LastCP)
                            offc = par.CoordAfter;
                        if (offc == null || !offc.GetAbsPos(out offset))
                        {
                            ret = new Point(0, 0);
                            return false;
                        }
                    }
                    else
                    {
                        // not supported

                    }

                    Point relpos = new Point(uX.GetInCM(), uY.GetInCM());
                    if (type == Tikz_CoordType.Polar)
                        relpos = Helper.PolToCartTC(relpos);

                    if (relto.parent != null)
                    {
                        TikzMatrix M;
                        if (!relto.parent.GetCurrentTransformAt(relto, out M))
                        {
                            ret = new Point(0, 0);
                            return false;
                        }
                        relpos = M.Transform(relpos, true);
                    }
                    if (OnlyOffset)
                    {
                        ret = offset;
                        return true;
                    }
                    else
                    {
                        ret = new Point(offset.X + relpos.X, offset.Y + relpos.Y);
                        return true;
                    }
                }

                // standard coordinate (not relative etc.)
                Point p = new Point(uX.GetInCM(), uY.GetInCM());
                if (type == Tikz_CoordType.Polar)
                    p = Helper.PolToCartTC(p);
                if (relto.parent == null)
                {
                    if (OnlyOffset)
                    {
                        ret = new Point(0, 0);
                    }
                    else
                    {
                        ret = p;
                    }
                    return true;
                }
                else
                {
                    TikzMatrix M;
                    if (!relto.parent.GetCurrentTransformAt(relto, out M))
                    {
                        ret = new Point(0, 0);
                        return false;
                    }
                    //Point pret;
                    if (OnlyOffset)
                    {
                        ret = M.Transform(new Point(0, 0));
                    }
                    else
                    {
                        ret = M.Transform(p);
                    }
                    return true;
                }
            }
            else // if (type == ...)
            {
                // Unsupported type 
                ret = new Point(0, 0);
                return false;
            }
        }
Example #15
0
 public int GetLengthBefore(TikzParseItem tpi)
 {
     int pos = 0;
     if (parent != null)
         pos = parent.GetLengthBefore(this);
     pos += starttag.Length;
     //if (options != null)
     //    pos += options.ToString().Length;
     
     foreach (TikzParseItem t in Children)
     {
         if (t == tpi)
             break;
         else 
             pos += t.ToString().Length;
     }
     return pos;
 }
Example #16
0
        private void pdfOverlay1_OnModified(TikzParseItem sender, string oldtext)
        {
            // update code
            int InsertAt = sender.StartPosition();
            if (InsertAt > txtCode.Text.Length)
            {
                MainWindow.AddStatusLine("Trying to insert code \"" + sender.ToString().Replace(Environment.NewLine, "<NEWLINE>") + "\" to position " + sender.StartPosition() + " but document has only " + txtCode.Text.Length + " characters."
                + " Inserting code at end of document instead. Code does probably not compile now. Please correct or choose undo.", true);
                InsertAt = txtCode.Text.Length;
            }

            txtCode.Document.Replace(InsertAt, oldtext.Length, sender.ToString());

        }
Example #17
0
        /// <summary>
        /// Draws the TikzParseItem tpi, if it is drawn, or its children, if they can be drawn, 
        /// or grandchildren etc..., and adds the drawn items to bag.
        /// </summary>
        /// <param name="tpi"></param>
        /// <param name="bag"></param>
        public void DrawObject(TikzParseItem tpi, List<OverlayShape> bag)
        {
            //BBGatherer bbg = new BBGatherer();
            if (bag == null)
                bag = new List<OverlayShape>();  // dummy, it is not used
            if (tpi is Tikz_Scope)
            {
                OverlayScope os = new OverlayScope(ShapeFactory.NewScopeView());
                os.pol = this;
                os.tikzitem = tpi as Tikz_Scope;
                foreach (TikzParseItem t in (tpi as TikzContainerParseItem).Children)
                    DrawObject(t, os.children);

                // don't draw scopes with no drawable children
                // (we don't know where to render them)
                if (os.children.Count > 0)
                {
                    bag.Add(os);
                    os.AdjustPosition(Resolution);
                    ////canvas1.Children.Add(os);
                }
            }
            else if (tpi is TikzContainerParseItem)
            {
                foreach (TikzParseItem t in (tpi as TikzContainerParseItem).Children)
                    DrawObject(t, bag);
            }
            if (tpi is Tikz_XYItem)
            {
                if ((tpi as Tikz_XYItem).HasEditableCoordinate())
                {
                    OverlayNode el;
                    if (tpi.parent is Tikz_Controls)
                        el = new OverlayControlPoint(ShapeFactory.NewCPView());     // control points for Bezier curves
                    else
                        el = new OverlayNode(ShapeFactory.NewNodeView());
                    el.pol = this;
                    el.tikzitem = tpi as Tikz_XYItem;
                    //Ellipse el = new Ellipse();                                   
                    //el.Stroke = Brushes.Red;

                    el.AdjustPosition(Resolution);

                    // add tooltip
                    Tikz_Node nref = TikzParseTreeHelper.GetReferenceableNode(tpi as Tikz_XYItem, ParseTree.GetTikzPicture());
                    if (nref != null && nref.name != "")
                    {
                        el.View.SetToolTip(nref.name);                        
                    }

                    ////canvas1.Children.Add(el);
                    bag.Add(el);

                    //bbg.Add(new Rect(Canvas.GetLeft(el), Canvas.GetTop(el), el.Width, el.Height));
                }
            }
            else if (tpi is Tikz_Path)
            {
                //could this be a possibility to show edges and provide backward search?

                //there are many possibility for draw commands. here we 
                /* string simpleEdge_RegexString = @"[ \t\s]*\\draw.*\((?<start>.*)\).*\((?<end>.*)\).*";
                Regex BB_Regex = new Regex(simpleEdge_RegexString);
                Match m = BB_Regex.Match(tpi.ToString());
                if (m.Success == true)
                {
                    //we just found a LaTex draw cmd, e.g.: \draw[default_edge] (v91) to (v99);

                    //get both nodes
                    Tikz_Node StartNode = tpi.parent.GetNodeByName(m.Groups[1].Value);
                    Tikz_Node EndNode = tpi.parent.GetNodeByName(m.Groups[2].Value);

                    if (StartNode != null && EndNode != null)
                    {
                        //and determine the position in between both nodes
                        Point start, end;
                        if (StartNode.GetAbsPos()
                        double x = (StartNode.GetAbsPos().X + EndNode.GetAbsPos().X) / 2;
                        double y = (StartNode.GetAbsPos().Y + EndNode.GetAbsPos().Y) / 2;

                        //draw an arrow at this pos.
                        //(new Point(x, y));
                        //and when clicked, jump to AvalonEdit at position tpi.StartPosition                        
                    }

                }       */
            }

        }