private static void WriteNeedleElementNode(XElement parent, NeedleElement element) { parent.Add(new XElement("Needle", new XElement("Location", $"{element.LocationX}, {element.LocationY}"), new XElement("Layer", element.Layer), WriteSubjectNode(element.Subject), new XElement("DaytimeImage", element.DaytimeImage), new XElement("NighttimeImage", element.NighttimeImage), new XElement("TransparentColor", element.TransparentColor), new XElement("DefinedRadius", element.DefinedRadius), new XElement("Radius", element.Radius), new XElement("Color", element.Color), new XElement("DefinedOrigin", element.DefinedOrigin), new XElement("Origin", $"{element.OriginX}, {element.OriginY}"), new XElement("InitialAngle", element.InitialAngle), new XElement("LastAngle", element.LastAngle), new XElement("Minimum", element.Minimum), new XElement("Maximum", element.Maximum), new XElement("DefinedNaturalFreq", element.DefinedNaturalFreq), new XElement("NaturalFreq", element.NaturalFreq), new XElement("DefinedDampingRatio", element.DefinedDampingRatio), new XElement("DampingRatio", element.DampingRatio), new XElement("Backstop", element.Backstop), new XElement("Smoothed", element.Smoothed) )); }
private static void ParseNeedleElementNode(XElement parent, out PanelElement element) { double[] location = ((string)parent.Element("Location")).Split(',').Select(double.Parse).ToArray(); double[] origin = ((string)parent.Element("Origin")).Split(',').Select(double.Parse).ToArray(); element = new NeedleElement { LocationX = location[0], LocationY = location[1], Layer = (int)parent.Element("Layer"), Subject = ParseSubjectNode(parent.Element("Subject")), DaytimeImage = (string)parent.Element("DaytimeImage"), NighttimeImage = (string)parent.Element("NighttimeImage"), TransparentColor = Color24.ParseHexColor((string)parent.Element("TransparentColor")), DefinedRadius = (bool)parent.Element("DefinedRadius"), Radius = (double)parent.Element("Radius"), Color = Color24.ParseHexColor((string)parent.Element("Color")), DefinedOrigin = (bool)parent.Element("DefinedOrigin"), OriginX = origin[0], OriginY = origin[1], InitialAngle = (double)parent.Element("InitialAngle"), LastAngle = (double)parent.Element("LastAngle"), Minimum = (double)parent.Element("Minimum"), Maximum = (double)parent.Element("Maximum"), DefinedNaturalFreq = (bool)parent.Element("DefinedNaturalFreq"), NaturalFreq = (double)parent.Element("NaturalFreq"), DefinedDampingRatio = (bool)parent.Element("DefinedDampingRatio"), DampingRatio = (double)parent.Element("DampingRatio"), Backstop = (bool)parent.Element("Backstop"), Smoothed = (bool)parent.Element("Smoothed") }; }
private static void WriteNeedleElementNode(string fileName, XElement parent, NeedleElement element) { XElement needleNode = new XElement("Needle", new XElement("Location", $"{element.LocationX}, {element.LocationY}"), new XElement("Layer", element.Layer), new XElement("Subject", element.Subject) ); if (!string.IsNullOrEmpty(element.DaytimeImage)) { needleNode.Add(new XElement("DaytimeImage", Utilities.MakeRelativePath(fileName, element.DaytimeImage))); } if (!string.IsNullOrEmpty(element.NighttimeImage)) { needleNode.Add(new XElement("NighttimeImage", Utilities.MakeRelativePath(fileName, element.NighttimeImage))); } needleNode.Add( new XElement("TransparentColor", element.TransparentColor), new XElement("Color", element.Color), new XElement("InitialAngle", element.InitialAngle.ToDegrees()), new XElement("LastAngle", element.LastAngle.ToDegrees()), new XElement("Minimum", element.Minimum), new XElement("Maximum", element.Maximum), new XElement("Backstop", element.Backstop), new XElement("Smoothed", element.Smoothed) ); if (element.DefinedRadius) { needleNode.Add(new XElement("Radius", element.Radius)); } if (element.DefinedOrigin) { needleNode.Add(new XElement("Origin", $"{element.OriginX}, {element.OriginY}")); } if (element.DefinedNaturalFreq) { needleNode.Add(new XElement("NaturalFreq", element.NaturalFreq)); } if (element.DefinedDampingRatio) { needleNode.Add(new XElement("DampingRatio", element.DampingRatio)); } parent.Add(needleNode); }
private static void WriteNeedleNode(string fileName, StringBuilder builder, NeedleElement element) { builder.AppendLine("[Needle]"); WriteKey(builder, "Subject", element.Subject.ToString()); WriteKey(builder, "Location", element.LocationX, element.LocationY); if (element.DefinedRadius) { WriteKey(builder, "Radius", element.Radius); } WriteKey(builder, "DaytimeImage", Utilities.MakeRelativePath(fileName, element.DaytimeImage)); WriteKey(builder, "NighttimeImage", Utilities.MakeRelativePath(fileName, element.NighttimeImage)); WriteKey(builder, "Color", element.Color.ToString()); WriteKey(builder, "TransparentColor", element.TransparentColor.ToString()); if (element.DefinedOrigin) { WriteKey(builder, "Origin", element.OriginX, element.OriginY); } WriteKey(builder, "InitialAngle", element.InitialAngle.ToDegrees()); WriteKey(builder, "LastAngle", element.LastAngle.ToDegrees()); WriteKey(builder, "Minimum", element.Minimum); WriteKey(builder, "Maximum", element.Maximum); if (element.DefinedNaturalFreq) { WriteKey(builder, "NaturalFreq", element.NaturalFreq); } if (element.DefinedDampingRatio) { WriteKey(builder, "DampingRatio", element.DampingRatio); } WriteKey(builder, "Backstop", element.Backstop.ToString()); WriteKey(builder, "Smoothed", element.Smoothed.ToString()); WriteKey(builder, "Layer", element.Layer); }
internal PanelViewModel(Panel panel) { CompositeDisposable treeItemDisposable = new CompositeDisposable(); CompositeDisposable listItemDisposable = new CompositeDisposable(); This = panel .ObserveProperty(x => x.This) .Do(_ => This?.Value.Dispose()) .Select(x => new ThisViewModel(x)) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); TreeItem = panel .ObserveProperty(x => x.TreeItem) .Do(_ => TreeItem?.Value.Dispose()) .Select(x => new TreeViewItemViewModel(x)) .ToReactiveProperty() .AddTo(disposable); TreeItem.Subscribe(x => { treeItemDisposable.Dispose(); treeItemDisposable = new CompositeDisposable(); x.PropertyChangedAsObservable() .ToReadOnlyReactivePropertySlim(mode: ReactivePropertyMode.None) .Subscribe(_ => TreeItem.ForceNotify()) .AddTo(treeItemDisposable); }) .AddTo(disposable); SelectedTreeItem = panel .ToReactivePropertyAsSynchronized( x => x.SelectedTreeItem, x => TreeItem.Value.SearchViewModel(x), x => x?.Model ) .AddTo(disposable); ListColumns = panel.ListColumns .ToReadOnlyReactiveCollection(x => new ListViewColumnHeaderViewModel(x)) .AddTo(disposable); ListItems = panel.ListItems .ToReadOnlyReactiveCollection(x => new ListViewItemViewModel(x)) .AddTo(disposable); SelectedListItem = panel .ToReactivePropertyAsSynchronized( x => x.SelectedListItem, x => ListItems.FirstOrDefault(y => y.Model == x), x => x?.Model ) .AddTo(disposable); SelectedTreeItem .Subscribe(_ => { SelectedListItem.Value = null; panel.CreateListColumns(); panel.CreateListItems(); }) .AddTo(disposable); SelectedListItem .Where(x => x != null) .Subscribe(x => { listItemDisposable.Dispose(); listItemDisposable = new CompositeDisposable(); CompositeDisposable tagDisposable = new CompositeDisposable(); x.Tag .OfType <INotifyPropertyChanged>() .Subscribe(y => { tagDisposable.Dispose(); tagDisposable = new CompositeDisposable(); CompositeDisposable subjectDisposable = new CompositeDisposable(); y.PropertyChangedAsObservable() .Subscribe(_ => panel.UpdateListItem(x.Model)) .AddTo(tagDisposable); Screen screen = y as Screen; PilotLampElement pilotLamp = y as PilotLampElement; NeedleElement needle = y as NeedleElement; DigitalNumberElement digitalNumber = y as DigitalNumberElement; DigitalGaugeElement digitalGauge = y as DigitalGaugeElement; LinearGaugeElement linearGauge = y as LinearGaugeElement; screen?.ObserveProperty(z => z.Number) .Select(_ => TreeItem.Value.Children[1].Children.FirstOrDefault(z => z.Tag.Value == screen)) .Where(z => z != null) .Subscribe(z => panel.RenameScreenTreeItem(z.Model)) .AddTo(tagDisposable); pilotLamp?.ObserveProperty(z => z.Subject) .Subscribe(z => { subjectDisposable.Dispose(); subjectDisposable = new CompositeDisposable(); z.PropertyChangedAsObservable() .Subscribe(_ => panel.UpdateListItem(x.Model)) .AddTo(subjectDisposable); }) .AddTo(tagDisposable); needle?.ObserveProperty(z => z.Subject) .Subscribe(z => { subjectDisposable.Dispose(); subjectDisposable = new CompositeDisposable(); z.PropertyChangedAsObservable() .Subscribe(_ => panel.UpdateListItem(x.Model)) .AddTo(subjectDisposable); }) .AddTo(tagDisposable); digitalNumber?.ObserveProperty(z => z.Subject) .Subscribe(z => { subjectDisposable.Dispose(); subjectDisposable = new CompositeDisposable(); z.PropertyChangedAsObservable() .Subscribe(_ => panel.UpdateListItem(x.Model)) .AddTo(subjectDisposable); }) .AddTo(tagDisposable); digitalGauge?.ObserveProperty(z => z.Subject) .Subscribe(z => { subjectDisposable.Dispose(); subjectDisposable = new CompositeDisposable(); z.PropertyChangedAsObservable() .Subscribe(_ => panel.UpdateListItem(x.Model)) .AddTo(subjectDisposable); }) .AddTo(tagDisposable); linearGauge?.ObserveProperty(z => z.Subject) .Subscribe(z => { subjectDisposable.Dispose(); subjectDisposable = new CompositeDisposable(); z.PropertyChangedAsObservable() .Subscribe(_ => panel.UpdateListItem(x.Model)) .AddTo(subjectDisposable); }) .AddTo(tagDisposable); subjectDisposable.AddTo(tagDisposable); }) .AddTo(listItemDisposable); tagDisposable.AddTo(listItemDisposable); }) .AddTo(disposable); SelectedScreen = SelectedListItem .Select(x => x?.Tag.Value as Screen) .Do(_ => SelectedScreen?.Value?.Dispose()) .Select(x => x != null ? new ScreenViewModel(x, panel.Screens.Where(y => y != x)) : null) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); SelectedPilotLamp = SelectedListItem .Select(x => x?.Tag.Value as PilotLampElement) .Do(_ => SelectedPilotLamp?.Value?.Dispose()) .Select(x => x != null ? new PilotLampElementViewModel(x) : null) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); SelectedNeedle = SelectedListItem .Select(x => x?.Tag.Value as NeedleElement) .Do(_ => SelectedNeedle?.Value?.Dispose()) .Select(x => x != null ? new NeedleElementViewModel(x) : null) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); SelectedDigitalNumber = SelectedListItem .Select(x => x?.Tag.Value as DigitalNumberElement) .Do(_ => SelectedDigitalNumber?.Value?.Dispose()) .Select(x => x != null ? new DigitalNumberElementViewModel(x) : null) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); SelectedDigitalGauge = SelectedListItem .Select(x => x?.Tag.Value as DigitalGaugeElement) .Do(_ => SelectedDigitalGauge?.Value?.Dispose()) .Select(x => x != null ? new DigitalGaugeElementViewModel(x) : null) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); SelectedLinearGauge = SelectedListItem .Select(x => x?.Tag.Value as LinearGaugeElement) .Do(_ => SelectedLinearGauge?.Value?.Dispose()) .Select(x => x != null ? new LinearGaugeElementViewModel(x) : null) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); SelectedTimetable = SelectedListItem .Select(x => x?.Tag.Value as TimetableElement) .Do(_ => SelectedTimetable?.Value?.Dispose()) .Select(x => x != null ? new TimetableElementViewModel(x) : null) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); SelectedTouch = SelectedListItem .Select(x => x?.Tag.Value as TouchElement) .Do(_ => SelectedTouch?.Value?.Dispose()) .Select(x => x != null ? new TouchElementViewModel(x) : null) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); AddScreen = SelectedTreeItem .Select(x => x == TreeItem.Value.Children[1]) .ToReactiveCommand() .WithSubscribe(panel.AddScreen) .AddTo(disposable); AddPilotLamp = SelectedTreeItem .Select(x => TreeItem.Value.Children[1].Children.Any(y => x == y.Children[0].Children[0]) || x == TreeItem.Value.Children[2].Children[0]) .ToReactiveCommand() .WithSubscribe(panel.AddPilotLamp) .AddTo(disposable); AddNeedle = SelectedTreeItem .Select(x => TreeItem.Value.Children[1].Children.Any(y => x == y.Children[0].Children[1]) || x == TreeItem.Value.Children[2].Children[1]) .ToReactiveCommand() .WithSubscribe(panel.AddNeedle) .AddTo(disposable); AddDigitalNumber = SelectedTreeItem .Select(x => TreeItem.Value.Children[1].Children.Any(y => x == y.Children[0].Children[2]) || x == TreeItem.Value.Children[2].Children[2]) .ToReactiveCommand() .WithSubscribe(panel.AddDigitalNumber) .AddTo(disposable); AddDigitalGauge = SelectedTreeItem .Select(x => TreeItem.Value.Children[1].Children.Any(y => x == y.Children[0].Children[3]) || x == TreeItem.Value.Children[2].Children[3]) .ToReactiveCommand() .WithSubscribe(panel.AddDigitalGauge) .AddTo(disposable); AddLinearGauge = SelectedTreeItem .Select(x => TreeItem.Value.Children[1].Children.Any(y => x == y.Children[0].Children[4]) || x == TreeItem.Value.Children[2].Children[4]) .ToReactiveCommand() .WithSubscribe(panel.AddLinearGauge) .AddTo(disposable); AddTimetable = SelectedTreeItem .Select(x => TreeItem.Value.Children[1].Children.Any(y => x == y.Children[0].Children[5]) || x == TreeItem.Value.Children[2].Children[5]) .ToReactiveCommand() .WithSubscribe(panel.AddTimetable) .AddTo(disposable); AddTouch = SelectedTreeItem .Select(x => TreeItem.Value.Children[1].Children.Any(y => x == y.Children[1])) .ToReactiveCommand() .WithSubscribe(panel.AddTouch) .AddTo(disposable); CopyScreen = SelectedScreen .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.CopyScreen) .AddTo(disposable); CopyPilotLamp = SelectedPilotLamp .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.CopyPilotLamp) .AddTo(disposable); CopyNeedle = SelectedNeedle .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.CopyNeedle) .AddTo(disposable); CopyDigitalNumber = SelectedDigitalNumber .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.CopyDigitalNumber) .AddTo(disposable); CopyDigitalGauge = SelectedDigitalGauge .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.CopyDigitalGauge) .AddTo(disposable); CopyLinearGauge = SelectedLinearGauge .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.CopyLinearGauge) .AddTo(disposable); CopyTimetable = SelectedTimetable .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.CopyTimetable) .AddTo(disposable); CopyTouch = SelectedTouch .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.CopyTouch) .AddTo(disposable); RemoveScreen = SelectedScreen .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.RemoveScreen) .AddTo(disposable); RemovePilotLamp = SelectedPilotLamp .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.RemovePilotLamp) .AddTo(disposable); RemoveNeedle = SelectedNeedle .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.RemoveNeedle) .AddTo(disposable); RemoveDigitalNumber = SelectedDigitalNumber .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.RemoveDigitalNumber) .AddTo(disposable); RemoveDigitalGauge = SelectedDigitalGauge .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.RemoveDigitalGauge) .AddTo(disposable); RemoveLinearGauge = SelectedLinearGauge .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.RemoveLinearGauge) .AddTo(disposable); RemoveTimetable = SelectedTimetable .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.RemoveTimetable) .AddTo(disposable); RemoveTouch = SelectedTouch .Select(x => x != null) .ToReactiveCommand() .WithSubscribe(panel.RemoveTouch) .AddTo(disposable); treeItemDisposable.AddTo(disposable); listItemDisposable.AddTo(disposable); }
internal NeedleElementViewModel(NeedleElement needle) : base(needle) { CultureInfo culture = CultureInfo.InvariantCulture; Subject = needle .ObserveProperty(x => x.Subject) .Do(_ => Subject?.Value.Dispose()) .Select(x => new SubjectViewModel(x)) .ToReadOnlyReactivePropertySlim() .AddTo(disposable); DaytimeImage = needle .ToReactivePropertyAsSynchronized(x => x.DaytimeImage) .AddTo(disposable); NighttimeImage = needle .ToReactivePropertyAsSynchronized(x => x.NighttimeImage) .AddTo(disposable); TransparentColor = needle .ToReactivePropertyAsSynchronized( x => x.TransparentColor, x => x.ToString(), Color24.ParseHexColor, ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { Color24 result; string message; Utilities.TryParse(x, out result, out message); return(message); }) .AddTo(disposable); DefinedRadius = needle .ToReactivePropertyAsSynchronized(x => x.DefinedRadius) .AddTo(disposable); Radius = needle .ToReactivePropertyAsSynchronized( x => x.Radius, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.NonZero, out result, out message); return(message); }) .AddTo(disposable); Color = needle .ToReactivePropertyAsSynchronized( x => x.Color, x => x.ToString(), Color24.ParseHexColor, ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { Color24 result; string message; Utilities.TryParse(x, out result, out message); return(message); }) .AddTo(disposable); DefinedOrigin = needle .ToReactivePropertyAsSynchronized(x => x.DefinedOrigin) .AddTo(disposable); OriginX = needle .ToReactivePropertyAsSynchronized( x => x.OriginX, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.Any, out result, out message); return(message); }) .AddTo(disposable); OriginY = needle .ToReactivePropertyAsSynchronized( x => x.OriginY, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.Any, out result, out message); return(message); }) .AddTo(disposable); InitialAngle = needle .ToReactivePropertyAsSynchronized( x => x.InitialAngle, x => x.ToDegrees().ToString(culture), x => double.Parse(x).ToRadians(), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.Any, out result, out message); return(message); }) .AddTo(disposable); LastAngle = needle .ToReactivePropertyAsSynchronized( x => x.LastAngle, x => x.ToDegrees().ToString(culture), x => double.Parse(x).ToRadians(), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.Any, out result, out message); return(message); }) .AddTo(disposable); Minimum = needle .ToReactivePropertyAsSynchronized( x => x.Minimum, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.Any, out result, out message); return(message); }) .AddTo(disposable); Maximum = needle .ToReactivePropertyAsSynchronized( x => x.Maximum, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.Any, out result, out message); return(message); }) .AddTo(disposable); DefinedNaturalFreq = needle .ToReactivePropertyAsSynchronized(x => x.DefinedNaturalFreq) .AddTo(disposable); NaturalFreq = needle .ToReactivePropertyAsSynchronized( x => x.NaturalFreq, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.NonNegative, out result, out message); return(message); }) .AddTo(disposable); DefinedDampingRatio = needle .ToReactivePropertyAsSynchronized(x => x.DefinedDampingRatio) .AddTo(disposable); DampingRatio = needle .ToReactivePropertyAsSynchronized( x => x.DampingRatio, x => x.ToString(culture), x => double.Parse(x, NumberStyles.Float, culture), ignoreValidationErrorValue: true ) .SetValidateNotifyError(x => { double result; string message; Utilities.TryParse(x, NumberRange.NonNegative, out result, out message); return(message); }) .AddTo(disposable); Backstop = needle .ToReactivePropertyAsSynchronized(x => x.Backstop) .AddTo(disposable); Smoothed = needle .ToReactivePropertyAsSynchronized(x => x.Smoothed) .AddTo(disposable); }