/// <summary> /// This method resets the recording module by calling /// <see cref="ITracker.Stop()" /> for the current tracker. /// </summary> private void ResetRecordInterface() { this.currentTracker.Stop(); ((MainForm)this.MdiParent).StatusLabel.Text = "Ready..."; this.currentSlide = null; // Reset counters this.trialSequenceCounter = -1; this.slideCounter = 0; this.recordingStarttime = -5; this.lastTimeStamp = -1; this.currentTrial = null; this.currentSlide = DefaultSlide; this.recordTimerWatch.Reset(); this.tmrRecordClock.Stop(); this.tmrRecordClock.Dispose(); this.tmrRecordClock = new System.Windows.Forms.Timer { Interval = 1000 }; this.tmrRecordClock.Tick += this.TmrRecordClockTick; // Stop updating viewer this.Picture.StopAnimation(); this.Picture.ResetPicture(); // Redraw panel this.NewSlideAvailable(); // this.forcePanelViewerUpdate = true; this.forcePanelViewerUpdate = false; }
/// <summary> /// This method updates the live viewer of the presentation module. /// It sets the <see cref="currentSlide" /> according to <see cref="currentTrial" /> /// </summary> private void NewSlideAvailable() { if (this.currentTrial == null) { this.currentSlide = DefaultSlide; } if (this.systemHasSecondaryScreen || this.forcePanelViewerUpdate) { // Wait for finished screenshot of newly navigated page // before updating recorder viewer, // otherwise we would have a blank screen if (this.currentSlide.VGStimuli.Count > 0) { if (this.currentSlide.VGStimuli[0] is VGScrollImage) { var webpageScreenshot = (VGScrollImage)this.currentSlide.VGStimuli[0]; // When the file exists it must be ensured, that it is released // by its creator... if it does not exist, it fails either. int attempts = 0; // Loop allow multiple attempts while (true) { try { FileStream fs = File.OpenRead(webpageScreenshot.FullFilename); // If we get here, the File.Open succeeded, so break out of the loop fs.Dispose(); break; } catch (IOException) { // IOExcception is thrown if the file is in use by another process. // Check the number of attempts to ensure no infinite loop attempts++; if (attempts > 20) { // Too many attempts,cannot Open File, break MessageBox.Show("Wait Time did not was enough"); break; } // Sleep before making another attempt Application.DoEvents(); Thread.Sleep(200); } } webpageScreenshot.CreateInternalImage(); } } // Load Slide into picture this.LoadSlide(this.currentSlide, ActiveXMode.Off); // Show or hide duplicated mouse cursor this.recordPicture.MouseCursorVisible = this.currentSlide.MouseCursorVisible; } }
/////////////////////////////////////////////////////////////////////////////// // Eventhandler for Custom Defined Events // /////////////////////////////////////////////////////////////////////////////// /// <summary> /// The <see cref="PresenterModule.CounterChanged"/> event handler. /// Indicates a slide change in the presenter, so update trial and slide /// counter and the live viewer. /// </summary> /// <param name="sender"> /// Source of the event. /// </param> /// <param name="e"> /// A <see cref="CounterChangedEventArgs"/> with the event data. /// </param> private void ObjPresenterCounterChanged(object sender, CounterChangedEventArgs e) { this.counterChangedTime = this.GetCurrentTime(); if (this.counterChangedTime < 0) { throw new ArgumentException("Tracking had not been started"); } if (this.recordingStarttime == -5) { this.recordingStarttime = this.counterChangedTime; this.recordTimerWatch.Start(); this.tmrRecordClock.Start(); // Start update timer of control panel viewer this.Picture.StartAnimation(); } lock (this) { this.slideCounter = e.SlideCounter; // Don´t use presenters trialCounter // Because of using links between trials. // and care of trials with multiple slides // don´t increase trial sequence counter on this. if (this.slideCounter == 0) { this.trialSequenceCounter++; } // Set current trial if (e.TrialID == -5) { this.currentTrial = null; } else { var trialIndex = this.trials.GetIndexOfTrialByID(e.TrialID); if (trialIndex < 0) { // The trial is not in the default trial list, so it might has been created during recording // or is a subtrial of a browsing trial trialIndex = PresenterModule.TrialsIncludingNavigatedWebpages.GetIndexOfTrialByID(e.TrialID); this.currentTrial = (Trial)PresenterModule.TrialsIncludingNavigatedWebpages[trialIndex].Clone(); } else { this.currentTrial = this.trials[trialIndex]; } } // Set current slide this.currentSlide = this.currentTrial != null ? this.currentTrial[this.slideCounter] : null; } }
/// <summary> /// This method loads the given slide content into the background of the /// <see cref="Picture"/>. If applicable any flash objects are /// initialized /// </summary> /// <param name="slide">The new <see cref="Slide"/> to be displayed in the /// background of the <see cref="Picture"/>.</param> /// <param name="activeXMode">The <see cref="ActiveXMode"/> that should /// be used to display slide and activeX controls. Use this /// to display them on top or in the background.</param> protected void LoadSlide(Slide slide, ActiveXMode activeXMode) { // This releases the resources of the used slide // including explicit disposing of flash objects this.Picture.ResetBackground(); if (slide == null) { return; } // Set presentation size slide.PresentationSize = Document.ActiveDocument.PresentationSize; if (slide.StimulusSize != Size.Empty) { this.Picture.StimulusSize = slide.StimulusSize; } else { this.Picture.StimulusSize = slide.PresentationSize; } this.Picture.PresentationSize = slide.PresentationSize; Slide slideCopy = (Slide)slide.Clone(); switch (activeXMode) { case ActiveXMode.Off: // set Pictures new background slide this.Picture.BgSlide = slideCopy; break; default: case ActiveXMode.BehindPicture: // set Pictures new background slide this.Picture.BgSlide = slideCopy; foreach (VGElement element in slideCopy.ActiveXStimuli) { if (element is VGFlash) { VGFlash flash = element as VGFlash; flash.InitializeOnControl(this.Picture.Parent, false, this.Picture.StimulusToScreen); } else if (element is VGBrowser) { // Don´t show browser control, use screenshot of whole website instead. // VGBrowser browser = element as VGBrowser; // browser.InitializeOnControl(this.Picture.Parent, false); } } break; case ActiveXMode.OnTop: // set Pictures new background slide this.Picture.BgSlide = slideCopy; foreach (VGElement element in slideCopy.ActiveXStimuli) { if (element is VGFlash) { VGFlash flash = element as VGFlash; flash.InitializeOnControl(this.Picture, false, this.Picture.StimulusToScreen); } else if (element is VGBrowser) { VGBrowser browser = element as VGBrowser; browser.InitializeOnControl(this.Picture, false); } } break; case ActiveXMode.Video: // Don´t use Slide this.Picture.BgSlide = null; break; } // Set autozoom, because websites could have changed in size this.AutoZoomPicture(); // Redraw picture this.Picture.Invalidate(); }
/// <summary> /// This method invokes the method to draw the given slide onto /// the given graphics asynchronously. /// That allows calling from a separate thread. /// </summary> /// <param name="slide"> /// A <see cref="Slide"/> that should be drawn. /// </param> /// <param name="g"> /// A <see cref="Graphics"/> on which the slide should be drawn. /// </param> private void DrawSlideAsyncMethod(Slide slide, Graphics g) { this.Invoke(new Slide.AsyncDrawSlideMethodCaller(Slide.DrawSlideAsync), slide, g); }
/// <summary> /// This method opens the given slide in a new <see cref="SlideDesignModule"/> form /// for modification. /// </summary> /// <param name="treeNode">The <see cref="SlideshowTreeNode"/> that indicates the slide.</param> /// <param name="currentSlide">The <see cref="Slide"/> to be edited.</param> private void OpenDesktopDesignForm(SlideshowTreeNode treeNode, Slide currentSlide) { DesktopDialog newDesktopDesignForm = new DesktopDialog(); newDesktopDesignForm.Slide = (Slide)currentSlide.Clone(); this.OpenDesktopDesignerForm(newDesktopDesignForm, treeNode.Name); }
/////////////////////////////////////////////////////////////////////////////// // Eventhandler for Custom Defined Events // /////////////////////////////////////////////////////////////////////////////// #region CUSTOMEVENTHANDLER #endregion //CUSTOMEVENTHANDLER #endregion //EVENTS /////////////////////////////////////////////////////////////////////////////// // Methods and Eventhandling for Background tasks // /////////////////////////////////////////////////////////////////////////////// #region BACKGROUNDWORKER #endregion //BACKGROUNDWORKER /////////////////////////////////////////////////////////////////////////////// // Inherited methods // /////////////////////////////////////////////////////////////////////////////// #region OVERRIDES #endregion //OVERRIDES /////////////////////////////////////////////////////////////////////////////// // Methods for doing main class job // /////////////////////////////////////////////////////////////////////////////// #region METHODS /// <summary> /// Update the dialog forms fields with the content from the given <see cref="Slide"/>. /// </summary> /// <param name="slide">The <see cref="Slide"/> whichs content should /// be shown in the dialog.</param> private void PopulateDialogWithSlide(Slide slide) { // Common properties this.txbName.Text = slide.Name; this.cbbCategory.Text = slide.Category; // Tab Timing foreach (StopCondition condition in slide.StopConditions) { this.lsbStopConditions.Items.Add(condition); } }
/// <summary> /// Creates a new <see cref="Slide" /> with the /// properties defined on this dialog and creates a thumb for it. /// </summary> /// <returns>The new <see cref="Slide" /> to be added to the slideshow.</returns> private Slide GetSlide() { var slide = new Slide(); // Store category and name. slide.Category = this.cbbCategory.Text; slide.Name = this.txbName.Text; slide.IsDisabled = this.chbIsDisabled.Checked; slide.IdOfPreSlideFixationTrial = -1; if (this.cbbPreSlideFixationTrial.SelectedItem != null) { var selectedTrial = (Trial)this.cbbPreSlideFixationTrial.SelectedItem; slide.IdOfPreSlideFixationTrial = selectedTrial.ID; } // Add standard stop condition if none is specified. if (this.lsbStopConditions.Items.Count == 0) { this.lsbStopConditions.Items.Add(new TimeStopCondition(5000)); } // Store Stop conditions foreach (StopCondition cond in this.lsbStopConditions.Items) { slide.StopConditions.Add(cond); } // Store correct responses foreach (StopCondition cond in this.lsbCorrectResponses.Items) { slide.CorrectResponses.Add(cond); } // Store links foreach (StopCondition cond in this.lsbLinks.Items) { slide.Links.Add(cond); } // Remove grab handles if there is a selected element in the picture. // Otherwise the thumb would be wrong displayed if (this.designPicture.SelectedElement != null) { this.designPicture.SelectedElement.IsInEditMode = false; this.designPicture.Refresh(); } // Store graphical elements. VGElementCollection allElements = this.designPicture.Elements; VGElementCollection targetElements = this.designPicture.Elements.FindAllGroupMembers(VGStyleGroup.AOI_TARGET); VGElementCollection activeXElements = this.designPicture.Elements.FindAllGroupMembers(VGStyleGroup.ACTIVEX); allElements.RemoveAll(targetElements); allElements.RemoveAll(activeXElements); slide.VGStimuli = allElements; // Store target shapes slide.TargetShapes = targetElements; // Store activeX elements slide.ActiveXStimuli = activeXElements; // Reset design properties foreach (VGElement element in allElements) { if (element is VGSound) { ((VGSound)element).DesignMode = false; } } // Store background properties slide.BackgroundColor = this.btnBackgroundColor.CurrentColor; slide.BackgroundImage = this.designPicture.BackgroundImage; if (this.bkgAudioControl.Sound != null && this.bkgAudioControl.Sound.FullFilename != null) { slide.BackgroundSound = this.bkgAudioControl.Sound; } // Store mouse properties. slide.MouseCursorVisible = this.rdbShowMouseCursor.Checked; slide.MouseInitialPosition = this.psbMouseCursor.CurrentPosition; slide.ForceMousePositionChange = !this.chbMouseDontChangePosition.Checked; // Store trigger properties slide.TriggerSignal = this.triggerControl.TriggerSignal; // Set presentation size slide.PresentationSize = Document.ActiveDocument.PresentationSize; // Set modified flag. slide.Modified = true; return slide; }
/// <summary> /// Update the dialog forms fields with the content from the given <see cref="Slide"/>. /// </summary> /// <param name="slide"> /// The <see cref="Slide"/> which content should /// be shown in the dialog. /// </param> private void PopulateDialogWithSlide(Slide slide) { // Common properties this.txbName.Text = slide.Name; this.cbbCategory.Text = slide.Category; this.chbIsDisabled.Checked = slide.IsDisabled; if (slide.IdOfPreSlideFixationTrial != -1) { Trial item = Document.ActiveDocument.ExperimentSettings.SlideShow.GetTrialByID(slide.IdOfPreSlideFixationTrial); foreach (object item1 in this.cbbPreSlideFixationTrial.Items) { var trial = item1 as Trial; if (trial != null && trial.ID == item.ID) { this.cbbPreSlideFixationTrial.SelectedItem = item1; break; } } } // Tab Timing foreach (StopCondition condition in slide.StopConditions) { this.lsbStopConditions.Items.Add(condition); } // Tab Testing foreach (StopCondition condition in slide.CorrectResponses) { this.lsbCorrectResponses.Items.Add(condition); } // Tab Link foreach (StopCondition condition in slide.Links) { this.lsbLinks.Items.Add(condition); } // Tab Background this.btnBackgroundColor.CurrentColor = slide.BackgroundColor; this.designPicture.BackColor = slide.BackgroundColor; this.designPicture.BackgroundImage = slide.BackgroundImage; this.bkgAudioControl.Sound = slide.BackgroundSound; // Tab Mouse this.rdbShowMouseCursor.Checked = slide.MouseCursorVisible; this.rdbHideMouseCursor.Checked = !slide.MouseCursorVisible; this.psbMouseCursor.CurrentPosition = slide.MouseInitialPosition; this.chbMouseDontChangePosition.Checked = !slide.ForceMousePositionChange; // Tab trigger this.triggerControl.TriggerSignal = slide.TriggerSignal; // VGElements foreach (VGElement element in slide.VGStimuli) { if (element is VGSound) { ((VGSound)element).DesignMode = true; } this.designPicture.Elements.Add(element); } // Flash objects are added but // loaded during OpenNewCreationDialog(...) foreach (VGElement element in slide.ActiveXStimuli) { this.designPicture.Elements.Add(element); } // Tab and Picture Targets // Add targets last in the list, to make them top visible foreach (VGElement targetShape in slide.TargetShapes) { this.chbOnlyWhenInTarget.Visible = true; this.designPicture.Elements.Add(targetShape); this.lsbTargets.Items.Add(targetShape.Name); this.cbbTestingTargets.Items.Add(targetShape.Name); this.cbbLinksTargets.Items.Add(targetShape.Name); } // Finish this.designPicture.DrawForeground(false); }
/// <summary> /// Creates a new <see cref="Slide"/> with the /// properties defined on this dialog and creates a thumb for it. /// </summary> /// <returns>The new <see cref="Slide"/> to be added to the slideshow.</returns> private BrowserTreeNode GetBrowserSlide() { if (this.browserTreeNode == null) { this.browserTreeNode = new BrowserTreeNode(); } // Store category and name. this.browserTreeNode.Category = this.cbbCategory.Text; this.browserTreeNode.Text = this.txbName.Text; this.browserTreeNode.OriginURL = this.txbURL.Text; this.browserTreeNode.BrowseDepth = (int)this.nudBrowseDepth.Value; // Add standard stop condition if none is specified. if (this.lsbStopConditions.Items.Count == 0) { this.lsbStopConditions.Items.Add(new TimeStopCondition(SlideDesignModule.SLIDEDURATIONINS * 1000)); } Slide baseURLSlide = new Slide(); baseURLSlide.Category = this.cbbCategory.Text; baseURLSlide.Modified = true; baseURLSlide.Name = this.txbName.Text; baseURLSlide.PresentationSize = Document.ActiveDocument.PresentationSize; baseURLSlide.MouseCursorVisible = true; // Store Stop conditions foreach (StopCondition cond in this.lsbStopConditions.Items) { baseURLSlide.StopConditions.Add(cond); } Bitmap screenshot = WebsiteThumbnailGenerator.GetWebSiteScreenshot( this.txbURL.Text, Document.ActiveDocument.PresentationSize); string screenshotFilename = GetFilenameFromUrl(new Uri(this.txbURL.Text)); var filename = Path.Combine(Document.ActiveDocument.ExperimentSettings.SlideResourcesPath, screenshotFilename); screenshot.Save(filename, System.Drawing.Imaging.ImageFormat.Png); VGScrollImage baseURLScreenshot = new VGScrollImage( ShapeDrawAction.None, Pens.Transparent, Brushes.Black, SystemFonts.DefaultFont, Color.Black, Path.GetFileName(screenshotFilename), Document.ActiveDocument.ExperimentSettings.SlideResourcesPath, ImageLayout.None, 1f, Document.ActiveDocument.PresentationSize, VGStyleGroup.None, baseURLSlide.Name, string.Empty); baseURLSlide.VGStimuli.Add(baseURLScreenshot); this.browserTreeNode.Slide = baseURLSlide; // HtmlElementCollection es = webBrowser1.Document.GetElementsByTagName("a"); // if (es != null && es.Count != 0) // { // HtmlElement ele = es[0]; // //This line is optional, it only visually scolls the first link element into view // ele.ScrollIntoView(true); // ele.Focus(); // SendKeys.Send("{ENTER}"); // } return this.browserTreeNode; }
/// <summary> /// This static method creates a slide with a sized image /// for each trial and adds it to the slideshow. /// </summary> /// <param name="detectonSettings"> /// The <see cref="DetectionSettings"/> /// used in this import. /// </param> /// <param name="mainWindow"> /// The <see cref="MainForm"/> to get access to the status label. /// </param> public static void GenerateOgamaSlideshowTrials(DetectionSettings detectonSettings, MainForm mainWindow) { // Stores found stimuli files List<string> trialNames = Document.ActiveDocument.ExperimentSettings.SlideShow.GetTrialNames(); foreach (KeyValuePair<int, int> kvp in detectonSettings.TrialSequenceToTrialIDAssignments) { int trialID = kvp.Value; string file = string.Empty; if (detectonSettings.TrialIDToImageAssignments.ContainsKey(trialID)) { file = detectonSettings.TrialIDToImageAssignments[trialID]; } string filename = Path.GetFileNameWithoutExtension(file); // Create slide var stopConditions = new StopConditionCollection { new MouseStopCondition( MouseButtons.Left, true, string.Empty, null, Point.Empty) }; VGImage stimulusImage = null; if (file != string.Empty) { stimulusImage = new VGImage( ShapeDrawAction.None, Pens.Black, Brushes.Black, SystemFonts.MenuFont, Color.White, Path.GetFileName(file), Document.ActiveDocument.ExperimentSettings.SlideResourcesPath, ImageLayout.Zoom, 1f, Document.ActiveDocument.PresentationSize, VGStyleGroup.None, filename, string.Empty, true) { Size = Document.ActiveDocument.PresentationSize }; } var newSlide = new Slide( filename, Color.White, null, stopConditions, null, string.Empty, Document.ActiveDocument.PresentationSize) { Modified = true, MouseCursorVisible = true }; // Only add stimulus if an image exists if (file != string.Empty) { newSlide.VGStimuli.Add(stimulusImage); } else { newSlide.Name = "No stimulus detected"; } // Create trial if (Document.ActiveDocument.ExperimentSettings.SlideShow.GetNodeByID(trialID) != null) { // trialID = int.Parse(Document.ActiveDocument.ExperimentSettings.SlideShow.GetUnusedNodeID()); // var message = string.Format("The trial with the ID:{0} exists already in the slideshow so it will not be created." // + Environment.NewLine + "Delete the trial with this ID in the slideshow design module if you want it to be newly created by the importer, or assign a new ID to the imported data.", trialID); // ExceptionMethods.ProcessMessage("This trial exists already", message); continue; } var newTrial = new Trial(filename, trialID) { Name = filename }; newTrial.Add(newSlide); if (trialNames.Contains(filename) || (filename == string.Empty && trialNames.Contains("No stimulus detected"))) { // Trial already exists continue; } trialNames.Add(filename); // Create slide node var slideNode = new SlideshowTreeNode(newSlide.Name) { Name = trialID.ToString(CultureInfo.InvariantCulture), Slide = newSlide }; // Add slide node to slideshow Document.ActiveDocument.ExperimentSettings.SlideShow.Nodes.Add(slideNode); Document.ActiveDocument.Modified = true; } mainWindow.StatusLabel.Text = "Saving slideshow to file ..."; if (!Document.ActiveDocument.SaveSettingsToFile(Document.ActiveDocument.ExperimentSettings.DocumentFilename)) { ExceptionMethods.ProcessErrorMessage("Couldn't save slideshow to experiment settings."); } mainWindow.StatusLabel.Text = "Refreshing context panel ..."; mainWindow.RefreshContextPanelImageTabs(); mainWindow.StatusLabel.Text = "Ready ..."; mainWindow.StatusProgressbar.Value = 0; }
/////////////////////////////////////////////////////////////////////////////// // Construction and Initializing methods // /////////////////////////////////////////////////////////////////////////////// #region CONSTRUCTION /// <summary> /// Initializes a new instance of the SlideChangedEventArgs class. /// </summary> /// <param name="newNextSlide">A <see cref="Slide"/> The <see cref="Slide"/> that is the new slide to show.</param> /// <param name="newResponse">The response of type <see cref="StopCondition"/> /// that ended the trial.</param> /// <param name="newSlideCounter">The index of the current visible slide /// in the current trial.</param> public SlideChangedEventArgs(Slide newNextSlide, StopCondition newResponse, int newSlideCounter) { this.nextSlide = newNextSlide; this.response = newResponse; this.slideCounter = newSlideCounter; }
/// <summary> /// This method replaces the Slide at the node with the given nodeID /// with the new given <see cref="Slide"/>. /// </summary> /// <param name="newSlide">The new <see cref="Slide"/> that replaces the old one.</param> /// <param name="nodeID">A <see cref="String"/> with the node ID of the <see cref="TreeView"/> /// node to be replaced.</param> private void OverwriteSlide(Slide newSlide, string nodeID) { // Update node TreeNode slideNode = this.GetTreeNodeByID(nodeID); if (slideNode != null) { slideNode.Text = newSlide.Name; ((SlideshowTreeNode)slideNode).Slide = newSlide; ((SlideshowTreeNode)slideNode).SetTreeNodeImageKey((SlideshowTreeNode)slideNode); this.UpdateListView(this.selectedNode); this.lsvDetails.SelectObject(slideNode); } else { ExceptionMethods.ProcessErrorMessage("No suitable slide found for overriding, so adding it"); this.AddSlide(newSlide); } }
/// <summary> /// This method adds the given <see cref="Slide"/> at the /// current treeview position. /// </summary> /// <param name="newSlide">The new <see cref="Slide"/> to be added to the slideshow.</param> private void AddSlide(Slide newSlide) { // Add node SlideshowTreeNode slideNode = new SlideshowTreeNode(newSlide.Name); slideNode.Name = this.slideshow.GetUnusedNodeID(); slideNode.Slide = newSlide; ((SlideshowTreeNode)slideNode).SetTreeNodeImageKey((SlideshowTreeNode)slideNode); // Get root node for insertion SlideshowTreeNode firstNode = this.trvSlideshow.Nodes[0] as SlideshowTreeNode; // If there is a selected node use this instead NodesCollection selectedNodes = this.trvSlideshow.SelectedNodes; if (selectedNodes.Count > 0) { firstNode = selectedNodes[0] as SlideshowTreeNode; this.trvSlideshow.SelectedNodes.Clear(); } // Add to node, if it is a slide node add to parent instead if (firstNode.Slide != null) { firstNode.Parent.Nodes.Add(slideNode); } else { firstNode.Nodes.Add(slideNode); } // Select added node. this.trvSlideshow.SelectedNodes.Add(slideNode); this.UpdateListView(this.trvSlideshow.SelectedNodes); }
/// <summary> /// Initializes a new instance of the Slide class as a clone of /// the given slide. /// </summary> /// <param name="slide">The <see cref="Slide"/> to clone.</param> public Slide(Slide slide) { // Clone stimuli this.stimuli = new VGElementCollection(); foreach (VGElement element in slide.VGStimuli) { this.stimuli.Add((VGElement)element.Clone()); } // Clone activeXElements this.activeXElements = new VGElementCollection(); foreach (VGElement element in slide.ActiveXStimuli) { this.activeXElements.Add((VGElement)element.Clone()); } // Clone stop conditions this.stopConditions = new StopConditionCollection(); foreach (StopCondition condition in slide.StopConditions) { this.stopConditions.Add((StopCondition)condition.Clone()); } // Clone background properties this.BackgroundColor = slide.BackgroundColor; if (slide.BackgroundImage != null) { this.BackgroundImage = (Image)slide.BackgroundImage.Clone(); } if (slide.BackgroundSound != null) { this.BackgroundSound = (AudioFile)slide.BackgroundSound.Clone(); } // Clone trigger this.TriggerSignal = slide.TriggerSignal; this.IsDesktopSlide = slide.IsDesktopSlide; this.IdOfPreSlideFixationTrial = slide.IdOfPreSlideFixationTrial; this.IsDisabled = slide.IsDisabled; // Clone correct responses this.correctResponses = new StopConditionCollection(); foreach (StopCondition condition in slide.CorrectResponses) { this.correctResponses.Add((StopCondition)condition.Clone()); } // Clone links this.links = new StopConditionCollection(); foreach (StopCondition condition in slide.Links) { this.links.Add((StopCondition)condition.Clone()); } // Clone description this.name = slide.Name; this.category = slide.Category; // Clone target areas this.targets = new VGElementCollection(); foreach (VGElement target in slide.TargetShapes) { this.targets.Add((VGElement)target.Clone()); } // Clone mouse properties this.MouseInitialPosition = slide.MouseInitialPosition; this.MouseCursorVisible = slide.MouseCursorVisible; this.ForceMousePositionChange = slide.ForceMousePositionChange; this.PresentationSize = slide.PresentationSize; this.Modified = slide.Modified; }
/////////////////////////////////////////////////////////////////////////////// // Eventhandler for Custom Defined Events // /////////////////////////////////////////////////////////////////////////////// #region CUSTOMEVENTHANDLER #endregion //CUSTOMEVENTHANDLER #endregion //EVENTS /////////////////////////////////////////////////////////////////////////////// // Methods and Eventhandling for Background tasks // /////////////////////////////////////////////////////////////////////////////// #region BACKGROUNDWORKER #endregion //BACKGROUNDWORKER /////////////////////////////////////////////////////////////////////////////// // Methods for doing main class job // /////////////////////////////////////////////////////////////////////////////// #region PRIVATEMETHODS /// <summary> /// This method does the parsing of the given path and creates for each readable /// image or media file a trial with the defined conditions. /// </summary> /// <returns>A <see cref="List{Slide}"/> to be imported in the slideshow of /// the experiment.</returns> private List<Slide> GetSlides() { var newSlides = new List<Slide>(); var dirInfoStimuli = new DirectoryInfo(this.txbFolder.Text); if (dirInfoStimuli.Exists) { var files = dirInfoStimuli.GetFiles(); Array.Sort(files, new NumericComparer()); foreach (var file in files) { var extension = file.Extension.ToLower(); // Ignore files with unrecognized extensions switch (extension) { case ".bmp": case ".png": case ".jpg": case ".wmf": case ".mp3": case ".wav": case ".wma": break; default: continue; } // Ignore hidden and MAC files if (file.Name.StartsWith(".")) { continue; } var newSlide = new Slide { BackgroundColor = this.clbBackground.CurrentColor, Modified = true, MouseCursorVisible = this.chbShowMouseCursor.Checked, MouseInitialPosition = this.psbMouseCursor.CurrentPosition, Name = Path.GetFileNameWithoutExtension(file.Name), PresentationSize = Document.ActiveDocument.PresentationSize }; StopCondition stop = null; if (this.rdbTime.Checked) { stop = new TimeStopCondition((int)(this.nudTime.Value * 1000)); } else if (this.rdbKey.Checked) { string selectedItemKeys = (string)this.cbbKeys.SelectedItem; KeyStopCondition ksc = new KeyStopCondition(); if (selectedItemKeys == "Any") { ksc.CanBeAnyInputOfThisType = true; } else { ksc.StopKey = (Keys)Enum.Parse(typeof(Keys), selectedItemKeys); } stop = ksc; } else if (this.rdbMouse.Checked) { string selectedItemMouse = (string)this.cbbMouseButtons.SelectedItem; MouseStopCondition msc = new MouseStopCondition(); msc.CanBeAnyInputOfThisType = selectedItemMouse == "Any" ? true : false; if (!msc.CanBeAnyInputOfThisType) { msc.StopMouseButton = (MouseButtons)Enum.Parse(typeof(MouseButtons), selectedItemMouse); } msc.Target = string.Empty; stop = msc; } else if (this.rdbDuration.Checked) { if (extension == ".mp3" || extension == ".wav" || extension == ".wma") { int duration = this.GetAudioFileLength(file.FullName); if (duration != 0) { stop = new TimeStopCondition(duration + (int)this.nudLatency.Value); } else { stop = new TimeStopCondition((int)(this.nudTime.Value * 1000)); } } else { stop = new TimeStopCondition((int)(this.nudTime.Value * 1000)); } } newSlide.StopConditions.Add(stop); foreach (VGElement element in this.lsbStandardItems.Items) { newSlide.VGStimuli.Add(element); } string destination = Path.Combine(Document.ActiveDocument.ExperimentSettings.SlideResourcesPath, file.Name); switch (extension) { case ".bmp": case ".png": case ".jpg": case ".wmf": if (!File.Exists(destination)) { File.Copy(file.FullName, destination, true); } VGImage image = new VGImage( ShapeDrawAction.None, Pens.Red, Brushes.Red, SystemFonts.MenuFont, Color.Red, file.Name, Document.ActiveDocument.ExperimentSettings.SlideResourcesPath, ImageLayout.Stretch, 1f, Document.ActiveDocument.PresentationSize, VGStyleGroup.None, file.Name, string.Empty, true); newSlide.VGStimuli.Add(image); newSlides.Add(newSlide); break; case ".mp3": case ".wav": case ".wma": File.Copy(file.FullName, destination, true); VGSound sound = new VGSound(ShapeDrawAction.None, Pens.Red, new Rectangle(0, 0, 200, 300)); sound.Center = newSlide.MouseInitialPosition; sound.Size = new SizeF(50, 50); AudioFile audioFile = new AudioFile(); audioFile.Filename = file.Name; audioFile.Filepath = Document.ActiveDocument.ExperimentSettings.SlideResourcesPath; audioFile.Loop = false; audioFile.ShouldPlay = true; audioFile.ShowOnClick = false; sound.Sound = audioFile; newSlide.VGStimuli.Add(sound); newSlides.Add(newSlide); break; } } } return newSlides; }
/////////////////////////////////////////////////////////////////////////////// // Public methods // /////////////////////////////////////////////////////////////////////////////// #region PUBLICMETHODS /// <summary> /// Draw the slide onto the given graphics in the background thread. /// </summary> /// <param name="slide">A <see cref="Slide"/> that should be drawn.</param> /// <param name="g">A <see cref="Graphics"/> on which the slide should be drawn.</param> public static void DrawSlideAsync(Slide slide, Graphics g) { slide.Draw(g); }
/// <summary> /// This method opens the given slide in a new <see cref="SlideDesignModule"/> form /// for modification. /// </summary> /// <param name="treeNode">The <see cref="SlideshowTreeNode"/> that indicates the slide.</param> /// <param name="currentSlide">The <see cref="Slide"/> to be edited.</param> private void OpenSlideDesignForm(SlideshowTreeNode treeNode, Slide currentSlide) { SlideDesignModule newStimulusDesignForm = new SlideDesignModule(StimuliTypes.None); newStimulusDesignForm.Slide = (Slide)currentSlide.Clone(); this.OpenStimulusDesignerForm(newStimulusDesignForm, treeNode.Name); }