protected override TopicLine CreateTopicLine(MindMapLayoutArgs e, Topic beginTopic, Topic endTopic, Vector4 beginSide, Vector4 endSide) { var beginRect = beginTopic.Bounds; var endRect = endTopic.Bounds; if (e.ShowLineArrowCap) { endRect.Inflate(LineAnchorSize, LineAnchorSize); } if (beginTopic != null && !beginTopic.IsRoot) { int foldBtnSize = endTopic.FoldingButton.Width; switch (beginSide) { case Vector4.Left: //beginRect.X -= foldBtnSize; //beginRect.Width += foldBtnSize; break; case Vector4.Right: // beginRect.Width += foldBtnSize; break; case Vector4.Top: beginRect.Y -= foldBtnSize; beginRect.Height += foldBtnSize; break; case Vector4.Bottom: beginRect.Height += foldBtnSize; break; } } if (beginTopic != null && endTopic != null && beginTopic.Type == TopicType.Barrier && beginTopic.IsParentOf(endTopic)) { beginRect.Y = beginTopic.ContentBounds.Bottom; beginRect.Height = 0; } if (endTopic != null) { if (endTopic.Type == TopicType.Threat || endTopic.Type == TopicType.Consequence || endTopic.Type == TopicType.Escalation) { endRect.Height = 60; // 60 is barrier height } else if (endTopic.Style.Shape == TopicShape.BaseLine) { endRect.Y = endRect.Bottom; endRect.Height = 0; } } return(new TopicLine(endTopic, beginSide, endSide, beginRect, endRect)); }
Size CalculateSizes(Topic parent, Size parentFullSize, Topic[] subTopics, MindMapLayoutArgs e, Vector4 vector, Hashtable layoutInfos) { Size fullSize = parentFullSize;// parent.Size; if (subTopics != null && subTopics.Length > 0) { bool first = true; foreach (Topic subTopic in subTopics) { subTopic.Size = CalculateNodeSize(subTopic, e); var subTopicFullSize = LayoutAttachments(subTopic, e); Size subSize = CalculateSizes(subTopic, subTopicFullSize, e, vector, layoutInfos); if (first) { fullSize.Height = Math.Max(parent.Size.Height, subSize.Height); first = false; } else { fullSize.Width = Math.Max(fullSize.Width, subSize.Width); fullSize.Height += subSize.Height + e.ItemsSpace; //fullSize.Height += subSize.Height + (int)((parent.IsRoot ? NodeSpaceRoot_V : NodeSpace_V) * args.Zoom); } } fullSize.Width += e.LayerSpace + parent.Size.Width / 2; } layoutInfos[parent] = new TopicLayoutInfo(fullSize); return(fullSize); }
Rectangle LayoutRoot(Topic topic, MindMapLayoutArgs e) { Hashtable layoutInfos = new Hashtable(); CalculateSizes(topic, layoutInfos, e); if (!layoutInfos.Contains(topic)) { return(Rectangle.Empty); } var tli = (TopicLayoutInfo)layoutInfos[topic]; int y = 0; int x; if (Vector == MindMapLayoutType.TreeLeft) { x = tli.FullSize.Width; } else { x = 0; } LayoutTopic(topic, layoutInfos, x, y, e); return(new Rectangle(0, 0, tli.FullSize.Width, tli.FullSize.Height)); }
private void LayoutView() { if (Map == null) { OriginalContentSize = Size.Empty; } else { if (ChartLayouter != null && Created) { Size size; if (Created) { using (Graphics grf = CreateGraphics()) { var args = new MindMapLayoutArgs(grf, this.Map, ChartBox.DefaultChartFont); size = ChartLayouter.LayoutMap(Map, args); } } else { var args = new MindMapLayoutArgs(this.Map, ChartBox.DefaultChartFont); size = ChartLayouter.LayoutMap(Map, args); } OriginalContentSize = size; } } }
Rectangle LayoutRoot(Topic topic, MindMapLayoutArgs e) { Hashtable layoutInfos = new Hashtable(); CalculateSizes(topic, layoutInfos, e); if (!layoutInfos.Contains(topic)) { return(Rectangle.Empty); } var tli = (TopicLayoutInfo)layoutInfos[topic]; int y; int x = 0; if (Vector == MindMapLayoutType.OrganizationUp) { y = tli.FullSize.Height - e.LayerSpace; } else { y = 0; } LayoutTopic(topic, layoutInfos, x, y, e); return(new Rectangle(0, 0, tli.FullSize.Width, tli.FullSize.Height)); }
protected override Size LayoutAttachments(Topic topic, MindMapLayoutArgs e) { var size = topic.Size; if (e.ShowRemarkIcon && topic.HaveRemark) { int x = 0; switch (Vector) { case MindMapLayoutType.TreeLeft: x = -2 - e.RemarkIconSize; break; case MindMapLayoutType.TreeRight: x = size.Width + 2; break; } topic.RemarkIconBounds = new Rectangle(x, 0, e.RemarkIconSize, e.RemarkIconSize); size.Width += 2 + e.RemarkIconSize; size.Height = Math.Max(size.Height, e.RemarkIconSize); } return(size); //return base.LayoutAttachments(topic, e); }
protected override TopicLine CreateTopicLine(MindMapLayoutArgs e, Topic beginTopic, Topic endTopic, Vector4 beginSide, Vector4 endSide) { var beginRect = beginTopic.Bounds; var endRect = endTopic.Bounds; if (e.ShowLineArrowCap) { endRect.Inflate(LineAnchorSize, LineAnchorSize); } if (!beginTopic.IsRoot) { int foldBtnSize = beginTopic.FoldingButton.Height; switch (Vector) { case MindMapLayoutType.OrganizationUp: beginRect.Y -= foldBtnSize; beginRect.Height += foldBtnSize; break; case MindMapLayoutType.OrganizationDown: default: beginRect.Height += foldBtnSize; break; } } return(new TopicLine(endTopic, beginSide, endSide, beginRect, endRect)); }
protected override TopicLine CreateTopicLine(MindMapLayoutArgs e, Topic beginTopic, Topic endTopic, Vector4 beginSide, Vector4 endSide) { var beginRect = beginTopic.Bounds; var endRect = endTopic.Bounds; if (e.ShowLineArrowCap) { endRect.Inflate(LineAnchorSize, LineAnchorSize); } if (beginTopic != null && !beginTopic.IsRoot) { int foldBtnSize = endTopic.FoldingButton.Width; switch (Vector) { case MindMapLayoutType.LogicLeft: beginRect.X -= foldBtnSize; beginRect.Width += foldBtnSize; break; case MindMapLayoutType.LogicRight: default: beginRect.Width += foldBtnSize; break; } } return(new TopicLine(endTopic, beginSide, endSide, beginRect, endRect)); }
protected override Rectangle Layout(Topic root, MindMapLayoutArgs e) { if (root == null) { throw new ArgumentNullException(); } return(LayoutRoot(root, e)); }
Rectangle LayoutRoot(Topic root, MindMapLayoutArgs args) { Size size = CalculateNodeSize(root, args); Point pt = new Point(0, 0); root.Bounds = new Rectangle(pt.X - size.Width / 2, pt.Y - size.Height / 2, size.Width, size.Height); var rootFullSize = LayoutAttachments(root, args); Vector4[] vectors = new Vector4[] { Vector4.Left, Vector4.Right }; int def = 0; int sideCount = Math.DivRem(root.Children.Count, vectors.Length, out def); Rectangle allBounds = root.Bounds; int subTopicIndex = 0; root.Lines.Clear(); Hashtable layoutInfos = new Hashtable(); for (int vi = 0; vi < vectors.Length; vi++) { int mySideCount = sideCount; if (vi < def) { mySideCount++; } int[] subSizes = new int[mySideCount]; Topic[] subTopics = new Topic[mySideCount]; for (int ti = 0; ti < mySideCount; ti++) { subTopics[ti] = root.Children[subTopicIndex + ti]; } Size fullSize = CalculateSizes(root, rootFullSize, subTopics, args, vectors[vi], layoutInfos); Rectangle rectFull = LayoutSubTopics(root, subTopics, vectors[vi], layoutInfos, args); //Rectangle fullRectangle; //switch(vectors[vi]) //{ // case HorizontalVector.Left: // fullRectangle = new Rectangle(pt.X - fullSize.Width, pt.Y - fullSize.Height/2, fullSize.Width, fullSize.Height); // break; // case HorizontalVector.Right: // default: // fullRectangle = new Rectangle(pt.X, pt.Y - fullSize.Height/2, fullSize.Width, fullSize.Height); // break; //} subTopicIndex += mySideCount; if (!rectFull.IsEmpty) { allBounds = Rectangle.Union(allBounds, rectFull); } } return(allBounds); }
Size CalculateSizes(Topic parent, Size parentFullSize, MindMapLayoutArgs e, Vector4 vector, Hashtable layoutInfos) { if (parent.Folded) { return(CalculateSizes(parent, parentFullSize, null, e, vector, layoutInfos)); } else { return(CalculateSizes(parent, parentFullSize, parent.Children.ToArray(), e, vector, layoutInfos)); } }
TopicLine CreateTopicLine(MindMapLayoutArgs e, Topic topic, Topic subTopic) { switch (Vector) { case MindMapLayoutType.OrganizationUp: return(CreateTopicLine(e, topic, subTopic, Vector4.Top, Vector4.Bottom)); case MindMapLayoutType.OrganizationDown: default: return(CreateTopicLine(e, topic, subTopic, Vector4.Bottom, Vector4.Top)); } }
XList <int> CalculateRow(Topic parent, MindMapLayoutArgs e) { Topic[] empty = { }; if (parent.Folded) { return(CalculateRow(parent, empty, e)); } else { return(CalculateRow(parent, parent.Children.ToArray(), e)); } }
TopicLine CreateTopicLine(MindMapLayoutArgs e, Topic topic, Topic subTopic) { switch (Vector) { case MindMapLayoutType.TreeLeft: return(CreateTopicLine(e, topic, subTopic, Vector4.Bottom, Vector4.Right)); case MindMapLayoutType.TreeRight: default: return(CreateTopicLine(e, topic, subTopic, Vector4.Bottom, Vector4.Left)); } }
Rectangle LayoutRoot(Topic root, MindMapLayoutArgs args) { Size size = root.Bounds.Size; // CalculateNodeSize(root, args); // datnq TODO Update calculateNodeSize Point pt = new Point(0, 0); root.Bounds = new Rectangle(pt.X - size.Width / 2, pt.Y - size.Height / 2, size.Width, size.Height); var rootFullSize = LayoutAttachments(root, args); Vector4[] vectors = new Vector4[] { Vector4.Left, Vector4.Top, Vector4.Right }; //int def = 0; //int sideCount = Math.DivRem(root.Children.Count, vectors.Length, out def); Rectangle allBounds = root.Bounds; //int subTopicIndex = 0; root.Lines.Clear(); Hashtable layoutInfos = new Hashtable(); for (int vi = 0; vi < vectors.Length; vi++) { TopicType type; if (vi == (int)Vector4.Left) { type = TopicType.Threat; } else if (vi == (int)Vector4.Right) { type = TopicType.Consequence; } else { type = TopicType.Hazard; } XList <Topic> children = root.GetChildrenByType(type); Topic[] subTopics = new Topic[children.Count]; for (int ti = 0, n = children.Count; ti < n; ti++) { subTopics[ti] = children[ti]; } XList <int> rows = CalculateRow(root, subTopics, args); XList <int> columns = CalculateColumn(root, subTopics); Rectangle rectFull = LayoutSubTopics(root, subTopics, vectors[vi], rows, columns, -1, -1, args); if (!rectFull.IsEmpty) { allBounds = Rectangle.Union(allBounds, rectFull); } } return(allBounds); }
protected virtual Size LayoutAttachments(Topic topic, MindMapLayoutArgs e) { var size = topic.Size; if (e.ShowRemarkIcon && topic.HaveRemark) { topic.RemarkIconBounds = new Rectangle(0, size.Height + 2, e.RemarkIconSize, e.RemarkIconSize); size.Height += 2 + e.RemarkIconSize; size.Width = Math.Max(size.Width, e.RemarkIconSize); } return(size); }
void LayoutTopic(Topic topic, Hashtable layoutInfos, int x, int y, MindMapLayoutArgs e) { var tli = (TopicLayoutInfo)layoutInfos[topic]; int foldBtnSize = FoldingButtonSize; int x2; if (Vector == MindMapLayoutType.TreeLeft) { topic.Location = new Point(x - topic.Width, y); topic.FoldingButton = new Rectangle(topic.Right, topic.Top + (int)Math.Round((topic.Height - foldBtnSize) / 2.0f, MidpointRounding.AwayFromZero), foldBtnSize, foldBtnSize); x2 = topic.Left + topic.Width / 2 - e.LayerSpace; } else { topic.Location = new Point(x, y); topic.FoldingButton = new Rectangle(topic.Left - foldBtnSize, topic.Top + (int)Math.Round((topic.Height - foldBtnSize) / 2.0f, MidpointRounding.AwayFromZero), foldBtnSize, foldBtnSize); x2 = topic.Left + topic.Width / 2 + e.LayerSpace; } topic.Lines.Clear(); if (!topic.Children.IsEmpty && !topic.Folded) { y += topic.Height + e.ItemsSpace; foreach (Topic subTopic in topic.Children) { LayoutTopic(subTopic, layoutInfos, x2, y, e); if (layoutInfos.Contains(subTopic)) { TopicLayoutInfo tli2 = (TopicLayoutInfo)layoutInfos[subTopic]; y += tli2.FullSize.Height + e.ItemsSpace; } // line var line = CreateTopicLine(e, topic, subTopic); if (line != null) { topic.Lines.Add(line); } } } }
Size CalculateTextSize(Topic topic, MindMapLayoutArgs e) { Size proposedSize = topic.TextBounds.Size; Font font = topic.Style.Font != null ? topic.Style.Font : e.Font; Size textSize; if (e.Graphics == null) { textSize = TextRenderer.MeasureText(topic.Text, font, proposedSize); } else { textSize = Size.Ceiling(e.Graphics.MeasureString(topic.Text, font, proposedSize.Width)); } return(textSize); }
void CalculateSizes(Topic topic, Hashtable layoutInfos, MindMapLayoutArgs e) { if (topic == null) { return; } topic.Size = CalculateNodeSize(topic, e); var topicFullSize = LayoutAttachments(topic, e); TopicLayoutInfo tlf = new TopicLayoutInfo(); int w = 0; int h = 0; if (!topic.Children.IsEmpty && !topic.Folded) { foreach (Topic subTopic in topic.Children) { CalculateSizes(subTopic, layoutInfos, e); if (layoutInfos.Contains(subTopic)) { TopicLayoutInfo tli = (TopicLayoutInfo)layoutInfos[subTopic]; h += tli.FullSize.Height; w = Math.Max(w, tli.FullSize.Width); } if (subTopic != topic.Children[0]) { h += e.ItemsSpace; } } tlf.ChildrenSize = new Size(w, h); tlf.FullSize = new Size(Math.Max(topicFullSize.Width, w + topicFullSize.Width / 2 + e.LayerSpace), topicFullSize.Height + e.ItemsSpace + h); } else { tlf.FullSize = new Size(topicFullSize.Width, topicFullSize.Height); } //if (!topic.Children.IsEmpty) //tlf.FullSize.Height += FoldingButtonSize; layoutInfos[topic] = tlf; }
public Size LayoutMap(MindMap map, MindMapLayoutArgs e) { if (map == null) { throw new ArgumentNullException(); } if (map.Root != null) { Rectangle bounds = Layout(map.Root, e); Rectangle linesBounds = GetLinksFullBounds(map); if (!linesBounds.IsEmpty) { bounds = Rectangle.Union(bounds, linesBounds); } // page size var psx = Math.Max(0, (map.PageSize.Width - (bounds.Width + map.Margin.Horizontal)) / 2); var psy = Math.Max(0, (map.PageSize.Height - (bounds.Height + map.Margin.Vertical)) / 2); Offset(map.Root, map.Margin.Left - bounds.X + psx, map.Margin.Top - bounds.Y + psy); // refresh line's layout Link[] lines = map.GetLinks(true); for (int i = 0; i < lines.Length; i++) { lines[i].RefreshLayout(); } bounds.Width += map.Margin.Horizontal; bounds.Height += map.Margin.Vertical; // page size bounds.Width = Math.Max(bounds.Width, map.PageSize.Width); bounds.Height = Math.Max(bounds.Height, map.PageSize.Height); map.LayoutInitialized = true; return(bounds.Size); } else { return(Size.Empty); } }
void CalculateSizes(Topic topic, Hashtable layoutInfos, MindMapLayoutArgs e) { if (topic == null) { return; } Size size = CalculateNodeSize(topic, e); if (size.Width % 2 == 0) { size = new Size(size.Width + 1, size.Height); } topic.Size = size; var topicFullSize = LayoutAttachments(topic, e); int w = 0; int h = 0; if (!topic.Children.IsEmpty && !topic.Folded) { foreach (var subTopic in topic.Children) { CalculateSizes(subTopic, layoutInfos, e); if (layoutInfos.Contains(subTopic)) { TopicLayoutInfo tli = (TopicLayoutInfo)layoutInfos[subTopic]; w += tli.FullSize.Width; h = Math.Max(h, tli.FullSize.Height); } if (subTopic != topic.Children[0]) { w += e.ItemsSpace; } } } TopicLayoutInfo tlf = new TopicLayoutInfo(); tlf.ChildrenSize = new Size(w, h); tlf.FullSize = new Size(Math.Max(w, topicFullSize.Width), h + topicFullSize.Height + e.LayerSpace); layoutInfos[topic] = tlf; }
protected override TopicLine CreateTopicLine(MindMapLayoutArgs e, Topic beginTopic, Topic endTopic, Vector4 beginSide, Vector4 endSide) { var beginRect = beginTopic.Bounds; var endRect = endTopic.Bounds; if (e.ShowLineArrowCap) { endRect.Inflate(LineAnchorSize, LineAnchorSize); } if (beginTopic != null && !beginTopic.IsRoot) { int foldBtnSize = endTopic.FoldingButton.Width; switch (beginSide) { case Vector4.Left: beginRect.X -= foldBtnSize; beginRect.Width += foldBtnSize; break; case Vector4.Right: beginRect.Width += foldBtnSize; break; case Vector4.Top: beginRect.Y -= foldBtnSize; beginRect.Height += foldBtnSize; break; case Vector4.Bottom: beginRect.Height += foldBtnSize; break; } } if (endTopic != null && endTopic.Style.Shape == TopicShape.BaseLine) { endRect.Y = endRect.Bottom; endRect.Height = 0; } return(new TopicLine(endTopic, beginSide, endSide, beginRect, endRect)); }
protected override TopicLine CreateTopicLine(MindMapLayoutArgs e, Topic beginTopic, Topic endTopic, Vector4 beginSide, Vector4 endSide) { var beginRect = beginTopic.Bounds; var endRect = endTopic.Bounds; if (e.ShowLineArrowCap) { endRect.Inflate(LineAnchorSize, LineAnchorSize); } if (endTopic != null && !endTopic.Children.IsEmpty) { int foldBtnSize = endTopic.FoldingButton.Width; switch (endSide) { case Vector4.Left: endRect.X -= foldBtnSize; endRect.Width += foldBtnSize; break; case Vector4.Right: endRect.Width += foldBtnSize; break; } } return(new TopicLine(endTopic, beginSide, endSide, beginRect, endRect)); //if (Vector == MindMapLayoutType.TreeLeft) //{ // beginTopic.Lines.Add(new TopicLine(endTopic, Vector4.Bottom, Vector4.Right)); //} //else //{ // beginTopic.Lines.Add(new TopicLine(endTopic, Vector4.Bottom, Vector4.Left)); //} }
/// <summary> /// 计算跟节点下的各个子节点之间的合适距离 /// </summary> /// <param name="subTopics">子节点集合</param> /// <param name="layerSpace"></param> /// <param name="minSpace">最小距离</param> /// <returns></returns> int GetRootItemsSpace(Topic parent, Topic[] subTopics, Hashtable layoutInfos, MindMapLayoutArgs e) { if (subTopics == null || subTopics.Length == 0) { return(0); } int layerSpace = e.LayerSpace; int count = subTopics.Length; double angle = Math.PI / (count + 1) * (count - 1); int c1 = (int)Math.Ceiling(Math.Sin(angle / 2) * layerSpace * 2); for (int i = 0; i < count; i++) { int h = subTopics[i].Height;// ((TopicLayoutInfo)layoutInfos[subTopics[i]]).FullSize.Height; if (i == 0 || i == count - 1) { c1 -= h / 2; } else { c1 -= h; } } return(Math.Max(c1, e.ItemsSpace)); }
protected override XList <TopicLine> CreateTopicLines(MindMapLayoutArgs e, Topic beginTopic, Topic endTopic, Vector4 beginSide, Vector4 endSide) { XList <TopicLine> lines = new XList <TopicLine>(); var beginRect = beginTopic.Bounds; var endRect = endTopic.Bounds; if (e.ShowLineArrowCap) { endRect.Inflate(LineAnchorSize, LineAnchorSize); } if (beginTopic != null && !beginTopic.IsRoot) { int foldBtnSize = endTopic.FoldingButton.Width; switch (beginSide) { case Vector4.Left: break; case Vector4.Right: break; case Vector4.Top: beginRect.Y -= foldBtnSize; beginRect.Height += foldBtnSize; break; case Vector4.Bottom: beginRect.Height += foldBtnSize; break; } } if (beginTopic != null && endTopic != null && beginTopic.Type == TopicType.Barrier && beginTopic.IsParentOf(endTopic)) { beginRect.Y = beginTopic.ContentBounds.Bottom; beginRect.Height = 0; } if (endTopic != null) { if (endTopic.Type == TopicType.Threat || endTopic.Type == TopicType.Consequence || endTopic.Type == TopicType.Escalation) { endRect.Height = 60; // 60 is barrier height } else if (endTopic.Style.Shape == TopicShape.BaseLine) { endRect.Y = endRect.Bottom; endRect.Height = 0; } } TopicLine line; if (endTopic != null && beginTopic != null && endTopic.Type == TopicType.Barrier && (beginTopic.IsRoot || beginTopic.Type == TopicType.Barrier)) { endRect = endTopic.ContentBounds; endRect.Height = endTopic.Bounds.Height; line = new TopicLine(endTopic, beginSide, endSide, beginRect, endRect); lines.Add(line); beginRect = endRect; int left = beginRect.Left; if (beginSide == Vector4.Left) { left += beginRect.Width; } else if (beginSide == Vector4.Right) { left -= beginRect.Width; } beginRect.Location = new Point(left, beginRect.Y); endRect = endTopic.Bounds; } line = new TopicLine(endTopic, beginSide, endSide, beginRect, endRect); lines.Add(line); return(lines); }
Rectangle CalculateWidgets(Topic topic, WidgetAlignment alignment, MindMapLayoutArgs e) { var widgets = topic.FindWidgets(alignment); if (widgets.Length == 0) { return(Rectangle.Empty); } var rect = Rectangle.Empty; var fitSize = Size.Empty; foreach (var widget in widgets) { var rectW = new Rectangle(Point.Empty, widget.CalculateSize(e)); rectW.Inflate(widget.Padding, widget.Padding); if (widget.CustomWidth.HasValue) { rectW.Width = widget.CustomWidth.Value; } if (widget.CustomHeight.HasValue) { rectW.Height = widget.CustomHeight.Value; } widget.Bounds = rectW; rectW.Width += e.Chart.WidgetMargin; rectW.Height += e.Chart.WidgetMargin; // switch (alignment) { case WidgetAlignment.Left: case WidgetAlignment.Right: if (widget.FitContainer) { fitSize.Width += rectW.Width; fitSize.Height = Math.Max(fitSize.Height, rectW.Height); } else { rect.Width = Math.Max(rect.Width, rectW.Width); rect.Height += rectW.Height; } break; case WidgetAlignment.Top: case WidgetAlignment.Bottom: if (widget.FitContainer) { fitSize.Height += rectW.Height; fitSize.Width = Math.Max(fitSize.Width, rectW.Width); } else { rect.Width += rectW.Width; rect.Height = Math.Max(rect.Height, rectW.Height); } break; } } switch (alignment) { case WidgetAlignment.Left: case WidgetAlignment.Right: rect.Width += fitSize.Width; rect.Height = Math.Max(rect.Height, fitSize.Height); break; case WidgetAlignment.Top: case WidgetAlignment.Bottom: rect.Width = Math.Max(rect.Width, fitSize.Width); rect.Height += fitSize.Height; break; } rect.Width += e.Chart.WidgetMargin; rect.Height += e.Chart.WidgetMargin; return(rect); }
//protected int Zoom(int value, float zoom) //{ // return (int)Math.Ceiling(value * zoom); //} protected virtual Size CalculateNodeSize(Topic topic, MindMapLayoutArgs e) { //if (topic.CustomWidth.HasValue && topic.CustomHeight.HasValue) // return new Size(topic.CustomWidth.Value, topic.CustomHeight.Value); // Size proposedSize = Size.Empty; if (topic.CustomWidth.HasValue && topic.CustomWidth.Value > 0) { proposedSize.Width = topic.CustomWidth.Value - topic.Style.Padding.Horizontal; } if (topic.CustomHeight.HasValue && topic.CustomHeight.Value > 0) { proposedSize.Height = topic.CustomHeight.Value - topic.Style.Padding.Vertical; } // Icon Size //Rectangle iconBounds = Rectangle.Empty; //if (topic.Icon != null) //{ // iconBounds = new Rectangle(0, 0, topic.Icon.Width, topic.Icon.Height); // if (proposedSize.Width > 0) // proposedSize.Width -= topic.IconBounds.Width + +topic.Style.IconPadding; //} // Text Size Rectangle rectText = Rectangle.Empty; Font font = topic.Style.Font != null ? topic.Style.Font : e.Font; Size textSize; if (e.Graphics == null) { textSize = TextRenderer.MeasureText(topic.Text, font, proposedSize); } else { textSize = Size.Ceiling(e.Graphics.MeasureString(topic.Text, font, new SizeF(proposedSize.Width, proposedSize.Height))); } rectText = new Rectangle(Point.Empty, textSize); // Widgets Size //var widgetAligns = new WidgetAlignment[] { WidgetAlignment.Left, WidgetAlignment.Top, WidgetAlignment.Right, WidgetAlignment.Bottom }; var rectLeft = CalculateWidgets(topic, WidgetAlignment.Left, e); var rectTop = CalculateWidgets(topic, WidgetAlignment.Top, e); var rectRight = CalculateWidgets(topic, WidgetAlignment.Right, e); var rectBottom = CalculateWidgets(topic, WidgetAlignment.Bottom, e); int maxWidth = Helper.GetMax(rectText.Width, rectTop.Width, rectBottom.Width) + rectLeft.Width + rectRight.Width; int totalHeight = Helper.GetMax(rectText.Height + rectTop.Height + rectBottom.Height, rectLeft.Height, rectRight.Height); rectText.Width = Helper.GetMax(rectText.Width, rectTop.Width, rectBottom.Width); // Desc Size if (e.ShowRemarkIcon && topic.HaveRemark) { maxWidth += 16; } // Calculate Size Size size = new Size(maxWidth + topic.Padding.Horizontal, totalHeight + topic.Padding.Vertical); //if (!iconBounds.IsEmpty) //{ // size.Width += topic.IconPadding + iconBounds.Width; // size.Height = Math.Max(topic.IconPadding + iconBounds.Height, size.Height); //} size.Width = Math.Max(MinNodeSize.Width, size.Width); size.Height = Math.Max(MinNodeSize.Height, size.Height); if (topic.CustomWidth.HasValue) { size.Width = topic.CustomWidth.Value; } else if (topic.CustomHeight.HasValue) { size.Height = topic.CustomHeight.Value; } // var rect = new Rectangle(0, 0, size.Width, size.Height); rect = rect.Inflate(topic.Style.Padding); // Text Location // Widgets Location int hh1 = rectText.Height + rectTop.Height + rectBottom.Height; if (hh1 < rect.Height) { int hh = (rect.Height - hh1) / 3; rectText.Height += hh; rectTop.Height += hh; rectBottom.Height += hh; } if (!rectText.IsEmpty) { rectText = new Rectangle( rect.X + rectLeft.Width, rect.Y + rectTop.Height, rect.Width - rectLeft.Width - rectRight.Width, rect.Height - rectTop.Height - rectBottom.Height); } rectLeft.Height = rectRight.Height = Helper.GetMax(rectLeft.Height, rectRight.Height, rectText.Height + rectTop.Height + rectBottom.Height); rectLeft.Y = rectRight.Y = rect.Y; rectLeft.X = rect.X; rectRight.X = rectLeft.Right + rectText.Width; rectTop.X = rectBottom.X = rectText.Left; rectTop.Width = rectBottom.Width = rectText.Width; rectTop.Y = rect.Y; rectBottom.Y = rectText.Bottom; topic.TextBounds = rectText; ResetWidgetLocation(e, topic, WidgetAlignment.Left, rectLeft); ResetWidgetLocation(e, topic, WidgetAlignment.Top, rectTop); ResetWidgetLocation(e, topic, WidgetAlignment.Right, rectRight); ResetWidgetLocation(e, topic, WidgetAlignment.Bottom, rectBottom); // return(size); }
protected abstract Rectangle Layout(Topic root, MindMapLayoutArgs e);
//public virtual void AdjustLineRect(TopicLine line, Topic fromTopic, ref Rectangle rectFrom, ref Rectangle rectTo) //{ //} protected virtual TopicLine CreateTopicLine(MindMapLayoutArgs e, Topic beginTopic, Topic endTopic, Vector4 beginSide, Vector4 endSide) { return(null); }
void ResetWidgetLocation(MindMapLayoutArgs e, Topic topic, WidgetAlignment alignment, Rectangle rect) { var widgets = topic.FindWidgets(alignment); if (widgets.Length == 0) { return; } var dynamicWidgets = widgets.Where(w => !w.FitContainer).ToArray(); if (alignment == WidgetAlignment.Left || alignment == WidgetAlignment.Right) { var totalHeight = dynamicWidgets.Sum(w => w.Bounds.Height); var maxWidth = dynamicWidgets.Length > 0 ? dynamicWidgets.Max(w => w.Bounds.Width) : 0; var widgetMargin = Math.Max(e.Chart.WidgetMargin, (rect.Height - totalHeight) / (dynamicWidgets.Length + 1)); int y = rect.Y + widgetMargin; int x = rect.X + e.Chart.WidgetMargin; int dx = -1; int dy = y; foreach (var w in widgets) { var rw = w.Bounds; if (w.FitContainer) { rw.X = x; rw.Y = rect.Y + e.Chart.WidgetMargin; rw.Height = rect.Height - e.Chart.WidgetMargin * 2; x += rw.Width + e.Chart.WidgetMargin; } else { if (dx < 0) { dx = x; x += maxWidth + e.Chart.WidgetMargin; } rw.X = dx + (maxWidth - w.Bounds.Width) / 2; rw.Y = dy; dy += rw.Height + widgetMargin; } w.Bounds = rw; } } else if (alignment == WidgetAlignment.Top || alignment == WidgetAlignment.Bottom) { var totalWidth = dynamicWidgets.Sum(w => w.Bounds.Width); var maxHeight = dynamicWidgets.Length > 0 ? dynamicWidgets.Max(w => w.Bounds.Height) : 0; var widgetPadding = Math.Max(e.Chart.WidgetMargin, (rect.Width - totalWidth) / (dynamicWidgets.Length + 1)); int y = rect.Y + e.Chart.WidgetMargin; int x = rect.X + widgetPadding; int dx = x; int dy = -1; foreach (var w in widgets) { var rw = w.Bounds; if (w.FitContainer) { rw.X = rect.X + e.Chart.WidgetMargin; rw.Y = y; rw.Width = rect.Width - e.Chart.WidgetMargin * 2; y += rw.Height + e.Chart.WidgetMargin; } else { if (dy < 0) { dy = y; y += maxHeight + e.Chart.WidgetMargin; } rw.X = dx; rw.Y = dy + (maxHeight - w.Bounds.Height) / 2; dx += rw.Width + widgetPadding; } w.Bounds = rw; } } }