private void PopulateTree(DisplayNode node, int level, TreeViewItem parentItem = null) { var item = new TreeViewItem(); item.Header = node.String; item.DataContext = node; item.Selected += Item_Selected; if (node.IsToken) { item.Foreground = Brushes.Green; } if (parentItem == null) { nodeTree.Items.Add(item); } else { parentItem.Items.Add(item); } if (level < AutoExpandTreeLevel) { item.IsExpanded = true; } foreach (var child in node.Children) { PopulateTree(child, level + 1, item); } }
public void UpdateModel(DisplayNode model) { _rootNode = model; nodeTree.Items.Clear(); PopulateTree(_rootNode, 0); view.ShowNodeTree(_rootNode, slider.Value); }
private void RenderNode(DisplayNode node) { TextBlock tb = new TextBlock(); tb.FontSize = _fontSize; tb.FontFamily = _fontFamily; tb.Text = node.String; if (node.IsToken) { tb.Foreground = Brushes.Green; } if (node.HasError) { tb.Background = new SolidColorBrush(Color.FromRgb(244, 213, 211)); } canvas.Children.Add(tb); tb.SetValue(Canvas.LeftProperty, node.Middle - node.Width / 2 + _padding / 2); tb.SetValue(Canvas.TopProperty, node.Top); _needWidth = Math.Max(_needWidth, node.Middle + node.Width / 2); _needHeight = Math.Max(_needHeight, node.Top + LevelHeightBase); foreach (var child in node.Children) { DrawLine(node.Middle, node.Top + _fontSize * 1.1, child.Middle, child.Top); RenderNode(child); } }
private void ClearPreviousCalculation(DisplayNode node) { node.Middle = 0; node.Top = 0; foreach (var child in node.Children) { ClearPreviousCalculation(child); } }
//put ternimal nodes in the middle of surrounding nodes(if any) private void ArangePositionPass2(DisplayNode node) { for (int i = 0; i < node.Children.Count; i++) { var child = node.Children[i]; if (i != 0 && i != node.Children.Count - 1 && child.Children.Count == 0) { child.Middle = (node.Children[i - 1].Middle + node.Children[i - 1].Width / 2 + node.Children[i + 1].Middle - node.Children[i + 1].Width / 2) / 2; } ArangePositionPass2(child); } }
public void PositionNodeModel(DisplayNode node, string fontName, double fontSize, double levelHeight, double padding) { this._fontType = new Typeface(fontName); this._fontSize = fontSize; this._levelHeight = levelHeight; this._padding = padding; ClearPreviousCalculation(node); CalculateWidth(node); _startPointOfLevels = new List <double>(); ArangePosition(node, 0); ArangePositionPass2(node); }
private void Item_Selected(object sender, RoutedEventArgs e) { e.Handled = true; var node = (sender as TreeViewItem).DataContext as DisplayNode; if (node.IsToken) { return; } _rootNode = node; view.ShowNodeTree(node, slider.Value); }
public DisplayNode GetDisplayNodeFromParseTree(IParseTree node, bool showRuleIndex) { var model = new DisplayNode(); if (node is TerminalNodeImpl) { var tNode = node as TerminalNodeImpl; model.String = tNode.GetText(); if (showRuleIndex) { model.String += " = " + tNode.Symbol.Type; } model.IsToken = true; if (_tokenExceptions.ContainsKey(tNode.Symbol) || tNode.Symbol.TokenIndex == -1) { model.HasError = true; } } else { var ruleNode = node as ParserRuleContext; //Add token to context if context does not have child, //This handels the extraneous token if (_contextTokenMapping.ContainsKey(ruleNode)) { var token = _contextTokenMapping[ruleNode]; model.HasError = true; if (token.Type != -1 && node.ChildCount == 0) { var errorTokenNode = new DisplayNode(); errorTokenNode.HasError = true; errorTokenNode.IsToken = true; errorTokenNode.String = token.Text; model.Children.Add(errorTokenNode); } } model.String = _ruleNames[ruleNode.RuleIndex]; if (showRuleIndex) { model.String += " = " + ruleNode.RuleIndex; } } for (int i = 0; i < node.ChildCount; i++) { var subAstNode = GetDisplayNodeFromParseTree(node.GetChild(i), showRuleIndex); model.Children.Add(subAstNode); } return(model); }
private void PushChildrenRight(DisplayNode displayNode, double amount, int level) { foreach (var child in displayNode.Children) { child.Middle += amount; if (_startPointOfLevels[level + 1] < child.Middle + child.Width / 2) { _startPointOfLevels[level + 1] = child.Middle + child.Width / 2; } PushChildrenRight(child, amount, level + 1); } }
private void CalculateWidth(DisplayNode displayNode) { if (displayNode.IsToken) { displayNode.Width = StringWidth(displayNode.String) + _padding; } else { double childrenWidth = 0.0; foreach (var child in displayNode.Children) { CalculateWidth(child); childrenWidth += child.Width; } displayNode.Width = StringWidth(displayNode.String) + _padding; } }
public void ShowNodeTree(DisplayNode rootNode, double zoomLevel) { if (zoomLevel <= 0) { throw new ArgumentException("zoomLevel must be > 0"); } canvas.Children.Clear(); _needWidth = 0; _needHeight = 0; _lineThickness = zoomLevel * LineThicknessBase; _padding = PaddingBase * zoomLevel; _fontSize = FontSizeBase * zoomLevel; new DisplayNodePositioner().PositionNodeModel(rootNode, "Arial", _fontSize, LevelHeightBase * zoomLevel, _padding); canvas.Children.Clear(); RenderNode(rootNode); canvas.Height = _needHeight; canvas.Width = _needWidth; }
private void ArangePosition(DisplayNode node, int level) { if (_startPointOfLevels.Count <= level) { _startPointOfLevels.Add(0); } node.Top = _levelHeight * level; if (node.Children.Count == 0) { node.Middle = _startPointOfLevels[level] + node.Width / 2; _startPointOfLevels[level] += node.Width; } else { //Arrange children's position first, use thier average point as parent's middle point foreach (var child in node.Children) { ArangePosition(child, level + 1); } var childrenMidPoint = node.Children.Average(x => x.Middle); //Howerever if parent width is too big that the middle point is right to the center point of children //Then push children to right. if (_startPointOfLevels[level] + node.Width / 2 > childrenMidPoint) { node.Middle = _startPointOfLevels[level] + node.Width / 2; var childrenNeedsRightShift = node.Middle - childrenMidPoint; PushChildrenRight(node, childrenNeedsRightShift, level); } else { node.Middle = childrenMidPoint; } _startPointOfLevels[level] = node.Middle + node.Width / 2; } }