private void ClearItems() { foreach (ItemDisplayInfo info in ItemDisplayInfos) { mainGrid.Children.Remove(info.ItemButton); mainGrid.Children.Remove(info.ItemLabel); } ItemDisplayInfos.Clear(); }
// This is a bit more complicated. // We have to account for all the stuff that hovering over/pressing/etc... on an item does. private void CreateDisplayInfo(PieItem pieItem, int number, int totalItems) { ItemDisplayInfo itemInfo = new ItemDisplayInfo(); // The PieItem itemInfo.Item = pieItem; // The Button control to be used in the main window. // Here, we set the non-user-configurable options. itemInfo.ItemButton = new Button(); itemInfo.ItemButton.HorizontalAlignment = HorizontalAlignment.Center; itemInfo.ItemButton.VerticalAlignment = VerticalAlignment.Center; itemInfo.ItemButton.Background = System.Windows.Media.Brushes.Transparent; itemInfo.ItemButton.BorderBrush = System.Windows.Media.Brushes.Transparent; // Currently just a blank image, will actually be set to something later on. var itemImage = new System.Windows.Controls.Image(); itemInfo.ItemButton.Content = itemImage; // The Label control to be used in the main window. itemInfo.ItemLabel = new Label(); itemInfo.ItemLabel.HorizontalAlignment = HorizontalAlignment.Center; itemInfo.ItemLabel.VerticalAlignment = VerticalAlignment.Center; // This fixes the flashing button issue if the mouse is on top of both the button and the label. itemInfo.ItemLabel.IsHitTestVisible = false; // Invisible by default. Will activate only on mouse hover on button. itemInfo.ItemLabel.Visibility = Visibility.Hidden; UpdateItemAppearance(itemInfo, number, totalItems); itemInfo.ItemButton.MouseEnter += (s, e) => { itemInfo.ItemLabel.Visibility = Visibility.Visible; }; itemInfo.ItemButton.MouseLeave += (s, e) => { itemInfo.ItemLabel.Visibility = Visibility.Hidden; }; // Handle custom clicking and dragging in these next three functions. // MouseDown just means the mouse has been pressed down on the button. // Dragging means the mouse has moved past the given threshold while MouseDown and we started visually dragging. itemInfo.ItemButton.PreviewMouseLeftButtonDown += (s, e) => { itemInfo.MouseDown = true; itemInfo.InitialMousePosition = Mouse.GetPosition(mainGrid); }; itemInfo.ItemButton.PreviewMouseLeftButtonUp += (s, e) => { if (itemInfo.Dragging) { RefreshFolder(); Config.SaveItems(RootFolder); } else { itemInfo.Item.LeftClick(this); } itemInfo.MouseDown = false; itemInfo.Dragging = false; itemInfo.ItemButton.RenderTransform = Transform.Identity; itemInfo.ItemLabel.RenderTransform = Transform.Identity; }; itemInfo.ItemButton.PreviewMouseMove += (s, e) => { if (!itemInfo.MouseDown) { return; } var currentMousePoint = Mouse.GetPosition(mainGrid); if (itemInfo.Dragging) { // TODO: Constantly creating a bunch of new objects here feels inefficient. var offset = new TranslateTransform(currentMousePoint.X - itemInfo.InitialMousePosition.X, currentMousePoint.Y - itemInfo.InitialMousePosition.Y); itemInfo.ItemButton.RenderTransform = offset; itemInfo.ItemLabel.RenderTransform = offset; // TODO: Handle item swapping here. System.Windows.Point centerPoint = new System.Windows.Point(mainGrid.Width / 2, mainGrid.Height / 2); double angle = Math.Atan2(currentMousePoint.Y - centerPoint.Y, currentMousePoint.X - centerPoint.X); // Make between $0$ and $2\pi$ if (angle < 0) { angle += 2 * Math.PI; } // itemInfo.ItemLabel.Content = angle.ToString(); // You're gonna need to draw a picture for this. // Sorry ahead of time. int oldPosition = CurrentFolder.Items.IndexOf(itemInfo.Item); int halfSpaces = (int)(2 * angle / (2 * Math.PI / CurrentFolder.Items.Count)); int newPosition; // Probably will never get strict inequality, but safety for roundoff nonsense. if (halfSpaces <= 0 || halfSpaces >= 2 * CurrentFolder.Items.Count - 1) { newPosition = 0; } else { newPosition = (halfSpaces + 1) / 2; } //itemInfo.ItemLabel.Content = oldPosition.ToString(); // Swap oldPosition and newPosition if (newPosition != oldPosition) { if (oldPosition < newPosition) { CurrentFolder.Items.Insert(newPosition + 1, itemInfo.Item); CurrentFolder.Items.RemoveAt(oldPosition); } else // newPosition < oldPosition { CurrentFolder.Items.Insert(newPosition, itemInfo.Item); CurrentFolder.Items.RemoveAt(oldPosition + 1); } // TODO: The behaviour when "swapping" the last and first items might not be // exactly what the user expects. Investigate making this more intuitive? RefreshFolder(); // Start dragging the new Button that was generated during RefreshFolder(). // Here's a cheap way to pull this off. Just replace the new one with the old one. int newInfoIndex = ItemDisplayInfos.FindIndex((s) => { return(s.Item == itemInfo.Item); }); mainGrid.Children.Remove(ItemDisplayInfos[newInfoIndex].ItemButton); mainGrid.Children.Remove(ItemDisplayInfos[newInfoIndex].ItemLabel); ItemDisplayInfos[newInfoIndex] = itemInfo; mainGrid.Children.Add(itemInfo.ItemButton); mainGrid.Children.Add(itemInfo.ItemLabel); } } else { if (System.Windows.Point.Subtract(currentMousePoint, itemInfo.InitialMousePosition).Length >= Config.PieItemDragSensitivity) // TODO: Implement custom tolerances { itemInfo.Dragging = true; } } }; // Create the context menu MenuItem settingsMenuItem = new MenuItem(); settingsMenuItem.Header = "Item settings"; settingsMenuItem.Click += (s, e) => { PieItemSettingsWindow pieItemSettingsWindow = new PieItemSettingsWindow(pieItem, CurrentFolder); pieItemSettingsWindow.ShowDialog(); // Replace the old pieItem with the new one if (pieItemSettingsWindow.Saved) { int i = CurrentFolder.Items.IndexOf(pieItem); // You know, I feel like this should never happen if (i == -1) { return; } CurrentFolder.Items[i] = pieItemSettingsWindow.NewPieItem; RefreshFolder(); Config.SaveItems(RootFolder); } }; MenuItem removeMenuItem = new MenuItem(); removeMenuItem.Header = "Remove"; removeMenuItem.Click += (s, e) => { CurrentFolder.Items.Remove(pieItem); RefreshFolder(); Config.SaveItems(RootFolder); }; itemInfo.ItemButton.ContextMenu = new ContextMenu(); itemInfo.ItemButton.ContextMenu.Items.Add(settingsMenuItem); itemInfo.ItemButton.ContextMenu.Items.Add(removeMenuItem); //TODO: Figure out transparency of background/border on hover. ItemDisplayInfos.Add(itemInfo); }