public static StreamControl CreateOnCanvas(DrawingCanvas canvas, AbstractStream stream) { StreamControl streamControl = new StreamControl(canvas, stream); canvas.AddNewChild(streamControl); return(streamControl); }
public ChangeStreamNumberWindow(AbstractStream stream, Workspace workspace) { InitializeComponent(); m_stream = stream; m_workspace = workspace; if (null != workspace) { // Make a list of integer options for stream numbers List <int> numOpts = new List <int>(); int max = 50; while (0 == numOpts.Count) { max *= 2; for (int i = 1; i <= 100; i++) { if (null == workspace.GetStream(i) || i == stream.Id) { numOpts.Add(i); } } } // Set them as the options in the combo box NumberComboBox.ItemsSource = numOpts; NumberComboBox.SelectedItem = stream.Id; } }
public AttachOutgoingStream(AbstractProcessUnit processUnit, AbstractStream outgoingStream) { if (null == processUnit || null == outgoingStream) { throw new ArgumentNullException(); } m_pu = processUnit; m_stream = outgoingStream; }
public SetStreamSourceLocation(AbstractStream stream, MathCore.Vector location) { m_stream = stream as AbstractStream; m_location = location; // Create the opposite action to set it back to where it is now m_opposite = new SetStreamSourceLocation(); m_opposite.m_location = stream.SourceLocation; m_opposite.m_opposite = this; m_opposite.m_stream = m_stream; }
private static void DeleteStreamWithUndo(ChemProV.PFD.Streams.StreamControl stream, DrawingCanvas canvas) { AbstractStream s = stream.Stream; // Special case: the old version (before I rewrote a bunch of logic) didn't let // you delete heat streams whose destination was a heat exchanger with utility. // I will keep this functionality. if (s is HeatStream && s.Destination is HeatExchangerWithUtility) { return; } // We need to build a list of undos List <IUndoRedoAction> actions = new List <IUndoRedoAction>(); if (null != s.Source) { // If the stream has a non-null source then we need to detach it and // make sure the undo would reattach it actions.Add(new Logic.Undos.AttachOutgoingStream(s.Source, s)); actions.Add(new Logic.Undos.SetStreamSource(s, s.Source, null, s.SourceLocation)); // Do the detachment so that the process unit (which is staying around) won't // have an outgoing stream that's been deleted s.Source.DetachOutgoingStream(s); s.Source = null; } if (null != s.Destination) { // If the stream has a non-null destination then we need to detach it and // make sure the undo would reattach it actions.Add(new Logic.Undos.AttachIncomingStream(s.Destination, s)); actions.Add(new Logic.Undos.SetStreamDestination(s, s.Destination, null, s.DestinationLocation)); // Do the detachment so that the process unit (which is staying around) won't // have an incoming stream that's been deleted s.Destination.DetachIncomingStream(s); s.Destination = null; } // In all cases we will need to add the stream back to the workspace actions.Add(new Logic.Undos.AddToWorkspace(stream.Stream)); // Delete the stream from the workspace. Event handlers will take care of updating the UI. canvas.GetWorkspace().RemoveStream(stream.Stream); // Add the undo that we built canvas.GetWorkspace().AddUndo( new UndoRedoCollection("Undo deletion of stream", actions.ToArray())); }
public SetStreamDestination(AbstractStream stream, AbstractProcessUnit destForThis, AbstractProcessUnit destForOpposite, MathCore.Vector location) { m_stream = stream as AbstractStream; m_pu = destForThis; m_location = location; // Create the opposite action m_opposite = new SetStreamDestination(); m_opposite.m_location = location; m_opposite.m_opposite = this; m_opposite.m_pu = destForOpposite; m_opposite.m_stream = m_stream; }
public SetStreamSource(AbstractStream stream, AbstractProcessUnit sourceForThis, AbstractProcessUnit sourceForOpposite, MathCore.Vector locationForDSE) { m_stream = stream as AbstractStream; m_pu = sourceForThis; m_location = locationForDSE; // Create the opposite action m_opposite = new SetStreamSource(); m_opposite.m_location = locationForDSE; m_opposite.m_opposite = this; m_opposite.m_pu = sourceForOpposite; m_opposite.m_stream = m_stream; }
public PFD.Streams.StreamControl GetStreamControl(AbstractStream stream) { foreach (UIElement uie in Children) { PFD.Streams.StreamControl s = uie as PFD.Streams.StreamControl; if (null != s) { if (Object.ReferenceEquals(s.Stream, stream)) { return(s); } } } return(null); }
public MovingStreamEndpoint(DraggableStreamEndpoint endpoint, DrawingCanvas canvas, bool creatingStream) { m_dragIcon = endpoint; m_canvas = canvas; m_creatingStream = creatingStream; m_stream = endpoint.ParentStream.Stream; if (m_dragIcon.IsSource) { m_startLocation = m_stream.SourceLocation; m_connectedToOnStart = m_stream.Source; } else { m_startLocation = m_stream.DestinationLocation; m_connectedToOnStart = m_stream.Destination; } }
private void WorkspaceStreamsCollectionChanged(object sender, EventArgs e) { // Remove previous event listeners foreach (TreeViewItem child in StreamsDebugNode.Items) { AbstractStream stream = child.Tag as AbstractStream; stream.PropertyChanged -= DebugStream_PropertyChanged; } // Clear and rebuild StreamsDebugNode.Items.Clear(); foreach (AbstractStream stream in m_workspace.Streams) { StreamsDebugNode.Items.Add(new TreeViewItem() { Header = stream.UIDString + "\n(src @ " + stream.SourceLocation.ToString() + ")\n(dst @ " + stream.DestinationLocation.ToString() + ")", Tag = stream }); stream.PropertyChanged += new PropertyChangedEventHandler(DebugStream_PropertyChanged); } }
private void DebugStream_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName.Equals("SourceLocation") || e.PropertyName.Equals("DestinationLocation")) { AbstractStream stream = sender as AbstractStream; // Find the tree view item for this stream TreeViewItem tvi = null; foreach (TreeViewItem tviTemp in StreamsDebugNode.Items) { if (object.ReferenceEquals(tviTemp.Tag, stream)) { tvi = tviTemp; break; } } if (null != tvi) { tvi.Header = stream.UIDString + "\n(src @ " + stream.SourceLocation.ToString() + ")\n(dst @ " + stream.DestinationLocation.ToString() + ")"; } } }
public void MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // We don't process messages if the placement icon is null if (null == m_placementIcon) { return; } // Handle heat exchanger with utility as a special case if (m_type.Equals(typeof(HeatExchangerWithUtility))) { MLBD_HEWU(sender, e); return; } // Start by getting the mouse position Point pos = e.GetPosition(m_canvas); MathCore.Vector vPos = new MathCore.Vector(pos.X, pos.Y); // See if we have a DraggableStreamEndpoint where we clicked DraggableStreamEndpoint endpoint = m_canvas.GetChildAt(pos, m_placementIcon) as DraggableStreamEndpoint; // Remove the placement icon and then set it to null to indicate state completion m_canvas.RemoveChild(m_placementIcon); m_placementIcon = null; // Determine a unique identifier for the process unit int uid; do { uid = AbstractProcessUnit.GetNextUID(); }while (null != m_workspace.GetProcessUnit(uid)); // If there's not an endpoint, we create the process unit with no stream connections if (null == endpoint) { AbstractProcessUnit unit = (AbstractProcessUnit)Activator.CreateInstance( m_type, uid); // Set the location unit.Location = new MathCore.Vector(pos.X, pos.Y); // Add it to the workspace m_workspace.AddProcessUnit(unit); // Add an undo that will remove it m_workspace.AddUndo(new UndoRedoCollection("Undo process unit creation", new ChemProV.Logic.Undos.RemoveProcessUnit(unit))); m_canvas.SelectedElement = null; // Tell the control palette to switch back to select mode and then return m_palette.SwitchToSelect(); return; } // Otherwise, if we HAVE clicked on an endpoint... // Check to see if we can't connect this way AbstractProcessUnit temp = (AbstractProcessUnit) Activator.CreateInstance(m_type, -1); if (!endpoint.CanConnectTo(temp)) { // The usability here may be debatable. But for now we'll cancel placement and // give the user an error message m_palette.SwitchToSelect(); Core.App.MessageBox("The stream endpoint that you clicked cannot connect with " + "the process unit that you were placing."); return; } // Otherwise, if we CAN connect this way... // Create the process unit AbstractProcessUnit apu = (AbstractProcessUnit) Activator.CreateInstance(m_type, uid); // Make the undo and then the actual attachment if (DraggableStreamEndpoint.EndpointType.StreamDestination == endpoint.Type) { // Set the location apu.Location = endpoint.ParentStream.Stream.DestinationLocation; // Create an undo that sets the stream destination back to what it was and removes the // process unit m_workspace.AddUndo(new UndoRedoCollection("Undo process unit creation + attachment", new Logic.Undos.SetStreamDestination(endpoint.ParentStream.Stream, null, apu, vPos), new Logic.Undos.RemoveProcessUnit(apu))); apu.AttachIncomingStream(endpoint.ParentStream.Stream); endpoint.ParentStream.Stream.Destination = apu; } else { // Set the location apu.Location = endpoint.ParentStream.Stream.SourceLocation; // Create an undo that sets the stream source back to what it was and removes the // process unit from the canvas AbstractStream stream = endpoint.ParentStream.Stream; m_workspace.AddUndo(new UndoRedoCollection("Undo process unit creation + attachment", new Logic.Undos.SetStreamSource(stream, null, apu, stream.SourceLocation), new Logic.Undos.RemoveProcessUnit(apu))); apu.AttachOutgoingStream(endpoint.ParentStream.Stream); endpoint.ParentStream.Stream.Source = apu; } // Don't forget to add the process unit to the workspace. Event handlers will update the // UI appropriately. m_workspace.AddProcessUnit(apu); m_canvas.SelectedElement = null; // Go back to select mode m_palette.SwitchToSelect(); }
public RemoveStream(AbstractStream streamToRemove) { m_streamToRemove = streamToRemove; }
private StreamControl(DrawingCanvas canvas, AbstractStream stream) { m_canvas = canvas; m_stream = stream; InitializeComponent(); if (null != canvas && null != stream) { // Create the brush for the stream line if (stream is HeatStream) { m_streamLineNotSelected = new SolidColorBrush(Colors.Red); } else { m_streamLineNotSelected = new SolidColorBrush(Colors.Black); } // Create the drag handle for the source m_sourceDragIcon = new DraggableStreamEndpoint( DraggableStreamEndpoint.EndpointType.StreamSource, this, canvas); m_sourceDragIcon.Width = m_sourceDragIcon.Height = 20.0; m_sourceDragIcon.Location = new Point(m_stream.SourceLocation.X, m_stream.SourceLocation.Y); // Add it to the canvas m_canvas.AddNewChild(m_sourceDragIcon); // Set the Z-index m_sourceDragIcon.SetValue(Canvas.ZIndexProperty, 2); // Setup mouse events m_sourceDragIcon.MouseLeftButtonDown += new MouseButtonEventHandler(DragIcon_MouseLeftButtonDown); // Create the drag handle for the destination m_dstDragIcon = new DraggableStreamEndpoint( DraggableStreamEndpoint.EndpointType.StreamDestination, this, canvas); // Add it to the canvas m_canvas.AddNewChild(m_dstDragIcon); // Set the Z-index m_dstDragIcon.SetValue(Canvas.ZIndexProperty, 2); // Show it if there's no destination, hide it otherwise m_dstDragIcon.Visibility = (null == m_stream.Destination) ? Visibility.Visible : System.Windows.Visibility.Collapsed; // Setup mouse events m_dstDragIcon.MouseLeftButtonDown += new MouseButtonEventHandler(DragIcon_MouseLeftButtonDown); // Create the arrow polygon control m_arrow = new Polygon(); // Set the fill m_arrow.Fill = m_streamLineNotSelected; // Add it to the canvas m_canvas.AddNewChild(m_arrow); // Set the Z-index m_arrow.SetValue(Canvas.ZIndexProperty, 2); // Add 3 points/vertices m_arrow.Points.Add(new Point()); m_arrow.Points.Add(new Point()); m_arrow.Points.Add(new Point()); // Hide it if there's no destination if (null == m_stream.Destination) { m_arrow.Visibility = Visibility.Collapsed; } // Setup mouse events if (!(m_stream.Destination is HeatExchangerWithUtility)) { m_arrow.MouseLeftButtonDown += new MouseButtonEventHandler(DestinationArrow_MouseLeftButtonDown); } UpdateStreamLocation(); // Create the table CreatePropertiesTable(m_stream.PropertiesTable); // Watch for when the table location changes m_stream.PropertiesTable.PropertyChanged += new PropertyChangedEventHandler(PropertiesTable_PropertyChanged); // Add it to the canvas and set it up m_canvas.AddNewChild(m_table as UIElement); UserControl tableAsUiElement = m_table as UserControl; //This sets the tables index to the greatest so it will be above everything tableAsUiElement.SetValue(System.Windows.Controls.Canvas.ZIndexProperty, 3); tableAsUiElement.MouseLeftButtonDown += new MouseButtonEventHandler((canvas as DrawingCanvas).MouseLeftButtonDownHandler); tableAsUiElement.MouseLeftButtonUp += new MouseButtonEventHandler((canvas as DrawingCanvas).MouseLeftButtonUpHandler); // Hook up event listeners to the stream if non-null. We need to monitor: // 1. Changes in the comment collection // 2. Changes to the source process units properties (position) // 3. Changes to the destination process units properties (position) // 4. Changes to the source or destination references // 1. // Setup the event listener for the comment collection. It is the responsibility of this // control to create and manage the sticky note controls for its comments m_stream.Comments.CollectionChanged += Comments_CollectionChanged; // Invoke the callback to create sticky notes for comments Comments_CollectionChanged(m_stream.Comments, null); // 2. if (null != stream.Source) { m_sourceEventItem = stream.Source; stream.Source.PropertyChanged += this.SourceOrDest_PropertyChanged; } // 3. if (null != stream.Destination) { m_destEventItem = stream.Destination; stream.Destination.PropertyChanged += this.SourceOrDest_PropertyChanged; } // 4. stream.PropertyChanged += new PropertyChangedEventHandler(Stream_PropertyChanged); } }
public void StateEnding() { // If the stream is null then we don't process events if (null == m_stream) { return; } // Clear the border color if we had set one if (null != m_changedBorderColor) { m_changedBorderColor.SetBorderColor(ProcessUnitBorderColor.NoBorder); m_changedBorderColor = null; } // Create an undo Workspace ws = m_canvas.GetWorkspace(); if (m_dragIcon.IsSource) { // There are 4 cases for what could have happened: // 1. Source was originally null and still is // 2. Source was originally null and now isn't // 3. Source was originally non-null and now is null // 4. Source was originally non-null and still is non-null // 4a. It is the same // 4b. It is different if (null == m_connectedToOnStart && null == m_stream.Source) { // This is just a move of the endpoint from one location to another ws.AddUndo(new UndoRedoCollection("Undo moving stream source", new Logic.Undos.SetStreamSourceLocation(m_stream, m_startLocation))); } else if (null == m_connectedToOnStart && null != m_stream.Source) { ws.AddUndo(new UndoRedoCollection("Undo changing stream source", new Logic.Undos.SetStreamSource(m_stream, null, m_stream.Source, m_startLocation), new Logic.Undos.DetachOutgoingStream(m_stream.Source, m_stream))); } else if (null != m_connectedToOnStart && null == m_stream.Source) { ws.AddUndo(new UndoRedoCollection("Undo detaching stream source", new Logic.Undos.SetStreamSource(m_stream, m_connectedToOnStart, null, m_stream.SourceLocation), new Logic.Undos.AttachOutgoingStream(m_connectedToOnStart, m_stream))); } else { // Only take action if we've changed the source if (!object.ReferenceEquals(m_connectedToOnStart, m_stream.Source)) { ws.AddUndo(new UndoRedoCollection("Undo changing stream source", new Logic.Undos.SetStreamSource(m_stream, m_connectedToOnStart, m_stream.Source, m_stream.SourceLocation), new Logic.Undos.DetachOutgoingStream(m_stream.Source, m_stream), new Logic.Undos.AttachOutgoingStream(m_connectedToOnStart, m_stream))); } } } else { // There are 4 cases for what could have happened: // 1. Destination was originally null and still is // 2. Destination was originally null and now isn't // 3. Destination was originally non-null and now is null // 4. Destination was originally non-null and still is non-null // 4a. It is the same // 4b. It is different if (null == m_connectedToOnStart && null == m_stream.Destination) { // This is just a move of the endpoint from one location to another ws.AddUndo(new UndoRedoCollection("Undo moving stream destination", new Logic.Undos.SetStreamDestinationLocation(m_stream, m_startLocation))); } else if (null == m_connectedToOnStart && null != m_stream.Destination) { ws.AddUndo(new UndoRedoCollection("Undo changing stream destination", new Logic.Undos.SetStreamDestination(m_stream, null, m_stream.Destination, m_startLocation), new Logic.Undos.DetachIncomingStream(m_stream.Destination, m_stream))); } else if (null != m_connectedToOnStart && null == m_stream.Destination) { ws.AddUndo(new UndoRedoCollection("Undo detaching stream destination", new Logic.Undos.SetStreamDestination(m_stream, m_connectedToOnStart, null, m_stream.DestinationLocation), new Logic.Undos.AttachIncomingStream(m_connectedToOnStart, m_stream))); } else { // Only take action if we've changed the destination if (!object.ReferenceEquals(m_connectedToOnStart, m_stream.Destination)) { ws.AddUndo(new UndoRedoCollection("Undo changing stream destination", new Logic.Undos.SetStreamDestination(m_stream, m_connectedToOnStart, m_stream.Destination, m_stream.DestinationLocation), new Logic.Undos.DetachIncomingStream(m_stream.Destination, m_stream), new Logic.Undos.AttachIncomingStream(m_connectedToOnStart, m_stream))); } } } if (m_creatingStream) { // Tell the stream control to show the table m_dragIcon.ParentStream.ShowTable(true); } // Set the stream reference to null to end this state m_stream = null; }
public void MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // If the canvas reference is null then we ignore mouse events if (null == m_canvas) { return; } // Here's where we need to flip over to the MovingStreamEndpoint state. We start by // finding out if we clicked on a process unit or not Point location = e.GetPosition(m_canvas); // Clear the border if we'd previously set one if (null != m_puWithAlteredBorderColor) { m_puWithAlteredBorderColor.SetBorderColor(ProcessUnitBorderColor.NoBorder); m_puWithAlteredBorderColor = null; } // Remove the floating icon m_canvas.RemoveChild(m_sourcePlacementIcon); m_sourcePlacementIcon = null; // Get a reference to the workspace Workspace ws = m_canvas.GetWorkspace(); // See if we clicked on a valid destination object ProcessUnitControl gpu = m_canvas.GetChildAt(location, m_sourcePlacementIcon) as ProcessUnitControl; if (null == gpu) { // This means that we clicked in an area where there's no process unit that we have // to attach to. m_stream.SourceLocation = new MathCore.Vector(location.X, location.Y); m_stream.DestinationLocation = m_stream.SourceLocation + (new MathCore.Vector(0, 20.0)); ws.AddStream(m_stream); // We need an undo to remove the stream that we just added. Note that we're going to switch // over to a different state below and that creates and undo as well. This is fine since // it allows you to undo the destination placement and stream creation separately. ws.AddUndo(new UndoRedoCollection("Undo stream creation", new Logic.Undos.RemoveStream(m_stream))); } else if (gpu.ProcessUnit.CanAcceptOutgoingStream(m_stream)) { // Setup the stream and add it to the workspace m_stream.SourceLocation = new MathCore.Vector(location.X, location.Y); m_stream.DestinationLocation = m_stream.SourceLocation + (new MathCore.Vector(0, 35.0)); m_stream.Source = gpu.ProcessUnit; ws.AddStream(m_stream); // Attach the outgoing stream to the process unit after we've added the stream to // the workspace gpu.ProcessUnit.AttachOutgoingStream(m_stream); // We've linked up the stream and added it to the workspace. Now create an undo that // does the opposite ws.AddUndo(new UndoRedoCollection("Undo stream creation", new Logic.Undos.DetachOutgoingStream(gpu.ProcessUnit, m_stream), new Logic.Undos.RemoveStream(m_stream))); } else { // This means we clicked on a process unit that we cannot connect to. In this case // we want to cancel everything. This is easy since we haven't modified the workspace, // so all we have to do it switch back to select mode. m_palette.SwitchToSelect(); return; } // Get the stream control that the DrawingCanvas should have added PFD.Streams.StreamControl streamControl = m_canvas.GetStreamControl(m_stream); // Tell it to hide the table streamControl.HideTable(); // Set references to null to indicate that this state should no longer process mouse input // messages after this. We are finishing up right here. DrawingCanvas c = m_canvas; m_canvas = null; m_stream = null; // Switch back to select mode m_palette.SwitchToSelect(); // Flip over to the state where we position the stream destination c.CurrentState = new MovingStreamEndpoint(streamControl.DestinationDragIcon, c, true); }
private void DropProcessUnit(ProcessUnitControl pu, Point location) { // We want to see if the process unit is being dragged and dropped onto a stream // source or destination // Get the element (besides the one being dragged) that's at the mouse location object dropTarget = m_canvas.GetChildAt(location, m_object); // If there is no child at that point or there is a child but it's not a stream endpoint // then this ends up just being a move of the process unit if (null == dropTarget || !(m_canvas.IsStreamEndpoint(dropTarget as UIElement))) { // Add an undo that will move the process unit back to where it was m_workspace.AddUndo(new UndoRedoCollection("Undo moving process unit", new Logic.Undos.SetProcessUnitLocation(pu.ProcessUnit, m_originalLocation))); // The control is already in the right position from the mouse-move event, so we're done return; } // Coming here means that we've dropped the process unit on a stream endpoint. We need to // check if this is a valid move or not and handle it appropriately. DraggableStreamEndpoint streamEndpoint = dropTarget as DraggableStreamEndpoint; if (streamEndpoint.CanConnectTo(pu)) { AbstractStream stream = streamEndpoint.ParentStream.Stream; switch (streamEndpoint.Type) { case DraggableStreamEndpoint.EndpointType.StreamDestination: m_workspace.AddUndo(new UndoRedoCollection("Undo moving and connecting process unit", new Logic.Undos.DetachIncomingStream(pu.ProcessUnit, streamEndpoint.ParentStream.Stream), new Logic.Undos.SetStreamDestination(stream, null, pu.ProcessUnit, m_originalLocation))); pu.ProcessUnit.AttachIncomingStream(streamEndpoint.ParentStream.Stream); stream.Destination = pu.ProcessUnit; break; case DraggableStreamEndpoint.EndpointType.StreamSource: m_workspace.AddUndo(new UndoRedoCollection("Undo moving and connecting process unit", new DetachOutgoingStream(pu.ProcessUnit, streamEndpoint.ParentStream.Stream), new SetStreamSource(stream, null, pu.ProcessUnit, new MathCore.Vector(streamEndpoint.Location.X, streamEndpoint.Location.Y)))); pu.ProcessUnit.AttachOutgoingStream(stream); stream.Source = pu.ProcessUnit; break; default: // Um.... break; } } else // Not a valid move { // In this case we simply snap it back to where it was when the move started. // Ideally we should have some sort of animation that makes it slide back to its original // location, but that can come much later if we want it. pu.Location = new Point(m_originalLocation.X, m_originalLocation.Y); // Note that in either case we've essentially canceled the action and no net-change has // been made. Thus we don't need to create an undo. return; } }
public PlacingNewStream(UI.ControlPalette sender, DrawingCanvas canvas, StreamType streamType) { // Quick error check on parameters if (null == sender || null == canvas) { throw new ArgumentNullException(); } if (StreamType.Chemical != streamType && StreamType.Heat != streamType) { // To save us from problems with future changes throw new NotImplementedException(); } m_palette = sender; m_canvas = canvas; // Create the stream (data structure, not control). Take care to pick an ID that's not // already in use. int newID; do { newID = AbstractStream.GetNextUID(); }while (canvas.GetWorkspace().StreamExists(newID)); if (StreamType.Chemical == streamType) { m_stream = new ChemicalStream(newID); } else { m_stream = new HeatStream(newID); } // Create the table m_stream.PropertiesTable = new StreamPropertiesTable(m_stream); // Create the default row if we have a heat stream. There is no default row // for chemical streams if (StreamType.Heat == streamType) { // Add a default row if it's not already there if (0 == m_stream.PropertiesTable.RowCount) { m_stream.PropertiesTable.AddNewRow(); } // Choose a default label m_stream.PropertiesTable.Rows[0].Label = "Q" + m_stream.Id.ToString(); // Select default units (m_stream.PropertiesTable.Rows[0] as HeatStreamData).SelectedUnits = HeatStreamData.EnergyUnitOptions[0]; // Flag it as not renamed by the user yet m_stream.PropertiesTable.Rows[0].UserHasRenamed = false; } // Create the source placement icon and add it to the canvas m_sourcePlacementIcon = new Image(); Uri uri = new Uri("/UI/Icons/pu_source.png", UriKind.Relative); ImageSource img = new System.Windows.Media.Imaging.BitmapImage(uri); m_sourcePlacementIcon.SetValue(Image.SourceProperty, img); m_canvas.AddNewChild(m_sourcePlacementIcon); m_sourcePlacementIcon.SetValue(Canvas.ZIndexProperty, 4); }
public void SetCommentObject(StickyNote comment, object parent) { if (null != m_sticky) { // Remove event handler before changing this value m_sticky.PropertyChanged -= this.StickyNote_PropertyChanged; } if (null != m_basic) { m_basic.OnTextChanged -= this.BasicComment_OnTextChanged; } // IMPORTANT: Unsubscribe from parent control property changes (if applicable) if (null != m_parentObject) { if (m_parentObject is AbstractProcessUnit) { (m_parentObject as AbstractProcessUnit).PropertyChanged -= this.ParentPU_PropertyChanged; } else if (m_parentObject is AbstractStream) { (m_parentObject as AbstractStream).PropertyChanged -= this.ParentStream_PropertyChanged; } } // Store references m_basic = null; m_sticky = comment; m_parentObject = parent; AbstractStream parentStream = parent as AbstractStream; AbstractProcessUnit parentAPU = parent as AbstractProcessUnit; // Update the UI elements if the comment is not null if (null != m_sticky) { CommentTextBox.Text = m_sticky.Text; UserNameLabel.Content = m_sticky.UserName; // Subsribe to property changes m_sticky.PropertyChanged += this.StickyNote_PropertyChanged; // Allow editing but not deletion CommentTextBox.IsReadOnly = false; XLabel.Visibility = System.Windows.Visibility.Collapsed; // Show or hide the icon based on the parent if (null != parentStream) { // Get the right icon for this type of stream string iconSource = PFD.Streams.StreamControl.GetIconSource(parent.GetType()); BitmapImage bmp = new BitmapImage(); bmp.UriSource = new Uri(iconSource, UriKind.Relative); IconImage.SetValue(Image.SourceProperty, bmp); // Make sure the icon is visible IconImage.Visibility = System.Windows.Visibility.Visible; TitleBarGrid.ColumnDefinitions[0].Width = new GridLength(20.0); // Give the icon a tooltip that tells what this is a comment for ToolTipService.SetToolTip(IconImage, "Comment for stream #" + parentStream.Id); // Subscribe to property changes for the stream parentStream.PropertyChanged += new PropertyChangedEventHandler(ParentStream_PropertyChanged); } else if (null != parentAPU) { // Get the right icon for this type of process unit string iconSource = ProcessUnitControl.GetIconSource(parent.GetType()); BitmapImage bmp = new BitmapImage(); bmp.UriSource = new Uri(iconSource, UriKind.Relative); IconImage.SetValue(Image.SourceProperty, bmp); // Make sure the icon is visible IconImage.Visibility = System.Windows.Visibility.Visible; TitleBarGrid.ColumnDefinitions[0].Width = new GridLength(20.0); // Give the icon a tooltip that tells what this is a comment for ToolTipService.SetToolTip(IconImage, "Comment for " + (m_parentObject as AbstractProcessUnit).Label); // Subscribe to property changes for the process unit parentAPU.PropertyChanged += new PropertyChangedEventHandler(ParentPU_PropertyChanged); } else { // Make sure the icon is hidden IconImage.Visibility = System.Windows.Visibility.Collapsed; TitleBarGrid.ColumnDefinitions[0].Width = new GridLength(0.0); } } }
/// <summary> /// Merges comments from two Xml document streams into a new output Xml document stream. Comment /// merging is not commutative. One document must be considered to be the parent and another a /// child. ALL content from the parent will appear in the output. Comments from the child /// document will only be written to the output if they exist for shared entities. That is, if /// there is a comment in the child document that is tied to a process unit with Id=GPU_30, then /// it will only be written the output document if the parent also contained a process unit with /// the same Id. /// </summary> public static void Merge(Stream parent, string parentUserNameIfNotInXml, Stream child, string childUserNameIfNotInXml, Stream output) { // We need all streams to be non-null if (null == parent) { throw new ArgumentNullException( "Parent stream for comment merging cannot be null"); } if (null == child) { throw new ArgumentNullException( "Child stream for comment merging cannot be null"); } if (null == output) { throw new ArgumentNullException( "Output stream for comment merging cannot be null"); } // Load the workspaces from the streams Workspace wsParent = new Workspace(); wsParent.Load(parent); Workspace wsChild = new Workspace(); wsChild.Load(child); // What we will do in this method is alter wsParent to contain relevant content from the // child workspace and then save it to the output stream. // Start by setting user names for comments in both workspaces. We leave the user names // alone if they are not null or empty but otherwise we set them to the values specified // by the caller. SetUserNameIfAbsent(wsParent, parentUserNameIfNotInXml); SetUserNameIfAbsent(wsChild, childUserNameIfNotInXml); // Start with the free-floating sticky note comments. We want to take the ones from the // child and add them into the parent. But we want to avoid duplicates in the process. foreach (StickyNote sn in wsChild.StickyNotes) { // If they have the same text and location then we'll skip if (WorkspaceUtility.ContainsFFSNWithValues(wsParent, sn.Text, new MathCore.Vector(sn.LocationX, sn.LocationY))) { continue; } // Add it to the parent wsParent.StickyNotes.Add(sn); } // Next do process units in the child foreach (AbstractProcessUnit apuChild in wsChild.ProcessUnits) { AbstractProcessUnit apuParent = wsParent.GetProcessUnit(apuChild.Id); // If the parent workspace doesn't contain a process unit with the same ID then we // skip it if (null == apuParent) { continue; } foreach (StickyNote comment in apuChild.Comments) { if (WorkspaceUtility.CollectionContainsItemWithText(apuParent.Comments, comment.Text)) { // Skip it if there's already a comment with the same text continue; } // Add it to the parent process unit apuParent.Comments.Add(comment); } } // Now do streams in the child foreach (AbstractStream sChild in wsChild.Streams) { AbstractStream sParent = wsParent.GetStream(sChild.Id); // If the parent workspace doesn't contain a stream with the same ID then we // skip it if (null == sParent) { continue; } foreach (StickyNote comment in sChild.Comments) { if (WorkspaceUtility.CollectionContainsItemWithText(sParent.Comments, comment.Text)) { // Skip it if there's already a comment with the same text continue; } // Add the comment to the parent stream sParent.Comments.Add(comment); } } // Equation comments need to be merged as well foreach (EquationModel emChild in wsChild.Equations) { // Get the equation object in the parent with the same ID EquationModel emParent = wsParent.Equations.GetById(emChild.Id); // If we can't find it then move on to the next if (null == emParent) { continue; } // Now add each comment in the child that isn't already in the parent foreach (BasicComment bcChild in emChild.Comments) { if (!emParent.ContainsComment(bcChild.CommentText)) { emParent.Comments.Add(bcChild); } } } // Lastly we deal with the comments for the degrees of freedom analysis. We only // merge in comments from the child if the analysis text is the same in both. if (wsParent.DegreesOfFreedomAnalysis.Text == wsChild.DegreesOfFreedomAnalysis.Text) { foreach (BasicComment bcChild in wsChild.DegreesOfFreedomAnalysis.Comments) { if (!wsParent.DegreesOfFreedomAnalysis.ContainsComment(bcChild.CommentText)) { wsParent.DegreesOfFreedomAnalysis.Comments.Add(bcChild); } } } // Now that we have everything merged into the parent workspace, we just save it to the // output stream wsParent.Save(output); }
public SetStreamId(AbstractStream stream, int id) { m_stream = stream; m_id = id; }
public DetachIncomingStream(AbstractProcessUnit processUnit, AbstractStream incomingStream) { m_pu = processUnit; m_stream = incomingStream; }
public void TestSaveLoad() { int i; Workspace ws1 = new Workspace(); Random rand = new Random(); // Add a random number of process units List <int> puIDs = new List <int>(); int numPU = rand.Next(25); for (i = 0; i < numPU; i++) { AbstractProcessUnit pu = new Mixer(); ws1.AddProcessUnit(pu); puIDs.Add(pu.Id); } // Add a random number of chemical streams int numStreams = rand.Next(10); for (i = 0; i < numStreams; i++) { AbstractStream stream = new ChemicalStream(AbstractStream.GetNextUID()); ws1.AddStream(stream); // Don't forget that the properties table needs to be created separately stream.PropertiesTable = new StreamPropertiesTable(stream); // 50% chance of connecting a destination (attempting a connect that is) if (0 == (rand.Next() % 2)) { AbstractProcessUnit pu = ws1.ProcessUnits[rand.Next(ws1.ProcessUnitCount)]; if (pu.AttachIncomingStream(stream)) { stream.Destination = pu; } } } // Save the workspace to a memory stream MemoryStream ms = new MemoryStream(); ws1.Save(ms, "TEST_VersionNA"); // Load to a new workspace Workspace ws2 = new Workspace(); ws2.Load(ms); // Make sure the number of process units and streams match Assert.IsTrue(numPU == ws2.ProcessUnitCount, "Number of process units between saved document (" + numPU.ToString() + ") and loaded document (" + ws2.ProcessUnitCount.ToString() + ") do not match"); Assert.IsTrue(numStreams == ws2.Streams.Count, "Number of streams between saved document (" + numStreams.ToString() + ") and loaded document (" + ws2.Streams.Count.ToString() + ") do not match"); // Test that the incoming/outgoing streams for process units match foreach (AbstractProcessUnit pu1 in ws1.ProcessUnits) { AbstractProcessUnit pu2 = ws2.GetProcessUnit(pu1.Id); Assert.IsNotNull(pu2, "Process unit with ID=" + pu1.Id.ToString() + " from workspace 1 (saved) was not " + "found in workspace 2 (loaded)."); // For now just compare outoging stream count Assert.IsTrue(pu1.OutgoingStreamCount == pu2.OutgoingStreamCount, "Mis-match outgoing stream count"); } }