/// <summary> /// Handles mouse-left-button-down event for placing a heat exchanger with utility /// </summary> public void MLBD_HEWU(object sender, MouseButtonEventArgs e) { // Start by getting the mouse position Point pos = e.GetPosition(m_canvas); // 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; // If there's not an endpoint: // 1. Create and attach an incoming heat stream. Position the source endpoint just // below the process unit // 2. Create an undo that will remove both // 3. Switch to the appropriate state for moving the source endpoint if (null == endpoint) { // Create the actual process unit AbstractProcessUnit apu = (AbstractProcessUnit)Activator.CreateInstance( m_type, AbstractProcessUnit.GetNextUID()); apu.Location = new MathCore.Vector(pos.X, pos.Y); HeatStream s = new HeatStream(); apu.AttachIncomingStream(s); s.Destination = apu; s.PropertiesTable = new StreamPropertiesTable(s); // Position the source of the heat stream. It's above the process unit by default, unless // that would make it go off the screen if (apu.Location.Y < 150.0) { s.SourceLocation = new MathCore.Vector( apu.Location.X - 10.0, apu.Location.Y + 80.0); s.PropertiesTable.Location = new MathCore.Vector( apu.Location.X + 10.0, apu.Location.Y + 140.0); } else { s.SourceLocation = new MathCore.Vector( apu.Location.X - 10.0, apu.Location.Y - 80.0); s.PropertiesTable.Location = new MathCore.Vector( apu.Location.X + 10.0, apu.Location.Y - 100.0); } // Add the stream and the process unit to the workspace. Event handlers will update // the UI appropriately. m_workspace.AddProcessUnit(apu); m_workspace.AddStream(s); m_workspace.AddUndo(new UndoRedoCollection("Undo creation of heat exchanger with utility", new Logic.Undos.DetachIncomingStream(apu, s), new Logic.Undos.SetStreamDestination(s, null, apu, s.DestinationLocation), new Logic.Undos.RemoveStream(s), new Logic.Undos.RemoveProcessUnit(apu))); // Select nothing on the canvas m_canvas.SelectedElement = null; m_palette.SwitchToSelect(); return; } // Otherwise, if we HAVE clicked on an endpoint, just deny it by doing nothing }
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(); }