public void MouseMove(object sender, MouseEventArgs e) { // Position the placement icon Point pos = e.GetPosition(m_canvas); m_placementIcon.SetValue(Canvas.LeftProperty, pos.X - 20.0); m_placementIcon.SetValue(Canvas.TopProperty, pos.Y - 20.0); // Show the placement icon if it wasn't already visible if (Visibility.Visible != m_placementIcon.Visibility) { m_placementIcon.Visibility = Visibility.Visible; } // Set border highlight if we're hoving over a stream endpoint DraggableStreamEndpoint endpoint = m_canvas.GetChildAt(pos, m_placementIcon) as DraggableStreamEndpoint; if (null == endpoint) { m_placementIcon.BorderThickness = new Thickness(0.0); } else { AbstractProcessUnit temp = (AbstractProcessUnit) Activator.CreateInstance(m_type, -1); m_placementIcon.BorderThickness = new Thickness(2.0); m_placementIcon.BorderBrush = (endpoint.CanConnectTo(temp) ? s_greenBrush : s_redBrush); } }
public void MouseMove(object sender, MouseEventArgs e) { if (!m_mouseDown) { return; } // We can't do anything if the canvas is read-only if (m_canvas.IsReadOnly) { return; } Point pt = e.GetPosition(m_canvas); MathCore.Vector diff = (new MathCore.Vector(pt.X, pt.Y)) - m_mouseDownPt; diff = (m_originalLocation + diff); pt = new Point(diff.X, diff.Y); // If we changed a border color, change it back and null the reference if (null != m_puThatGotBorderChange) { m_puThatGotBorderChange.SetBorderColor(ProcessUnitBorderColor.Selected); m_puThatGotBorderChange = null; } // Various objects have slightly different moving rules so we need to check the type ProcessUnitControl lpu = m_object as ProcessUnitControl; if (null != lpu) { // First off, move the process unit lpu.ProcessUnit.Location = new MathCore.Vector(pt.X, pt.Y); // See if we're dragging it over anything else object hoveringOver = m_canvas.GetChildAt(pt, lpu); // See if it's a stream connection endpoint DraggableStreamEndpoint endpoint = hoveringOver as DraggableStreamEndpoint; if (null != endpoint) { m_puThatGotBorderChange = lpu; // Set the process unit's border color m_puThatGotBorderChange.SetBorderColor(endpoint.CanConnectTo(lpu) ? ProcessUnitBorderColor.AcceptingStreams : ProcessUnitBorderColor.NotAcceptingStreams); } } else { // Other items just get their locations set m_object.Location = pt; } // NOTE: Stream-oriented moving stuff is handled elsewhere. See the MovingStreamEndpoint class }
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 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; } }
/// <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(); }