diff --git a/DiagramControl.cs b/DiagramControl.cs index 0462527..d2e3b12 100644 --- a/DiagramControl.cs +++ b/DiagramControl.cs @@ -33,10 +33,38 @@ namespace XSDDiagram ControlStyles.OptimizedDoubleBuffer, true); } - protected override void WndProc(ref Message m) + protected override bool IsInputKey(Keys keyData) + { + switch (keyData) + { + case Keys.Right: + case Keys.Left: + case Keys.Up: + case Keys.Down: + case Keys.PageDown: + case Keys.PageUp: + case Keys.Home: + case Keys.End: + case Keys.Delete: + return true; + case Keys.Shift | Keys.Right: + case Keys.Shift | Keys.Left: + case Keys.Shift | Keys.Up: + case Keys.Shift | Keys.Down: + case Keys.Shift | Keys.PageDown: + case Keys.Shift | Keys.PageUp: + case Keys.Shift | Keys.Home: + case Keys.Shift | Keys.End: + case Keys.Shift | Keys.Delete: + return true; + } + return base.IsInputKey(keyData); + } + + protected override void WndProc(ref Message m) { - if (m.Msg == WM_SETFOCUS) - return; + //if (m.Msg == WM_SETFOCUS) + // return; base.WndProc(ref m); } } diff --git a/MainForm.Designer.cs b/MainForm.Designer.cs index 1c5a8e4..6fc1816 100644 --- a/MainForm.Designer.cs +++ b/MainForm.Designer.cs @@ -63,7 +63,6 @@ namespace XSDDiagram this.splitContainerMain = new System.Windows.Forms.SplitContainer(); this.tabControlView = new System.Windows.Forms.TabControl(); this.tabPageDiagram = new System.Windows.Forms.TabPage(); - this.panelDiagram = new XSDDiagram.DiagramControlContainer(); this.splitContainerDiagramElement = new System.Windows.Forms.SplitContainer(); this.tabControlElement = new System.Windows.Forms.TabControl(); this.tabPageElementAttibutes = new System.Windows.Forms.TabPage(); @@ -102,6 +101,8 @@ namespace XSDDiagram this.expandOneLevelToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.textBoxElementPath = new System.Windows.Forms.TextBox(); this.toolTip = new System.Windows.Forms.ToolTip(this.components); + this.expandToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.panelDiagram = new XSDDiagram.DiagramControlContainer(); this.menuStripMain.SuspendLayout(); this.statusStripMain.SuspendLayout(); this.toolStripMain.SuspendLayout(); @@ -599,23 +600,6 @@ namespace XSDDiagram this.tabPageDiagram.Text = "Diagram"; this.tabPageDiagram.UseVisualStyleBackColor = true; // - // panelDiagram - // - this.panelDiagram.AllowDrop = true; - this.panelDiagram.AutoScroll = true; - this.panelDiagram.BackColor = System.Drawing.Color.WhiteSmoke; - this.panelDiagram.CausesValidation = false; - this.panelDiagram.Dock = System.Windows.Forms.DockStyle.Fill; - this.panelDiagram.Location = new System.Drawing.Point(0, 0); - this.panelDiagram.Margin = new System.Windows.Forms.Padding(0); - this.panelDiagram.Name = "panelDiagram"; - this.panelDiagram.Size = new System.Drawing.Size(650, 499); - this.panelDiagram.TabIndex = 0; - this.panelDiagram.VirtualPoint = new System.Drawing.Point(0, 0); - this.panelDiagram.VirtualSize = new System.Drawing.Size(10, 10); - this.panelDiagram.DragDrop += new System.Windows.Forms.DragEventHandler(this.panelDiagram_DragDrop); - this.panelDiagram.DragEnter += new System.Windows.Forms.DragEventHandler(this.panelDiagram_DragEnter); - // // splitContainerDiagramElement // this.splitContainerDiagramElement.Dock = System.Windows.Forms.DockStyle.Fill; @@ -887,13 +871,14 @@ namespace XSDDiagram // this.contextMenuStripDiagram.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.gotoXSDFileToolStripMenuItem, + this.expandToolStripMenuItem, this.removeFromDiagramToolStripMenuItem, this.toolStripMenuItem3, this.addAllToolStripMenuItem, this.removeAllToolStripMenuItem, this.expandOneLevelToolStripMenuItem}); this.contextMenuStripDiagram.Name = "contextMenuStripDiagram"; - this.contextMenuStripDiagram.Size = new System.Drawing.Size(197, 120); + this.contextMenuStripDiagram.Size = new System.Drawing.Size(197, 164); this.contextMenuStripDiagram.Opened += new System.EventHandler(this.contextMenuStripDiagram_Opened); // // gotoXSDFileToolStripMenuItem @@ -938,7 +923,7 @@ namespace XSDDiagram this.expandOneLevelToolStripMenuItem.Image = global::XSDDiagram.Properties.Resources.Expand; this.expandOneLevelToolStripMenuItem.Name = "expandOneLevelToolStripMenuItem"; this.expandOneLevelToolStripMenuItem.Size = new System.Drawing.Size(196, 22); - this.expandOneLevelToolStripMenuItem.Text = "&Expand One Level"; + this.expandOneLevelToolStripMenuItem.Text = "&Expand All One Level"; this.expandOneLevelToolStripMenuItem.Click += new System.EventHandler(this.expandOneLevelToolStripMenuItem_Click); // // textBoxElementPath @@ -956,6 +941,31 @@ namespace XSDDiagram this.toolTip.OwnerDraw = true; this.toolTip.ShowAlways = true; // + // expandToolStripMenuItem + // + this.expandToolStripMenuItem.Image = global::XSDDiagram.Properties.Resources.Expand; + this.expandToolStripMenuItem.Name = "expandToolStripMenuItem"; + this.expandToolStripMenuItem.Size = new System.Drawing.Size(196, 22); + this.expandToolStripMenuItem.Text = "E&xpand / Collapse"; + this.expandToolStripMenuItem.Click += new System.EventHandler(this.expandToolStripMenuItem_Click); + // + // panelDiagram + // + this.panelDiagram.AllowDrop = true; + this.panelDiagram.AutoScroll = true; + this.panelDiagram.BackColor = System.Drawing.Color.WhiteSmoke; + this.panelDiagram.CausesValidation = false; + this.panelDiagram.Dock = System.Windows.Forms.DockStyle.Fill; + this.panelDiagram.Location = new System.Drawing.Point(0, 0); + this.panelDiagram.Margin = new System.Windows.Forms.Padding(0); + this.panelDiagram.Name = "panelDiagram"; + this.panelDiagram.Size = new System.Drawing.Size(650, 499); + this.panelDiagram.TabIndex = 0; + this.panelDiagram.VirtualPoint = new System.Drawing.Point(0, 0); + this.panelDiagram.VirtualSize = new System.Drawing.Size(10, 10); + this.panelDiagram.DragDrop += new System.Windows.Forms.DragEventHandler(this.panelDiagram_DragDrop); + this.panelDiagram.DragEnter += new System.Windows.Forms.DragEventHandler(this.panelDiagram_DragEnter); + // // MainForm // this.AllowDrop = true; @@ -1090,6 +1100,7 @@ namespace XSDDiagram private System.Windows.Forms.ToolStripMenuItem closeToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem recentFilesToolStripMenuItem; private System.Windows.Forms.ToolStripButton toolStripButtonShowDocumentation; + private System.Windows.Forms.ToolStripMenuItem expandToolStripMenuItem; } } diff --git a/MainForm.cs b/MainForm.cs index cb7164a..3b791be 100644 --- a/MainForm.cs +++ b/MainForm.cs @@ -44,6 +44,8 @@ namespace XSDDiagram public partial class MainForm : Form { private DiagramPrinter _diagramPrinter; + private DiagramGdiRenderer _diagramGdiRenderer; + private Rectangle _renderingClipRectangle = new Rectangle(); private Diagram diagram = new Diagram(); private Schema schema = new Schema(); @@ -94,13 +96,15 @@ namespace XSDDiagram this.toolStripComboBoxSchemaElement.Items.Add(""); this.diagram.RequestAnyElement += new Diagram.RequestAnyElementEventHandler(diagram_RequestAnyElement); - this.panelDiagram.DiagramControl.ContextMenuStrip = this.contextMenuStripDiagram; + this.panelDiagram.VirtualSize = new Size(0, 0); + this.panelDiagram.DiagramControl.ContextMenuStrip = this.contextMenuStripDiagram; this.panelDiagram.DiagramControl.MouseWheel += new MouseEventHandler(DiagramControl_MouseWheel); this.panelDiagram.DiagramControl.MouseClick += new MouseEventHandler(DiagramControl_MouseClick); this.panelDiagram.DiagramControl.MouseHover += new EventHandler(DiagramControl_MouseHover); - this.panelDiagram.DiagramControl.MouseMove += new MouseEventHandler(DiagramControl_MouseMove); - this.panelDiagram.VirtualSize = new Size(0, 0); - this.panelDiagram.DiagramControl.Paint += new PaintEventHandler(DiagramControl_Paint); + this.panelDiagram.DiagramControl.MouseMove += new MouseEventHandler(DiagramControl_MouseMove); + //this.panelDiagram.DiagramControl.KeyDown += DiagramControl_KeyDown; + this.panelDiagram.DiagramControl.KeyDown += new KeyEventHandler(DiagramControl_KeyDown); + this.panelDiagram.DiagramControl.Paint += new PaintEventHandler(DiagramControl_Paint); this.schema.RequestCredential += schema_RequestCredential; this.backupUsername = Options.Username; @@ -333,13 +337,21 @@ namespace XSDDiagram void DiagramControl_Paint(object sender, PaintEventArgs e) { - Point virtualPoint = this.panelDiagram.VirtualPoint; - e.Graphics.TranslateTransform(-(float)virtualPoint.X, -(float)virtualPoint.Y); - e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; - e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; + if (_diagramGdiRenderer == null) + _diagramGdiRenderer = new DiagramGdiRenderer(e.Graphics); + else if (e.Graphics != _diagramGdiRenderer.Graphics) + _diagramGdiRenderer.Graphics = e.Graphics; + if (_diagramGdiRenderer != null) + { + Point virtualPoint = this.panelDiagram.VirtualPoint; + e.Graphics.TranslateTransform(-(float)virtualPoint.X, -(float)virtualPoint.Y); + e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; + _renderingClipRectangle.Location = virtualPoint; + _renderingClipRectangle.Size = this.panelDiagram.DiagramControl.ClientRectangle.Size; - DiagramGdiRenderer.Draw(diagram, e.Graphics, - new Rectangle(virtualPoint, this.panelDiagram.DiagramControl.ClientRectangle.Size)); + _diagramGdiRenderer.Render(diagram, _renderingClipRectangle); + } } private void UpdateDiagram() @@ -501,9 +513,10 @@ namespace XSDDiagram else resultElement.ShowChildElements ^= true; - UpdateDiagram(); - this.panelDiagram.ScrollTo(this.diagram.ScalePoint(resultElement.Location), true); - } + //UpdateDiagram(); + //this.panelDiagram.ScrollTo(this.diagram.ScalePoint(resultElement.Location), true); + SelectDiagramElement(resultElement, true); + } } else if (resultRegion == DiagramHitTestRegion.Element) { @@ -520,21 +533,18 @@ namespace XSDDiagram } } - private void SelectDiagramElement(DiagramItem element) + private void SelectDiagramElement(DiagramItem element, bool scrollToElement = false) { this.textBoxElementPath.Text = ""; - if (element == null) + + if (element == null) { this.toolStripComboBoxSchemaElement.SelectedItem = ""; this.propertyGridSchemaObject.SelectedObject = null; this.listViewAttributes.Items.Clear(); - return; } - - if (element is DiagramItem) + else { - //if (this.schema.ElementsByName[element.FullName] != null) - // this.toolStripComboBoxSchemaElement.SelectedItem = this.schema.ElementsByName[element.FullName]; XSDObject xsdObject; if (this.schema.ElementsByName.TryGetValue(element.FullName, out xsdObject) && xsdObject != null) this.toolStripComboBoxSchemaElement.SelectedItem = xsdObject; @@ -553,14 +563,15 @@ namespace XSDDiagram } this.textBoxElementPath.Text = path; } - else - { - this.toolStripComboBoxSchemaElement.SelectedItem = ""; - SelectSchemaElement(element); - } - } - private void SelectSchemaElement(XSDObject xsdObject) + if (element != this.diagram.SelectedElement) + this.diagram.SelectElement(element); + if (scrollToElement) + this.panelDiagram.ScrollTo(this.diagram.ScalePoint(element.Location), true); + UpdateDiagram(); + } + + private void SelectSchemaElement(XSDObject xsdObject) { SelectSchemaElement(xsdObject.Tag, xsdObject.NameSpace); } @@ -1233,7 +1244,8 @@ namespace XSDDiagram private void contextMenuStripDiagram_Opened(object sender, EventArgs e) { this.gotoXSDFileToolStripMenuItem.Enabled = false; - this.removeFromDiagramToolStripMenuItem.Enabled = false; + this.expandToolStripMenuItem.Enabled = false; + this.removeFromDiagramToolStripMenuItem.Enabled = false; Point contextualMenuMousePosition = this.panelDiagram.DiagramControl.PointToClient(MousePosition); contextualMenuMousePosition.Offset(this.panelDiagram.VirtualPoint); @@ -1246,7 +1258,8 @@ namespace XSDDiagram { this.contextualMenuPointedElement = resultElement; this.gotoXSDFileToolStripMenuItem.Enabled = this.schema.ElementsByName.ContainsKey(this.contextualMenuPointedElement.FullName); - this.removeFromDiagramToolStripMenuItem.Enabled = true; + this.expandToolStripMenuItem.Enabled = true; + this.removeFromDiagramToolStripMenuItem.Enabled = true; } } } @@ -1268,22 +1281,30 @@ namespace XSDDiagram this.contextualMenuPointedElement = null; } - private void removeFromDiagramToolStripMenuItem_Click(object sender, EventArgs e) + private void expandToolStripMenuItem_Click(object sender, EventArgs e) + { + ExpandCollapseElement(this.contextualMenuPointedElement, false); + this.contextualMenuPointedElement = null; + } + + private void removeFromDiagramToolStripMenuItem_Click(object sender, EventArgs e) { - if (this.contextualMenuPointedElement != null) - { - DiagramItem parentDiagram = this.contextualMenuPointedElement.Parent; - this.diagram.Remove(this.contextualMenuPointedElement); - UpdateDiagram(); - if (parentDiagram != null) - this.panelDiagram.ScrollTo(this.diagram.ScalePoint(parentDiagram.Location), true); - else - this.panelDiagram.ScrollTo(new Point(0, 0)); - } - this.contextualMenuPointedElement = null; + RemoveElement(this.contextualMenuPointedElement); + this.contextualMenuPointedElement = null; } - private void tabControlView_Selected(object sender, TabControlEventArgs e) + private void RemoveElement(DiagramItem element) + { + DiagramItem parentDiagram = element.Parent; + this.diagram.Remove(element); + UpdateDiagram(); + if (parentDiagram != null) + this.panelDiagram.ScrollTo(this.diagram.ScalePoint(parentDiagram.Location), true); + else + this.panelDiagram.ScrollTo(new Point(0, 0)); + } + + private void tabControlView_Selected(object sender, TabControlEventArgs e) { if (tabControlView.SelectedTab.Tag != null) { @@ -1640,12 +1661,97 @@ namespace XSDDiagram { } - //private void toolTip_Popup(object sender, PopupEventArgs e) - //{ - // //toolTip.SetToolTip(e.AssociatedControl, "AAAAAAAAAA"); - //} + //private void toolTip_Popup(object sender, PopupEventArgs e) + //{ + // //toolTip.SetToolTip(e.AssociatedControl, "AAAAAAAAAA"); + //} - private void toolTip_Draw(object sender, DrawToolTipEventArgs e) + private void DiagramControl_KeyDown(object sender, KeyEventArgs e) + { + if (this.diagram.RootElements.Count > 0) + { + if (e.KeyCode == Keys.Space || e.KeyCode == Keys.Return || e.KeyCode == Keys.Enter) + ExpandCollapseElement(this.diagram.SelectedElement, true); + if (e.KeyCode == Keys.Delete) + { + DiagramItem parentElement = this.diagram.SelectedElement.Parent; + RemoveElement(this.diagram.SelectedElement); + if (parentElement != null) + SelectDiagramElement(this.diagram.SelectedElement.Parent, true); + else + SelectDiagramElement(null); + } + else if (e.KeyCode == Keys.Right || e.KeyCode == Keys.Left + || e.KeyCode == Keys.Down || e.KeyCode == Keys.Up + || e.KeyCode == Keys.PageDown || e.KeyCode == Keys.PageUp + || e.KeyCode == Keys.Home || e.KeyCode == Keys.End + ) + { + DiagramItem element = this.diagram.SelectedElement; + if (element == null) + SelectDiagramElement(this.diagram.RootElements[0], true); + else + { + switch (e.KeyCode) + { + case Keys.Right: + if (element.HasChildElements) + { + if (element.ChildElements.Count == 0) + this.diagram.ExpandChildren(element); + element.ShowChildElements = true; + SelectDiagramElement(element.ChildElements[0], true); + } + break; + case Keys.Left: + if (element.Parent != null) + SelectDiagramElement(element.Parent, true); + break; + case Keys.Down: + { + IList children = element.Parent == null ? this.diagram.RootElements : element.Parent.ChildElements; + if (children != null) + { + var pos = children.IndexOf(element); + if (pos + 1 < children.Count) + SelectDiagramElement(children[pos + 1], true); + } + } + break; + case Keys.Up: + { + IList children = element.Parent == null ? this.diagram.RootElements : element.Parent.ChildElements; + if (children != null) + { + var pos = children.IndexOf(element); + if (pos - 1 >= 0) + SelectDiagramElement(children[pos - 1], true); + } + } + break; + } + } + } + } + } + + private void ExpandCollapseElement(DiagramItem element, bool scrollToElement = false) + { + if (element != null && element.HasChildElements) + { + if (element.ChildElements.Count == 0) + { + this.diagram.ExpandChildren(element); + element.ShowChildElements = true; + } + else + element.ShowChildElements ^= true; + UpdateDiagram(); + this.panelDiagram.ScrollTo(this.diagram.ScalePoint(element.Location), true); + } + } + + private void toolTip_Draw(object sender, DrawToolTipEventArgs e) { Point diagramMousePosition = e.AssociatedControl.PointToClient(MousePosition); string text = string.Format("AAAA {0} {1}\nA Que\n\nCoucou", diagramMousePosition.X, diagramMousePosition.Y); diff --git a/MainForm.resx b/MainForm.resx index a5a930f..0c3a423 100644 --- a/MainForm.resx +++ b/MainForm.resx @@ -126,15 +126,15 @@ 271, 17 - - 197, 61 - 384, 61 577, 61 + + 197, 61 + 17, 61 diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index e27398e..a1f57df 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.18.0.0")] -[assembly: AssemblyFileVersion("0.18.0.0")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ReadMe.txt b/ReadMe.txt index 3a85379..0ec60bf 100644 --- a/ReadMe.txt +++ b/ReadMe.txt @@ -109,7 +109,6 @@ TODO LIST: - Tooltips above the diagram element with a summary (xpath/attributes/doc) (display 200ms after the mouse move -> avoid 100 %CPU) o The optional display of attributes inside the diagram - Columns in the element/attributes tabs for restrictions (length/pattern/enumerations) -- Element selection in the diagram + move from one element to another with the arrow key - Multi-selection (i.e.: to remove several element at once) - Save the current UI state (open file/diagram/zoom/...) - XML sample (skeleton) generation (the ability to generate random test XML files complying with the open schema) @@ -118,10 +117,11 @@ TODO LIST: CHANGES: -version 0.18 (Not released yet) +version 1.0a (Not released yet) - Add the documentation in the diagram (experimental). - Add a close entry in the File menu. - Add a recently opened list. +- Add the selection of an element in the diagram and allow to move from one element to another with the arrow key. - Show the Windows Explorer registration menu only if we have the adminitrative right. - Disable the impossible actions in the menu and the toolbar when XSD file are not loaded. - Increase the icon resolution. diff --git a/XSDDiagram.exe b/XSDDiagram.exe index f4d9b27..fc5819c 100644 Binary files a/XSDDiagram.exe and b/XSDDiagram.exe differ diff --git a/XSDDiagramConsole.exe b/XSDDiagramConsole.exe index 3a643af..5189562 100644 Binary files a/XSDDiagramConsole.exe and b/XSDDiagramConsole.exe differ diff --git a/XSDDiagrams/Properties/AssemblyInfo.cs b/XSDDiagrams/Properties/AssemblyInfo.cs index 4df3110..41847b6 100644 --- a/XSDDiagrams/Properties/AssemblyInfo.cs +++ b/XSDDiagrams/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.17.0.0")] -[assembly: AssemblyFileVersion("0.17.0.0")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/XSDDiagrams/Rendering/Diagram.cs b/XSDDiagrams/Rendering/Diagram.cs index 4d7e2f5..4e5a689 100644 --- a/XSDDiagrams/Rendering/Diagram.cs +++ b/XSDDiagrams/Rendering/Diagram.cs @@ -34,11 +34,12 @@ namespace XSDDiagram.Rendering private Font _documentationFont; private Font _documentationFontScaled; - private Rectangle _boundingBox; + private Rectangle _boundingBox; private DiagramAlignement _alignement; - private List _rootElements; private IDictionary _elementsByName; + private List _rootElements; + private DiagramItem _selectedElement; private XMLSchema.any _fakeAny; @@ -55,6 +56,7 @@ namespace XSDDiagram.Rendering _boundingBox = Rectangle.Empty; _alignement = DiagramAlignement.Center; _rootElements = new List(); + _selectedElement = null; _elementsByName = new Dictionary(StringComparer.OrdinalIgnoreCase); } @@ -79,6 +81,7 @@ namespace XSDDiagram.Rendering public IDictionary ElementsByName { get { return _elementsByName; } set { _elementsByName = value; } } public List RootElements { get { return _rootElements; } } + public DiagramItem SelectedElement { get { return _selectedElement; } } #endregion @@ -430,10 +433,12 @@ namespace XSDDiagram.Rendering public void Clear() { - _rootElements.Clear(); - } + _elementsByName.Clear(); + _rootElements.Clear(); + _selectedElement = null; + } - public void Layout(Graphics g) + public void Layout(Graphics g) { string fontName = "Arial"; // "Verdana"; // "Arial"; @@ -611,6 +616,17 @@ namespace XSDDiagram.Rendering } } + public void SelectElement(DiagramItem element) + { + if(_selectedElement != null) + _selectedElement.IsSelected = false; + if (element != null) + { + _selectedElement = element; + element.IsSelected = true; + } + } + #endregion #region Private Methods diff --git a/XSDDiagrams/Rendering/DiagramExporter.cs b/XSDDiagrams/Rendering/DiagramExporter.cs index 20143f3..ca7e41e 100644 --- a/XSDDiagrams/Rendering/DiagramExporter.cs +++ b/XSDDiagrams/Rendering/DiagramExporter.cs @@ -175,14 +175,14 @@ namespace XSDDiagram.Rendering { _diagram.Scale = 1.0f; _diagram.Layout(referenceGraphics); - using (StreamWriter sw = new StreamWriter(stream)) + using (StreamWriter streamWriter = new StreamWriter(stream)) { - using (DiagramSvgRenderer renderer = new DiagramSvgRenderer(sw)) + using (DiagramSvgRenderer renderer = new DiagramSvgRenderer(streamWriter, referenceGraphics)) { renderer.Render(_diagram); } - sw.Close(); + streamWriter.Close(); } result = true; } diff --git a/XSDDiagrams/Rendering/DiagramGdiRenderer.cs b/XSDDiagrams/Rendering/DiagramGdiRenderer.cs index 520fe9d..034b824 100644 --- a/XSDDiagrams/Rendering/DiagramGdiRenderer.cs +++ b/XSDDiagrams/Rendering/DiagramGdiRenderer.cs @@ -56,6 +56,10 @@ namespace XSDDiagram.Rendering { return _graphics; } + set + { + _graphics = value; + } } #endregion @@ -116,11 +120,16 @@ namespace XSDDiagram.Rendering { //System.Diagnostics.Trace.WriteLine("DiagramElement.Paint\n\tName: " + drawingItem.Name); - Brush background = new SolidBrush(Color.White); + Color backgroundColor = Color.White; + if(drawingItem.IsSelected) + backgroundColor = Color.FromArgb(0xA6, 0xCA, 0xF0); + + Brush background = new SolidBrush(backgroundColor); + Brush backgroundExpandBox = new SolidBrush(Color.White); SolidBrush foreground = new SolidBrush(Color.Black); if (drawingItem.IsDisabled) { - background = new HatchBrush(HatchStyle.BackwardDiagonal, Color.Gray, Color.White); + background = new HatchBrush(HatchStyle.BackwardDiagonal, Color.Gray, backgroundColor); foreground = new SolidBrush(Color.Gray); } Pen foregroundPen = new Pen(foreground); @@ -570,7 +579,7 @@ namespace XSDDiagram.Rendering if (drawingItem.HasChildElements) { Rectangle scaledChildExpandButtonBox = drawingItem.ScaleRectangle(drawingItem.ChildExpandButtonBox); - _graphics.FillRectangle(background, scaledChildExpandButtonBox); + _graphics.FillRectangle(backgroundExpandBox, scaledChildExpandButtonBox); _graphics.DrawRectangle(foregroundPen, scaledChildExpandButtonBox); Point middle = new Point(scaledChildExpandButtonBox.Width / 2, scaledChildExpandButtonBox.Height / 2); diff --git a/XSDDiagrams/Rendering/DiagramItem.cs b/XSDDiagrams/Rendering/DiagramItem.cs index 2126789..45cd3e2 100644 --- a/XSDDiagrams/Rendering/DiagramItem.cs +++ b/XSDDiagrams/Rendering/DiagramItem.cs @@ -14,6 +14,7 @@ using System; using System.Drawing; using System.Collections.Generic; using System.Text.RegularExpressions; +using System.Text; namespace XSDDiagram.Rendering { @@ -29,6 +30,7 @@ namespace XSDDiagram.Rendering private bool _isReference; private bool _isSimpleContent; private bool _isDisabled; + private bool _isSelected; private bool _hasChildElements; private bool _showChildElements; @@ -190,19 +192,31 @@ namespace XSDDiagram.Rendering _isSimpleContent = value; } } - - public bool IsDisabled - { - get - { - return _isDisabled; - } - set - { - _isDisabled = value; - } + + public bool IsDisabled + { + get + { + return _isDisabled; + } + set + { + _isDisabled = value; + } } - + + public bool IsSelected + { + get + { + return _isSelected; + } + set + { + _isSelected = value; + } + } + public int MinOccurrence { get @@ -468,7 +482,7 @@ namespace XSDDiagram.Rendering return _diagram.ScaleRectangle(rectangle); } - public string GetTextDocumentation(bool autoWrap = false) + public string GetTextDocumentation() { string text = null; XMLSchema.annotated annotated = this.TabSchema as XMLSchema.annotated; @@ -542,18 +556,10 @@ namespace XSDDiagram.Rendering if (text != null) { SizeF sizeF = g.MeasureString(text, DocumentationFont); - double documentationWidth = Math.Max(1.0, _size.Width + _padding.Width * 2.0); + double documentationWidth = Math.Max(1.0, _size.Width + _padding.Width); // * 2.0); double documentationHeight = (Math.Ceiling(sizeF.Width / documentationWidth) + 1) * sizeF.Height; _documentationBox = new Rectangle(new Point(0, 0), new Size((int)documentationWidth, (int)documentationHeight)); - //_boundingBox.Height += (_diagram.Alignement == DiagramAlignement.Center ? 2 : 1) * _documentationBox.Height + 2 * _padding.Height; - //if(_diagram.Alignement == DiagramAlignement.Center) - //{ - // _boundingBox.Height = Math.Max(_size.Height + 2 * _padding.Height + 2 * _documentationBox.Height + 2 * _padding.Height, childBoundingBoxHeight); - //} - //else - { - _boundingBox.Height = Math.Max(_size.Height + 2 * _padding.Height + _documentationBox.Height + 2 * _padding.Height, childBoundingBoxHeight); - } + _boundingBox.Height = Math.Max(_size.Height + 2 * _padding.Height + _documentationBox.Height + 2 * _padding.Height, childBoundingBoxHeight); } } @@ -627,9 +633,9 @@ namespace XSDDiagram.Rendering if (_documentationBox != null) { if(_diagram.Alignement == DiagramAlignement.Far) - _documentationBox.Offset(_location.X, _location.Y - _documentationBox.Height - _padding.Height); + _documentationBox.Offset(_location.X - _padding.Height / 2, _location.Y - _documentationBox.Height - _padding.Height); else - _documentationBox.Offset(_location.X, _location.Y + _elementBox.Height + _padding.Height); + _documentationBox.Offset(_location.X - _padding.Height / 2, _location.Y + _elementBox.Height + _padding.Height); } } diff --git a/XSDDiagrams/Rendering/DiagramSvgRenderer.cs b/XSDDiagrams/Rendering/DiagramSvgRenderer.cs index 5c7495e..8bd8f2d 100644 --- a/XSDDiagrams/Rendering/DiagramSvgRenderer.cs +++ b/XSDDiagrams/Rendering/DiagramSvgRenderer.cs @@ -14,6 +14,7 @@ using System; using System.IO; using System.Text; using System.Drawing; +using System.Collections.Generic; namespace XSDDiagram.Rendering { @@ -22,12 +23,13 @@ namespace XSDDiagram.Rendering #region Private Fields private TextWriter _writer; + private Graphics _graphics; #endregion #region Constructors and Destructor - public DiagramSvgRenderer(TextWriter writer) + public DiagramSvgRenderer(TextWriter writer, Graphics referenceGraphics = null) { if (writer == null) { @@ -35,6 +37,7 @@ namespace XSDDiagram.Rendering } _writer = writer; + _graphics = referenceGraphics; } #endregion @@ -87,6 +90,8 @@ namespace XSDDiagram.Rendering public override void Render(DiagramItem drawingItem) { + bool showDocumentation = drawingItem.Diagram.ShowDocumentation && drawingItem.DocumentationBox != null && _graphics != null; + //if (drawingItem.diagram.ShowBoundingBox) //{ // int color = 255 - depth * 8; @@ -116,7 +121,6 @@ namespace XSDDiagram.Rendering // Draw the children lines if (drawingItem.ShowChildElements && drawingItem.ChildElements.Count > 0) { - bool showDocumentation = (drawingItem.Diagram.ShowDocumentation && drawingItem.DocumentationBox != null); if (drawingItem.ChildElements.Count == 1 && !showDocumentation) { int parentMidleY = drawingItem.ScaleInt(drawingItem.Location.Y + drawingItem.Size.Height / 2); @@ -463,18 +467,19 @@ namespace XSDDiagram.Rendering } // Draw Documentation - if (drawingItem.Diagram.ShowDocumentation && drawingItem.DocumentationBox != null) + if (showDocumentation) { string text = drawingItem.GetTextDocumentation(); if (text != null) { + List lines = WrapText(_graphics, drawingItem.DocumentationFont, text, drawingItem.ScaleRectangle(drawingItem.DocumentationBox).Width); + //stringFormatText.Trimming = StringTrimming.EllipsisCharacter; Rectangle scaledDocumentationBox = drawingItem.ScaleRectangle(drawingItem.DocumentationBox); string style = String.Format( "font-family:{0};font-size:{1}pt;fill:{2};font-weight:bold;text-anchor:start;dominant-baseline:central;inline-size={3}", drawingItem.DocumentationFont.Name, drawingItem.DocumentationFont.Size * fontScale, foregroundColor, scaledDocumentationBox.Width); - SVGText(text, style, - new Rectangle(scaledDocumentationBox.X, scaledDocumentationBox.Y, scaledDocumentationBox.Width, scaledDocumentationBox.Height)); + SVGText(lines, style, new Point(scaledDocumentationBox.X, scaledDocumentationBox.Y), drawingItem.DocumentationFont.Size * fontScale * 1.333333f); } } @@ -597,6 +602,14 @@ namespace XSDDiagram.Rendering _writer.WriteLine("{3}", rect.X + rect.Width / 2.0, rect.Y + rect.Height / 2.0, style, text); } + private void SVGText(List text, string style, Point point, float fontSize) + { + _writer.WriteLine("{3}", + point.X, point.Y, style, text.Count > 0 ? text[0] : ""); + for (int i = 1; i < text.Count; i++) + _writer.WriteLine("{2}", point.X, point.Y + i * fontSize, text[i]); + _writer.WriteLine(""); + } private string SVGPolygonToDrawCommand(Point[] pathPoint) { @@ -610,6 +623,60 @@ namespace XSDDiagram.Rendering return result.ToString(); } + private static List WrapText0(Graphics g, Font font, string text, int pixels) + { + List wordwrapped = new List(); + string currentLine = string.Empty; + for (int i = 0; i < text.Length; i++) + { + char currentChar = text[i]; + currentLine += currentChar; + if (g.MeasureString(currentLine, font).Width > pixels) + { + // exceeded length, back up to last space + int moveback = 0; + while (currentChar != ' ') + { + moveback++; + i--; + currentChar = text[i]; + } + string lineToAdd = currentLine.Substring(0, currentLine.Length - moveback); + wordwrapped.Add(lineToAdd); + currentLine = string.Empty; + } + } + + return wordwrapped; + } + + static List WrapText(Graphics g, Font font, string text, int pixels) + { + string[] originalLines = text.Split(new string[] { " " }, StringSplitOptions.None); + List wrappedLines = new List(); + StringBuilder actualLine = new StringBuilder(); + float actualWidth = 0; + + foreach (var item in originalLines) + { + SizeF formatted = g.MeasureString(item, font); + actualLine.Append(item + " "); + actualWidth += formatted.Width; + if (actualWidth > pixels) + { + wrappedLines.Add(actualLine.ToString()); + actualLine.Length = 0; + //actualLine.Clear(); + actualWidth = 0; + } + } + + if (actualLine.Length > 0) + wrappedLines.Add(actualLine.ToString()); + + return wrappedLines; + } + #endregion #region IDisposable Members