5
// Lluis Sanchez <lluis@xamarin.com>
7
// Copyright (c) 2011 Xamarin Inc
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
10
// of this software and associated documentation files (the "Software"), to deal
11
// in the Software without restriction, including without limitation the rights
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
// copies of the Software, and to permit persons to whom the Software is
14
// furnished to do so, subject to the following conditions:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
using System.Collections.Generic;
28
using System.Runtime.InteropServices;
30
namespace Xwt.GtkBackend
32
public class CustomListModel: GLib.Object, Gtk.TreeModelImplementor
34
IListDataSource source;
35
Dictionary<int,int> nodeHash = new Dictionary<int,int> ();
36
Dictionary<int,int> handleHash = new Dictionary<int,int> ();
39
Gtk.TreeModelAdapter adapter;
42
public CustomListModel (IntPtr p): base (p)
46
public CustomListModel (IListDataSource source, Gtk.Widget w)
50
adapter = new Gtk.TreeModelAdapter (this);
51
colTypes = source.ColumnTypes;
52
source.RowChanged += HandleRowChanged;
53
source.RowDeleted += HandleRowDeleted;
54
source.RowInserted += HandleRowInserted;
55
source.RowsReordered += HandleRowsReordered;
58
void HandleRowsReordered (object sender, ListRowOrderEventArgs e)
60
var p = new Gtk.TreePath (new int[] { e.Row });
61
var it = IterFromNode (e.Row);
62
adapter.EmitRowsReordered (p, it, e.ChildrenOrder);
63
parent.QueueResize ();
66
void HandleRowInserted (object sender, ListRowEventArgs e)
68
var p = new Gtk.TreePath (new int[] { e.Row });
69
var it = IterFromNode (e.Row);
70
adapter.EmitRowInserted (p, it);
71
parent.QueueResize ();
74
void HandleRowDeleted (object sender, ListRowEventArgs e)
76
var p = new Gtk.TreePath (new int[] { e.Row });
77
adapter.EmitRowDeleted (p);
78
parent.QueueResize ();
81
void HandleRowChanged (object sender, ListRowEventArgs e)
83
var p = new Gtk.TreePath (new int[] { e.Row });
84
var it = IterFromNode (e.Row);
85
adapter.EmitRowChanged (p, it);
86
parent.QueueResize ();
89
public Gtk.TreeModelAdapter Store {
90
get { return adapter; }
93
Gtk.TreeIter IterFromNode (int node)
96
if (!handleHash.TryGetValue (node, out gch)) {
98
handleHash [node] = gch;
99
nodeHash [gch] = node;
101
Gtk.TreeIter result = Gtk.TreeIter.Zero;
102
result.UserData = (IntPtr)gch;
106
int NodeFromIter (Gtk.TreeIter iter)
109
int gch = (int)iter.UserData;
110
nodeHash.TryGetValue (gch, out node);
114
#region TreeModelImplementor implementation
115
public GLib.GType GetColumnType (int index)
117
return (GLib.GType)colTypes [index];
120
public bool GetIter (out Gtk.TreeIter iter, Gtk.TreePath path)
122
iter = Gtk.TreeIter.Zero;
123
if (path.Indices.Length == 0)
125
int row = path.Indices [0];
126
if (row >= source.RowCount) {
129
iter = IterFromNode (row);
133
public Gtk.TreePath GetPath (Gtk.TreeIter iter)
135
int row = NodeFromIter (iter);
136
return new Gtk.TreePath (new int[] { row });
139
public void GetValue (Gtk.TreeIter iter, int column, ref GLib.Value value)
141
int row = NodeFromIter (iter);
142
var v = source.GetValue (row, column);
143
value = v != null ? new GLib.Value (v) : GLib.Value.Empty;
146
public bool IterNext (ref Gtk.TreeIter iter)
148
int row = NodeFromIter (iter);
149
if (++row < source.RowCount) {
150
iter = IterFromNode (row);
156
public bool IterChildren (out Gtk.TreeIter iter, Gtk.TreeIter parent)
158
iter = Gtk.TreeIter.Zero;
162
public bool IterHasChild (Gtk.TreeIter iter)
167
public int IterNChildren (Gtk.TreeIter iter)
169
if (iter.Equals (Gtk.TreeIter.Zero))
170
return source.RowCount;
175
public bool IterNthChild (out Gtk.TreeIter iter, Gtk.TreeIter parent, int n)
177
if (parent.Equals (Gtk.TreeIter.Zero)) {
178
iter = IterFromNode (n);
181
iter = Gtk.TreeIter.Zero;
186
public bool IterParent (out Gtk.TreeIter iter, Gtk.TreeIter child)
188
iter = Gtk.TreeIter.Zero;
192
public void RefNode (Gtk.TreeIter iter)
196
public void UnrefNode (Gtk.TreeIter iter)
200
public Gtk.TreeModelFlags Flags {
202
return Gtk.TreeModelFlags.ItersPersist | Gtk.TreeModelFlags.ListOnly;
206
public int NColumns {
208
return colTypes.Length;