public IUndoRedoAction Execute(Workspace sender) { // First allocate the undo/redo that does the opposite IUndoRedoAction opposite = new DetachOutgoingStream(m_pu, m_stream); // Do the simple attachment m_pu.AttachOutgoingStream(m_stream); return(opposite); }
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(); }