/// <summary> /// The <see cref="Control.Click"/> event handler for the /// <see cref="Button"/> <see cref="btnPreviewSlideshow"/>. /// Starts a <see cref="PresenterModule"/> with the given slides. /// </summary> /// <param name="sender">Source of the event.</param> /// <param name="e">An empty <see cref="EventArgs"/></param> private void BtnPreviewSlideshowClick(object sender, EventArgs e) { if (!RecordModule.CheckForCorrectPresentationScreenResolution(PresentationScreen.GetPresentationResolution())) { return; } PresenterModule objPresenter = new PresenterModule(); // Create a newly randomized trial list. TrialCollection trials = this.slideshow.GetRandomizedTrials(); // Create a hardcopy of the trials. TrialCollection copyOfTrials = (TrialCollection)trials.Clone(); // Set slide list of presenter objPresenter.TrialList = copyOfTrials; // Show presenter form, that starts presentation. objPresenter.ShowDialog(); // Update slideshow pictures of newly created trials Document.ActiveDocument.ExperimentSettings.SlideShow.UpdateExperimentPathOfResources(Document.ActiveDocument.ExperimentSettings.SlideResourcesPath); }
/// <summary> /// This method initializes the presentation thread /// and raises an error if no slides are defined. /// </summary> /// <returns> /// <strong>True</strong>, if presentation could be started, /// otherwise <strong>false</strong>. /// </returns> private bool StartPresentation() { if (CheckForModifiedSlideshow()) { return false; } if (!CheckForCorrectPresentationScreenResolution(PresentationScreen.GetPresentationResolution())) { return false; } this.InitializeScreenCapture(); this.lblRecordedTime.Text = "00:00:00"; this.xPosition = PresentationScreen.GetPresentationBounds().X; this.yPosition = PresentationScreen.GetPresentationBounds().Y; // Reread slideshow Slideshow slideshow = Document.ActiveDocument.ExperimentSettings.SlideShow; if (slideshow != null && slideshow.Slides.Count > 0) { ((MainForm)this.MdiParent).StatusLabel.Text = "Recording..."; // Create a newly randomized trial list. this.trials = slideshow.GetRandomizedTrials(); // Dispose webcam to be recreated in presentation thread // with old preview window this.webcamPreview.DisposeDxCapture(); // CaptureMode for usercam var mode = CaptureMode.None; string userVideoFilename = Path.Combine( Document.ActiveDocument.ExperimentSettings.ThumbsPath, Document.ActiveDocument.SelectionState.SubjectName + ".avi"); if (this.btnUsercam.Checked) { mode |= CaptureMode.VideoPreview; } if (this.chbRecordAudio.Checked) { mode |= CaptureMode.Audio; // Only set filname when recording is choosen this.webcamPreview.Properties.Filename = userVideoFilename; } if (this.chbRecordVideo.Checked) { mode |= CaptureMode.Video; // Only set filname when recording is choosen this.webcamPreview.Properties.Filename = userVideoFilename; } this.webcamPreview.Properties.CaptureMode = mode; var threadParameters = new List<object> { this.trials, this.generalTrigger, this.btnTrigger.Checked, this.screenCaptureProperties }; if (this.btnUsercam.Checked) { threadParameters.Add(this.webcamPreview.Properties); } // Start recording this.currentTrialVideoStartTime = 0; this.currentTracker.Record(); var stopwatch = new Stopwatch(); stopwatch.Start(); // Wait for first sample to be received while (this.GetCurrentTime() < 0) { Application.DoEvents(); if (stopwatch.ElapsedMilliseconds > 5000) { string message = "Could not start recording, because we received no gaze samples from the tracking device during 5 seconds." + Environment.NewLine + "Please be sure your tracker is up and running and collecting gaze data, resp. is correct calibrated."; InformationDialog.Show("No incoming tracker data", message, false, MessageBoxIcon.Warning); stopwatch.Stop(); return false; } } stopwatch.Stop(); // Set recording flag this.recordingBusy = true; // Initialize presentation thread this.presentationThread = new Thread(this.PresentationThreadDoWork); this.presentationThread.SetApartmentState(ApartmentState.STA); this.presentationThread.Start(threadParameters); // Start presentation has ended timer this.tmrWaitForPresentationEnd.Start(); // Update live viewer and slide counter this.NewSlideAvailable(); } else { string message = "Could not start presentation, because there are no slides defined." + Environment.NewLine + "Please use the Slides Design Interface"; InformationDialog.Show("No slides available", message, false, MessageBoxIcon.Warning); return false; } return true; }
/// <summary> /// This method iterates recursively through the tree to return only the trials /// contained in the tree. /// </summary> /// <param name="trials">Ref. The output <see cref="TrialCollection"/> of trials.</param> /// <param name="node">The <see cref="TreeNode"/> to parse.</param> private void ParseNodeForTrials(ref TrialCollection trials, TreeNode node) { Trial trial = null; // Add trial if this node is marked to be a trial if (node.Tag != null && node.Tag.ToString() == "Trial") { trial = new Trial(node.Text, Slideshow.GetIdOfNode(node)); trials.Add(trial); } foreach (TreeNode subNode in node.Nodes) { SlideshowTreeNode subSlideNode = subNode as SlideshowTreeNode; Slide slide = subSlideNode.Slide; if (slide != null) { // By default use a new trial for each slide trial = new Trial(subNode.Text, Slideshow.GetIdOfNode(subNode)); // If parent is already marked as trial use this // instead. if (subNode.Parent != null && subNode.Parent.Tag != null && subNode.Parent.Tag.ToString() == "Trial") { trial = trials[trials.Count - 1]; } // Add slide to correct trial trial.Add(slide); } // Iterate through the tree. this.ParseNodeForTrials(ref trials, subNode); // If a trial was found, add it to the list. if (trial != null && !trials.Contains(trial)) { trials.Add(trial); } } }
/// <summary> /// This method returns a <see cref="TrialCollection"/> of all trials contained /// in this slideshow. /// </summary> /// <returns>A <see cref="TrialCollection"/> of all trials contained /// in this slideshow.</returns> private TrialCollection GetTrials() { TrialCollection trials = new TrialCollection(); this.ParseNodeForTrials(ref trials, this); return trials; }
/// <summary> /// This method iterates recursively through the tree to return a /// shuffled trial collection using the <see cref="CustomShuffling"/>. /// </summary> /// <param name="node">The <see cref="TreeNode"/> to parse.</param> /// <returns>A <see cref="List{Object}"/> with the shuffled trials separated in /// shuffle groups.</returns> private List<object> ParseNodeForCustomShuffledTrials(TreeNode node) { // Get sections var sections = new List<object>(); foreach (TreeNode subNode in node.Nodes) { var nodeCollection = this.ParseNodeForRandomizedTrials(subNode); var trials = new TrialCollection(); this.GetTrialsFromObjectCollection(nodeCollection, ref trials); this.InsertPreSlideTrials(ref trials); // Convert to List<object> var trialsObjectCollection = new List<object>(); trialsObjectCollection.AddRange(trials.ToArray()); // Shuffle sections if applicable if (this.shuffling.ShuffleSectionItems) { trialsObjectCollection = (List<object>)CollectionUtils<object>.Shuffle(trialsObjectCollection); } sections.Add(trialsObjectCollection); } // Create groups var groups = new List<object>(); int index = 0; var finish = false; do { var group = new List<object>(); for (int i = 0; i < sections.Count; i++) { var coll = (List<object>)sections[i]; if (coll.Count == index) { finish = true; break; } for (int j = 0; j < this.shuffling.NumItemsOfSectionInGroup; j++) { group.Add(coll[index + j]); } } if (this.shuffling.ShuffleGroupItems) { group = (List<object>)CollectionUtils<object>.Shuffle(group); } if (!finish) { groups.Add(group); } index += this.shuffling.NumItemsOfSectionInGroup; } while (!finish); // Shuffle groups if (this.shuffling.ShuffleGroups) { groups = (List<object>)CollectionUtils<object>.Shuffle(groups); } return groups; }
/// <summary> /// Inserts the pre slide trials. /// </summary> /// <param name="trials">The trials.</param> private void InsertPreSlideTrials(ref TrialCollection trials) { var trialsWithPreSlideTrials = new TrialCollection(); foreach (var trial in trials) { foreach (var slideobject in trial) { // if we have a preslide fixation trial add this trial before var preSlideTrialID = slideobject.IdOfPreSlideFixationTrial; if (preSlideTrialID != -1) { var preSlideNode = this.GetNodeByID(preSlideTrialID); var preTrial = new Trial(preSlideNode.Text, preSlideTrialID); preTrial.AddRange(this.GetPreSlideTrialSlides(preSlideNode)); trialsWithPreSlideTrials.Add(preTrial); } } trialsWithPreSlideTrials.Add(trial); } trials = trialsWithPreSlideTrials; }
/// <summary> /// Returns the current <see cref="TrialCollection"/> that was randomized /// according to the shuffling settings defined. /// </summary> /// <returns>The current <see cref="TrialCollection"/> that was randomized /// according to the shuffling settings defined.</returns> public TrialCollection GetRandomizedTrials() { List<object> nodeCollection = this.ParseNodeForRandomizedTrials(this); var trials = new TrialCollection(); this.GetTrialsFromObjectCollection(nodeCollection, ref trials); this.InsertPreSlideTrials(ref trials); return trials; }
/// <summary> /// This method iterates the given shuffled object collection recursively /// to return the one dimensional <see cref="TrialCollection"/> that is used /// during presentation. /// </summary> /// <param name="collection">A <see cref="List{Object}"/> with the shuffled trials separated in /// shuffle groups.</param> /// <param name="trials">Ref. The output <see cref="TrialCollection"/>.</param> private void GetTrialsFromObjectCollection(List<object> collection, ref TrialCollection trials) { foreach (object item in collection) { if (item is Trial) { Trial trial = item as Trial; trials.Add(trial); } else if (item is List<object>) { this.GetTrialsFromObjectCollection((List<object>)item, ref trials); } } }