Inheritance: Common.Controls.Timeline.Element
Ejemplo n.º 1
0
        private void timelineControl_ContextSelected(object sender, ContextSelectedEventArgs e)
        {
            _contextMenuStrip.Items.Clear();

            Element element          = e.ElementsUnderCursor.FirstOrDefault();
            TimedSequenceElement tse = element as TimedSequenceElement;

            #region Add Effect

            ToolStripMenuItem contextMenuItemAddEffect = new ToolStripMenuItem("Add Effect(s)")
            {
                Image = Resources.effects
            };
            IEnumerable <IEffectModuleDescriptor> effectDesriptors =
                ApplicationServices.GetModuleDescriptors <IEffectModuleInstance>()
                .Cast <IEffectModuleDescriptor>()
                .OrderBy(x => x.EffectGroup)
                .ThenBy(n => n.EffectName);
            EffectGroups group = effectDesriptors.First().EffectGroup;
            foreach (IEffectModuleDescriptor effectDesriptor in effectDesriptors)
            {
                if (effectDesriptor.EffectName == "Nutcracker")
                {
                    continue;                                                             //Remove this when the Nutcracker module is removed
                }
                if (effectDesriptor.EffectGroup != group)
                {
                    ToolStripSeparator seperator = new ToolStripSeparator();
                    contextMenuItemAddEffect.DropDownItems.Add(seperator);
                    group = effectDesriptor.EffectGroup;
                }
                // Add an entry to the menu
                ToolStripMenuItem contextMenuItemEffect = new ToolStripMenuItem(effectDesriptor.EffectName);
                contextMenuItemEffect.Image       = effectDesriptor.GetRepresentativeImage();
                contextMenuItemEffect.Tag         = effectDesriptor.TypeId;
                contextMenuItemEffect.ToolTipText = @"Use Shift key to add multiple effects of the same type.";
                contextMenuItemEffect.Click      += (mySender, myE) =>
                {
                    if (e.Row != null)
                    {
                        //add multiple
                        if (ModifierKeys == Keys.Shift || ModifierKeys == (Keys.Shift | Keys.Control))
                        {
                            AddMultipleEffects(e.GridTime, effectDesriptor.EffectName, (Guid)contextMenuItemEffect.Tag, e.Row);
                        }
                        else                         //add single
                        {
                            AddNewEffectById((Guid)contextMenuItemEffect.Tag, e.Row, e.GridTime, TimeSpan.FromSeconds(2), true);
                        }
                    }
                };

                contextMenuItemAddEffect.DropDownItems.Add(contextMenuItemEffect);
            }

            _contextMenuStrip.Items.Add(contextMenuItemAddEffect);

            #endregion

            #region Layer Section

            ConfigureLayerMenu(e);

            #endregion

            #region Effect Alignment Section

            ToolStripMenuItem contextMenuItemAlignment = new ToolStripMenuItem("Alignment")
            {
                Enabled = TimelineControl.grid.OkToUseAlignmentHelper(TimelineControl.SelectedElements),
                Image   = Resources.alignment
            };
            //Disables the Alignment menu if too many effects are selected in a row.
            if (!contextMenuItemAlignment.Enabled)
            {
                contextMenuItemAlignment.ToolTipText = @"Disabled, maximum selected effects per row is 32.";
            }

            ToolStripMenuItem contextMenuItemAlignStart = new ToolStripMenuItem("Align Start Times")
            {
                ToolTipText = @"Holding shift will align the start times, while holding duration.",
                Image       = Resources.alignStart
            };
            contextMenuItemAlignStart.Click +=
                (mySender, myE) =>
                TimelineControl.grid.AlignElementStartTimes(TimelineControl.SelectedElements, element, ModifierKeys == Keys.Shift);
            contextMenuItemAlignStart.ShortcutKeyDisplayString = @"(Shift)+S";

            ToolStripMenuItem contextMenuItemAlignEnd = new ToolStripMenuItem("Align End Times")
            {
                ToolTipText = @"Holding shift will align the end times, while holding duration.",
                Image       = Resources.alignEnd
            };
            contextMenuItemAlignEnd.Click +=
                (mySender, myE) =>
                TimelineControl.grid.AlignElementEndTimes(TimelineControl.SelectedElements, element, ModifierKeys == Keys.Shift);
            contextMenuItemAlignEnd.ShortcutKeyDisplayString = @"(Shift)+E";

            ToolStripMenuItem contextMenuItemAlignBoth = new ToolStripMenuItem("Align Both Times")
            {
                Image = Resources.alignBoth
            };
            contextMenuItemAlignBoth.Click +=
                (mySender, myE) => TimelineControl.grid.AlignElementStartEndTimes(TimelineControl.SelectedElements, element);
            contextMenuItemAlignBoth.ShortcutKeyDisplayString = @"B";

            ToolStripMenuItem contextMenuItemMatchDuration = new ToolStripMenuItem("Match Duration")
            {
                ToolTipText =
                    @"Holding shift will hold the effects end time and adjust the start time, by default the end time is adjusted.",
                Image = Resources.matchDuration
            };
            contextMenuItemMatchDuration.Click +=
                (mySender, myE) =>
                TimelineControl.grid.AlignElementDurations(TimelineControl.SelectedElements, element, ModifierKeys == Keys.Shift);
            contextMenuItemMatchDuration.ShortcutKeyDisplayString = @"(Shift)";

            ToolStripMenuItem contextMenuItemAlignStartToEnd = new ToolStripMenuItem("Align Start to End")
            {
                ToolTipText =
                    @"Holding shift will hold the effects end time and only adjust the start time, by default the entire effect is moved.",
                Image = Resources.alignStartEnd
            };
            contextMenuItemAlignStartToEnd.Click +=
                (mySender, myE) =>
                TimelineControl.grid.AlignElementStartToEndTimes(TimelineControl.SelectedElements, element,
                                                                 ModifierKeys == Keys.Shift);
            contextMenuItemAlignStartToEnd.ShortcutKeyDisplayString = @"(Shift)";

            ToolStripMenuItem contextMenuItemAlignEndToStart = new ToolStripMenuItem("Align End to Start")
            {
                ToolTipText =
                    @"Holding shift will hold the effects start time and only adjust the end time, by default the entire effect is moved.",
                Image = Resources.alignStartEnd
            };
            contextMenuItemAlignEndToStart.Click +=
                (mySender, myE) =>
                TimelineControl.grid.AlignElementEndToStartTime(TimelineControl.SelectedElements, element,
                                                                ModifierKeys == Keys.Shift);
            contextMenuItemAlignEndToStart.ShortcutKeyDisplayString = @"(Shift)";

            ToolStripMenuItem contextMenuItemDistDialog = new ToolStripMenuItem("Distribute Effects")
            {
                Image = Resources.distribute
            };
            contextMenuItemDistDialog.Click += (mySender, myE) => DistributeSelectedEffects();

            ToolStripMenuItem contextMenuItemAlignCenter = new ToolStripMenuItem("Align Centerpoints")
            {
                Image = Resources.alignCenter
            };
            contextMenuItemAlignCenter.Click +=
                (mySender, myE) => TimelineControl.grid.AlignElementCenters(TimelineControl.SelectedElements, element);

            ToolStripMenuItem contextMenuItemDistributeEqually = new ToolStripMenuItem("Distribute Equally")
            {
                ToolTipText =
                    @"This will stair step the selected elements, starting with the element that has the earlier start mouseLocation on the time line.",
                Image = Resources.distribute
            };
            contextMenuItemDistributeEqually.Click += (mySender, myE) => DistributeSelectedEffectsEqually();

            ToolStripMenuItem contextMenuItemAlignStartToMark = new ToolStripMenuItem("Align Start to nearest mark")
            {
                Image = Resources.alignStartMark
            };
            contextMenuItemAlignStartToMark.Click += (mySender, myE) => AlignEffectsToNearestMarks("Start");
            contextMenuItemAlignStartToMark.ShortcutKeyDisplayString = @"Ctrl+Shift+S";

            ToolStripMenuItem contextMenuItemAlignEndToMark = new ToolStripMenuItem("Align End to nearest mark")
            {
                Image = Resources.alignEndMark
            };
            contextMenuItemAlignEndToMark.Click += (mySender, myE) => AlignEffectsToNearestMarks("End");
            contextMenuItemAlignEndToMark.ShortcutKeyDisplayString = @"Ctrl+Shift+E";

            ToolStripMenuItem contextMenuItemAlignBothToMark = new ToolStripMenuItem("Align Both to nearest mark")
            {
                Image = Resources.alignBothMark
            };
            contextMenuItemAlignBothToMark.Click += (mySender, myE) => AlignEffectsToNearestMarks("Both");
            contextMenuItemAlignBothToMark.ShortcutKeyDisplayString = @"Ctrl+Shift+B";

            _contextMenuStrip.Items.Add(contextMenuItemAlignment);
            contextMenuItemAlignment.DropDown.Items.Add(contextMenuItemAlignStart);
            contextMenuItemAlignment.DropDown.Items.Add(contextMenuItemAlignEnd);
            contextMenuItemAlignment.DropDown.Items.Add(contextMenuItemAlignBoth);
            contextMenuItemAlignment.DropDown.Items.Add(contextMenuItemAlignCenter);
            contextMenuItemAlignment.DropDown.Items.Add(contextMenuItemMatchDuration);
            contextMenuItemAlignment.DropDown.Items.Add(contextMenuItemAlignStartToEnd);
            contextMenuItemAlignment.DropDown.Items.Add(contextMenuItemAlignEndToStart);
            contextMenuItemAlignment.DropDown.Items.Add(contextMenuItemDistributeEqually);
            contextMenuItemAlignment.DropDown.Items.Add(contextMenuItemDistDialog);
            contextMenuItemAlignment.DropDown.Items.Add(contextMenuItemAlignStartToMark);
            contextMenuItemAlignment.DropDown.Items.Add(contextMenuItemAlignEndToMark);
            contextMenuItemAlignment.DropDown.Items.Add(contextMenuItemAlignBothToMark);

            if (TimelineControl.SelectedElements.Count() > 1 || (TimelineControl.SelectedElements.Any() && !element.Selected))
            {
                contextMenuItemDistributeEqually.Enabled = true;
                contextMenuItemDistDialog.Enabled        = true;
                contextMenuItemAlignStart.Enabled        = true;
                contextMenuItemAlignEnd.Enabled          = true;
                contextMenuItemAlignBoth.Enabled         = true;
                contextMenuItemAlignCenter.Enabled       = true;
                contextMenuItemMatchDuration.Enabled     = true;
                contextMenuItemAlignEndToStart.Enabled   = true;
                contextMenuItemAlignStartToEnd.Enabled   = true;
                contextMenuItemAlignment.Enabled         = true;
                contextMenuItemAlignment.ToolTipText     = string.Empty;
            }
            else
            {
                contextMenuItemDistributeEqually.Enabled = false;
                contextMenuItemDistDialog.Enabled        = false;
                contextMenuItemAlignStart.Enabled        = false;
                contextMenuItemAlignEnd.Enabled          = false;
                contextMenuItemAlignBoth.Enabled         = false;
                contextMenuItemAlignCenter.Enabled       = false;
                contextMenuItemMatchDuration.Enabled     = false;
                contextMenuItemAlignEndToStart.Enabled   = false;
                contextMenuItemAlignStartToEnd.Enabled   = false;
                contextMenuItemAlignment.Enabled         = false;
                if (TimelineControl.SelectedElements.Count() == 1)
                {
                    contextMenuItemAlignment.ToolTipText =
                        @"Select more then one effect or ensure you have Marks added to enable the Alignment feature.";
                }
                else
                {
                    contextMenuItemAlignment.ToolTipText = @"Select more then one effect to enable the Alignment feature.";
                }
            }

            contextMenuItemAlignStartToMark.Enabled = false;
            contextMenuItemAlignEndToMark.Enabled   = false;
            contextMenuItemAlignBothToMark.Enabled  = false;

            foreach (MarkCollection mc in _sequence.LabeledMarkCollections)
            {
                if (mc.Marks.Any())
                {
                    contextMenuItemAlignStartToMark.Enabled = true;
                    contextMenuItemAlignEndToMark.Enabled   = true;
                    contextMenuItemAlignBothToMark.Enabled  = true;
                    contextMenuItemAlignment.Enabled        = true;
                    contextMenuItemAlignment.ToolTipText    = string.Empty;
                    break;
                }
            }
            #endregion

            #region Effect Manipulation Section
            if (tse != null)
            {
                ToolStripMenuItem contextMenuItemManipulation     = new ToolStripMenuItem("Manipulation");
                ToolStripMenuItem contextMenuItemManipulateDivide = new ToolStripMenuItem("Divide at cursor")
                {
                    Image = Resources.divide
                };
                contextMenuItemManipulateDivide.Click += (mySender, myE) =>
                {
                    if (TimelineControl.SelectedElements.Any())
                    {
                        TimelineControl.grid.SplitElementsAtTime(
                            TimelineControl.SelectedElements.Where(elem => elem.StartTime <e.GridTime && elem.EndTime> e.GridTime)
                            .ToList(), e.GridTime);
                    }
                    else
                    {
                        TimelineControl.grid.SplitElementsAtTime(new List <Element> {
                            element
                        }, e.GridTime);
                    }
                };

                ToolStripMenuItem contextMenuItemManipulationClone = new ToolStripMenuItem("Clone")
                {
                    Image = Resources.page_copy
                };
                contextMenuItemManipulationClone.Click += (mySender, myE) =>
                {
                    if (TimelineControl.SelectedElements.Any())
                    {
                        CloneElements(TimelineControl.SelectedElements ?? new List <Element> {
                            element
                        });
                    }
                    else
                    {
                        CloneElements(new List <Element> {
                            element
                        });
                    }
                };

                ToolStripMenuItem contextMenuItemManipulationCloneToOther = new ToolStripMenuItem("Clone to selected effects")
                {
                    Image = Resources.copySelect
                };
                contextMenuItemManipulationCloneToOther.Click += (mySender, myE) =>
                {
                    if (TimelineControl.SelectedElements.Any(elem => elem.EffectNode.Effect.TypeId != element.EffectNode.Effect.TypeId))
                    {
                        //messageBox Arguments are (Text, Title, No Button Visible, Cancel Button Visible)
                        MessageBoxForm.msgIcon = SystemIcons.Warning;                         //this is used if you want to add a system icon to the message form.
                        var messageBox = new MessageBoxForm(string.Format(
                                                                "Some of the selected effects are not of the same type, only effects of {0} type will be modified.",
                                                                element.EffectNode.Effect.EffectName), @"Multiple type effect selected", false, true);
                        messageBox.ShowDialog();
                        if (messageBox.DialogResult == DialogResult.Cancel)
                        {
                            return;
                        }
                    }

                    foreach (
                        Element elem in
                        TimelineControl.SelectedElements.Where(elem => elem != element)
                        .Where(elem => elem.EffectNode.Effect.TypeId == element.EffectNode.Effect.TypeId))
                    {
                        elem.EffectNode.Effect.ParameterValues = element.EffectNode.Effect.ParameterValues;
                        elem.RenderElement();
                    }
                };
                contextMenuItemManipulationCloneToOther.Enabled = (TimelineControl.SelectedElements.Count() > 2);

                _contextMenuStrip.Items.Add(contextMenuItemManipulation);
                contextMenuItemManipulation.DropDown.Items.Add(contextMenuItemManipulateDivide);
                contextMenuItemManipulation.DropDown.Items.Add(contextMenuItemManipulationClone);
                contextMenuItemManipulation.DropDown.Items.Add(contextMenuItemManipulationCloneToOther);

                ToolStripMenuItem contextMenuItemEditTime = new ToolStripMenuItem("Edit Time")
                {
                    Image = Resources.clock_edit
                };
                contextMenuItemEditTime.Click += (mySender, myE) =>
                {
                    EffectTimeEditor editor = new EffectTimeEditor(tse.EffectNode.StartTime, tse.EffectNode.TimeSpan, SequenceLength);
                    if (editor.ShowDialog(this) != DialogResult.OK)
                    {
                        return;
                    }

                    if (TimelineControl.SelectedElements.Any())
                    {
                        var elementsToMove = TimelineControl.SelectedElements.ToDictionary(elem => elem,
                                                                                           elem => new Tuple <TimeSpan, TimeSpan>(editor.Start, editor.Start + editor.Duration));
                        TimelineControl.grid.MoveResizeElements(elementsToMove);
                    }
                    else
                    {
                        TimelineControl.grid.MoveResizeElement(element, editor.Start, editor.Duration);
                    }
                };
                //Why do we set .Tag ?
                contextMenuItemEditTime.Tag     = tse;
                contextMenuItemEditTime.Enabled = TimelineControl.grid.OkToUseAlignmentHelper(TimelineControl.SelectedElements);
                if (!contextMenuItemEditTime.Enabled)
                {
                    contextMenuItemEditTime.ToolTipText = @"Disabled, maximum selected effects per row is 32.";
                }
                _contextMenuStrip.Items.Add(contextMenuItemEditTime);
            }
            #endregion

            #region Cut Copy Paste Section

            _contextMenuStrip.Items.Add("-");

            ToolStripMenuItem contextMenuItemCopy = new ToolStripMenuItem("Copy", null, toolStripMenuItem_Copy_Click)
            {
                ShortcutKeyDisplayString = @"Ctrl+C",
                Image = Resources.page_copy
            };
            ToolStripMenuItem contextMenuItemCut = new ToolStripMenuItem("Cut", null, toolStripMenuItem_Cut_Click)
            {
                ShortcutKeyDisplayString = @"Ctrl+X",
                Image = Resources.cut
            };
            contextMenuItemCopy.Enabled = contextMenuItemCut.Enabled = TimelineControl.SelectedElements.Any();
            ToolStripMenuItem contextMenuItemPaste = new ToolStripMenuItem("Paste", null, toolStripMenuItem_Paste_Click)
            {
                ShortcutKeyDisplayString = @"Ctrl+V", Image = Resources.page_white_paste,
                Enabled = ClipboardHasData()
            };

            _contextMenuStrip.Items.AddRange(new ToolStripItem[] { contextMenuItemCut, contextMenuItemCopy, contextMenuItemPaste });

            if (TimelineControl.SelectedElements.Any())
            {
                //Add Delete/Collections
                ToolStripMenuItem contextMenuItemDelete = new ToolStripMenuItem("Delete Effect(s)", null,
                                                                                toolStripMenuItem_deleteElements_Click)
                {
                    ShortcutKeyDisplayString = @"Del", Image = Resources.delete
                };
                _contextMenuStrip.Items.Add(contextMenuItemDelete);
                AddContextCollectionsMenu();
            }

            #endregion

            #region Mark Section

            ToolStripMenuItem contextMenuItemAddMark = new ToolStripMenuItem("Add Marks to Effects")
            {
                Image = Resources.marks
            };
            contextMenuItemAddMark.Click += (mySender, myE) => AddMarksToSelectedEffects();
            _contextMenuStrip.Items.Add(contextMenuItemAddMark);

            #endregion

            e.AutomaticallyHandleSelection = false;
            _contextMenuStrip.Show(MousePosition);
        }
Ejemplo n.º 2
0
        public static void Rasterize(TimedSequenceElement tsElement, Graphics g, TimeSpan visibleStartOffset, TimeSpan visibleEndOffset, int overallWidth)
        {
            //var sw = new System.Diagnostics.Stopwatch(); sw.Start();
            IEffectModuleInstance effect = tsElement.EffectNode.Effect;

            if (effect.ForceGenerateVisualRepresentation || Vixen.Common.Graphics.DisableEffectsEditorRendering)
            {
                var startX = (int)((visibleStartOffset.Ticks / (float)tsElement.Duration.Ticks) * overallWidth);
                effect.GenerateVisualRepresentation(g, new Rectangle(-startX, 0, overallWidth, (int)g.VisibleClipBounds.Height));
            }
            else
            {
                double width  = g.VisibleClipBounds.Width;
                double height = g.VisibleClipBounds.Height;

                // As recommended by R#
                if (Math.Abs(width - 0) < double.Epsilon || Math.Abs(height - 0) < double.Epsilon)
                {
                    return;
                }

                // limit the number of 'rows' rasterized
                int tmpsiz = (int)(height / 2) + 1;

                EffectIntents effectIntents = effect.Render();

                int count = effectIntents.Count;

                int skipCount = count > tmpsiz ? count / tmpsiz: 1;

                double heightPerElement = height / (count / skipCount);

                double y   = 0;
                int    ctr = 0;

                var elements = effect.TargetNodes.GetElements();

                foreach (var element in elements)
                {
                    if (ctr++ % skipCount != 0)
                    {
                        continue;
                    }

                    IntentNodeCollection elementIntents = effectIntents.GetIntentNodesForElement(element.Id);                    //effectIntents.GetIntentNodesForElement(element.Id);
                    if (elementIntents != null && elementIntents.Count > 0)
                    {
                        //Determine if we have parallel intents used on this element for this effect.
                        var stack = new List <List <IIntentNode> > {
                            new List <IIntentNode> {
                                elementIntents[0]
                            }
                        };
                        for (int i = 1; i < elementIntents.Count; i++)
                        {
                            bool add = true;
                            foreach (List <IIntentNode> t in stack)
                            {
                                if (elementIntents[i].StartTime >= t.Last().EndTime)
                                {
                                    t.Add(elementIntents[i]);
                                    add = false;
                                    break;
                                }
                            }
                            if (add)
                            {
                                stack.Add(new List <IIntentNode> {
                                    elementIntents[i]
                                });
                            }
                        }
                        int skip = 0;
                        //Check for base or minimum level intent.
                        if (stack.Count > 1 && stack[0].Count == 1 && stack[0][0].TimeSpan.Equals(effect.TimeSpan) && stack[1][0].TimeSpan != effect.TimeSpan)
                        {
                            //this is most likely a underlying base intent like chase, spin and twinkle use to provide a minimum value
                            //so render it full size as it is usually a lower intensity and the pulses can be drawn over the top and look nice.

                            intentRasterizer.Rasterize(stack[0][0].Intent,
                                                       new RectangleF(0, (float)y, (float)width,
                                                                      (float)heightPerElement), g, visibleStartOffset, stack[0][0].TimeSpan);
                            skip = 1;
                        }

                        float h          = (float)heightPerElement / (stack.Count - skip);
                        int   stackCount = 0;
                        //Now we have a good idea what our element should look like, lets draw it up
                        foreach (List <IIntentNode> intentNodes in stack.Skip(skip))
                        {
                            foreach (IntentNode elementIntentNode in intentNodes)
                            {
                                if (elementIntentNode == null)
                                {
                                    Logging.Error("Error: elementIntentNode was null when Rasterizing an effect (ID: " + effect.InstanceId + ")");
                                    continue;
                                }

                                if (elementIntentNode.EndTime < visibleStartOffset || elementIntentNode.StartTime > visibleEndOffset)
                                {
                                    continue;
                                }

                                TimeSpan visibleIntentStart = elementIntentNode.StartTime < visibleStartOffset
                                                                        ? visibleStartOffset - elementIntentNode.StartTime
                                                                        : TimeSpan.Zero;

                                TimeSpan visibleIntentEnd = elementIntentNode.EndTime > visibleEndOffset
                                                                        ? visibleEndOffset - elementIntentNode.StartTime
                                                                        : elementIntentNode.TimeSpan;

                                double startPixelX = overallWidth * _GetPercentage(elementIntentNode.StartTime, effect.TimeSpan);
                                double widthPixelX = overallWidth * _GetPercentage(elementIntentNode.TimeSpan, effect.TimeSpan);

                                widthPixelX = widthPixelX * ((visibleIntentEnd.TotalMilliseconds - visibleIntentStart.TotalMilliseconds) / elementIntentNode.TimeSpan.TotalMilliseconds);
                                if (visibleIntentStart == TimeSpan.Zero)
                                {
                                    startPixelX -= overallWidth * _GetPercentage(visibleStartOffset, effect.TimeSpan);
                                }
                                else
                                {
                                    startPixelX = 0;
                                }


                                intentRasterizer.Rasterize(elementIntentNode.Intent,
                                                           new RectangleF((float)startPixelX, (float)y + h * stackCount, (float)widthPixelX,
                                                                          h), g, visibleIntentStart, visibleIntentEnd);
                            }

                            stackCount++;
                        }
                    }

                    y += heightPerElement;
                }
                //long tRast = sw.ElapsedMilliseconds - tRend;
                //if( tRast > 10)
                //	Logging.Debug(" oh: {0}, rend: {1}, rast: {2}, eff: {3}, node:{4}", tOh, tRend, tRast, effect.EffectName, effect.TargetNodes[0].Name);
            }
        }
Ejemplo n.º 3
0
 private void EditElement(TimedSequenceElement element)
 {
     EditElements(new[] { element });
 }
Ejemplo n.º 4
0
 private TimedSequenceElement setupNewElementFromNode(EffectNode node)
 {
     TimedSequenceElement element = new TimedSequenceElement(node);
     element.ContentChanged += ElementContentChangedHandler;
     element.TimeChanged += ElementTimeChangedHandler;
     return element;
 }
        /// <summary>
        /// Populates the TimelineControl grid with a new TimedSequenceElement for the given EffectNode.
        /// Will add a single TimedSequenceElement to in each row that each targeted channel of
        /// the EffectNode references. It will also add callbacks to event handlers for the element.
        /// </summary>
        /// <param name="node">The EffectNode to make element(s) in the grid for.</param>
        private TimedSequenceElement addElementForEffectNode(EffectNode node)
        {
            TimedSequenceElement element = new TimedSequenceElement(node);
            element.ContentChanged += ElementContentChangedHandler;
            element.TimeChanged += ElementTimeChangedHandler;

            // for the effect, make a single element and add it to every row that represents its target channels
            foreach(ChannelNode target in node.Effect.TargetNodes) {
                if(_channelNodeToRows.ContainsKey(target)) {
                    // Add the element to each row that represents the channel this command is in.
                    foreach(Row row in _channelNodeToRows[target]) {
                        if(!_effectNodeToElement.ContainsKey(node))
                            _effectNodeToElement[node] = element;
                        //else
                        //    VixenSystem.Logging.Debug("TimedSequenceEditor: Making a new element, but the map already has one!");

                        row.AddElement(element);
                    }
                } else {
                    // we don't have a row for the channel this effect is referencing; most likely, the row has
                    // been deleted, or we're opening someone else's sequence, etc. Big fat TODO: here for that, then.
                    // dunno what we want to do: prompt to add new channels for them? map them to others? etc.
                    string message = "No Timeline.Row is associated with a target ChannelNode for this EffectNode. It now exists in the sequence, but not in the GUI.";
                    MessageBox.Show(message);
                    VixenSystem.Logging.Error(message);
                }
            }

            return element;
        }
 // copy ctor
 public TimedSequenceElement(TimedSequenceElement other)
     : base(other)
 {
     //TODO: This needs to be a deep-copy of the effect node.
     EffectNode = other.EffectNode;
 }
Ejemplo n.º 7
0
		// copy ctor
		public TimedSequenceElement(TimedSequenceElement other)
			: base(other)
		{
			//TODO: This needs to be a deep-copy of the effect node.
			EffectNode = other.EffectNode;
		}
Ejemplo n.º 8
0
		public static void Rasterize(TimedSequenceElement tsElement, Graphics g, TimeSpan visibleStartOffset, TimeSpan visibleEndOffset, int overallWidth)
		{
			//var sw = new System.Diagnostics.Stopwatch(); sw.Start();
			IEffectModuleInstance effect = tsElement.EffectNode.Effect;
			if (effect.ForceGenerateVisualRepresentation || Vixen.Common.Graphics.DisableEffectsEditorRendering) {
				effect.GenerateVisualRepresentation(g, new Rectangle(0, 0, (int)g.VisibleClipBounds.Width, (int)g.VisibleClipBounds.Height));
			} else {
				double width = g.VisibleClipBounds.Width;
				double height = g.VisibleClipBounds.Height;

				// As recommended by R#
				if (Math.Abs(width - 0) < double.Epsilon || Math.Abs(height - 0) < double.Epsilon)
					return;

				IEnumerable<Element> elements = effect.TargetNodes.GetElements();

				// limit the number of 'rows' rasterized
				int tmpsiz = (int)(height / 2) + 1;
				if (elements.Count() > tmpsiz)
				{
					int skip = elements.Count() / tmpsiz;
					elements = elements.Where((element, index) => (index + 1) % skip == 0);
					}

				double heightPerElement = height / elements.Count();

				//long tOh = sw.ElapsedMilliseconds;
				EffectIntents effectIntents = effect.Render();

				//long tRend = sw.ElapsedMilliseconds - tOh;

				

				double y = 0;
				foreach (Element element in elements)
				{
					//Getting exception on null elements here... A simple check to look for these null values and ignore them
					if (element != null) {
						IntentNodeCollection elementIntents = effectIntents.GetIntentNodesForElement(element.Id);
						if (elementIntents != null && elementIntents.Count > 0)
						{
							//Determine if we have parallel intents used on this element for this effect.
							var stack = new List<List<IIntentNode>> {new List<IIntentNode> {elementIntents[0]}};
							for (int i = 1; i < elementIntents.Count; i++)
							{
								bool add = true;
								foreach (List<IIntentNode> t in stack)
								{
									if (elementIntents[i].StartTime >= t.Last().EndTime)
									{
										t.Add(elementIntents[i]);
										add = false;
										break;
									}
								}
								if (add) stack.Add(new List<IIntentNode> { elementIntents[i] });
							}
							int skip = 0;
							//Check for base or minimum level intent.
							if (stack.Count > 1 && stack[0].Count == 1 && stack[0][0].TimeSpan.Equals(effect.TimeSpan) && stack[1][0].TimeSpan != effect.TimeSpan)
							{
								//this is most likely a underlying base intent like chase, spin and twinkle use to provide a minimum value
								//so render it full size as it is usually a lower intensity and the pulses can be drawn over the top and look nice.
								
								intentRasterizer.Rasterize(stack[0][0].Intent,
														   new RectangleF(0, (float)y, (float)width,
																		  (float)heightPerElement), g, visibleStartOffset,stack[0][0].TimeSpan);
								skip=1;
							}

							float h = (float)heightPerElement / (stack.Count-skip);
							int stackCount = 0;
							//Now we have a good idea what our element should look like, lets draw it up
							foreach (List<IIntentNode> intentNodes in stack.Skip(skip))
							{
								foreach (IntentNode elementIntentNode in intentNodes)
								{
									if (elementIntentNode == null)
									{
										Logging.Error("Error: elementIntentNode was null when Rasterizing an effect (ID: " + effect.InstanceId + ")");
										continue;
									}
									
									if(elementIntentNode.EndTime<visibleStartOffset || elementIntentNode.StartTime>visibleEndOffset) continue;

									TimeSpan visibleIntentStart = elementIntentNode.StartTime < visibleStartOffset
										? visibleStartOffset - elementIntentNode.StartTime
										: TimeSpan.Zero;

									TimeSpan visibleIntentEnd = elementIntentNode.EndTime > visibleEndOffset
										? visibleEndOffset - elementIntentNode.StartTime
										: elementIntentNode.TimeSpan;

									double startPixelX = overallWidth * _GetPercentage(elementIntentNode.StartTime, effect.TimeSpan);
									double widthPixelX = overallWidth * _GetPercentage(elementIntentNode.TimeSpan, effect.TimeSpan);

									widthPixelX = widthPixelX * ((visibleIntentEnd.TotalMilliseconds - visibleIntentStart.TotalMilliseconds) / elementIntentNode.TimeSpan.TotalMilliseconds);
									if (visibleIntentStart == TimeSpan.Zero)
									{
										startPixelX -= overallWidth*_GetPercentage(visibleStartOffset, effect.TimeSpan);
									}
									else
									{
										startPixelX = 0;
									}
									

									intentRasterizer.Rasterize(elementIntentNode.Intent,
															   new RectangleF((float)startPixelX, (float)y+h*stackCount , (float)widthPixelX,
																			  h), g, visibleIntentStart , visibleIntentEnd);
								}

								stackCount++;
							}	
						}
					}
					y += heightPerElement;
				}
				//long tRast = sw.ElapsedMilliseconds - tRend;
				//if( tRast > 10)
				//	Logging.Debug(" oh: {0}, rend: {1}, rast: {2}, eff: {3}, node:{4}", tOh, tRend, tRast, effect.EffectName, effect.TargetNodes[0].Name);
			}
		}
        private void EditElement(TimedSequenceElement element)
        {
            if (element == null)
                return;

            using (TimedSequenceEditorEffectEditor editor = new TimedSequenceEditorEffectEditor(element.EffectNode)) {
                DialogResult result = editor.ShowDialog();
                if (result == System.Windows.Forms.DialogResult.OK)
                    sequenceModified();
            }
        }