using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Windows; using System.Windows.Media; using System.Windows.Shapes; using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.WPF; using Syncfusion.UI.Xaml.Diagram; using Color = System.Drawing.Color; using Image = System.Windows.Controls.Image; using Path = System.Windows.Shapes.Path; namespace PRSDesktop { public class QuoteDiagramSymbolModel : NodeViewModel { } public class QuoteDiagramAreaModel : NodeViewModel { } public class QuoteDiagramConnectorModel : ConnectorViewModel { } public class QuoteDiagramScalerModel : NodeViewModel { } public static class QuoteDiagramSymbolCache { private static MultiQuery _data; private static CoreTable _documents; private static ObservableCollection _symbols; private static ResourceDictionary _resources; public static ResourceDictionary Resources => GetResources(); public static IEnumerable Symbols { get { CheckCache(); return _symbols.OfType(); } } public static IEnumerable Areas { get { CheckCache(); return _symbols.OfType(); } } public static IEnumerable Connectors { get { CheckCache(); return _symbols.OfType(); } } public static IEnumerable Scalers { get { CheckCache(); return _symbols.OfType(); } } private static ResourceDictionary GetResources() { if (_resources == null) { _resources = new ResourceDictionary(); _resources.Source = new Uri("/Syncfusion.SfDiagram.Wpf;component/Resources/BasicShapes.xaml", UriKind.RelativeOrAbsolute); } return _resources; } private static TModel CreateModel(CoreRow row) where TModel : GroupableViewModel, new() where TEntity : QuoteDiagramEntity { var result = new TModel(); result.ID = row.Get(x => x.ID).ToString(); result.Key = row.Get(x => x.Group); result.Name = row.Get(x => x.Caption); return result; } private static QuoteDiagramSymbolModel CreateSymbol(CoreRow row) { var result = CreateModel(row); result.UnitHeight = row.Get(x => x.Length) / 100F; result.UnitWidth = row.Get(x => x.Width) / 100F; result.ContentTemplate = TemplateGenerator.CreateDataTemplate(() => { var symbolid = row.EntityLinkID(x => x.Symbol) ?? Guid.Empty; if (symbolid != Guid.Empty) { var Image = new Image(); var docrow = _documents.Rows.FirstOrDefault(r => r.Get(c => c.ID).Equals(symbolid)); if (docrow != null) { var data = docrow.Get(x => x.Data); if (data != null && data.Length != 0) using (var ms = new MemoryStream(data)) { var emf = new Metafile(ms); //Image.Source = emf.AsBitmapSource((int)(node.UnitWidth * 100.0F), (int)(node.UnitHeight * 100.0F), System.Drawing.Color.Red); Image.Source = emf.AsBitmapSource((int)(result.UnitWidth * 10.0F), (int)(result.UnitHeight * 10.0F), Color.Transparent); } } return Image; } return null; //else //{ // var svg = new System.Windows.Shapes.Path(); // String geometry = row.Get(x => x.Geometry); // if (String.IsNullOrWhiteSpace(geometry)) // svg.Data = new RectangleGeometry(new Rect(0, 0, row.Get(x => x.Width), row.Get(x => x.Length))); // else // svg.Data = Geometry.Parse(geometry); // svg.Stretch = Stretch.Fill; // svg.Fill = new SolidColorBrush(ImageUtils.StringToMediaColor(row.Get(x => x.FillColor))); // svg.Stroke = new SolidColorBrush(ImageUtils.StringToMediaColor(row.Get(x => x.LineColor))); // svg.StrokeThickness = 1.0F; // return svg; //} }); if (row.Get(x => x.ShowCaption)) result.Annotations = new AnnotationCollection { new AnnotationEditorViewModel { Content = row.Get(x => x.Caption) } }; var json = row.Get(x => x.Ports); var ports = string.IsNullOrWhiteSpace(json) ? new QuoteDiagramSymbolPort[] { } : Serialization.Deserialize(json); if (ports.Any()) { (result.Ports as PortCollection).Clear(); foreach (var port in ports) { var model = new NodePortViewModel { NodeOffsetX = port.X / 100.0F, NodeOffsetY = port.Y / 100.0F }; (result.Ports as PortCollection).Add(model); } } return result; } private static QuoteDiagramAreaModel CreateArea(CoreRow row) { var result = CreateModel(row); result.UnitHeight = row.Get(x => x.Length) / 100F; result.UnitWidth = row.Get(x => x.Width) / 100F; result.ContentTemplate = TemplateGenerator.CreateDataTemplate(() => { var svg = new Path(); svg.Data = new RectangleGeometry(new Rect(0, 0, result.UnitWidth, result.UnitHeight)); svg.Stretch = Stretch.Fill; svg.Fill = new SolidColorBrush(ImageUtils.StringToMediaColor(row.Get(x => x.FillColor))) { Opacity = 0.5f }; svg.Stroke = new SolidColorBrush(ImageUtils.StringToMediaColor(row.Get(x => x.LineColor))); svg.StrokeThickness = 1.0F; return svg; }); result.Constraints = NodeConstraints.Default & ~NodeConstraints.Connectable; result.Annotations = new AnnotationCollection { new AnnotationEditorViewModel { Content = row.Get(x => x.Caption) } }; return result; } private static QuoteDiagramConnectorModel CreateConnector(CoreRow row) { var result = CreateModel(row); var width = (double)row.Get(x => x.Width) / 100F; var length = (double)row.Get(x => x.Length) / 100F; if (length == 0.0F) length = 100F; length = length * length; var side = length / 2.0F; side = Math.Sqrt(side); result.SourcePoint = new Point(width, width); result.TargetPoint = new Point(side + width, side + width); var connectorstyle = new Style(typeof(Path)); connectorstyle.Setters.Add(new Setter(Shape.StrokeProperty, new SolidColorBrush(ImageUtils.StringToMediaColor(row.Get(x => x.Color))))); connectorstyle.Setters.Add(new Setter(Shape.StrokeThicknessProperty, width)); result.ConnectorGeometryStyle = connectorstyle; IConnectorSegment segment = null; if (row.Get(x => x.Type) == QuoteDiagramConnectorType.StraightLine) segment = new StraightSegment(); else if (row.Get(x => x.Type) == QuoteDiagramConnectorType.OrthogonalLine) segment = new OrthogonalSegment(); else if (row.Get(x => x.Type) == QuoteDiagramConnectorType.CubicBezier) segment = new CubicCurveSegment(); else if (row.Get(x => x.Type) == QuoteDiagramConnectorType.QuadraticBezier) segment = new QuadraticCurveSegment(); if (segment is StraightSegment || segment is OrthogonalSegment) result.CornerRadius = width; result.Segments = new ObservableCollection { segment }; return result; } public static QuoteDiagramScalerModel CreateScaler() { var result = new QuoteDiagramScalerModel(); result.ID = CoreUtils.FullGuid.ToString(); result.Key = ""; result.Name = ""; result.UnitHeight = 10F; result.UnitWidth = 100F; result.ContentTemplate = TemplateGenerator.CreateDataTemplate(() => { var svg = new Path(); svg.Data = svg.Data = Geometry.Parse( "M 000 000 L 000 100 M 050 025 L 000 050 L 050 075 M 000 050 L 400 050 L 400 075 L 600 075 L 600 025 L 400 025 L 400 050 M 600 050 L 1000 050 M 1000 000 L 1000 100 M 950 25 L 1000 050 L 950 075"); svg.Stretch = Stretch.Fill; svg.Stroke = new SolidColorBrush(Colors.Firebrick); svg.StrokeThickness = 1.0F; return svg; }); result.Constraints = NodeConstraints.AllowDrop | NodeConstraints.ResizeWest | NodeConstraints.ResizeEast | NodeConstraints.Draggable | NodeConstraints.Selectable | NodeConstraints.Rotatable | NodeConstraints.Delete; result.Annotations = new AnnotationCollection { new AnnotationEditorViewModel { Content = "1000" } }; return result; } private static void CheckCache() { if (_symbols == null) { var bLoading = true; _symbols = new ObservableCollection(); _data = new MultiQuery(); _data.Add(new Filter(x => x.Active).IsEqualTo(true)); _data.Add(new Filter(x => x.Active).IsEqualTo(true)); _data.Add(new Filter(x => x.Active).IsEqualTo(true)); _data.Query(); var symbols = _data.Get(); var docids = symbols.ExtractValues(x => x.Symbol.ID).Where(x => x != Guid.Empty).ToArray(); _documents = new Client().Query(new Filter(x => x.ID).InList(docids)); foreach (var row in symbols.Rows) _symbols.Add(CreateSymbol(row)); var areas = _data.Get(); foreach (var row in areas.Rows) _symbols.Add(CreateArea(row)); var connectors = _data.Get(); foreach (var row in connectors.Rows) _symbols.Add(CreateConnector(row)); _symbols.Add(CreateScaler()); bLoading = false; } } public static void Refresh() { _data = null; _documents = null; _symbols = null; _resources = null; } } }