/// <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); }
/// <summary> /// This static method draws a chain icon at the bottom right corner of the list view item /// to the given graphics object with the given bounding rect. /// </summary> /// <param name="g">The <see cref="Graphics"/> to draw to.</param> /// <param name="boundsWithoutPadding">The bounding <see cref="Rectangle"/> of the list view item.</param> /// <param name="node">The <see cref="SlideshowTreeNode"/> that is the object of the list view item.</param> protected static void DrawChains(Graphics g, Rectangle boundsWithoutPadding, SlideshowTreeNode node) { if (node.Parent != null) { // Draw Chains int nodesAtLevel = node.Parent.Nodes.Count; if (nodesAtLevel > 1) { bool randomize = ((SlideshowTreeNode)node.Parent).Randomize; if (node.Index == 0) { DrawLeftConnectionPart(g, boundsWithoutPadding, randomize); } else if (node.Index > 0 && node.Index < nodesAtLevel - 1) { DrawLeftConnectionPart(g, boundsWithoutPadding, randomize); DrawRightConnectionPart(g, boundsWithoutPadding, randomize); } else { DrawRightConnectionPart(g, boundsWithoutPadding, randomize); } } } }
/// <summary> /// This method initializes the <see cref="ObjectListView"/> how to populate /// and render it. Please refer to the <see cref="ObjectListView"/> /// documentation to understand. /// </summary> private void InitializeDetailListView() { this.colPosition.AspectToStringConverter = cellValue => cellValue.ToString(); this.colPosition.AspectGetter = row => ((SlideshowTreeNode)row).Index; this.colPosition.ToolTipGetter = delegate(object row) { SlideshowTreeNode node = row as SlideshowTreeNode; Slide slide = node.Slide; if (slide != null) { return(slide.StopConditions.ToString()); } else { return("Contains: " + node.Nodes.Count + " items"); } }; this.colPosition.Renderer = new SlideshowTreeNodeRenderer(); this.SetListViewTileSize(Slide.SlideDesignThumbSize); this.lsvDetails.View = View.Tile; this.lsvDetails.InsertionMark.Color = Color.Green; }
/// <summary> /// This method adds the given <see cref="BrowserTreeNode"/> at the /// current treeview position. /// </summary> /// <param name="newBrowserSlideNode">The new <see cref="BrowserTreeNode"/> to be added to the slideshow.</param> private void AddBrowserSlide(BrowserTreeNode newBrowserSlideNode) { // Add node string newID = this.slideshow.GetUnusedNodeID(); newBrowserSlideNode.Name = newID; newBrowserSlideNode.UrlToID.Add(newBrowserSlideNode.OriginURL, Convert.ToInt32(newID)); // 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(newBrowserSlideNode); } else { firstNode.Nodes.Add(newBrowserSlideNode); } // Select added node. this.trvSlideshow.SelectedNodes.Add(newBrowserSlideNode); this.UpdateListView(this.trvSlideshow.SelectedNodes); }
/// <summary> /// The <see cref="Control.Click"/> event handler for the /// <see cref="ToolStripMenuItem"/> <see cref="cmuShuffle"/>. /// Occurs when the context menues shuffle entry is clicked. /// Sets ur unsets the nodes randomize flag. /// </summary> /// <param name="sender">Source of the event.</param> /// <param name="e">An empty <see cref="EventArgs"/>.</param> private void cmuShuffle_Click(object sender, EventArgs e) { NodesCollection selectedNodes = this.trvSlideshow.SelectedNodes; if (selectedNodes.Count != 1) { return; } SlideshowTreeNode node = this.trvSlideshow.SelectedNodes[0] as SlideshowTreeNode; if (node != null) { if (node.Slide == null) { node.Randomize = this.cmuShuffle.Checked; } else { ExceptionMethods.ProcessMessage( "Please note:", "You cannot shuffle/unshuffle single slides, please select the parent node"); } } this.trvSlideshow.Invalidate(); this.lsvDetails.Invalidate(); }
/// <summary> /// The <see cref="ToolStripComboBox.SelectedIndexChanged"/> event handler for the /// <see cref="ToolStripComboBox"/> <see cref="cmuCountCombo"/>. /// Indicates the number of items in the child nodes collection /// that should be used during presentation of the shuffled collection. /// </summary> /// <remarks>Use this to reduce the stimuli that are shown during presentation /// to a limited number of shuffled items of the child collection.</remarks> /// <param name="sender">Source of the event.</param> /// <param name="e">An empty <see cref="EventArgs"/>.</param> private void cmuCountCombo_SelectedIndexChanged(object sender, EventArgs e) { NodesCollection selectedNodes = this.trvSlideshow.SelectedNodes; if (selectedNodes.Count != 1) { return; } SlideshowTreeNode node = this.trvSlideshow.SelectedNodes[0] as SlideshowTreeNode; if (node != null) { if (node.Slide == null) { if (this.cmuCountCombo.SelectedItem.ToString() == "All") { node.NumberOfItemsToUse = node.Nodes.Count; } else { node.NumberOfItemsToUse = (int)this.cmuCountCombo.SelectedItem; } } else { ExceptionMethods.ProcessMessage( "Please note:", "You cannot change subitem range for single slides, please select the parent node"); } } this.trvSlideshow.Invalidate(); this.lsvDetails.Invalidate(); }
/// <summary> /// The <see cref="Control.Click"/> event handler for the /// <see cref="Button"/> <see cref="btnAddFolder"/>. /// Inserts an empty folder for slides in the treeview. /// </summary> /// <param name="sender">Source of the event.</param> /// <param name="e">An empty <see cref="EventArgs"/></param> private void btnAddFolder_Click(object sender, EventArgs e) { SlideshowTreeNode folderNode = new SlideshowTreeNode("SlideFolder"); folderNode.ImageKey = "Folder"; folderNode.Name = this.slideshow.GetUnusedNodeID(); // 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(folderNode); } else { firstNode.Nodes.Add(folderNode); } // Select added node. this.trvSlideshow.SelectedNodes.Add(folderNode); this.UpdateListView(this.trvSlideshow.SelectedNodes); }
/// <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); }
/// <summary> /// The <see cref="Control.Click"/> event handler for the /// <see cref="ToolStripComboBox"/> <see cref="cmuShuffle"/>. /// Occurs when the context menues combine to trial entry is clicked. /// Combines the selected nodes to a trial, if applicable create a new group for /// the trial. /// </summary> /// <param name="sender">Source of the event.</param> /// <param name="e">An empty <see cref="EventArgs"/>.</param> private void cmuCombineToTrial_Click(object sender, EventArgs e) { if (this.cmuCombineToTrial.Checked) { NodesCollection nodes = this.trvSlideshow.SelectedNodes; if (nodes.Count > 1) { SlideshowTreeNode firstNode = nodes[0] as SlideshowTreeNode; if (firstNode.Slide != null) { TreeNode parent = firstNode.Parent; foreach (TreeNode subNode in nodes) { if (subNode.Parent != parent) { ExceptionMethods.ProcessMessage( "Please note:", "You can only combine slides with the same parent node to a trial."); return; } } // If all nodes of parent were marked to be a trial // it is enough to mark the parent with the "Trial" tag, // except it is the base node // otherwise create a new "Trial" marked group with the items if (parent.Nodes.Count != nodes.Count || parent.Text == "Slideshow") { this.MoveNodesLevelUp(nodes, true); } else { parent.Tag = "Trial"; ((SlideshowTreeNode)parent).Randomize = false; ((SlideshowTreeNode)parent).SetTreeNodeImageKey((SlideshowTreeNode)parent); } } else { ExceptionMethods.ProcessMessage( "Please note:", "You can only combine slide nodes to a trial."); } } } else { // Remove trial tag NodesCollection nodes = this.trvSlideshow.SelectedNodes; if (nodes.Count == 1) { SlideshowTreeNode firstNode = nodes[0] as SlideshowTreeNode; firstNode.Tag = string.Empty; } } this.trvSlideshow.Invalidate(); this.lsvDetails.Invalidate(); }
/// <summary> /// Saves the current slides collection to a OGAMA slideshow file. /// </summary> /// <param name="filePath">Path to slideshow file.</param> /// <returns><strong>True</strong> if successful, /// otherwise <strong>false</strong>.</returns> private DialogResult SaveSlideshowToFile(string filePath) { try { if (this.trvSlideshow.Nodes[0].Nodes.Count == 0) { return(DialogResult.Cancel); } using (TextWriter writer = new StreamWriter(filePath)) { string message = "Would you like to export the whole slideshow ?" + Environment.NewLine + "Otherwise only the selected tree node will be exported"; DialogResult result = InformationDialog.Show("Save whole slideshow ?", message, true, MessageBoxIcon.Question); switch (result) { case DialogResult.Cancel: return(DialogResult.Cancel); case DialogResult.No: // Create an instance of the XmlSerializer class; // specify the type of object to serialize XmlSerializer serializer = new XmlSerializer(typeof(SlideshowTreeNode)); SlideshowTreeNode currentNode = this.slideshow; if (this.trvSlideshow.SelectedNodes.Count > 0) { currentNode = (SlideshowTreeNode)this.trvSlideshow.SelectedNodes[0]; } // Serialize the Nodes serializer.Serialize(writer, currentNode); break; case DialogResult.Yes: // Create an instance of the XmlSerializer class; // specify the type of object to serialize serializer = new XmlSerializer(typeof(Slideshow)); Slideshow currentSlideshow = this.slideshow; // Serialize the Nodes serializer.Serialize(writer, currentSlideshow); return(DialogResult.OK); } } } catch (Exception ex) { ExceptionMethods.HandleException(ex); return(DialogResult.Abort); } return(DialogResult.OK); }
/// <summary> /// This method deletes the given node from the listview, /// and updates the views. /// </summary> /// <param name="treeNode">The <see cref="SlideshowTreeNode"/> to delete.</param> private void DeleteNode(SlideshowTreeNode treeNode) { if (treeNode == null) { return; } Slide deleteSlide = treeNode.Slide; if (deleteSlide != null) { deleteSlide.Dispose(); } foreach (SlideshowTreeNode subNode in treeNode.Nodes) { this.DeleteNode(subNode); } // Update UrlToID dictionary of BrowserTreeNodes if (treeNode.Parent is BrowserTreeNode) { BrowserTreeNode parent = (BrowserTreeNode)treeNode.Parent; string keyToRemove = string.Empty; foreach (KeyValuePair <string, int> urlToID in parent.UrlToID) { if (urlToID.Value == Convert.ToInt32(treeNode.Name)) { keyToRemove = urlToID.Key; } } if (keyToRemove != string.Empty) { var fileName = Path.Combine(Document.ActiveDocument.ExperimentSettings.SlideResourcesPath, keyToRemove); if (File.Exists(fileName)) { File.Delete(fileName); } parent.UrlToID.Remove(keyToRemove); } } // Update TreeView. treeNode.Remove(); this.UpdateListView(this.trvSlideshow.SelectedNodes); }
/// <summary> /// The <see cref="Control.DragDrop"/> event handler for the /// <see cref="TreeView"/> <see cref="trvSlideshow"/>. /// Occurs when a drag-and-drop operation is completed. /// Inserts the moved or copied tree node item and updates the member slideshow. /// </summary> /// <param name="sender">Source of the event.</param> /// <param name="e">An <see cref="DragEventArgs"/> that contains the event data. </param> private void trvSlideshow_DragDrop(object sender, DragEventArgs e) { // If the insertion mark is not visible, exit the method. if (e.Effect == DragDropEffects.None) { return; } // Retrieve the client coordinates of the mouse pointer. Point targetPoint = this.trvSlideshow.PointToClient(new Point(e.X, e.Y)); TreeNode targetItem = this.trvSlideshow.GetNodeAt(targetPoint); // Retrieve the dragged items. NodesCollection draggedItems = (NodesCollection)e.Data.GetData(typeof(NodesCollection)); this.trvSlideshow.BeginUpdate(); if (e.Effect == DragDropEffects.Move) { foreach (TreeNode node in draggedItems) { // Update TreeView node.Parent.Nodes.Remove(node); targetItem.Nodes.Add(node); } } else if (e.Effect == DragDropEffects.Copy) { List <string> names = new List <string>(); this.slideshow.GetNodeNames(this.slideshow, ref names); foreach (TreeNode node in draggedItems) { // Update TreeView And Slideshow names SlideshowTreeNode copyNode = (SlideshowTreeNode)node.Clone(); this.RenameNodes(copyNode, ref names); targetItem.Nodes.Add(copyNode); } } this.trvSlideshow.EndUpdate(); this.SlideShowModified(); this.UpdateListView(this.trvSlideshow.SelectedNodes); }
/////////////////////////////////////////////////////////////////////////////// // Eventhandler for UI, Menu, Buttons, Toolbars etc. // /////////////////////////////////////////////////////////////////////////////// #region WINDOWSEVENTHANDLER /// <summary> /// The <see cref="Control.DoubleClick"/> event handler for the /// <see cref="ListView"/> <see cref="lsvDetails"/>. /// Opens a designer form for the current slide. /// </summary> /// <param name="sender">Source of the event.</param> /// <param name="e">An empty <see cref="EventArgs"/></param> private void lsvDetails_DoubleClick(object sender, EventArgs e) { // Retrieve the client coordinates of the mouse pointer. Point mouseClientLocation = this.lsvDetails.PointToClient(Control.MousePosition); OLVColumn column; OLVListItem item = this.lsvDetails.GetItemAt(mouseClientLocation.X, mouseClientLocation.Y, out column); if (item == null) { return; } SlideshowTreeNode treeNode = item.RowObject as SlideshowTreeNode; if (treeNode is BrowserTreeNode) { this.OpenBrowserDesignerForm(treeNode as BrowserTreeNode); } else { // If there is a slide open it, otherwise zoom in. Slide currentSlide = treeNode.Slide; if (currentSlide != null) { if (currentSlide.IsDesktopSlide) { this.OpenDesktopDesignForm(treeNode, currentSlide); } else { this.OpenSlideDesignForm(treeNode, currentSlide); } } else { this.lsvDetails.SetObjects(treeNode.Nodes); } } }
/// <summary> /// The <see cref="Control.DragOver"/> event handler for the /// <see cref="TreeView"/> <see cref="trvSlideshow"/>. /// Occurs when an object is dragged over the control's bounds. /// Updates the drag cursor with copy or move state, referring to Modifier Key. /// Ensures the visibility of the item under the mouse cursor. /// </summary> /// <param name="sender">Source of the event.</param> /// <param name="e">An <see cref="DragEventArgs"/> that contains the event data. </param> private void trvSlideshow_DragOver(object sender, DragEventArgs e) { // Retrieve the client coordinates of the mouse pointer. Point targetPoint = this.trvSlideshow.PointToClient(new Point(e.X, e.Y)); SlideshowTreeNode targetNode = this.trvSlideshow.GetNodeAt(targetPoint) as SlideshowTreeNode; // Retrieve the dragged items. NodesCollection draggedItems = (NodesCollection)e.Data.GetData(typeof(NodesCollection)); if (targetNode != null) { if (((SlideshowTreeNode)draggedItems[0]).Contains(targetNode) || targetNode == draggedItems[0]) { e.Effect = DragDropEffects.None; return; } bool isSlide = targetNode.Slide != null; // If target is not a slide if (!isSlide) { if (Control.ModifierKeys == Keys.Control) { e.Effect = DragDropEffects.Copy; } else { e.Effect = DragDropEffects.Move; } return; } } e.Effect = DragDropEffects.None; }
/// <summary> /// This method moves the given nodes on level up. /// They can be marked as a trial using the second parameter. /// </summary> /// <param name="nodes">A <see cref="NodesCollection"/> with the <see cref="TreeView"/> nodes.</param> /// <param name="markAsTrial"><strong>True</strong> if the nodes in the collection /// are referred to be one trial in the presentation.</param> private void MoveNodesLevelUp(NodesCollection nodes, bool markAsTrial) { nodes.Sort(); if (nodes.Count > 0) { TreeNode firstNode = nodes[0]; // Skip if the node is the root node if (firstNode.Parent == null) { return; } int insertionIndex = firstNode.Index; string parentNodeName = this.slideshow.GetUnusedNodeID(); SlideshowTreeNode newParent = new SlideshowTreeNode(parentNodeName); newParent.Name = parentNodeName; if (markAsTrial) { newParent.Tag = "Trial"; } newParent.SetTreeNodeImageKey(newParent); firstNode.Parent.Nodes.Insert(insertionIndex, newParent); foreach (TreeNode collectionNode in nodes) { collectionNode.Remove(); newParent.Nodes.Add(collectionNode); } } this.UpdateListView(this.trvSlideshow.SelectedNodes); this.SlideShowModified(); }
/// <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> /// The <see cref="ToolStripDropDown.Opening"/> event handler for the /// <see cref="ContextMenuStrip"/> <see cref="cmuItemView"/>. /// Occurs when the context menu is opening. /// Updates the menus items visibility and read only states according /// to selected node. /// </summary> /// <param name="sender">Source of the event.</param> /// <param name="e">An <see cref="CancelEventArgs"/> that contains the event data. </param> private void cmuItemView_Opening(object sender, CancelEventArgs e) { this.cmuDisable.Text = "Disable Slide"; this.cmuDisable.Checked = false; int itemCount = this.trvSlideshow.SelectedNodes.Count; if (itemCount > 1) { this.cmuShuffle.Enabled = false; this.cmuCountCombo.Enabled = false; this.cmuDescription.Enabled = false; // If the selected nodes are trial nodes enable the combine to trial menu item // otherwise disable. SlideshowTreeNode firstNode = this.trvSlideshow.SelectedNodes[0] as SlideshowTreeNode; if (firstNode.Slide != null) { this.cmuCombineToTrial.Enabled = true; this.cmuCombineToTrial.Checked = false; } else { this.cmuCombineToTrial.Enabled = false; this.cmuCombineToTrial.Checked = false; } } else { this.cmuCombineToTrial.Enabled = false; this.cmuCombineToTrial.Checked = false; // Update the shuffle item status. if (this.trvSlideshow.SelectedNodes[0].Tag != null && this.trvSlideshow.SelectedNodes[0].Tag.ToString() == "Trial") { this.cmuShuffle.Enabled = false; this.cmuShuffle.Checked = false; this.cmuCombineToTrial.Checked = true; this.cmuCombineToTrial.Enabled = true; this.cmuCountCombo.Enabled = false; this.cmuCountCombo.Items.Clear(); this.cmuDescription.Enabled = false; } else { SlideshowTreeNode node = this.trvSlideshow.SelectedNodes[0] as SlideshowTreeNode; if (node.Slide != null && node.Slide.IsDisabled) { this.cmuDisable.Text = "Enable Slide"; this.cmuDisable.Checked = true; } this.cmuShuffle.Enabled = true; this.cmuShuffle.Checked = node.Randomize; if (this.cmuShuffle.Checked) { this.cmuCountCombo.Enabled = true; this.cmuDescription.Enabled = true; this.cmuCountCombo.Items.Clear(); this.cmuCountCombo.Items.Add("All"); int subNodesCount = node.Nodes.Count; for (int i = 1; i <= subNodesCount; i++) { this.cmuCountCombo.Items.Add(i); } if (node.NumberOfItemsToUse == 0 || node.NumberOfItemsToUse == subNodesCount) { this.cmuCountCombo.SelectedItem = "All"; } else { this.cmuCountCombo.SelectedItem = node.NumberOfItemsToUse; } this.cmuCombineToTrial.Enabled = false; this.cmuCombineToTrial.Checked = false; } else { this.cmuCountCombo.Enabled = false; this.cmuDescription.Enabled = false; } } } }
/////////////////////////////////////////////////////////////////////////////// // Eventhandler // /////////////////////////////////////////////////////////////////////////////// #region EVENTS /////////////////////////////////////////////////////////////////////////////// // Eventhandler for UI, Menu, Buttons, Toolbars etc. // /////////////////////////////////////////////////////////////////////////////// #region WINDOWSEVENTHANDLER #endregion //WINDOWSEVENTHANDLER /////////////////////////////////////////////////////////////////////////////// // 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 main job of drawing the given <see cref="SlideshowTreeNode"/> /// in the given <see cref="Rectangle"/> using the given <see cref="Graphics"/> object. /// It calls the various drawing methods from the base class <see cref="CustomRenderer"/>. /// </summary> /// <param name="node">The <see cref="SlideshowTreeNode"/> to be rendered.</param> /// <param name="thumbRect">A <see cref="Rectangle"/> with the bounds for the node.</param> /// <param name="g">The <see cref="Graphics"/> to be used.</param> private void DrawNodeInRect(SlideshowTreeNode node, Rectangle thumbRect, Graphics g) { if (thumbRect.Width < 8 || thumbRect.Height < 5) { return; } int nodeCount = node.Nodes.Count; Rectangle newBounds = thumbRect; newBounds.Inflate(-2, -2); int newWidth = newBounds.Width; int newHeight = newBounds.Height; if (nodeCount == 0) { if (node.Slide != null) { if (node.Slide.PresentationSize == Size.Empty) { node.Slide.PresentationSize = Document.ActiveDocument.PresentationSize; } g.DrawImage(node.Slide.Thumb, newBounds); } else { StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; g.DrawString("No slides defined ...", SystemFonts.MenuFont, Brushes.Black, thumbRect, sf); } } else if (nodeCount == 1) { this.DrawNodeInRect((SlideshowTreeNode)node.Nodes[0], newBounds, g); } else if (nodeCount <= 4) { g.DrawRectangle(Pens.DarkGray, newBounds); newWidth = (int)((newBounds.Width - 1) / 2f); newHeight = (int)((newBounds.Height - 1) / 2f); Rectangle subItemRect = new Rectangle(newBounds.Location, new Size(newWidth, newHeight)); for (int i = 0; i < nodeCount; i++) { this.DrawNodeInRect((SlideshowTreeNode)node.Nodes[i], subItemRect, g); if (i % 2 == 0) { subItemRect.Offset(newWidth + 1, 0); } else { subItemRect.Offset(-newWidth - 1, newHeight + 1); } } } else { g.DrawRectangle(Pens.DarkGray, newBounds); newWidth = (int)((newBounds.Width - 2) / 3f); newHeight = (int)((newBounds.Height - 2) / 3f); Rectangle subItemRect = new Rectangle(newBounds.Location, new Size(newWidth, newHeight)); for (int i = 0; i <= Math.Min(9, nodeCount - 1); i++) { if (i == 8 && nodeCount > 9) { int itemsLeft = nodeCount - i; g.DrawString(itemsLeft.ToString() + " more", SystemFonts.MenuFont, Brushes.Red, subItemRect); return; } this.DrawNodeInRect((SlideshowTreeNode)node.Nodes[i], subItemRect, g); if (i == 2 || i == 5) { subItemRect.Offset(-newWidth * 2 - 2, newHeight + 1); } else { subItemRect.Offset(newWidth + 1, 0); } } } }
/////////////////////////////////////////////////////////////////////////////// // Defining Constants // /////////////////////////////////////////////////////////////////////////////// #region CONSTANTS #endregion //CONSTANTS /////////////////////////////////////////////////////////////////////////////// // Defining Variables, Enumerations, Events // /////////////////////////////////////////////////////////////////////////////// #region FIELDS #endregion //FIELDS /////////////////////////////////////////////////////////////////////////////// // Construction and Initializing methods // /////////////////////////////////////////////////////////////////////////////// #region CONSTRUCTION #endregion //CONSTRUCTION /////////////////////////////////////////////////////////////////////////////// // Defining Enumerations // /////////////////////////////////////////////////////////////////////////////// #region ENUMS #endregion ENUMS /////////////////////////////////////////////////////////////////////////////// // Defining Properties // /////////////////////////////////////////////////////////////////////////////// #region PROPERTIES #endregion //PROPERTIES /////////////////////////////////////////////////////////////////////////////// // Public methods // /////////////////////////////////////////////////////////////////////////////// #region PUBLICMETHODS #endregion //PUBLICMETHODS /////////////////////////////////////////////////////////////////////////////// // Inherited methods // /////////////////////////////////////////////////////////////////////////////// #region OVERRIDES /// <summary> /// Overridden. Defines specialized handling for drawing /// list view items thats object are of type <see cref="SlideshowTreeNode"/> /// </summary> /// <param name="g">The <see cref="Graphics"/> to be used.</param> /// <param name="r">The bounding <see cref="Rectangle"/> of the item.</param> /// <returns><strong>True</strong> if this method handled the drawing, /// otherwise <strong>false</strong>.</returns> public override bool OptionalRender(Graphics g, Rectangle r) { // If we're in any other view than Tile, just let the default process do it's stuff if (this.ListView.View != View.Tile) { return(false); } try { Rectangle boundsWithoutPadding = r; boundsWithoutPadding.Inflate(2, 2); BufferedGraphics buffered; Rectangle thumbRect = this.GetThumbRect(ref g, r, out buffered); SlideshowTreeNode node = this.RowObject as SlideshowTreeNode; if (node.Slide != null) { if (node.Slide.PresentationSize == Size.Empty) { node.Slide.PresentationSize = Document.ActiveDocument.PresentationSize; } g.DrawImage(node.Slide.Thumb, thumbRect); if (node.Slide.MouseCursorVisible) { DrawMouse(g, r, thumbRect); } // Draw audio icon if (node.Slide.BackgroundSound != null && node.Slide.BackgroundSound.ShouldPlay) { DrawAudioIcon(g, r, thumbRect); } } else { g.FillRectangle(Brushes.LightGray, thumbRect); g.DrawRectangle(Pens.DarkGray, thumbRect); this.DrawNodeInRect(node, thumbRect, g); } // Draw title DrawTitle(g, r, thumbRect, node.Text); // Draw chains DrawChains(g, boundsWithoutPadding, node); // Draw dice icon if (node.Randomize) { DrawDice(g, r, thumbRect); } // Draw Trial icon if (node.Tag != null) { if (node.Tag.ToString() == "Trial") { DrawTrialIcon(g, r, thumbRect); } } // Finally render the buffered graphics buffered.Render(); buffered.Dispose(); } catch (Exception ex) { ExceptionMethods.HandleException(ex); } // Return true to say that we've handled the drawing return(true); }