2
* Copyright (c) 2011-2012 Scott Ringwelski <sgringwe@mtu.edu>
4
* Originally Written by Scott Ringwelski for BeatBox Music Player
5
* BeatBox Music Player: http://www.launchpad.net/beat-box
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Library General Public
9
* License as published by the Free Software Foundation; either
10
* version 2 of the License, or (at your option) any later version.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Library General Public License for more details.
17
* You should have received a copy of the GNU Library General Public
18
* License along with this library; if not, write to the
19
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
* Boston, MA 02111-1307, USA.
25
/** Since this class is not publicly facing (the FastView is public part),
26
* this model is low level and optimized. We are not worried about stupid
29
public class BeatBox.FastGridModel : GLib.Object, TreeModel, TreeDragSource {
30
int stamp; // all iters must match this
32
/* data storage variables */
33
HashTable<int, GLib.Object> rows; // internal id -> user specified object
34
GLib.Object default_value; // Used when calling append
36
/* user specific function for get_value() */
37
public delegate Value ValueReturnFunc (int row, int column, GLib.Object o);
38
private unowned ValueReturnFunc value_func;
40
/** Initialize data storage, columns, etc. **/
41
public FastGridModel(GLib.Object default_value) {
42
rows = new HashTable<int, GLib.Object>(null, null);
43
this.default_value = default_value;
45
stamp = (int)GLib.Random.next_int();
48
public Type get_column_type (int col) {
50
return typeof(Gdk.Pixbuf);
52
return typeof(string);
54
return typeof(string);
56
return typeof(GLib.Object);
59
public TreeModelFlags get_flags () {
60
return TreeModelFlags.LIST_ONLY;
63
public bool get_iter (out TreeIter iter, TreePath path) {
65
int path_index = path.get_indices()[0];
66
if(rows.size() == 0 || path_index < 0 || path_index >= rows.size() || rows.get(path_index) == null)
69
iter.stamp = this.stamp;
70
iter.user_data = (void*)path_index;
75
public int get_n_columns () {
79
public TreePath? get_path (TreeIter iter) {
80
return new TreePath.from_string (((int)iter.user_data).to_string());
83
public void get_value (TreeIter iter, int column, out Value val) {
84
val = Value(get_column_type(column));
86
if(iter.stamp != this.stamp || column < 0 || column >= get_n_columns()) {
90
int row = (int)iter.user_data;
91
if(!(row >= rows.size())) {
92
var object = rows.get(row);
93
val = value_func(row, column, object);
97
public bool iter_children (out TreeIter iter, TreeIter? parent) {
102
public bool iter_has_child (TreeIter iter) {
107
public int iter_n_children (TreeIter? iter) {
109
return (int)rows.size();
114
public bool iter_next (ref TreeIter iter) {
115
if(iter.stamp != this.stamp)
118
iter.user_data = (void*)(((int)iter.user_data) + 1);
120
if(((int)iter.user_data) >= rows.size())
126
public bool iter_nth_child (out TreeIter iter, TreeIter? parent, int n) {
129
if(n < 0 || n >= rows.size() || parent != null)
132
iter.stamp = this.stamp;
133
iter.user_data = (void*)n;
138
public bool iter_parent (out TreeIter iter, TreeIter child) {
144
public void append (out TreeIter iter) {
147
TreePath path = new TreePath.from_string(((int)rows.size()).to_string());
148
rows.set((int)rows.size(), default_value);
149
iter.stamp = this.stamp;
150
iter.user_data = (void*)rows.size;
152
row_inserted(path, iter);
155
public void remove (TreeIter iter) {
156
if(iter.stamp != this.stamp)
159
var path = new TreePath.from_string(((int)iter.user_data).to_string());
160
rows.remove((int)iter.user_data);
163
// TODO: swap all indices > this iter's index down to maintain that
164
// the table has row ids 0..n where n is rows.size (consecutive ids)
167
// Not applicable to this custom treemodel
168
public new void set (TreeIter iter, ...) {
172
public void ref_node (TreeIter iter) {}
173
public void unref_node (TreeIter iter) {}
175
/** The beauty of this custom model. This tree model is simply a visual
176
* representation of a HashTable of objects. Before calling this
177
* method, the user should set tree_view.set_model(null). After
178
* calling this, set the tree_view.set_model(fast_model). By doing this
179
* the treeview will not listen for append events and will recalculate
180
* and draw when the model is re-added.
182
* @objects Must be a consecutive ordered hash table with indexes
183
* 0-n where n is size of the hashtable (no gaps).
185
public void set_table (HashTable<int, GLib.Object> table) {
187
for(int i = 0; i < table.size(); ++i)
188
rows.set(i, table.get(i));
191
/** Crucial. Must be set by user. Allows for this model to be abstract
192
* by allowing the user to specify the function that returns values
193
* based on the object (row) and column. **/
194
public void set_value_func (ValueReturnFunc func) {
198
public void update_row (int index) {
199
TreePath path = new TreePath.from_string(index.to_string());
200
TreeIter iter = TreeIter();
201
iter.stamp = this.stamp;
202
iter.user_data = (void*)index;
204
row_changed(path, iter);
207
/************************************
209
************************************/
210
bool drag_data_delete(TreePath path) {
214
bool drag_data_get(TreePath path, SelectionData data) {
215
/*string[] old = data.get_uris();
216
string[] cp = new string[old.length + 1];
217
for(int i = 0; i < old.length; ++i)
220
cp[cp.length - 1] = rows[int.parse(path.to_string())].uri;*/
225
bool row_draggable(TreePath path) {