void ResizeAndRepositionGroups() { int iconWidth = (IconSize + IconPadding); int iconHeight = (IconSize + IconPadding); int groupY = IconPadding; int vScroll = this.VerticalScrollBar().Value; int newWidth = this.Viewport().Width(); bool filterChanged = (m_LastTextFilter != m_Model.TextFilter); lock (m_Groups) { foreach (RosterItemGroup group in this.SortedGroups) { int itemY = 0; var children = group.ChildItems(); int visibleChildren = 0; foreach (QGraphicsItem child in children) { if (child is RosterItem <T> ) { if (m_Model.IsVisible(((RosterItem <T>)child).Item)) { visibleChildren++; } } } bool groupVisibilityChanged = false; bool groupVisible = visibleChildren > 0; if (group.IsVisible() != groupVisible) { if (filterChanged) { group.SetVisible(groupVisible); } else { group.BeginFade(groupVisible); } } if (group.Y() != groupY) { if (groupVisibilityChanged || !group.IsVisible() || (group.X() == 0 && group.Y() == 0) || filterChanged) { group.SetPos(0, groupY); } else { group.BeginMove(new QPointF(0, groupY)); } } if (groupVisible) { itemY += m_HeaderHeight + IconPadding; int itemCount = children.Count; if (itemCount > 0) { int perRow = Math.Max((((int)newWidth - IconPadding) / iconWidth), 1); if (m_ListMode) { perRow = 1; } int x = IconPadding; int row = 0; int thisRow = 0; // Arrange the items for (int n = 0; n < itemCount; n++) { RosterItem <T> item = (RosterItem <T>)children[n]; bool itemVisible = m_Model.IsVisible(item.Item) && group.IsExpanded; if (item.IsVisible() != itemVisible) { if (groupVisibilityChanged) { // No need to fade children in this case. item.Opacity = itemVisible ? 1 : 0; item.SetVisible(itemVisible); } else { item.BeginFade(itemVisible); } } if (itemVisible) { // Move down to the next row if needed. if (thisRow == perRow) { row++; thisRow = 0; x = IconPadding; itemY += iconHeight; } if (item.X() != x || item.Y() != itemY) { if (groupVisibilityChanged || !item.IsVisible() || (item.X() == 0 && item.Y() == 0) || filterChanged) { item.SetPos(x, itemY); } else { item.BeginMove(new QPointF(x, itemY)); } } x += iconWidth; thisRow++; } } if (thisRow > 0) { itemY += iconHeight; } group.RowCount = row + 1; } else { group.RowCount = 0; } } else { group.RowCount = 0; } groupY += itemY; } // Update the scene's height int newHeight = groupY; var currentRect = m_Scene.SceneRect; if (currentRect.Width() != newWidth || currentRect.Height() != newHeight) { m_Scene.SetSceneRect(0, 0, newWidth, newHeight); } // Restore the scroll position if (this.VerticalScrollBar().Value != vScroll) { this.VerticalScrollBar().SetValue(vScroll); } } m_LastTextFilter = m_Model.TextFilter; }
private void model_ItemChanged(IAvatarGridModel <T> model, T item) { if (model.ModelUpdating) { return; } QApplication.Invoke(delegate { bool visibilityChanged = false; bool groupsChanged = false; lock (m_Items) { if (!m_Items.ContainsKey(item)) { Console.Error.WriteLine("Item changed before being added: " + item); // model_ItemAdded(model, item); return; } List <string> toRemove = new List <string>(); // Check if item was added to any groups foreach (string groupName in model.GetItemGroups(item)) { if (!m_Items[item].ContainsKey(groupName)) { AddItemToGroup(item, groupName); groupsChanged = true; } } // Check if item needs to be removed from any groups, redraw others. // FIXME: Don't need to redraw items we just added. foreach (RosterItem <T> gitem in m_Items[item].Values.ToArray()) { RosterItemGroup group = (RosterItemGroup)gitem.ParentItem(); var groups = model.GetItemGroups(item); if (groups.Contains(group.Name) || (groups.Count() == 0 && group.Name == "No Group")) { if (model.IsVisible(item) != gitem.IsVisible()) { visibilityChanged = true; } else { gitem.Update(); } } else { toRemove.Add(group.Name); groupsChanged = true; } } foreach (string groupName in toRemove) { RemoveItemFromGroup(item, groupName, false); } } if (visibilityChanged || groupsChanged) { ResizeAndRepositionGroups(); } }); }