/// <summary> /// Same as FindAncestors, but stops at the Tikz_Picture. /// I.e., the last node in the list is the one below the Tikz_Picture /// </summary> /// <param name="t">The node. Must not be null.</param> /// <returns></returns> public static List <TikzParseItem> FindAncestorsInPicture(TikzParseItem t) { List <TikzParseItem> ret = new List <TikzParseItem>(); TikzParseItem cur = t; do { ret.Add(cur); cur = cur.parent; } while (cur != null && !(cur is Tikz_Picture)); return(ret); }
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()); }
void IPdfOverlayView.JumpToSourceDoIt(OverlayShapeVM o) { if (JumpToSource != null) { TikzParseItem tpi = o.item; if (tpi != null) { JumpToSource(this, new JumpToSourceEventArgs() { JumpToPos = tpi.StartPosition(), SelectionLength = tpi.Length }); } } }
private void pdfOverlay1_JumpToSource(object sender) { TikzParseItem tpi = sender as TikzParseItem; int spos = tpi.StartPosition(); if (spos > txtCode.Text.Length) { MainWindow.AddStatusLine("Trying to jump to position " + spos + " but document only has " + txtCode.Text.Length + " characters. Please correct any parser errors or restart TikzEdt.", true); return; } txtCode.SelectionLength = 0; //deselect first txtCode.CaretOffset = spos; txtCode.SelectionStart = spos; txtCode.SelectionLength = tpi.ToString().Length; txtCode.ScrollToLine(txtCode.Document.GetLineByOffset(spos).LineNumber); txtCode.Focus(); }
/// <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(); }
/// <summary> /// Selects all descendants of a node fulfilling a certain criterion. /// </summary> /// <param name="tpi"></param> /// <param name="?"></param> /// <returns></returns> public static HashSet <TikzParseItem> SelectDescendants(TikzParseItem tpi, Predicate <TikzParseItem> criterion) { HashSet <TikzParseItem> ret = new HashSet <TikzParseItem>(); if (!(tpi is TikzContainerParseItem)) { return(ret); } foreach (var t in (tpi as TikzContainerParseItem).Children) { if (criterion(t)) { ret.Add(t); } foreach (var ll in SelectDescendants(t, criterion)) { ret.Add(ll); } } return(ret); }
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 } }
/// <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 * } * * } */ } }
/// <summary> /// Checks if tp1 is an ancestor of tp2 /// </summary> /// <param name="tp1"></param> /// <param name="tp2"></param> /// <returns></returns> public static bool IsAncestorOf(TikzParseItem tp1, TikzParseItem tp2) { // Note that first item returned by findancestors is the node itself -> skip it return(FindAncestors(tp2).Skip(1).Contains(tp1)); }
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); }