2012-01-24 03:01:53 +04:00
|
|
|
|
//
|
|
|
|
|
// TreeStoreBackend.cs
|
|
|
|
|
//
|
|
|
|
|
// Author:
|
2012-04-04 22:34:32 +04:00
|
|
|
|
// Eric Maupin <ermau@xamarin.com>
|
2012-01-24 03:01:53 +04:00
|
|
|
|
//
|
2012-04-04 22:34:32 +04:00
|
|
|
|
// Copyright (c) 2012 Xamarin, Inc.
|
2012-01-24 03:01:53 +04:00
|
|
|
|
//
|
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
|
|
|
// in the Software without restriction, including without limitation the rights
|
|
|
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
|
|
|
// furnished to do so, subject to the following conditions:
|
2012-04-04 22:34:32 +04:00
|
|
|
|
//
|
2012-01-24 03:01:53 +04:00
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
|
// all copies or substantial portions of the Software.
|
2012-04-04 22:34:32 +04:00
|
|
|
|
//
|
2012-01-24 03:01:53 +04:00
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
|
// THE SOFTWARE.
|
|
|
|
|
|
|
|
|
|
using System;
|
2012-04-04 22:34:32 +04:00
|
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.ObjectModel;
|
|
|
|
|
using System.Collections.Specialized;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Linq;
|
2012-01-24 03:01:53 +04:00
|
|
|
|
using Xwt.Backends;
|
|
|
|
|
|
|
|
|
|
namespace Xwt.WPFBackend
|
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public class TreeStoreBackend
|
|
|
|
|
: Backend, ITreeStoreBackend, INotifyPropertyChanged, INotifyCollectionChanged, IEnumerable
|
2012-02-10 05:57:45 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
2012-02-10 05:57:45 +04:00
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public event NotifyCollectionChangedEventHandler CollectionChanged
|
2012-02-10 05:57:45 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
add { this.topNodes.CollectionChanged += value; }
|
|
|
|
|
remove { this.topNodes.CollectionChanged -= value; }
|
2012-02-10 05:57:45 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-01-24 03:01:53 +04:00
|
|
|
|
public event EventHandler<TreeNodeEventArgs> NodeInserted;
|
|
|
|
|
public event EventHandler<TreeNodeChildEventArgs> NodeDeleted;
|
|
|
|
|
public event EventHandler<TreeNodeEventArgs> NodeChanged;
|
|
|
|
|
public event EventHandler<TreeNodeOrderEventArgs> NodesReordered;
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public Type[] ColumnTypes
|
|
|
|
|
{
|
|
|
|
|
get { return this.columnTypes; }
|
|
|
|
|
}
|
2012-02-10 05:57:45 +04:00
|
|
|
|
|
2012-01-24 03:01:53 +04:00
|
|
|
|
public void Initialize (Type[] columnTypes)
|
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
this.columnTypes = columnTypes.ToArray ();
|
|
|
|
|
OnPropertyChanged ("ColumnTypes");
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public TreePosition GetParent (TreePosition pos)
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
var node = (TreeStoreNode) pos;
|
|
|
|
|
if (node.Parent == null)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
return node.Parent;
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public TreePosition GetChild (TreePosition pos, int index)
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
var node = (TreeStoreNode) pos;
|
2012-04-05 19:40:37 +04:00
|
|
|
|
var list = GetListForNode (node);
|
|
|
|
|
if (list.Count == 0 || index >= list.Count)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
return list [index];
|
2012-02-10 05:57:45 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public int GetChildrenCount (TreePosition pos)
|
2012-02-10 05:57:45 +04:00
|
|
|
|
{
|
2012-04-05 19:30:56 +04:00
|
|
|
|
return GetListForNode ((TreeStoreNode) pos).Count;
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public object GetValue (TreePosition pos, int column)
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-05 20:21:38 +04:00
|
|
|
|
return ((TreeStoreNode) pos)[column];
|
2012-04-04 22:34:32 +04:00
|
|
|
|
}
|
2012-03-25 22:13:46 +04:00
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public void SetValue (TreePosition pos, int column, object value)
|
|
|
|
|
{
|
|
|
|
|
var node = (TreeStoreNode) pos;
|
2012-04-05 20:21:38 +04:00
|
|
|
|
node[column] = value;
|
2012-03-25 22:13:46 +04:00
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
OnNodeChanged (new TreeNodeEventArgs (pos));
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public TreePosition InsertBefore (TreePosition pos)
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
var node = (TreeStoreNode) pos;
|
|
|
|
|
|
|
|
|
|
var newNode = new TreeStoreNode (
|
|
|
|
|
new object[this.columnTypes.Length],
|
|
|
|
|
node);
|
|
|
|
|
|
|
|
|
|
var list = GetContainingList (node);
|
|
|
|
|
int index = list.IndexOf (node);
|
|
|
|
|
list.Insert (index, newNode);
|
|
|
|
|
|
|
|
|
|
OnNodeInserted (new TreeNodeEventArgs (newNode));
|
|
|
|
|
|
|
|
|
|
return newNode;
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public TreePosition InsertAfter (TreePosition pos)
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
var node = (TreeStoreNode) pos;
|
|
|
|
|
|
|
|
|
|
var newNode = new TreeStoreNode (
|
|
|
|
|
new object[this.columnTypes.Length],
|
|
|
|
|
node);
|
|
|
|
|
|
|
|
|
|
var list = GetContainingList (node);
|
|
|
|
|
int index = list.IndexOf (node);
|
|
|
|
|
list.Insert (index + 1, newNode);
|
|
|
|
|
|
|
|
|
|
OnNodeInserted (new TreeNodeEventArgs (newNode));
|
|
|
|
|
|
|
|
|
|
return newNode;
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public TreePosition AddChild (TreePosition pos)
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
var parent = (TreeStoreNode) pos;
|
2012-03-25 22:13:46 +04:00
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
var childNode = new TreeStoreNode (
|
|
|
|
|
new object[this.columnTypes.Length],
|
|
|
|
|
parent);
|
2012-03-25 22:13:46 +04:00
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
GetListForNode (parent).Add (childNode);
|
2012-03-25 22:13:46 +04:00
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
OnNodeInserted (new TreeNodeEventArgs (childNode));
|
|
|
|
|
|
|
|
|
|
return childNode;
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public void Remove (TreePosition pos)
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
var node = (TreeStoreNode) pos;
|
|
|
|
|
|
|
|
|
|
var list = GetContainingList (node);
|
|
|
|
|
int index = list.IndexOf (node);
|
|
|
|
|
list.RemoveAt (index);
|
|
|
|
|
|
|
|
|
|
OnNodeDeleted (new TreeNodeChildEventArgs (node.Parent, index));
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public TreePosition GetNext (TreePosition pos)
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
var node = (TreeStoreNode) pos;
|
|
|
|
|
|
|
|
|
|
var list = GetContainingList (node);
|
|
|
|
|
int index = list.IndexOf (node) + 1;
|
|
|
|
|
|
|
|
|
|
return (index < list.Count) ? list [index] : null;
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public TreePosition GetPrevious (TreePosition pos)
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
var node = (TreeStoreNode) pos;
|
|
|
|
|
|
|
|
|
|
var list = GetContainingList (node);
|
|
|
|
|
int index = list.IndexOf (node) - 1;
|
|
|
|
|
|
|
|
|
|
return (index > 0) ? list [index] : null;
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public void Clear ()
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
this.topNodes.Clear();
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
public IEnumerator GetEnumerator ()
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
return this.topNodes.GetEnumerator ();
|
|
|
|
|
}
|
2012-03-25 22:13:46 +04:00
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
private Type[] columnTypes;
|
|
|
|
|
private readonly ObservableCollection<TreeStoreNode> topNodes = new ObservableCollection<TreeStoreNode> ();
|
2012-03-25 22:13:46 +04:00
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
private ObservableCollection<TreeStoreNode> GetContainingList (TreeStoreNode node)
|
|
|
|
|
{
|
|
|
|
|
return (node.Parent == null) ? this.topNodes : node.Parent.Children;
|
|
|
|
|
}
|
2012-03-25 22:13:46 +04:00
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
private ObservableCollection<TreeStoreNode> GetListForNode (TreeStoreNode node)
|
|
|
|
|
{
|
|
|
|
|
return (node == null) ? this.topNodes : node.Children;
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
private void OnPropertyChanged (string name)
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
var changed = PropertyChanged;
|
|
|
|
|
if (changed != null)
|
|
|
|
|
changed (this, new PropertyChangedEventArgs (name));
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
private void OnNodeInserted (TreeNodeEventArgs e)
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
var handler = NodeInserted;
|
|
|
|
|
if (handler != null)
|
|
|
|
|
handler (this, e);
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
private void OnNodeDeleted (TreeNodeChildEventArgs e)
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
var handler = NodeDeleted;
|
|
|
|
|
if (handler != null)
|
|
|
|
|
handler (this, e);
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
private void OnNodeChanged (TreeNodeEventArgs e)
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
var handler = NodeChanged;
|
|
|
|
|
if (handler != null)
|
|
|
|
|
handler (this, e);
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
|
2012-04-04 22:34:32 +04:00
|
|
|
|
private void OnNodesReordered (TreeNodeOrderEventArgs e)
|
2012-01-24 03:01:53 +04:00
|
|
|
|
{
|
2012-04-04 22:34:32 +04:00
|
|
|
|
var handler = NodesReordered;
|
|
|
|
|
if (handler != null)
|
|
|
|
|
handler (this, e);
|
2012-01-24 03:01:53 +04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|