示例#1
0
        public void MouseMove(object sender, MouseEventArgs e)
        {
            // If the canvas reference is null then we ignore mouse events
            if (null == m_canvas)
            {
                return;
            }

            Point mousePt = 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;
            }

            // See if we're hovering over a process unit (will be null if we're not)
            m_puWithAlteredBorderColor =
                m_canvas.GetChildAt(e.GetPosition(m_canvas), m_sourcePlacementIcon) as ProcessUnitControl;

            // Set the location of icon so that it's right under the mouse pointer
            m_sourcePlacementIcon.SetValue(Canvas.LeftProperty, mousePt.X - m_sourcePlacementIcon.ActualWidth / 2.0);
            m_sourcePlacementIcon.SetValue(Canvas.TopProperty, mousePt.Y - m_sourcePlacementIcon.ActualHeight / 2.0);

            // If we're over a process unit then we need to set its border
            if (null != m_puWithAlteredBorderColor)
            {
                m_puWithAlteredBorderColor.SetBorderColor(
                    m_puWithAlteredBorderColor.ProcessUnit.CanAcceptOutgoingStream(m_stream) ?
                    ProcessUnitBorderColor.AcceptingStreams : ProcessUnitBorderColor.NotAcceptingStreams);
            }
        }
示例#2
0
        /// <summary>
        /// The member variable m_highlightedHover can be a reference to a process unit with a highlighted
        /// border or a stream with a specially colored stem line. This method removes either of these
        /// highlights and sets the member variable back to null.
        /// </summary>
        private void UnhighlightHover()
        {
            if (null == m_highlightedHover)
            {
                return;
            }

            ProcessUnitControl gpu = m_highlightedHover as ProcessUnitControl;

            if (null != gpu)
            {
                gpu.SetBorderColor(ProcessUnitBorderColor.NoBorder);
            }
            else
            {
                PFD.Streams.StreamControl s = m_highlightedHover as PFD.Streams.StreamControl;
                if (null != s)
                {
                    s.Selected = true;
                    s.Selected = false;
                }
            }

            m_highlightedHover = null;
        }
示例#3
0
        public void MouseMove(object sender, MouseEventArgs e)
        {
            if (null == m_placementIcon)
            {
                return;
            }

            // Set the location of the icon to follow the mouse
            Point p = e.GetPosition(m_canvas);

            m_placementIcon.SetValue(Canvas.LeftProperty, p.X - m_placementIcon.Width / 2.0);
            m_placementIcon.SetValue(Canvas.TopProperty, p.Y - m_placementIcon.Height / 2.0);

            // If we've highlighted a process unit or stream then clear the highlight
            UnhighlightHover();

            // See if we're hovering over a process unit (will be null if we're not)
            m_highlightedHover = m_canvas.GetChildAtIncludeStreams(p, m_placementIcon);
            ProcessUnitControl pu = m_highlightedHover as ProcessUnitControl;

            ChemProV.PFD.Streams.StreamControl stream =
                m_highlightedHover as ChemProV.PFD.Streams.StreamControl;

            // Set the border if we are hovering over a process unit to indicate that we can attach
            // an anchored comment to it
            if (null != pu)
            {
                pu.SetBorderColor(ProcessUnitBorderColor.AcceptingStreams);
            }
            else if (null != stream)
            {
                stream.SetLineBrush(new SolidColorBrush(Colors.Green));
            }
        }
示例#4
0
        public PlacingNewProcessUnit(ControlPalette sender, DrawingCanvas canvas,
                                     Type processUnitType)
        {
            m_canvas    = canvas;
            m_palette   = sender;
            m_type      = processUnitType;
            m_workspace = canvas.GetWorkspace();

            SolidColorBrush whiteBrush = new SolidColorBrush(Colors.White);

            // Create the placement icon. This will hover under the mouse pointer
            // as it moves and a mouse-down event will complete the placement.
            BitmapImage bmp = new BitmapImage();

            bmp.UriSource = new Uri(ProcessUnitControl.GetIconSource(processUnitType), UriKind.Relative);
            Image img = new Image()
            {
                Source = bmp,
                Width  = 44.0,
                Height = 44.0
            };

            m_placementIcon                 = new Border();
            m_placementIcon.Background      = whiteBrush;
            m_placementIcon.Child           = img;
            m_placementIcon.BorderThickness = new Thickness(0.0);

            // Add it to the canvas but don't show it until we get our first mouse-move event
            canvas.AddNewChild(m_placementIcon);
            m_placementIcon.Visibility = Visibility.Collapsed;

            // Deselect
            canvas.SelectedElement = null;
        }
示例#5
0
        // Refactoring on this method is done (logic-wise, could use some cleanup otherwise)
        private static void DeleteHEWU(ProcessUnitControl he, DrawingCanvas canvas)
        {
            Workspace ws = canvas.GetWorkspace();

            // Heat exchangers with utilities must also delete the heat stream that's incoming
            // Normally the heat stream is at index 0 among the incoming streams, but it seems like
            // this does not always hold true when loading from files so it's just safer to search
            // for it
            HeatStream heatStream = null;

            foreach (AbstractStream incomingStream in he.ProcessUnit.IncomingStreams)
            {
                if (incomingStream is HeatStream)
                {
                    heatStream = incomingStream as HeatStream;
                    break;
                }
            }
            PFD.Streams.StreamControl heatStreamControl =
                canvas.GetStreamControl(heatStream) as PFD.Streams.StreamControl;

            List <IUndoRedoAction> undos = new List <IUndoRedoAction>();

            undos.Add(new Logic.Undos.AddToWorkspace(heatStream));
            undos.Add(new Logic.Undos.AddToWorkspace(he.ProcessUnit));

            // We need to check if the attached stream has a source
            if (null != heatStream.Source)
            {
                // Detach with undo
                undos.Add(new Logic.Undos.AttachOutgoingStream(heatStream.Source, heatStream));
                heatStream.Source.DetachOutgoingStream(heatStream);
            }

            // Detach all outgoing streams and make undos
            foreach (AbstractStream s in he.ProcessUnit.OutgoingStreams)
            {
                undos.Add(new Logic.Undos.SetStreamSource(s, he.ProcessUnit, null,
                                                          s.SourceLocation));
                s.Source = null;
            }

            // Detach all incoming streams and make undos
            foreach (AbstractStream s in he.ProcessUnit.IncomingStreams)
            {
                undos.Add(new Logic.Undos.SetStreamDestination(s, he.ProcessUnit, null,
                                                               s.DestinationLocation));
                s.Destination = null;
            }

            ws.AddUndo(new UndoRedoCollection(
                           "Undo deletion of heat exchanger with utility", undos.ToArray()));

            // Remove the stream and process unit from the workspace. Event handlers will update the UI.
            ws.RemoveStream(heatStream);
            ws.RemoveProcessUnit(he.ProcessUnit);
        }
示例#6
0
        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
        }
        /// <summary>
        /// This returns the rule that needs to be checked for the GenericProcessUnit
        /// Currently it returns the ReactorProcessUnitRule if pu is a reactor otherwise
        /// it returns the GenericProcessUnitRule
        /// </summary>
        /// <param name="pu">The process unit that will be checked with the rule returned</param>
        /// <returns>GenericProcessUnitRule which could be a ReactorProcessUnitRule since it inherients from GenericProcessUnitRule</returns>
        public static GenericProcessUnitRule GetProcessUnitRule(ProcessUnitControl pu)
        {
            GenericProcessUnitRule puRule;

            if (pu.ProcessUnit is Reactor)
            {
                puRule = new ReactorProcessUnitRule();
            }
            else if (pu.ProcessUnit is HeatExchangerNoUtility)
            {
                puRule = new HeatExchangerWithoutUtilityProcessUnitRule();
            }
            else
            {
                puRule = new GenericProcessUnitRule();
            }
            return(puRule);
        }
示例#8
0
        private static void DeleteProcessUnitWithUndo(ProcessUnitControl pu, Workspace ws)
        {
            // Initialize the list of undos
            List <IUndoRedoAction> undos = new List <IUndoRedoAction>();

            undos.Add(new ChemProV.Logic.Undos.AddToWorkspace(pu.ProcessUnit));

            // Deleting a process unit could potentially affect equations because equations can reference
            // a process unit as their scope. Therefore we need to check all equations if they have this
            // process unit set as their scope and change w/ undo if they do.
            foreach (EquationModel em in ws.Equations)
            {
                if (em.Scope.Classification == EquationScopeClassification.SingleUnit &&
                    em.Scope.Name == pu.ProcessUnit.Label)
                {
                    undos.Add(new Logic.Undos.SetProperty(em, "Scope", em.Scope));
                    em.Scope = new EquationScope(EquationScopeClassification.Overall, "Overall");
                }
            }

            // Detach all incoming streams and make undos
            foreach (AbstractStream s in pu.ProcessUnit.IncomingStreams)
            {
                undos.Add(new SetStreamDestination(s, pu.ProcessUnit, null, s.DestinationLocation));
                s.Destination = null;
            }

            // Detach all outgoing streams and make undos
            foreach (AbstractStream s in pu.ProcessUnit.OutgoingStreams)
            {
                undos.Add(new SetStreamSource(s, pu.ProcessUnit, null, s.SourceLocation));
                s.Source = null;
            }

            // Remove the process unit from the workspace. Event handlers will update UI.
            ws.RemoveProcessUnit(pu.ProcessUnit);

            // Finalize the undo
            ws.AddUndo(new UndoRedoCollection("Undo deletion of process unit", undos.ToArray()));
        }
示例#9
0
 /// <summary>
 /// Determines whether or not this endpoint can connect to the specified process unit control
 /// </summary>
 public bool CanConnectTo(ProcessUnitControl processUnit)
 {
     return(CanConnectTo(processUnit.ProcessUnit));
 }
示例#10
0
        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;
            }
        }
示例#11
0
        /// <summary>
        /// Adds menu options for the subprocess color changing
        /// </summary>
        private void AddSubprocessMenuOptions(ContextMenu newContextMenu, ProcessUnitControl pu)
        {
            MenuItem parentMenuItem = new MenuItem();

            parentMenuItem.Header = "Subprocess";
            newContextMenu.Items.Add(parentMenuItem);
            // We're using this item as a label, so don't let the user click it
            parentMenuItem.IsHitTestVisible = false;
            // Change the colors to signal to the user that it's a label
            parentMenuItem.Background = new SolidColorBrush(Colors.LightGray);
            parentMenuItem.Foreground = new SolidColorBrush(Color.FromArgb(255, 100, 100, 100));
            parentMenuItem.FontWeight = FontWeights.Bold;

            if (false)
            {
                // Create a submenu for colors. See the declaration of the Core.NamedColors.All array for
                // the list of colors that are being used. Make changes in that array (not in this code)
                // to change the list of available colors.
                foreach (Core.NamedColor nc in Core.NamedColors.All)
                {
                    MenuItem menuItem = new MenuItem();
                    menuItem.Header = nc.Name;
                    menuItem.Tag    = System.Tuple.Create <ProcessUnitControl, Color>(
                        pu, nc.Color);

                    // Show the menu item with a check next to it if it's the current color
                    if (nc.Color.Equals(pu.Subprocess))
                    {
                        menuItem.Icon = Core.App.CreateImageFromSource("check_16x16.png");
                    }

                    // Add it to the menu
                    newContextMenu.Items.Add(menuItem);

                    // Use an anonymous delegate to handle the click event
                    menuItem.Click += delegate(object sender, RoutedEventArgs e)
                    {
                        // Get the objects we need
                        MenuItem tempMI = sender as MenuItem;
                        System.Tuple <ProcessUnitControl, Color> t = tempMI.Tag as
                                                                     System.Tuple <ProcessUnitControl, Color>;

                        // Create undo item before setting the new subgroup
                        m_workspace.AddUndo(new UndoRedoCollection("Undo subprocess change",
                                                                   new Logic.Undos.SetSubprocess(t.Item1.ProcessUnit)));

                        // Set the subgroup
                        t.Item1.Subprocess = t.Item2;

                        // Make sure to remove the popup menu from the canvas
                        m_canvas.Children.Remove(m_contextMenu);
                        m_contextMenu = null;

                        // Flip back to the default state for the canvas (null)
                        m_canvas.CurrentState = null;
                    };
                }
            }

            MenuItem mi = new MenuItem();

            mi.Header = "Select subprocess...";
            mi.Click += delegate(object sender, RoutedEventArgs r)
            {
                SubprocessChooserWindow win = new SubprocessChooserWindow(
                    pu as ProcessUnitControl, m_workspace);
                win.Show();

                // Make sure to remove the popup menu from the canvas
                m_canvas.Children.Remove(m_contextMenu);
                m_contextMenu = null;

                // Flip back to the default state for the canvas (null)
                m_canvas.CurrentState = null;
            };
            newContextMenu.Items.Add(mi);
        }
示例#12
0
        private void AddCommentCollectionMenuOptions(ContextMenu newContextMenu, string title)
        {
            // Make the header in the menu for the comment-specific options
            MenuItem menuItem = new MenuItem();

            menuItem.Header = title;
            newContextMenu.Items.Add(menuItem);
            // We're using this item as a label, so don't let the user click it
            menuItem.IsHitTestVisible = false;
            // Change the colors to signal to the user that it's a label
            menuItem.Background = new SolidColorBrush(Colors.LightGray);
            menuItem.Foreground = new SolidColorBrush(Color.FromArgb(255, 100, 100, 100));
            menuItem.FontWeight = FontWeights.Bold;

            menuItem        = new MenuItem();
            menuItem.Header = "Add new comment";
            menuItem.Tag    = m_canvas.SelectedElement;
            newContextMenu.Items.Add(menuItem);

            // Use an anonymous delegate to handle the click event
            menuItem.Click += delegate(object sender, RoutedEventArgs e)
            {
                MenuItem tempMI = sender as MenuItem;
                PFD.Streams.StreamControl stream = tempMI.Tag as PFD.Streams.StreamControl;
                ProcessUnitControl        unit   = tempMI.Tag as ProcessUnitControl;

                // Get a reference to the comment collection
                IList <StickyNote> comments;
                if (null != stream)
                {
                    comments = stream.Stream.Comments;
                }
                else
                {
                    comments = unit.ProcessUnit.Comments;
                }

                // Compute the location for the new comment
                MathCore.Vector location = StickyNoteControl.ComputeNewCommentNoteLocation(
                    m_canvas, tempMI.Tag, 100.0, 100.0);

                // Create the new sticky note and add it to the workspace. Event handlers will update
                // the UI appropriately
                StickyNote sn = new StickyNote()
                {
                    Width     = 100.0,
                    Height    = 100.0,
                    LocationX = location.X,
                    LocationY = location.Y
                };
                comments.Add(sn);

                // Add an undo that will remove the comment
                m_workspace.AddUndo(new UndoRedoCollection("Undo creation of comment",
                                                           new RemoveComment(comments, comments.IndexOf(sn))));

                // Make sure to remove the popup menu from the canvas
                m_canvas.Children.Remove(m_contextMenu);
                m_contextMenu = null;

                // Flip back to the default state for the canvas (null)
                m_canvas.CurrentState = null;
            };

            string objName = "selected object";

            if (m_canvas.SelectedElement is ProcessUnitControl)
            {
                objName = (m_canvas.SelectedElement as ProcessUnitControl).ProcessUnit.Label;
            }
            else if (m_canvas.SelectedElement is ChemProV.PFD.Streams.StreamControl)
            {
                objName = "selected stream";
            }

            // Add a new menu item to hide all comments
            menuItem        = new MenuItem();
            menuItem.Header = "Hide all comments for " + objName;
            menuItem.Tag    = m_canvas.SelectedElement;
            newContextMenu.Items.Add(menuItem);
            menuItem.Click += delegate(object sender, RoutedEventArgs e)
            {
                MenuItem tempMI = sender as MenuItem;
                (tempMI.Tag as UI.ICommentControlManager).HideAllComments();

                // Make sure to remove the popup menu from the canvas
                m_canvas.Children.Remove(m_contextMenu);
                m_contextMenu = null;

                // Flip back to the default state for the canvas (null)
                m_canvas.CurrentState = null;
            };

            // Add one to show all comments too
            menuItem        = new MenuItem();
            menuItem.Header = "Show all comments for " + objName;
            menuItem.Tag    = m_canvas.SelectedElement;
            newContextMenu.Items.Add(menuItem);
            menuItem.Click += delegate(object sender, RoutedEventArgs e)
            {
                MenuItem tempMI = sender as MenuItem;
                (tempMI.Tag as UI.ICommentControlManager).ShowAllComments();

                // Make sure to remove the popup menu from the canvas
                m_canvas.Children.Remove(m_contextMenu);
                m_contextMenu = null;

                // Flip back to the default state for the canvas (null)
                m_canvas.CurrentState = null;
            };
        }
示例#13
0
 /// <summary>
 /// Every stream has a source and destination process unit. This method determines whether or
 /// not the specified unit is a valid destination. This may depend on multiple things, such
 /// as the type of the stream and whether or not the process unit can accept more incoming
 /// streams.
 /// </summary>
 /// <returns>True if the unit is a valid destination, false otherwise.</returns>
 public bool IsValidDestination(ProcessUnitControl unit)
 {
     return(m_stream.IsValidDestination((unit as ProcessUnitControl).ProcessUnit));
 }
示例#14
0
        public void MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            // If the stream is null then we don't process events
            if (null == m_stream)
            {
                return;
            }

            Point p = e.GetPosition(m_canvas);

            // We handle things in a special way if we're creating a stream. If the mouse is
            // let up near the source location then we go to "click-click" creation mode
            // instead of "click-drag-release" creation mode.
            MathCore.Vector v = new Vector(p.X, p.Y);
            if (m_creatingStream && (v - m_stream.SourceLocation).Length < 20.0)
            {
                // Ignore this event and wait for the next mouse down
                return;
            }

            // Clear the border color if we had set one
            if (null != m_changedBorderColor)
            {
                m_changedBorderColor.SetBorderColor(ProcessUnitBorderColor.NoBorder);
                m_changedBorderColor = null;
            }

            // If the mouse is let up over a process unit that we cannot connect to, then send the
            // endpoint back to where it was originally.
            ProcessUnitControl puc = m_canvas.GetChildAt(p, m_dragIcon) as ProcessUnitControl;

            if (null != puc)
            {
                if ((m_dragIcon.IsSource && object.ReferenceEquals(puc.ProcessUnit, m_stream.Source)) ||
                    (!m_dragIcon.IsSource && object.ReferenceEquals(puc.ProcessUnit, m_stream.Destination)))
                {
                    // This means we've already connected and we're good to go
                }
                else if (!m_dragIcon.CanConnectTo(puc))
                {
                    // Set the state back to what it was when we started
                    if (m_dragIcon.IsSource)
                    {
                        m_stream.SourceLocation = m_startLocation;
                        m_stream.Source         = m_connectedToOnStart;
                    }
                    else
                    {
                        m_stream.DestinationLocation = m_startLocation;
                        m_stream.Destination         = m_connectedToOnStart;
                    }

                    //m_stream = null;
                    //Core.App.ControlPalette.SwitchToSelect();
                    //return;
                }
            }

            StateEnding();
            Core.App.ControlPalette.SwitchToSelect();
        }
示例#15
0
        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);
        }
示例#16
0
        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;
        }
示例#17
0
 /// <summary>
 /// Every stream has a source and destination process unit. This method determines whether or
 /// not the specified unit is a valid source. This may depend on multiple things, such
 /// as the type of the stream and whether or not the process unit can accept more outgoing
 /// streams.
 /// </summary>
 /// <returns>True if the unit is a valid source, false otherwise.</returns>
 public bool IsValidSource(ProcessUnitControl unit)
 {
     return(m_stream.IsValidSource((unit as ProcessUnitControl).ProcessUnit));
 }
示例#18
0
        public void MouseMove(object sender, MouseEventArgs e)
        {
            // If the stream is null then we don't process events
            if (null == m_stream)
            {
                return;
            }

            // Get the mouse position relative to the canvas
            Point p = e.GetPosition(m_canvas);

            // Clear the border color if we had set one
            if (null != m_changedBorderColor)
            {
                m_changedBorderColor.SetBorderColor(ProcessUnitBorderColor.NoBorder);
                m_changedBorderColor = null;
            }

            // Find out if we're hovering over a process unit
            ProcessUnitControl lpu = m_canvas.GetChildAt(p, m_dragIcon) as ProcessUnitControl;

            if (null == lpu)
            {
                // All we need to do on a mouse move is make the changes in the m_stream data structure. The
                // application is designed such that UI controls monitor changes in these data structures and
                // update themselves appropriately.
                if (m_dragIcon.IsSource)
                {
                    // If the source is not null, we need to disconnect
                    if (null != m_stream.Source)
                    {
                        m_stream.Source.DetachOutgoingStream(m_stream);
                        m_stream.Source = null;
                    }
                    m_stream.SourceLocation = new Vector(p.X, p.Y);
                }
                else
                {
                    // If the destination is not null, we need to disconnect
                    if (null != m_stream.Destination)
                    {
                        m_stream.Destination.DetachIncomingStream(m_stream);
                        m_stream.Destination = null;
                    }
                    m_stream.DestinationLocation = new Vector(p.X, p.Y);
                }
            }
            else
            {
                // We are hovering over a process unit
                m_changedBorderColor = lpu;
                if (m_dragIcon.IsSource)
                {
                    if (object.ReferenceEquals(m_stream.Source, lpu.ProcessUnit))
                    {
                        // This means that the process unit we're dragging the source icon over is
                        // already set as the source, so we don't have to do anything.
                    }
                    else if (lpu.ProcessUnit.CanAcceptOutgoingStream(m_stream))
                    {
                        // If we had a non-null source then disconnect
                        if (null != m_stream.Source)
                        {
                            m_stream.Source.DetachOutgoingStream(m_stream);
                        }

                        m_stream.Source = lpu.ProcessUnit;
                        lpu.ProcessUnit.AttachOutgoingStream(m_stream);

                        // Set the border color to indicate that we can make this connection
                        lpu.SetBorderColor(ProcessUnitBorderColor.AcceptingStreams);
                    }
                    else
                    {
                        // If we had a non-null source then disconnect
                        if (null != m_stream.Source)
                        {
                            m_stream.Source.DetachOutgoingStream(m_stream);
                            m_stream.Source = null;
                        }

                        // This means that the connection cannot be made
                        lpu.SetBorderColor(ProcessUnitBorderColor.NotAcceptingStreams);
                        m_stream.SourceLocation = new Vector(p.X, p.Y);
                    }
                }
                else
                {
                    if (object.ReferenceEquals(m_stream.Destination, lpu.ProcessUnit))
                    {
                        // This means that the process unit we're dragging the destination icon over
                        // is already set as the destination, so we don't have to do anything.
                    }
                    else if (lpu.ProcessUnit.CanAcceptIncomingStream(m_stream))
                    {
                        // If we had a non-null destination then disconnect
                        if (null != m_stream.Destination)
                        {
                            m_stream.Destination.DetachIncomingStream(m_stream);
                        }

                        m_stream.Destination = lpu.ProcessUnit;
                        lpu.ProcessUnit.AttachIncomingStream(m_stream);

                        // Set the border color to indicate that we can make this connection
                        lpu.SetBorderColor(ProcessUnitBorderColor.AcceptingStreams);
                    }
                    else
                    {
                        // If we had a non-null destination then disconnect
                        if (null != m_stream.Destination)
                        {
                            m_stream.Destination.DetachIncomingStream(m_stream);
                            m_stream.Destination = null;
                        }

                        // This means that the connection cannot be made
                        lpu.SetBorderColor(ProcessUnitBorderColor.NotAcceptingStreams);
                        m_stream.DestinationLocation = new Vector(p.X, p.Y);
                    }
                }
            }
        }