using PamhagenSysCtrl.Helpers; using PamhagenSysCtrl.Helpers.Pipeline; using System.Windows; using System.Windows.Input; using System.Windows.Media; namespace PamhagenSysCtrl.Windows { public partial class PlantSchemeWindow : Window { private readonly PamhagenGraph Graph; private readonly List Paths = []; private ISource? _lastSource; private ISet? _lastSelected; public PlantSchemeWindow() { InitializeComponent(); App.Plant?.Update += OnUpdate; Graph = new(); Graph.Draw(SchemeCanvas); } private void SchemeCanvas_MouseMove(object sender, MouseEventArgs evt) { var p = evt.GetPosition(SchemeCanvas); UpdateScheme(evt.GetPosition(SchemeCanvas), evt.LeftButton == MouseButtonState.Pressed); } private void SchemeCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs evt) { var p = evt.GetPosition(SchemeCanvas); _lastSelected = UpdateScheme(evt.GetPosition(SchemeCanvas), evt.LeftButton == MouseButtonState.Pressed); } private void SchemeCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs evt) { var p = evt.GetPosition(SchemeCanvas); var curSelected = UpdateScheme(evt.GetPosition(SchemeCanvas), evt.LeftButton == MouseButtonState.Pressed); var clicked = curSelected.Intersect(_lastSelected ?? new HashSet()).ToList(); _lastSource?.IsSelected = false; if (clicked.Count == 0) { _lastSource = null; } foreach (var c in clicked) { if (_lastSource != null && c is ISink sink) { var path = Graph.GetPath(_lastSource, sink, (n) => n is not ISink && (n is not Valve v || !v.IsLocked)); if (path != null) { Paths.Add(path.Value); _lastSource = null; } } else if (c is ISource source) { _lastSource = source; _lastSource.IsSelected = true; } else { _lastSource = null; } } UpdateScheme(evt.GetPosition(SchemeCanvas), evt.LeftButton == MouseButtonState.Pressed); } private ISet UpdateScheme(Point pos, bool down) { foreach (var e in Graph.Edges) { e.Highlight = null; } foreach (var p in Paths) { var c = Brushes.Green; foreach (var (edge, node) in p.Hops) { edge.Highlight = Brushes.Green; if (node is Pump) c = Brushes.Orange; ColorSubgraph(node, c, (v) => v.IsLocked = true); } } var hover = Graph.Update(pos.X, pos.Y, down); if (_lastSource != null && hover.Count > 0) { var path = Graph.GetPath(_lastSource, hover.First(), (n) => n is not ISink && (n is not Valve v || !v.IsLocked)); if (path != null) { var c = Brushes.Green; foreach (var (edge, node) in path.Value.Hops) { edge.Highlight = Brushes.Green; if (node is Pump) c = Brushes.Orange; ColorSubgraph(node, c); } } Graph.Update(pos.X, pos.Y, down); } return hover; } private void ColorSubgraph(INode start, Brush color, Action? valveAction = null) { if (start is Valve v) { valveAction?.Invoke(v); return; } else if (start is ISink || start is Pump) { return; } foreach (var edge in start.Inputs) { if (edge.Highlight != null) continue; edge.Highlight = color; ColorSubgraph(edge.Start, color, valveAction); } foreach (var edge in start.Outputs) { if (edge.Highlight != null) continue; edge.Highlight = color; ColorSubgraph(edge.End, color, valveAction); } } public void OnUpdate(object? sender, PlantEventArgs evt) { if (sender is not PamhagenPlant plant) return; } } }