Implemented Editable Cells from gtk3-demo

This commit is contained in:
Igor Vornovskii 2022-01-03 17:29:53 +05:00 committed by Harry
parent e82b07ede1
commit 1add3d8868

View File

@ -0,0 +1,291 @@
using System;
using System.Collections.Generic;
using Gtk;
namespace Samples.Sections.Widgets
{
[Section(ContentType = typeof(EditableCellsSection), Category = Category.Widgets)]
class EditableCellsSection : Box
{
private readonly TreeView _treeView;
private readonly ListStore _itemsModel;
private readonly Dictionary<CellRenderer, int> _cellColumnsRender;
private List<Item> _articles;
public EditableCellsSection() : base(Orientation.Vertical, 3)
{
_cellColumnsRender = new Dictionary<CellRenderer, int>();
ListStore numbers_model;
ScrolledWindow sw = new ScrolledWindow
{
ShadowType = ShadowType.EtchedIn
};
sw.SetPolicy(PolicyType.Automatic, PolicyType.Automatic);
this.PackStart(sw, true, true, 0);
/* create models */
_itemsModel = CreateItemsModel();
numbers_model = CreateNumbersModel();
/* create tree view */
_treeView = new TreeView(_itemsModel);
_treeView.Selection.Mode = SelectionMode.Single;
AddColumns(numbers_model);
sw.Add(_treeView);
/* some buttons */
Box hbox = new Box(Orientation.Horizontal, 4)
{
Homogeneous = true
};
this.PackStart(hbox, false, false, 0);
Button button = new Button("Add item");
button.Clicked += AddItem;
hbox.PackStart(button, true, true, 0);
button = new Button("Remove item");
button.Clicked += RemoveItem;
hbox.PackStart(button, true, true, 0);
}
private class Item
{
public int Number;
public string Product;
public int Yummy;
}
private enum ColumnItem
{
Number,
Product,
Yummy,
Num
};
private enum ColumnNumber
{
Text,
Num
};
private ListStore CreateItemsModel()
{
ListStore model;
TreeIter iter;
/* create array */
_articles = new List<Item>();
AddItems();
/* create list store */
model = new ListStore(typeof(int), typeof(string), typeof(int), typeof(bool));
/* add items */
for (int i = 0; i < _articles.Count; i++)
{
iter = model.Append();
model.SetValue(iter, (int)ColumnItem.Number, _articles[i].Number);
model.SetValue(iter, (int)ColumnItem.Product, _articles[i].Product);
model.SetValue(iter, (int)ColumnItem.Yummy, _articles[i].Yummy);
}
return model;
}
private static ListStore CreateNumbersModel()
{
ListStore model;
TreeIter iter;
/* create list store */
model = new ListStore(typeof(string), typeof(int));
/* add numbers */
for (int i = 0; i < 10; i++)
{
iter = model.Append();
model.SetValue(iter, (int)ColumnNumber.Text, i.ToString());
}
return model;
}
private void AddItems()
{
Item foo = new Item
{
Number = 3,
Product = "bottles of coke",
Yummy = 20
};
_articles.Add(foo);
foo = new Item
{
Number = 5,
Product = "packages of noodles",
Yummy = 50
};
_articles.Add(foo);
foo = new Item
{
Number = 2,
Product = "packages of chocolate chip cookies",
Yummy = 90
};
_articles.Add(foo);
foo = new Item
{
Number = 1,
Product = "can vanilla ice cream",
Yummy = 60
};
_articles.Add(foo);
foo = new Item
{
Number = 6,
Product = "eggs",
Yummy = 10
};
_articles.Add(foo);
}
private void AddColumns(ITreeModel numbersModel)
{
/* number column */
CellRendererCombo rendererCombo = new CellRendererCombo
{
Model = numbersModel,
TextColumn = (int)ColumnNumber.Text,
HasEntry = false,
Editable = true
};
rendererCombo.Edited += CellEdited;
rendererCombo.EditingStarted += EditingStarted;
_cellColumnsRender.Add(rendererCombo, (int)ColumnItem.Number);
_treeView.InsertColumn(-1, "Number", rendererCombo, "text", (int)ColumnItem.Number);
/* product column */
CellRendererText rendererText = new CellRendererText
{
Editable = true
};
rendererText.Edited += CellEdited;
_cellColumnsRender.Add(rendererText, (int)ColumnItem.Product);
_treeView.InsertColumn(-1, "Product", rendererText, "text", (int)ColumnItem.Product);
/* yummy column */
CellRendererProgress rendererProgress = new CellRendererProgress();
_cellColumnsRender.Add(rendererProgress, (int)ColumnItem.Yummy);
_treeView.InsertColumn(-1, "Yummy", rendererProgress, "value", (int)ColumnItem.Yummy);
}
private void AddItem(object sender, EventArgs e)
{
TreeIter iter;
if (_articles == null)
{
return;
}
Item foo = new Item
{
Number = 0,
Product = "Description here",
Yummy = 50
};
_articles.Add(foo);
/* Insert a new row below the current one */
_treeView.GetCursor(out TreePath path, out _);
if (path != null)
{
_ = _itemsModel.GetIter(out TreeIter current, path);
iter = _itemsModel.InsertAfter(current);
}
else
{
iter = _itemsModel.Insert(-1);
}
/* Set the data for the new row */
_itemsModel.SetValue(iter, (int)ColumnItem.Number, foo.Number);
_itemsModel.SetValue(iter, (int)ColumnItem.Product, foo.Product);
_itemsModel.SetValue(iter, (int)ColumnItem.Yummy, foo.Yummy);
/* Move focus to the new row */
path = _itemsModel.GetPath(iter);
TreeViewColumn column = _treeView.GetColumn(0);
_treeView.SetCursor(path, column, false);
}
private void RemoveItem(object sender, EventArgs e)
{
TreeSelection selection = _treeView.Selection;
if (selection.GetSelected(out TreeIter iter))
{
TreePath path = _itemsModel.GetPath(iter);
int i = path.Indices[0];
_itemsModel.Remove(ref iter);
_articles.RemoveAt(i);
}
}
private void CellEdited(object data, EditedArgs args)
{
TreePath path = new TreePath(args.Path);
int column = _cellColumnsRender[(CellRenderer)data];
_itemsModel.GetIter(out TreeIter iter, path);
switch (column)
{
case (int)ColumnItem.Number:
{
int i = path.Indices[0];
_articles[i].Number = int.Parse(args.NewText);
_itemsModel.SetValue(iter, column, _articles[i].Number);
}
break;
case (int)ColumnItem.Product:
{
string oldText = (string)_itemsModel.GetValue(iter, column);
int i = path.Indices[0];
_articles[i].Product = args.NewText;
_itemsModel.SetValue(iter, column, _articles[i].Product);
}
break;
}
}
private void EditingStarted(object o, EditingStartedArgs args)
{
((ComboBox)args.Editable).RowSeparatorFunc += SeparatorRow;
}
private bool SeparatorRow(ITreeModel model, TreeIter iter)
{
TreePath path = model.GetPath(iter);
int idx = path.Indices[0];
return idx == 5;
}
}
}