/// <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; }
/// <summary> /// Takes an XYItem (like (2,2) or a node) and tries to make it into a referenceable node /// (i.e, one with a name) /// /// Concretely, the routine does the following: /// - if item is a named node, return item. /// - if item is an unnamed node, give it a unique name and return item. /// - if item is a coordinate, see if there is a node at this coordinate /// (algorithm: see if next non-tikz_something item is a node) /// - if yes, start anew with item=this node /// - if no, add a named node at the specified coordinate /// </summary> /// <param name="item"></param> /// <returns></returns> protected Tikz_Node MakeReferenceableNode(Tikz_XYItem item) { Tikz_Picture tpict = overlay.ParseTree.GetTikzPicture(); if (item is Tikz_Node) { Tikz_Node n = item as Tikz_Node; if (n.name == "") { n.SetName(tpict.GetUniqueName()); n.UpdateText(); } return n; } else if (item is Tikz_Coord) { // find the next node for (int i = item.parent.Children.IndexOf(item) + 1; i < item.parent.Children.Count; i++) { if (item.parent.Children[i] is Tikz_Node) { // check if the node is really at the same position as the coordinate item if ((item.parent.Children[i] as Tikz_Node).coord == null) return MakeReferenceableNode(item.parent.Children[i] as Tikz_Node); else break; } if (!(item.parent.Children[i] is Tikz_Something)) break; } // if we get here, nothing was found => add a new node Tikz_Something ws = new Tikz_Something(" "); Tikz_Node n = new Tikz_Node(); n.coord = null; item.parent.InsertChildAt(ws, item.parent.Children.IndexOf(item) + 1); item.parent.InsertChildAt(n, item.parent.Children.IndexOf(item) + 2); n.SetName(tpict.GetUniqueName()); n.UpdateText(); return n; } else throw new NotImplementedException("MakeReferenceableNode not implemented for this type"); }