示例#1
0
        public bool IntersectsAnyPU(MathCore.LineSegment segment, params AbstractProcessUnit[] exclusionList)
        {
            foreach (UIElement uie in Children)
            {
                ProcessUnitControl puc = uie as ProcessUnitControl;
                if (null == puc)
                {
                    // Not a process unit control
                    continue;
                }

                if (null != exclusionList)
                {
                    bool goNext = false;
                    foreach (AbstractProcessUnit excludeMe in exclusionList)
                    {
                        // See if we want to exclude this one
                        if (object.ReferenceEquals(puc.ProcessUnit, excludeMe))
                        {
                            goNext = true;
                            break;
                        }
                    }

                    if (goNext)
                    {
                        continue;
                    }
                }

                // Build a rectangle for the control
                Point pt = new Point(
                    (double)puc.GetValue(Canvas.LeftProperty),
                    (double)puc.GetValue(Canvas.TopProperty));
                MathCore.Rectangle r;
                if (double.IsNaN(puc.Width) || double.IsNaN(puc.Height) ||
                    0.0 == puc.Width || 0.0 == puc.Height)
                {
                    // Silverlight UI stuff can be funky so we have a condition to use
                    // hard coded dimensions as opposed to getting them from the control
                    r = MathCore.Rectangle.CreateFromCanvasRect(pt, 40.0, 40.0);
                }
                else
                {
                    r = MathCore.Rectangle.CreateFromCanvasRect(pt, puc.Width, puc.Height);
                }

                if (r.GetIntersections(segment).Length > 0)
                {
                    return(true);
                }
            }

            return(false);
        }
        public SubprocessChooserWindow(ProcessUnitControl lpu, Workspace workspace)
        {
            InitializeComponent();

            // Store a reference to the process unit and workspace
            m_lpu       = lpu;
            m_workspace = workspace;

            if (null != lpu)
            {
                // Initialize the color options
                bool didFirst = false;
                OptionsStackPanel.Children.Clear();
                foreach (Core.NamedColor nc in Core.NamedColors.All)
                {
                    Border b = new Border();
                    b.BorderBrush     = new SolidColorBrush(Colors.LightGray);
                    b.CornerRadius    = new CornerRadius(3.0);
                    b.BorderThickness = new Thickness(2.0);
                    b.Background      = new SolidColorBrush(nc.Color);
                    if (didFirst)
                    {
                        b.Margin = new Thickness(3.0, 0.0, 3.0, 3.0);
                    }
                    else
                    {
                        b.Margin = new Thickness(3.0);
                        didFirst = true;
                    }

                    // Create the radio button to put in the border
                    RadioButton rb = new RadioButton();
                    rb.GroupName = "A";
                    rb.Content   = nc.Name;
                    rb.Tag       = nc;
                    b.Child      = rb;
                    // Setup check-change event
                    rb.Checked += new RoutedEventHandler(rb_Checked);

                    // If the color matches the existing subprocess then check it
                    if (nc.Color.Equals(lpu.Subprocess))
                    {
                        rb.IsChecked = true;
                    }

                    // Add it to the stack panel
                    OptionsStackPanel.Children.Add(b);
                }
            }
        }
        public static ProcessUnitControl CreateOnCanvas(DrawingCanvas canvas,
                                                        AbstractProcessUnit processUnit)
        {
            ProcessUnitControl pu = new ProcessUnitControl(canvas, processUnit);

            canvas.AddNewChild(pu);

            // Set the initial location
            pu.SetValue(Canvas.LeftProperty, processUnit.Location.X - pu.Width / 2.0);
            pu.SetValue(Canvas.TopProperty, processUnit.Location.Y - pu.Height / 2.0);

            // Make sure we have the right z-order
            pu.SetValue(Canvas.ZIndexProperty, 1);

            return(pu);
        }
示例#4
0
        public ProcessUnitControl GetProcessUnitControl(AbstractProcessUnit unit)
        {
            foreach (UIElement uie in Children)
            {
                if (!(uie is ProcessUnitControl))
                {
                    continue;
                }

                ProcessUnitControl pu = uie as ProcessUnitControl;
                if (object.ReferenceEquals(pu.ProcessUnit, unit))
                {
                    return(pu);
                }
            }

            return(null);
        }
示例#5
0
        /// <summary>
        /// Callback for when the collection of process units in the workspace changes. We must update
        /// the UI to match the workspace.
        /// </summary>
        private void ProcessUnits_CollectionChanged(object sender, EventArgs e)
        {
            // First go through all process unit controls on the canvas and remove ones that are
            // no longer in the workspace.
            List <AbstractProcessUnit> unitsThatHaveControls =
                new List <AbstractProcessUnit>();

            for (int i = 0; i < Children.Count; i++)
            {
                ProcessUnitControl lpu = Children[i] as ProcessUnitControl;
                if (null == lpu)
                {
                    continue;
                }

                // Add it to a list that we'll use later
                unitsThatHaveControls.Add(lpu.ProcessUnit);

                if (!m_workspace.ProcessUnits.Contains(lpu.ProcessUnit))
                {
                    // Tell the process unit to remove itself. It will also remove any
                    // controls used to represent comments.
                    lpu.RemoveSelfFromCanvas(this);

                    // Reset the index since a bunch of child controls could have potentially just
                    // been removed
                    i = -1;
                }
            }

            // Now go through and add any process units that are missing
            foreach (AbstractProcessUnit apu in m_workspace.ProcessUnits)
            {
                if (!unitsThatHaveControls.Contains(apu))
                {
                    // Create the process unit. The static method will create it, put it on
                    // the canvas, and take care of all comment sticky notes as well.
                    ProcessUnitControl lpuNew = ProcessUnitControl.CreateOnCanvas(this, apu);
                }
            }
        }
示例#6
0
        /// <summary>
        /// Refreshes the control palette with appropriate controls based on the difficulty setting. This
        /// must be called each time the user changes the difficulty setting in the application.
        /// </summary>
        public void RefreshPalette(OptionDifficultySetting setting)
        {
            // Show or hide the heat stream button based on the setting
            if ((new HeatStream(-1)).IsAvailableWithDifficulty(setting))
            {
                HeatStreamButton.Visibility = System.Windows.Visibility.Visible;
            }
            else
            {
                HeatStreamButton.Visibility = System.Windows.Visibility.Collapsed;
            }

            // Now we use reflection to create the process unit buttons

            // First clear the content in the process unit stack panel
            ProcessUnitsPanel.Children.Clear();

            // We will create potentially multiple stack panels for rows of buttons
            StackPanel spPUs = null;

            // Keep track of how many buttons we create
            int puBtns = 0;

            // Use reflection to find appropriate process units and streams for the palette
            Assembly a = typeof(Logic.AbstractProcessUnit).Assembly;

            foreach (Type t in a.GetTypes())
            {
                // Ignore abstract types
                if (t.IsAbstract)
                {
                    continue;
                }

                // We only are interested in types that inherit from AbstractProcessUnit
                if (t.IsSubclassOf(typeof(AbstractProcessUnit)) && !t.IsAbstract)
                {
                    // We've found a potential process unit, but we need to make sure that
                    // it can be created under the specified difficulty setting
                    AbstractProcessUnit unit =
                        Activator.CreateInstance(t, (int)-1) as AbstractProcessUnit;
                    if (unit.IsAvailableWithDifficulty(setting))
                    {
                        if (0 == (puBtns % m_buttonsPerRow))
                        {
                            // Create a new row
                            spPUs             = new StackPanel();
                            spPUs.Orientation = Orientation.Horizontal;

                            // Add the first button to it
                            spPUs.Children.Add(CreateButton(
                                                   ProcessUnitControl.GetIconSource(t), unit.Description, t));

                            ProcessUnitsPanel.Children.Add(spPUs);
                        }
                        else
                        {
                            spPUs.Children.Add(CreateButton(
                                                   ProcessUnitControl.GetIconSource(t), unit.Description, t));
                        }

                        puBtns++;
                    }
                }
            }
        }
示例#7
0
        public static MathCore.Vector ComputeNewCommentNoteLocation(DrawingCanvas canvas, object parentControl,
                                                                    double controlWidth = 100.0, double controlHeight = 100.0)
        {
            // First resolve the "center point" of the parent object. Also get a reference to the collection
            // of comments.
            Point location;
            IList <StickyNote> comments;
            ProcessUnitControl lpu = parentControl as ProcessUnitControl;

            PFD.Streams.StreamControl stream = parentControl as PFD.Streams.StreamControl;
            if (null != lpu)
            {
                location = lpu.Location;
                comments = lpu.ProcessUnit.Comments;
            }
            else if (null != stream)
            {
                location = stream.StreamLineMidpoint;
                comments = stream.Stream.Comments;
            }
            else
            {
                throw new ArgumentException(
                          "Parent control for a comment sticky note must be a stream or process unit " +
                          "control.\n Method: ComputeNewCommentNoteLocation");
            }

            // Get a reference to the workspace. We will look at other sticky notes in this workspace to
            // try to avoid direct overlap.
            Workspace ws = canvas.GetWorkspace();

            MathCore.Vector loc;
            int             attempts = 0;

            while (true)
            {
                // Compute a location
                double radius = 150.0;
                double angle  = (double)(comments.Count % 6) * 60.0 / 180.0 * Math.PI;
                loc = new MathCore.Vector(
                    location.X + radius * Math.Cos(angle),
                    location.Y + radius * Math.Sin(angle));

                // Make sure this location wouldn't make the control go off the canvas
                if (loc.X - (controlWidth / 2.0) < 0.0 ||
                    loc.Y - (controlHeight / 2.0) < 0.0)
                {
                    attempts++;
                }
                else if ((null != stream && stream.Stream.ContainsCommentWithLocation(loc.X, loc.Y)) ||
                         (null != lpu && lpu.ProcessUnit.ContainsCommentWithLocation(loc.X, loc.Y)))
                {
                    attempts++;
                }
                else
                {
                    // This means the location is ok and we can return it
                    return(loc);
                }

                // Try cascading if radial position failed
                if (attempts > 6)
                {
                    // Reset attempts because we're about to try another method of positioning
                    attempts = 0;

                    double offset = 10.0;
                    while (true)
                    {
                        loc.X = location.X + radius + offset;
                        loc.Y = location.Y + offset;

                        // Make sure this location wouldn't make the control go off the canvas
                        if (loc.X - (controlWidth / 2.0) < 0.0 ||
                            loc.Y - (controlHeight / 2.0) < 0.0)
                        {
                            attempts++;
                        }
                        else if ((null != stream && stream.Stream.ContainsCommentWithLocation(loc.X, loc.Y)) ||
                                 (null != lpu && lpu.ProcessUnit.ContainsCommentWithLocation(loc.X, loc.Y)))
                        {
                            attempts++;
                        }
                        else
                        {
                            // This means the location is ok and we can return it
                            return(loc);
                        }

                        attempts++;
                        if (attempts > 50)
                        {
                            // Just give up and choose an arbitrary position
                            return(new MathCore.Vector(location.X + radius, location.Y));
                        }

                        // Increase the offset for the next attempt
                        offset += 10.0;
                    }
                }
            }
        }
        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);
                }
            }
        }