mirror of
https://github.com/sourcegit-scm/sourcegit
synced 2025-05-26 22:54:59 +00:00
refactor<*>: rewrite all codes...
This commit is contained in:
parent
89ff8aa744
commit
30ab8ae954
342 changed files with 17208 additions and 19633 deletions
228
src/Views/Controls/Tree.cs
Normal file
228
src/Views/Controls/Tree.cs
Normal file
|
@ -0,0 +1,228 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace SourceGit.Views.Controls {
|
||||
|
||||
/// <summary>
|
||||
/// 树
|
||||
/// </summary>
|
||||
public class Tree : TreeView {
|
||||
public static readonly DependencyProperty MultiSelectionProperty = DependencyProperty.Register(
|
||||
"MultiSelection",
|
||||
typeof(bool),
|
||||
typeof(Tree),
|
||||
new PropertyMetadata(false));
|
||||
|
||||
public bool MultiSelection {
|
||||
get { return (bool)GetValue(MultiSelectionProperty); }
|
||||
set { SetValue(MultiSelectionProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty IndentProperty = DependencyProperty.Register(
|
||||
"Indent",
|
||||
typeof(double),
|
||||
typeof(TreeItem),
|
||||
new PropertyMetadata(16.0));
|
||||
|
||||
public double Indent {
|
||||
get { return (double)GetValue(IndentProperty); }
|
||||
set { SetValue(IndentProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly RoutedEvent SelectionChangedEvent = EventManager.RegisterRoutedEvent(
|
||||
"SelectionChanged",
|
||||
RoutingStrategy.Bubble,
|
||||
typeof(RoutedEventHandler),
|
||||
typeof(Tree));
|
||||
|
||||
public event RoutedEventHandler SelectionChanged {
|
||||
add { AddHandler(SelectionChangedEvent, value); }
|
||||
remove { RemoveHandler(SelectionChangedEvent, value); }
|
||||
}
|
||||
|
||||
public List<object> Selected {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public Tree() {
|
||||
Selected = new List<object>();
|
||||
PreviewMouseDown += OnPreviewMouseDown;
|
||||
}
|
||||
|
||||
public TreeItem FindItem(DependencyObject elem) {
|
||||
if (elem == null) return null;
|
||||
if (elem is TreeItem) return elem as TreeItem;
|
||||
if (elem is Tree) return null;
|
||||
return FindItem(VisualTreeHelper.GetParent(elem));
|
||||
}
|
||||
|
||||
public void SelectAll() {
|
||||
SelectAllChildren(this);
|
||||
RaiseEvent(new RoutedEventArgs(SelectionChangedEvent));
|
||||
}
|
||||
|
||||
public void UnselectAll() {
|
||||
if (Selected.Count == 0) return;
|
||||
|
||||
UnselectAllChildren(this);
|
||||
Selected.Clear();
|
||||
RaiseEvent(new RoutedEventArgs(SelectionChangedEvent));
|
||||
}
|
||||
|
||||
protected override DependencyObject GetContainerForItemOverride() {
|
||||
return new TreeItem(0, Indent);
|
||||
}
|
||||
|
||||
protected override bool IsItemItsOwnContainerOverride(object item) {
|
||||
return item is TreeItem;
|
||||
}
|
||||
|
||||
protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue) {
|
||||
base.OnItemsSourceChanged(oldValue, newValue);
|
||||
|
||||
if (Selected.Count > 0) {
|
||||
Selected.Clear();
|
||||
RaiseEvent(new RoutedEventArgs(SelectionChangedEvent));
|
||||
}
|
||||
}
|
||||
|
||||
private TreeItem FindItemByDataContext(ItemsControl control, object data) {
|
||||
if (control == null) return null;
|
||||
|
||||
for (int i = 0; i < control.Items.Count; i++) {
|
||||
var child = control.ItemContainerGenerator.ContainerFromIndex(i) as TreeItem;
|
||||
if (control.Items[i] == data) return child;
|
||||
|
||||
var found = FindItemByDataContext(child, data);
|
||||
if (found != null) return found;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e) {
|
||||
var hit = VisualTreeHelper.HitTest(this, e.GetPosition(this));
|
||||
if (hit == null || hit.VisualHit == null) return;
|
||||
|
||||
var item = FindItem(hit.VisualHit);
|
||||
if (item == null) return;
|
||||
|
||||
if (!MultiSelection) {
|
||||
if (item.IsChecked) return;
|
||||
AddSelected(item, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) {
|
||||
if (item.IsChecked) {
|
||||
RemoveSelected(item);
|
||||
} else {
|
||||
AddSelected(item, false);
|
||||
}
|
||||
} else if ((Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)) && Selected.Count > 0) {
|
||||
var last = FindItemByDataContext(this, Selected.Last());
|
||||
if (last == item) return;
|
||||
|
||||
var lastPos = last.PointToScreen(new Point(0, 0));
|
||||
var curPos = item.PointToScreen(new Point(0, 0));
|
||||
if (lastPos.Y > curPos.Y) {
|
||||
SelectRange(this, item, last);
|
||||
} else {
|
||||
SelectRange(this, last, item);
|
||||
}
|
||||
|
||||
AddSelected(item, false);
|
||||
} else if (e.RightButton == MouseButtonState.Pressed) {
|
||||
if (item.IsChecked) return;
|
||||
AddSelected(item, true);
|
||||
} else {
|
||||
if (item.IsChecked && Selected.Count == 1) return;
|
||||
AddSelected(item, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddSelected(TreeItem item, bool removeOthers) {
|
||||
if (removeOthers && Selected.Count > 0) {
|
||||
UnselectAllChildren(this);
|
||||
Selected.Clear();
|
||||
}
|
||||
|
||||
item.IsChecked = true;
|
||||
Selected.Add(item.DataContext);
|
||||
RaiseEvent(new RoutedEventArgs(SelectionChangedEvent));
|
||||
}
|
||||
|
||||
private void RemoveSelected(TreeItem item) {
|
||||
item.IsChecked = false;
|
||||
Selected.Remove(item.DataContext);
|
||||
RaiseEvent(new RoutedEventArgs(SelectionChangedEvent));
|
||||
}
|
||||
|
||||
private void SelectAllChildren(ItemsControl control) {
|
||||
for (int i = 0; i < control.Items.Count; i++) {
|
||||
var child = control.ItemContainerGenerator.ContainerFromIndex(i) as TreeItem;
|
||||
if (child == null) continue;
|
||||
|
||||
child.IsChecked = true;
|
||||
Selected.Add(control.Items[i]);
|
||||
SelectAllChildren(child);
|
||||
}
|
||||
}
|
||||
|
||||
private void UnselectAllChildren(ItemsControl control) {
|
||||
for (int i = 0; i < control.Items.Count; i++) {
|
||||
var child = control.ItemContainerGenerator.ContainerFromIndex(i) as TreeItem;
|
||||
if (child == null) continue;
|
||||
if (child.IsChecked) child.IsChecked = false;
|
||||
UnselectAllChildren(child);
|
||||
}
|
||||
}
|
||||
|
||||
private int SelectRange(ItemsControl control, TreeItem from, TreeItem to, int matches = 0) {
|
||||
for (int i = 0; i < control.Items.Count; i++) {
|
||||
var child = control.ItemContainerGenerator.ContainerFromIndex(i) as TreeItem;
|
||||
if (child == null) continue;
|
||||
|
||||
if (matches == 1) {
|
||||
if (child == to) return 2;
|
||||
Selected.Add(control.Items[i]);
|
||||
child.IsChecked = true;
|
||||
if (TryEndRangeSelection(child, to)) return 2;
|
||||
} else if (child == from) {
|
||||
matches = 1;
|
||||
if (TryEndRangeSelection(child, to)) return 2;
|
||||
} else {
|
||||
matches = SelectRange(child, from, to, matches);
|
||||
if (matches == 2) return 2;
|
||||
}
|
||||
}
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
private bool TryEndRangeSelection(ItemsControl control, TreeItem end) {
|
||||
for (int i = 0; i < control.Items.Count; i++) {
|
||||
var child = control.ItemContainerGenerator.ContainerFromIndex(i) as TreeItem;
|
||||
if (child == null) continue;
|
||||
|
||||
if (child == end) {
|
||||
return true;
|
||||
} else {
|
||||
Selected.Add(control.Items[i]);
|
||||
child.IsChecked = true;
|
||||
|
||||
var ended = TryEndRangeSelection(child, end);
|
||||
if (ended) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue