/// <summary>Callback that is invoked whenever anything is added or removed from <see cref="Tabs" /> so that we can trigger a redraw of the tabs.</summary> /// <param name="sender">Object for which this event was raised.</param> /// <param name="e">Arguments associated with the event.</param> private void _tabs_CollectionModified(object sender, ListModificationEventArgs e) { SetFrameSize(); if (e.Modification == ListModification.ItemAdded || e.Modification == ListModification.RangeAdded) { for (int i = 0; i < e.Count; i++) { TitleBarTab currentTab = Tabs[i + e.StartIndex]; currentTab.Content.TextChanged += Content_TextChanged; currentTab.Closing += TitleBarTabs_Closing; if (AeroPeekEnabled) { TaskbarManager.Instance.TabbedThumbnail.SetActiveTab(CreateThumbnailPreview(currentTab)); } } } if (_overlay != null) { _overlay.Render(true); } }
/// <summary> /// When items are added to the tabs collection, we need to ensure that the <see cref="_parentWindow" />'s minimum width is set so that we can display at /// least each tab and its close buttons. /// </summary> /// <param name="sender">List of tabs in the <see cref="_parentWindow" />.</param> /// <param name="e">Arguments associated with the event.</param> private void Tabs_CollectionModified(object sender, ListModificationEventArgs e) { ListWithEvents <TitleBarTab> tabs = (ListWithEvents <TitleBarTab>)sender; if (tabs.Count == 0) { return; } int minimumWidth = tabs.Sum( tab => GetTabLeftImage(tab).Width + GetTabRightImage(tab).Width + (tab.ShowCloseButton ? tab.CloseButtonArea.Width + CloseButtonMarginLeft : 0)); minimumWidth += OverlapWidth; minimumWidth += (_parentWindow.ControlBox ? SystemInformation.CaptionButtonSize.Width : 0) - (_parentWindow.MinimizeBox ? SystemInformation.CaptionButtonSize.Width : 0) - (_parentWindow.MaximizeBox ? SystemInformation.CaptionButtonSize.Width : 0) + (ShowAddButton ? _addButtonImage.Width + AddButtonMarginLeft + AddButtonMarginRight : 0); _parentWindow.MinimumSize = new Size(minimumWidth, 0); }
/// <summary>Raises <see cref="CollectionModified" /> events.</summary> /// <param name="e">An <see cref="ListModificationEventArgs" /> that contains the event data.</param> protected virtual void OnCollectionModified(ListModificationEventArgs e) { if (_suppressEvents) { return; } if (CollectionModified != null) { CollectionModified(this, e); } }
/// <summary> /// When items are added to the tabs collection, we need to ensure that the <see cref="_parentWindow" />'s minimum width is set so that we can display at /// least each tab and its close buttons. /// </summary> /// <param name="sender">List of tabs in the <see cref="_parentWindow" />.</param> /// <param name="e">Arguments associated with the event.</param> private void Tabs_CollectionModified(object sender, ListModificationEventArgs e) { ListWithEvents<TitleBarTab> tabs = (ListWithEvents<TitleBarTab>) sender; if (tabs.Count == 0) { return; } int minimumWidth = tabs.Sum( tab => (tab.Active ? _activeLeftSideImage.Width : _inactiveLeftSideImage.Width) + (tab.Active ? _activeRightSideImage.Width : _inactiveRightSideImage.Width) + (tab.ShowCloseButton ? tab.CloseButtonArea.Width + CloseButtonMarginLeft : 0)); minimumWidth += OverlapWidth; minimumWidth += (_parentWindow.ControlBox ? SystemInformation.CaptionButtonSize.Width : 0) - (_parentWindow.MinimizeBox ? SystemInformation.CaptionButtonSize.Width : 0) - (_parentWindow.MaximizeBox ? SystemInformation.CaptionButtonSize.Width : 0) + (ShowAddButton ? _addButtonImage.Width + AddButtonMarginLeft + AddButtonMarginRight : 0); _parentWindow.MinimumSize = new Size(minimumWidth, 0); }
/// <summary> /// When a child folder is added to/removed from <see cref="BookmarksFolder.ChildFolders"/>, we add that folder to the tree view, update /// <see cref="IConnection.ParentFolder"/> for each connection in the folder, and add the folder to <see cref="_folderTreeNodes"/> if necessary. /// </summary> /// <param name="sender"><see cref="BookmarksFolder.ChildFolders"/> instance that's being modified.</param> /// <param name="e">Range specifier indicating which items were added to/removed from the collection.</param> private void ChildFolders_CollectionModified(object sender, ListModificationEventArgs e) { ListWithEvents<BookmarksFolder> childFolders = sender as ListWithEvents<BookmarksFolder>; bool sortListView = false; // If items are being added to the list of child folders if (e.Modification == ListModification.ItemModified || e.Modification == ListModification.ItemAdded || e.Modification == ListModification.RangeAdded) { for (int i = e.StartIndex; i < e.StartIndex + e.Count; i++) { // Get the tree nodes in the tree view for the parent (which will always exist) and the child (which will exist if the folder is not // newly-created and is instead being moved from another folder) BookmarksFolder currentFolder = childFolders[i]; TreeNode parentTreeNode = _folderTreeNodes.Single(kvp => kvp.Value == currentFolder.ParentFolder).Key; TreeNode folderTreeNode = _folderTreeNodes.SingleOrDefault(kvp => kvp.Value == currentFolder).Key; // If we don't have a tree node for this child (it's newly created) if (folderTreeNode == null) { // Create a new TreeNode for this child and add it to the parent folderTreeNode = new TreeNode(currentFolder.Name); parentTreeNode.Nodes.Add(folderTreeNode); // Add this tree node to the lookup _folderTreeNodes[folderTreeNode] = currentFolder; // Assign the child folders/bookmarks collection modification event handlers currentFolder.ChildFolders.CollectionModified += ChildFolders_CollectionModified; currentFolder.Bookmarks.CollectionModified += Bookmarks_CollectionModified; // Call this method recursively for the child folders under this child folder; this is necessary when we're first setting up the UI // from InitializeTreeView to ensure that all the child folders are added to the tree view and all the list modification event handlers // are assigned properly ChildFolders_CollectionModified( currentFolder.ChildFolders, new ListModificationEventArgs(ListModification.RangeAdded, 0, currentFolder.ChildFolders.Count)); } // If it's just being moved from another location, simply update its parent else { folderTreeNode.Parent.Nodes.Remove(folderTreeNode); parentTreeNode.Nodes.Add(folderTreeNode); } // If this node in the tree view is currently focused, add the child folder to the list view and set the flag indicating that we should // sort the list view if (_bookmarksFoldersTreeView.SelectedNode == parentTreeNode) { ListViewItem newItem = new ListViewItem(currentFolder.Name, 0); _bookmarksListView.Items.Add(newItem); _listViewFolders[newItem] = currentFolder; sortListView = true; } } } // Otherwise, items are being deleted from the list of child folders else { KeyValuePair<TreeNode, BookmarksFolder> containerFolder = _folderTreeNodes.SingleOrDefault(kvp => kvp.Value.ChildFolders == childFolders); if (containerFolder.Key != null) { // Responding to delete requests is a little confusing since the items have already been removed from the collection, so we look at each // child tree node in the parent tree view folder and see which ones correspond to folders that are no longer in the BookmarksFolder's // ChildFolders collection for (int i = 0; i < containerFolder.Key.Nodes.Count; i++) { TreeNode treeNode = containerFolder.Key.Nodes[i]; // We can't find this folder corresponding to this child tree node in the parent's ChildFolders collection so we know it was deleted if (!containerFolder.Value.ChildFolders.Contains(_folderTreeNodes[treeNode])) { KeyValuePair<ListViewItem, BookmarksFolder> listViewItem = _listViewFolders.SingleOrDefault(kvp => kvp.Value == _folderTreeNodes[treeNode]); // If the folder being removed from the collection is in the list view, remove it from there and set the sort flag if (listViewItem.Key != null) { _bookmarksListView.Items.Remove(listViewItem.Key); _listViewFolders.Remove(listViewItem.Key); sortListView = true; } // Remove this node and all of its children from the tree view RemoveAllFolders(treeNode); containerFolder.Key.Nodes.Remove(treeNode); i--; } } } } if (IsHandleCreated && !_deferSort) { // Sort the tree view and, if necessary, the list view _bookmarksFoldersTreeView.BeginInvoke(new Action(SortTreeView)); if (sortListView) _bookmarksListView.BeginInvoke(new Action(_bookmarksListView.Sort)); } }
/// <summary> /// When a bookmark is added to/removed from <see cref="BookmarksFolder.Bookmarks"/>, we update <see cref="_bookmarksListView"/> if the parent folder /// is currently selected. /// </summary> /// <param name="sender"><see cref="BookmarksFolder.Bookmarks"/> collection that's being modified.</param> /// <param name="e">Range specifier indicating which items were added to/removed from the collection..</param> private void Bookmarks_CollectionModified(object sender, ListModificationEventArgs e) { ListWithEvents<IConnection> bookmarks = sender as ListWithEvents<IConnection>; bool sortListView = false; // Bookmarks are being added to the collection if (e.Modification == ListModification.ItemModified || e.Modification == ListModification.ItemAdded || e.Modification == ListModification.RangeAdded) { for (int i = e.StartIndex; i < e.StartIndex + e.Count; i++) { IConnection currentBookmark = bookmarks[i]; TreeNode parentTreeNode = _folderTreeNodes.Single(kvp => kvp.Value == currentBookmark.ParentFolder).Key; // If the parent folder is currently selected in the tree view, update the list view to add the items and set the flag to sort the list // view if (_bookmarksFoldersTreeView.SelectedNode == parentTreeNode) { ListViewItem newItem = new ListViewItem(currentBookmark.DisplayName, _connectionTypeIcons[currentBookmark.GetType()]); newItem.SubItems.Add(currentBookmark.Host); _listViewConnections[newItem] = currentBookmark; _bookmarksListView.Items.Add(newItem); sortListView = true; } } } // Otherwise, bookmarks are being removed from the collection else { KeyValuePair<TreeNode, BookmarksFolder> containerFolder = _folderTreeNodes.SingleOrDefault(kvp => kvp.Value.Bookmarks == bookmarks); if (containerFolder.Key != null && containerFolder.Key == _bookmarksFoldersTreeView.SelectedNode) { // Responding to delete requests is a little confusing since the items have already been removed from the collection, so we look at each // list view item in the list view and see which ones correspond to bookmarks that are no longer in the BookmarksFolder's Bookmarks // collection for (int i = 0; i < _bookmarksListView.Items.Count; i++) { ListViewItem bookmark = _bookmarksListView.Items[i]; if (bookmark.ImageIndex == 0) continue; // If the list view doesn't contain this bookmark, it's been deleted, so remove it from the list view and set the sort flag if (!containerFolder.Value.Bookmarks.Contains(_listViewConnections[bookmark])) { _listViewConnections.Remove(bookmark); _bookmarksListView.Items.Remove(bookmark); sortListView = true; i--; } } } } // Sort the list view if necessary if (IsHandleCreated && sortListView && !_deferSort) _bookmarksListView.BeginInvoke(new Action(_bookmarksListView.Sort)); }
/// <summary> /// Handler method that's called when the contents of <see cref="_childFolders"/> are modified. Sets the <see cref="ParentFolder"/> property of each /// added/modified child folder to this folder. /// </summary> /// <param name="sender">Object from which this event originated; <see cref="_childFolders"/> in this case.</param> /// <param name="e">Arguments associated with this event.</param> private void _childFolders_CollectionModified(object sender, ListModificationEventArgs e) { if (e.Modification == ListModification.ItemAdded || e.Modification == ListModification.RangeAdded || e.Modification == ListModification.ItemModified) { for (int i = e.StartIndex; i < e.StartIndex + e.Count; i++) _childFolders[i].ParentFolder = this; } }