//private bool IsValidDropTarget(UIElement target) //{ // if (target == null) return false; // var targetTreeViewItem = GetNearestContainer(target); // if (targetTreeViewItem == null) return false; // var targetBookItem = targetTreeViewItem.Header as BookItem; // if (targetBookItem == null) return false; // return IsValidDropTarget(targetBookItem, _sourceItem); //} private bool IsValidDropTarget(BookItem target, int relative /*, BookItem dragging*/) { var dragging = _sourceItem; switch (target.Type) { // cannot drop onto recents case BookItemType.Recents: case BookItemType.Recent: return(false); case BookItemType.Solution: // always, whatever the value of relative return(target != dragging && !IsDescendant(target, dragging) && !IsCloseSibling(target, dragging, relative)); case BookItemType.Folder: if (target == dragging || IsDescendant(target, dragging)) { return(false); } if (target == dragging.Parent) { return(relative < 0); // not ON parent but before } return(true); //return target != dragging && target != dragging.Parent && !IsDescendant(target, dragging); } return(false); }
/// <summary> /// Clone a book item under a new parent and with a new type. /// </summary> /// <param name="newParent">The new parent item.</param> /// <param name="newType">The new type.</param> /// <returns>The cloned book item.</returns> /// <remarks> /// <para>The cloned item shares its <see cref="Items"/> collection with the source item.</para> /// <para>The cloned item is *not* added to the new parent.</para> /// </remarks> public BookItem Clone(BookItem newParent, BookItemType newType) { return(new BookItem(newParent, newType, Path, Items) { Header = Header }); }
public IEnumerable <BookItem> GetAll() { var recentItems = RecentSource.GetRecents(); var settingItems = ItemSource.Load(); var root = new List <BookItem>(); var recentFolder = new BookItem(null, BookItemType.Recents) { Header = "Recent" }; root.Add(recentFolder); foreach (var item in recentItems) { // fixme test availability? var solutionName = Path.GetFileNameWithoutExtension(item.Path); recentFolder.Items.Add(new BookItem(recentFolder, BookItemType.Recent, item.Path) { Header = solutionName }); } foreach (var item in settingItems) { root.Add(item); } return(root); }
/// <summary> /// Gets the items from the settings. /// </summary> public IList <BookItem> Load() { var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "SolutionBook.settings"); if (!File.Exists(path)) { return(new List <BookItem>()); } void Read(IEnumerable <XElement> elements, ICollection <BookItem> items, BookItem parent) { foreach (var element in elements) { if (element.Name == "Solution") { items.Add(new BookItem(parent, BookItemType.Solution, element.Attribute("path").Value) { Header = element.Attribute("name").Value }); } else { var folder = new BookItem(parent, BookItemType.Folder) { Header = element.Attribute("name").Value }; items.Add(folder); Read(element.Elements(), folder.Items, folder); } } } XDocument document = null; var attempts = 0; while (document == null && attempts++ < 8) { try { using (var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None)) { document = XDocument.Load(stream); } } catch { Thread.Sleep(250); } } var settingItems = new List <BookItem>(); if (document != null) { Read(document.Root.Elements(), settingItems, null); } return(settingItems); }
/// <summary> /// Initializes a new instance of the <see cref="BookItem"/> class with a parent item. /// </summary> /// <param name="parent">A parent item, or <c>null</c> for root items.</param> /// <param name="type">The book item type.</param> /// <param name="path">The path of the solution.</param> /// <param name="items">The child items.</param> private BookItem(BookItem parent, BookItemType type, string path, ObservableCollection <BookItem> items) { Items = items; Parent = parent; Type = type; Path = path; }
private void DoDrop(DragDropEffects effect) { if (_targetItem == null) { return; } if (effect == DragDropEffects.Move) { if (_sourceItem.Parent == null) { Book.Items.Remove(_sourceItem); } else { _sourceItem.Parent.Items.Remove(_sourceItem); } } int targetIndex = _targetItem.Parent == null ? Book.Items.IndexOf(_targetItem) : _targetItem.Parent.Items.IndexOf(_targetItem); if (effect == DragDropEffects.Move || effect == DragDropEffects.Copy) { var newType = _sourceItem.Type == BookItemType.Recent ? BookItemType.Solution : _sourceItem.Type; var newParent = _targetRelative == 0 ? _targetItem : _targetItem.Parent; var newItem = _sourceItem.Clone(newParent, newType); if (_targetRelative == 0) { newParent.Items.Add(newItem); } else { if (_targetRelative > 0) { targetIndex += 1; } if (newParent == null) { Book.Items.Insert(targetIndex, newItem); } else { newParent.Items.Insert(targetIndex, newItem); } } } _targetItem = null; _targetRelative = 0; _sourceItem = null; //Save(); }
private bool CanBeDragged(BookItem bookItem) { if (bookItem == null) { return(false); } // that one does not move return(bookItem.Type != BookItemType.Recents); }
private bool IsDescendant(BookItem item, BookItem parent) { while (item != null) { if (item.Parent == parent) { return(true); } item = item.Parent; } return(false); }
private void EndEdit(string value = null) { if (_editItem == null) { return; } _editItem.Header = string.IsNullOrWhiteSpace(value) ? _editOrigin : value; _editItem.IsEditing = false; _editItem = null; //if (!string.IsNullOrWhiteSpace(value)) // Save(); }
private bool IsCloseSibling(BookItem target, BookItem dragging, int relative) { if (relative == 0) { return(false); } if (target.Parent != dragging.Parent) { return(false); } var targetIndex = GetItemIndex(target); var draggingIndex = GetItemIndex(dragging); return(draggingIndex == targetIndex + relative); }
private double GetWidth(BookItem target, TreeViewItem targetViewItem, int relative) { var index = target.Parent == null ? Book.Items.IndexOf(target) : target.Parent.Items.IndexOf(target); if (index < 0) { throw new Exception("panic"); } index += relative; if (index < 0) { index++; } var count = target.Parent == null ? Book.Items.Count : target.Parent.Items.Count; if (index == count) { index--; } if (index < 0) { throw new Exception("panic"); } var other = target.Parent == null ? Book.Items[index] as BookItem : target.Parent.Items[index]; //Debug.WriteLine("W: " + target.Header + " - " + other.Header); var targetPresenter = GetPresenter(targetViewItem); var otherViewItem = GetContainerFromItem(other) as TreeViewItem; var otherPresenter = GetPresenter(otherViewItem); var offset = targetPresenter.TranslatePoint(new Point(0, 0), targetViewItem).X; return(offset + Math.Max(otherPresenter.DesiredSize.Width, targetPresenter.DesiredSize.Width)); }
private void Book_MouseMove(object sender, MouseEventArgs e) { if (e.LeftButton != MouseButtonState.Pressed) { return; } // Note: This should be based on some accessibility number and not just 2 pixels const double trigger = 2.0; var currentPosition = e.GetPosition(Book); var dx = Math.Abs(currentPosition.X - _lastMouseDown.X); var dy = Math.Abs(currentPosition.Y - _lastMouseDown.Y); if (dx <= trigger || dy <= trigger) { return; } // todo: cannot drag 'Recents' folder, anything else is ok // todo: cannot drag folder to child? var selectedItem = (BookItem)Book.SelectedItem; if (selectedItem == null || !CanBeDragged(selectedItem)) { return; } var container = GetContainerFromItem(selectedItem); if (container != null) { _sourceItem = selectedItem; var finalDropEffect = DragDrop.DoDragDrop(container, selectedItem, DragDropEffect); SetAdorner(null); lock (_booklock) { DoDrop(finalDropEffect); } } }
private TreeViewItem GetContainerFromItem(BookItem item) { var _stack = new Stack <BookItem>(); _stack.Push(item); var parent = item.Parent; while (parent != null) { _stack.Push(parent); parent = parent.Parent; } ItemsControl container = Book; while ((_stack.Count > 0) && (container != null)) { BookItem top = _stack.Pop(); container = (ItemsControl)container.ItemContainerGenerator.ContainerFromItem(top); } return(container as TreeViewItem); }
private int GetItemIndex(BookItem item) { return(item.Parent == null?Book.Items.IndexOf(item) : item.Parent.Items.IndexOf(item)); }
private void BeginEdit(BookItem bookItem) { _editItem = bookItem; _editOrigin = bookItem.Header; bookItem.IsEditing = true; }
/// <summary> /// Initializes a new instance of the <see cref="BookItem"/> class with a parent item. /// </summary> /// <param name="parent">A parent item, or <c>null</c> for root items.</param> /// <param name="type">The book item type.</param> /// <param name="path">The path of the solution.</param> public BookItem(BookItem parent, BookItemType type, string path = null) : this(parent, type, path, new ObservableCollection <BookItem>()) { }