/// <summary>
        /// The parse calls this static method to construct a Tikz_Node from 
        /// a node in the abstract syntax tree produced by antlr
        /// </summary>
        /// <param name="t">The node in the abstract syntax tree. Must be of type IM_NODE</param>
        /// <param name="tokens">A reference to the Antlr tokenstream. This is used to extract e.g. the node label.</param>
        /// <returns></returns>
        public static Tikz_Node FromCommonTree(CommonTree t, CommonTokenStream tokens)
        {
            // IM_NODE (OPTIONS | nodename | coord)* STRING
            Tikz_Node n = new Tikz_Node();
            n.options = "";
            foreach (CommonTree childt in t.Children)
            {
                switch (childt.Type)
                {
                    case simpletikzParser.IM_OPTIONS:
                        n.options = n.options + TikzParser.getTokensString(tokens, childt);
                        break;
                    case simpletikzParser.IM_COORD:
                        n.coord = Tikz_Coord.FromCommonTree(childt, tokens);
                        break;
                    case simpletikzParser.IM_NODENAME:
                        n.name = TikzParser.getTokensString(tokens, childt.GetChild(0));
                        n.name = Helper.RemoveMultipleWhitespace(n.name);
                        break;
                    case simpletikzParser.IM_STRING:
                        n.label = TikzParser.getTokensString(tokens, childt);
                        // remove leading and trailing {} TODO: do it in parser
                        n.label = n.label.Substring(1, n.label.Length - 2);
                        break;
                }
            }
/*            int i = 0;
            if (t.GetChild(i).Type == simpletikzParser.IM_OPTIONS)
            {
                //i++;
                n.options = TikzParser.getTokensString(tokens, t.GetChild(i++));
            }
            if (t.GetChild(i).Type == simpletikzParser.IM_NODENAME)
            {
                n.name = TikzParser.getTokensString(tokens, t.GetChild(i++).GetChild(0)); //t.GetChild(i++).GetChild(0).Text;
            }
            if (t.GetChild(i).Type == simpletikzParser.IM_COORD)
            {
                n.coord = Tikz_Coord.FromCommonTree(t.GetChild(i++), tokens);
                //n.x = n.coord.uX.number; //hack
                //n.y = n.coord.uY.number;
            }

            // the text of the node
            n.label = TikzParser.getTokensString(tokens, t.GetChild(i));  //t.GetChild(i).Text.Trim();
            // remove leading and trailing {} TODO: do it in parser
            n.label = n.label.Substring(1, n.label.Length - 2);
            */
            return n;
        }
 public override void AddNodeRef(Tikz_Node tn)
 {
     nodelist[TikzParseTreeHelper.CleanName(tn.name)] = tn;
 }
 /// <summary>
 /// Called in repsonse to RegisterNodeAndStyleRefs by its children
 /// </summary>
 /// <param name="tn"></param>
 public virtual void AddNodeRef(Tikz_Node tn)
 {
     if (parent != null)
         parent.AddNodeRef(tn);
 }
        /// <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");
        }
        public override void OnLeftMouseButtonDown(OverlayShapeVM item, Point p, TEMouseArgs e)
        {
            if (!EnsureParseTreeExists())
                return;

            p = overlay.Rasterizer.RasterizePixelToTikz(p);
            if (ContinueWithBigImage(p) == false)
                return;

            overlay.BeginUpdate();

            //overlay.SetCorrectRaster(overlay.CurEditing, true);
            UpdateRaster();
            //Point p = new Point(e.GetPosition(canvas1).X, Height - e.GetPosition(canvas1).Y);


            // find next tikzpicture and add
            bool lcreated;
            if (EnsureCurAddToExists(out lcreated))
            {
                // on double click -> close path
                if (e.ClickCount == 2)
                {
                    if (!lcreated)
                    {
                        //if (!Keyboard.Modifiers.HasFlag(ModifierKeys.Control))
                        curAddTo.AddChild(new Parser.Tikz_Something(" -- cycle"));
                        //else
                        //    curAddTo.AddChild(new Parser.Tikz_Something(" cycle"));
                    }
                }
                else
                {
                    if (!lcreated)
                    {
                        if (!overlay.KeyboardModifiers.HasFlag(TEModifierKeys.Control))
                            // add an edge
                            curAddTo.AddChild(new Parser.Tikz_Something(" -- "));
                        else
                            curAddTo.AddChild(new Parser.Tikz_Something(" "));
                    }

                    // create new coordinate. If some node was clicked, set a reference to that node. Otherwise, just make new coordinates
                    Tikz_Coord tc = new Tikz_Coord();
                    if (item is OverlayNode && IsReferenceable(item))
                    {
                        Tikz_Node tn = MakeReferenceableNode((item as OverlayNode).tikzitem);
                        tc.type = Tikz_CoordType.Named;
                        tc.nameref = tn.name;
                        curAddTo.AddChild(tc);
                    }
                    else
                    {
                        // do it here since the coordinate calculation needs the parents' coord. transform
                        tc.type = overlay.UsePolarCoordinates ? Tikz_CoordType.Polar : Tikz_CoordType.Cartesian;
                        if (!lcreated)
                            tc.deco = overlay.NewNodeModifier;  // first node should always be in absolute coordinates

                        curAddTo.AddChild(tc);
                        tc.SetAbsPos(new Point(p.X, p.Y)); //hack

                        // if a nonempty node style is selected, also add a node with that style
                        if (!String.IsNullOrWhiteSpace(overlay.NodeStyle))
                        {
                            Tikz_Node tn = new Tikz_Node()
                            {
                                options = "[" + overlay.NodeStyle + "]",
                                coord = null,
                                text = ""
                            };
                            curAddTo.AddChild(new Tikz_Something(" "));
                            curAddTo.AddChild(tn);
                        }
                    }
                    //tn.UpdateText();
                    curAddTo.UpdateText();
                    //tpict.UpdateText();

                    // draw the added object in the overlay
                    //          overlay.AddToDisplayTree(tc);
                }
            }

            overlay.EndUpdate();
            UpdateRaster();

            // doubleclick also stops path drawing
            if (e.ClickCount == 2)
                overlay.ActivateDefaultTool();
        }
Exemple #6
0
        public override void OnLeftMouseButtonDown(OverlayShape item, Point p, TEMouseArgs e) 
        {
            if (!EnsureParseTreeExists())
                return;

            overlay.BeginUpdate();

            overlay.SetCorrectRaster(overlay.CurEditing, true);

            //Point p = new Point(e.GetPosition(canvas1).X, Height - e.GetPosition(canvas1).Y);
            p = overlay.Rasterizer.RasterizePixelToTikz(p);
            if (ContinueWithBigImage(p) == false)
                return;

            // find next tikzpicture and add
            Parser.Tikz_Picture tpict = overlay.ParseTree.GetTikzPicture();
            if (tpict != null)
            {
                Parser.Tikz_Node tn = new Parser.Tikz_Node();
                tn.label = "";
                tn.coord = new Parser.Tikz_Coord();
                if (overlay.NodeStyle != "")
                    tn.options = "[" + overlay.NodeStyle + "]";

                Parser.Tikz_Path tp = new Parser.Tikz_Path();
                tp.starttag = @"\node ";
                tp.endtag = ";";

                tp.AddChild(tn);
                if (overlay.CurEditing != null)
                {
                    overlay.CurEditing.tikzitem.AddChild(tp);
                    overlay.CurEditing.tikzitem.AddChild(new Parser.Tikz_Something("\r\n"));
                }
                else
                {
                    tpict.AddChild(tp);
                    tpict.AddChild(new Parser.Tikz_Something("\r\n"));
                }
                // do it here since the coordinate calculation needs the parents' coord. transform
                tn.SetAbsPos(new Point(p.X, p.Y)); //hack

                //tn.UpdateText();
                tp.UpdateText();
                //tpict.UpdateText();

                //RedrawObjects();
                overlay.AddToDisplayTree(tp);
            }

            overlay.EndUpdate();
        }