1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace Tango.MachineStudio.Common.Controls
{
public class TableGrid : Grid
{
public TableGrid()
{
ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) });
ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
this.Loaded += TableGrid_Loaded;
}
private void TableGrid_Loaded(object sender, RoutedEventArgs e)
{
InvalidateGrid();
}
protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved)
{
base.OnVisualChildrenChanged(visualAdded, visualRemoved);
}
protected override Size ArrangeOverride(Size arrangeSize)
{
return base.ArrangeOverride(arrangeSize);
}
private void InvalidateGrid()
{
RowDefinitions.Clear();
RowDefinitions.Add(new RowDefinition() { Height = new GridLength(50, GridUnitType.Pixel) });
int currentRow = 0;
for (int i = 0; i < Children.Count; i++)
{
SetRow(Children[i], currentRow);
if (i % 2 != 0)
{
SetColumn(Children[i], 1);
(Children[i] as FrameworkElement).Margin = new Thickness(20, 0, 0, 0);
currentRow++;
RowDefinitions.Add(new RowDefinition() { Height = new GridLength(50, GridUnitType.Pixel) });
}
(Children[i] as FrameworkElement).VerticalAlignment = VerticalAlignment.Bottom;
}
}
}
}
span>
HeightTreeNode node = this;
HeightTreeNode oldNode;
do {
oldNode = node;
node = node.parent;
// go up until we are coming out of a left subtree
} while (node != null && node.right == oldNode);
return node;
}
}
}
/// <summary>
/// The number of lines in this node and its child nodes.
/// Invariant:
/// totalCount = 1 + left.totalCount + right.totalCount
/// </summary>
internal int totalCount;
/// <summary>
/// The total height of this node and its child nodes, excluding directly collapsed nodes.
/// Invariant:
/// totalHeight = left.IsDirectlyCollapsed ? 0 : left.totalHeight
/// + lineNode.IsDirectlyCollapsed ? 0 : lineNode.Height
/// + right.IsDirectlyCollapsed ? 0 : right.totalHeight
/// </summary>
internal double totalHeight;
/// <summary>
/// List of the sections that hold this node collapsed.
/// Invariant 1:
/// For each document line in the range described by a CollapsedSection, exactly one ancestor
/// contains that CollapsedSection.
/// Invariant 2:
/// A CollapsedSection is contained either in left+middle or middle+right or just middle.
/// Invariant 3:
/// Start and end of a CollapsedSection always contain the collapsedSection in their
/// documentLine (middle node).
/// </summary>
internal List<CollapsedLineSection> collapsedSections;
internal bool IsDirectlyCollapsed {
get {
return collapsedSections != null;
}
}
internal void AddDirectlyCollapsed(CollapsedLineSection section)
{
if (collapsedSections == null) {
collapsedSections = new List<CollapsedLineSection>();
totalHeight = 0;
}
Debug.Assert(!collapsedSections.Contains(section));
collapsedSections.Add(section);
}
internal void RemoveDirectlyCollapsed(CollapsedLineSection section)
{
Debug.Assert(collapsedSections.Contains(section));
collapsedSections.Remove(section);
if (collapsedSections.Count == 0) {
collapsedSections = null;
totalHeight = lineNode.TotalHeight;
if (left != null)
totalHeight += left.totalHeight;
if (right != null)
totalHeight += right.totalHeight;
}
}
#if DEBUG
public override string ToString()
{
return "[HeightTreeNode "
+ documentLine.LineNumber + " CS=" + GetCollapsedSections(collapsedSections)
+ " Line.CS=" + GetCollapsedSections(lineNode.collapsedSections)
+ " Line.Height=" + lineNode.height
+ " TotalHeight=" + totalHeight
+ "]";
}
static string GetCollapsedSections(List<CollapsedLineSection> list)
{
if (list == null)
return "{}";
return "{" +
string.Join(",",
list.ConvertAll(cs=>cs.ID).ToArray())
+ "}";
}
#endif
}
}
|