Add support for custom data sources for ListView, TreeView and ComboBox

This commit is contained in:
Lluis Sanchez 2011-11-11 11:53:53 +01:00
Родитель 33b06f4e6c
Коммит 5734e4a555
28 изменённых файлов: 878 добавлений и 79 удалений

Просмотреть файл

@ -48,6 +48,7 @@ namespace Samples
AddSample (null, "Boxes", typeof(Boxes));
AddSample (null, "Buttons", typeof(ButtonSample));
AddSample (null, "ComboBox", typeof(ComboBoxes));
AddSample (null, "Drag & Drop", typeof(DragDrop));
var n = AddSample (null, "Drawing", null);
// AddSample (n, "Chart", typeof(ChartSample));

Просмотреть файл

@ -55,6 +55,7 @@
<Compile Include="Samples\ScrollWindowSample.cs" />
<Compile Include="Samples\ButtonSample.cs" />
<Compile Include="Samples\DrawingTransforms.cs" />
<Compile Include="Samples\ComboBoxes.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>

Просмотреть файл

@ -1,5 +1,5 @@
//
// IListViewSource.cs
// ComboBoxes.cs
//
// Author:
// Lluis Sanchez <lluis@xamarin.com>
@ -23,16 +23,23 @@
// 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;
using Xwt;
namespace Xwt
namespace Samples
{
public interface IListViewSource
public class ComboBoxes: VBox
{
int RowCount { get; }
object GetValue (int row, int column);
void SetValue (int row, int column, object value);
public ComboBoxes ()
{
ComboBox c = new ComboBox ();
c.Items.Add ("One");
c.Items.Add ("Two");
c.Items.Add ("Three");
c.SelectedIndex = 1;
PackStart (c);
}
}
}

Просмотреть файл

@ -66,6 +66,8 @@
<Compile Include="Xwt.GtkBackend\Platform.cs" />
<Compile Include="Xwt.GtkBackend\ScrollViewBackend.cs" />
<Compile Include="Xwt.GtkBackend\ComboBoxBackend.cs" />
<Compile Include="Xwt.GtkBackend\CustomTreeModel.cs" />
<Compile Include="Xwt.GtkBackend\CustomListModel.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>

Просмотреть файл

@ -60,12 +60,14 @@ namespace Xwt.GtkBackend
CellUtil.CreateCellRenderer (this, null, v);
}
public void SetSource (IListViewSource source, IBackend sourceBackend)
public void SetSource (IListDataSource source, IBackend sourceBackend)
{
ListStoreBackend b = sourceBackend as ListStoreBackend;
if (b == null)
throw new NotSupportedException ("Custom list stores are not supported");
Widget.Model = b.Store;
if (b == null) {
CustomListModel model = new CustomListModel (source);
Widget.Model = model.Store;
} else
Widget.Model = b.Store;
}
public int SelectedRow {

Просмотреть файл

@ -0,0 +1,199 @@
//
// CustomTreeModel.cs
//
// Author:
// Lluis Sanchez <lluis@xamarin.com>
//
// Copyright (c) 2011 Xamarin Inc
//
// 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:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// 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;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Xwt.GtkBackend
{
public class CustomListModel: GLib.Object, Gtk.TreeModelImplementor
{
IListDataSource source;
Dictionary<int,int> nodeHash = new Dictionary<int,int> ();
Dictionary<int,int> handleHash = new Dictionary<int,int> ();
Type[] colTypes;
int counter = 1;
Gtk.TreeModelAdapter adapter;
public CustomListModel (IListDataSource source)
{
this.source = source;
adapter = new Gtk.TreeModelAdapter (this);
colTypes = source.ColumnTypes;
source.RowChanged += HandleRowChanged;
source.RowDeleted += HandleRowDeleted;
source.RowInserted += HandleRowInserted;
source.RowsReordered += HandleRowsReordered;
}
void HandleRowsReordered (object sender, ListRowOrderEventArgs e)
{
var p = new Gtk.TreePath (new int[] { e.Row });
var it = IterFromNode (e.Row);
adapter.EmitRowsReordered (p, it, e.ChildrenOrder);
}
void HandleRowInserted (object sender, ListRowEventArgs e)
{
var p = new Gtk.TreePath (new int[] { e.Row });
var it = IterFromNode (e.Row);
adapter.EmitRowInserted (p, it);
}
void HandleRowDeleted (object sender, ListRowEventArgs e)
{
var p = new Gtk.TreePath (new int[] { e.Row });
adapter.EmitRowDeleted (p);
}
void HandleRowChanged (object sender, ListRowEventArgs e)
{
var p = new Gtk.TreePath (new int[] { e.Row });
var it = IterFromNode (e.Row);
adapter.EmitRowChanged (p, it);
}
public Gtk.TreeModelAdapter Store {
get { return adapter; }
}
Gtk.TreeIter IterFromNode (int node)
{
int gch;
if (!handleHash.TryGetValue (node, out gch)) {
gch = counter++;
handleHash [node] = gch;
nodeHash [gch] = node;
}
Gtk.TreeIter result = Gtk.TreeIter.Zero;
result.UserData = (IntPtr)gch;
return result;
}
int NodeFromIter (Gtk.TreeIter iter)
{
int node;
int gch = (int)iter.UserData;
nodeHash.TryGetValue (gch, out node);
return node;
}
#region TreeModelImplementor implementation
public GLib.GType GetColumnType (int index)
{
return (GLib.GType)colTypes [index];
}
public bool GetIter (out Gtk.TreeIter iter, Gtk.TreePath path)
{
if (path.Indices.Length == 0)
return false;
int row = path.Indices [0];
iter = IterFromNode (row);
return true;
}
public Gtk.TreePath GetPath (Gtk.TreeIter iter)
{
int row = NodeFromIter (iter);
return new Gtk.TreePath (new int[] { row });
}
public void GetValue (Gtk.TreeIter iter, int column, ref GLib.Value value)
{
int row = NodeFromIter (iter);
var v = source.GetValue (row, column);
value = new GLib.Value (v);
}
public bool IterNext (ref Gtk.TreeIter iter)
{
int row = NodeFromIter (iter);
if (++row < source.RowCount) {
iter = IterFromNode (row);
return true;
} else
return false;
}
public bool IterChildren (out Gtk.TreeIter iter, Gtk.TreeIter parent)
{
return false;
}
public bool IterHasChild (Gtk.TreeIter iter)
{
return false;
}
public int IterNChildren (Gtk.TreeIter iter)
{
if (iter.Equals (Gtk.TreeIter.Zero))
return source.RowCount;
else
return 0;
}
public bool IterNthChild (out Gtk.TreeIter iter, Gtk.TreeIter parent, int n)
{
if (parent.Equals (Gtk.TreeIter.Zero)) {
iter = IterFromNode (n);
return true;
} else {
iter = Gtk.TreeIter.Zero;
return false;
}
}
public bool IterParent (out Gtk.TreeIter iter, Gtk.TreeIter child)
{
iter = Gtk.TreeIter.Zero;
return false;
}
public void RefNode (Gtk.TreeIter iter)
{
}
public void UnrefNode (Gtk.TreeIter iter)
{
}
public Gtk.TreeModelFlags Flags {
get {
return Gtk.TreeModelFlags.ItersPersist | Gtk.TreeModelFlags.ListOnly;
}
}
public int NColumns {
get {
return colTypes.Length;
}
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,250 @@
//
// CustomTreeModel.cs
//
// Author:
// Lluis Sanchez <lluis@xamarin.com>
//
// Copyright (c) 2011 Xamarin Inc
//
// 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:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// 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;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Xwt.GtkBackend
{
public class CustomTreeModel: Gtk.TreeModelImplementor
{
ITreeDataSource source;
Dictionary<GCHandle,TreePosition> nodeHash = new Dictionary<GCHandle,TreePosition> ();
Dictionary<TreePosition,GCHandle> handleHash = new Dictionary<TreePosition,GCHandle> ();
Type[] colTypes;
Gtk.TreeModelAdapter adapter;
public CustomTreeModel (ITreeDataSource source)
{
this.source = source;
adapter = new Gtk.TreeModelAdapter (this);
colTypes = source.ColumnTypes;
source.NodeChanged += HandleNodeChanged;
source.NodeDeleted += HandleNodeDeleted;
source.NodeInserted += HandleNodeInserted;
source.NodesReordered += HandleNodesReordered;
}
public Gtk.TreeModelAdapter Store {
get { return adapter; }
}
public IntPtr Handle {
get {
return IntPtr.Zero;
}
}
Gtk.TreeIter IterFromNode (TreePosition node)
{
GCHandle gch;
if (!handleHash.TryGetValue (node, out gch)) {
gch = GCHandle.Alloc (node);
handleHash [node] = gch;
nodeHash [gch] = node;
}
Gtk.TreeIter result = Gtk.TreeIter.Zero;
result.UserData = (IntPtr)gch;
return result;
}
TreePosition NodeFromIter (Gtk.TreeIter iter)
{
TreePosition node;
GCHandle gch = (GCHandle)iter.UserData;
nodeHash.TryGetValue (gch, out node);
return node;
}
#region TreeModelImplementor implementation
void HandleNodesReordered (object sender, TreeNodeOrderEventArgs e)
{
Gtk.TreeIter it = IterFromNode (e.Node);
adapter.EmitRowsReordered (GetPath (it), it, e.ChildrenOrder);
}
void HandleNodeInserted (object sender, TreeNodeEventArgs e)
{
Gtk.TreeIter it = IterFromNode (e.Node);
adapter.EmitRowInserted (GetPath (it), it);
}
void HandleNodeDeleted (object sender, TreeNodeChildEventArgs e)
{
if (e.Node == null) {
adapter.EmitRowDeleted (new Gtk.TreePath (new int[] { e.ChildIndex }));
} else {
Gtk.TreeIter it = IterFromNode (e.Node);
var p = GetPath (it);
int[] idx = new int [p.Indices.Length + 1];
p.Indices.CopyTo (idx, 0);
idx [idx.Length - 1] = e.ChildIndex;
adapter.EmitRowDeleted (new Gtk.TreePath (idx));
}
}
void HandleNodeChanged (object sender, TreeNodeEventArgs e)
{
Gtk.TreeIter it = IterFromNode (e.Node);
adapter.EmitRowChanged (GetPath (it), it);
}
public GLib.GType GetColumnType (int index)
{
return (GLib.GType) colTypes [index];
}
public bool GetIter (out Gtk.TreeIter iter, Gtk.TreePath path)
{
TreePosition pos = null;
int[] indices = path.Indices;
if (indices.Length == 0)
return false;
for (int n=0; n<indices.Length; n++) {
pos = source.GetChild (pos, indices [n]);
if (pos == null)
return false;
}
iter = IterFromNode (pos);
return true;
}
public Gtk.TreePath GetPath (Gtk.TreeIter iter)
{
TreePosition pos = NodeFromIter (iter);
List<int> idx = new List<int> ();
while (pos != null) {
var parent = source.GetParent (pos);
idx.Add (GetIndex (parent, pos));
pos = parent;
}
idx.Reverse ();
return new Gtk.TreePath (idx.ToArray ());
}
int GetIndex (TreePosition parent, TreePosition pos)
{
int n = 0;
do {
var c = source.GetChild (parent, n);
if (c == null)
return -1;
if (c == pos)
return n;
n++;
} while (true);
}
public void GetValue (Gtk.TreeIter iter, int column, ref GLib.Value value)
{
TreePosition pos = NodeFromIter (iter);
var v = source.GetValue (pos, column);
value = new GLib.Value (v);
}
public bool IterNext (ref Gtk.TreeIter iter)
{
TreePosition pos = NodeFromIter (iter);
TreePosition parent = source.GetParent (pos);
int i = GetIndex (parent, pos);
pos = source.GetChild (parent, i + 1);
if (pos != null) {
iter = IterFromNode (pos);
return true;
} else
return false;
}
public bool IterChildren (out Gtk.TreeIter iter, Gtk.TreeIter parent)
{
TreePosition pos = NodeFromIter (parent);
pos = source.GetChild (pos, 0);
if (pos != null) {
iter = IterFromNode (pos);
return true;
} else
return false;
}
public bool IterHasChild (Gtk.TreeIter iter)
{
TreePosition pos = NodeFromIter (iter);
return source.GetChildrenCount (pos) != 0;
}
public int IterNChildren (Gtk.TreeIter iter)
{
TreePosition pos = NodeFromIter (iter);
return source.GetChildrenCount (pos);
}
public bool IterNthChild (out Gtk.TreeIter iter, Gtk.TreeIter parent, int n)
{
TreePosition pos = NodeFromIter (parent);
pos = source.GetChild (pos, n);
if (pos != null) {
iter = IterFromNode (pos);
return true;
} else
return false;
}
public bool IterParent (out Gtk.TreeIter iter, Gtk.TreeIter child)
{
TreePosition pos = NodeFromIter (iter);
pos = source.GetParent (pos);
if (pos != null) {
iter = IterFromNode (pos);
return true;
} else
return false;
}
public void RefNode (Gtk.TreeIter iter)
{
}
public void UnrefNode (Gtk.TreeIter iter)
{
}
public Gtk.TreeModelFlags Flags {
get {
return Gtk.TreeModelFlags.ItersPersist;
}
}
public int NColumns {
get {
return colTypes.Length;
}
}
#endregion
}
}

Просмотреть файл

@ -32,11 +32,19 @@ namespace Xwt.GtkBackend
{
public class ListStoreBackend: TableStoreBackend, IListStoreBackend
{
Type[] columnTypes;
public override Gtk.TreeModel InitializeModel (Type[] columnTypes)
{
this.columnTypes = columnTypes;
return new Gtk.ListStore (columnTypes);
}
public event EventHandler<ListRowEventArgs> RowInserted;
public event EventHandler<ListRowEventArgs> RowDeleted;
public event EventHandler<ListRowEventArgs> RowChanged;
public event EventHandler<ListRowOrderEventArgs> RowsReordered;
public Gtk.ListStore List {
get { return (Gtk.ListStore) Store; }
}
@ -63,6 +71,12 @@ namespace Xwt.GtkBackend
}
}
public Type[] ColumnTypes {
get {
return columnTypes;
}
}
public int AddRow ()
{
List.Append ();

Просмотреть файл

@ -31,12 +31,14 @@ namespace Xwt.GtkBackend
{
public class ListViewBackend: TableViewBackend, IListViewBackend
{
public void SetSource (IListViewSource source, IBackend sourceBackend)
public void SetSource (IListDataSource source, IBackend sourceBackend)
{
ListStoreBackend b = sourceBackend as ListStoreBackend;
if (b == null)
throw new NotSupportedException ("Custom list stores are not supported");
Widget.Model = b.Store;
if (b == null) {
CustomListModel model = new CustomListModel (source);
Widget.Model = model.Store;
} else
Widget.Model = b.Store;
}
public void SelectRow (int row)

Просмотреть файл

@ -50,15 +50,23 @@ namespace Xwt.GtkBackend
public class TreeStoreBackend: TableStoreBackend, ITreeStoreBackend
{
Type[] columnTypes;
public Gtk.TreeStore Tree {
get { return (Gtk.TreeStore) Store; }
}
public override Gtk.TreeModel InitializeModel (Type[] columnTypes)
{
this.columnTypes = columnTypes;
return new Gtk.TreeStore (columnTypes);
}
public event EventHandler<TreeNodeEventArgs> NodeInserted;
public event EventHandler<TreeNodeChildEventArgs> NodeDeleted;
public event EventHandler<TreeNodeEventArgs> NodeChanged;
public event EventHandler<TreeNodeOrderEventArgs> NodesReordered;
public TreePosition GetChild (TreePosition pos, int index)
{
IterPos tpos = (IterPos) pos;
@ -136,7 +144,7 @@ namespace Xwt.GtkBackend
public TreePosition AddChild (TreePosition pos)
{
IterPos tpos = (IterPos) pos;
IterPos tpos = (IterPos)pos;
Gtk.TreeIter it;
if (pos == null)
it = Tree.AppendNode ();
@ -144,6 +152,13 @@ namespace Xwt.GtkBackend
it = Tree.AppendNode (tpos.Iter);
return new IterPos (it);
}
public void Remove (TreePosition pos)
{
IterPos tpos = (IterPos)pos;
Gtk.TreeIter it = tpos.Iter;
Tree.Remove (ref it);
}
public TreePosition GetNext (TreePosition pos)
{
@ -161,13 +176,19 @@ namespace Xwt.GtkBackend
public TreePosition GetParent (TreePosition pos)
{
IterPos tpos = (IterPos) pos;
IterPos tpos = (IterPos)pos;
Gtk.TreeIter it;
if (!Tree.IterParent (out it, tpos.Iter))
return null;
return new IterPos (it);
}
public Type[] ColumnTypes {
get {
return columnTypes;
}
}
public void EnableEvent (object eventId)
{
}

Просмотреть файл

@ -31,12 +31,14 @@ namespace Xwt.GtkBackend
{
public class TreeViewBackend: TableViewBackend, ITreeViewBackend
{
public void SetSource (ITreeViewSource source, IBackend sourceBackend)
public void SetSource (ITreeDataSource source, IBackend sourceBackend)
{
TreeStoreBackend b = sourceBackend as TreeStoreBackend;
if (b == null)
throw new NotSupportedException ("Custom tree stores are not supported");
Widget.Model = b.Store;
if (b == null) {
CustomTreeModel model = new CustomTreeModel (source);
Widget.Model = model.Store;
} else
Widget.Model = b.Store;
}
public TreePosition[] SelectedItems {

Просмотреть файл

@ -34,7 +34,7 @@ namespace Xwt.Mac
{
public class ListViewBackend: TableViewBackend<NSTableView,IListViewEventSink>, IListViewBackend
{
IListViewSource source;
IListDataSource source;
ListSource tsource;
protected override NSTableView CreateView ()
@ -46,7 +46,7 @@ namespace Xwt.Mac
get { return "NSTableViewSelectionDidChangeNotification"; }
}
public void SetSource (IListViewSource source, IBackend sourceBackend)
public void SetSource (IListDataSource source, IBackend sourceBackend)
{
this.source = source;
tsource = new ListSource (source);
@ -90,9 +90,9 @@ namespace Xwt.Mac
class ListSource: NSTableViewDataSource
{
IListViewSource source;
IListDataSource source;
public ListSource (IListViewSource source)
public ListSource (IListDataSource source)
{
this.source = source;
}

Просмотреть файл

@ -35,7 +35,7 @@ namespace Xwt.Mac
{
public class TreeViewBackend: TableViewBackend<NSOutlineView,ITreeViewEventSink>, ITreeViewBackend
{
ITreeViewSource source;
ITreeDataSource source;
TreeSource tsource;
NSOutlineView Tree {
@ -59,7 +59,7 @@ namespace Xwt.Mac
return tcol;
}
public void SetSource (ITreeViewSource source, IBackend sourceBackend)
public void SetSource (ITreeDataSource source, IBackend sourceBackend)
{
this.source = source;
tsource = new TreeSource (source);
@ -117,12 +117,12 @@ namespace Xwt.Mac
class TreeSource: NSOutlineViewDataSource
{
ITreeViewSource source;
ITreeDataSource source;
// TODO: remove unused positions
Dictionary<TreePosition,TreeItem> items = new Dictionary<TreePosition, TreeItem> ();
public TreeSource (ITreeViewSource source)
public TreeSource (ITreeDataSource source)
{
this.source = source;
}

Просмотреть файл

@ -30,7 +30,7 @@ namespace Xwt.Backends
public interface IComboBoxBackend: IWidgetBackend
{
void SetViews (CellViewCollection views);
void SetSource (IListViewSource source, IBackend sourceBackend);
void SetSource (IListDataSource source, IBackend sourceBackend);
int SelectedRow { get; set; }
}

Просмотреть файл

@ -28,7 +28,7 @@ using System;
namespace Xwt.Backends
{
public interface IListStoreBackend: IListViewSource, IBackend
public interface IListStoreBackend: IListDataSource, IBackend
{
void Initialize (Type[] columnTypes);

Просмотреть файл

@ -30,7 +30,7 @@ namespace Xwt.Backends
{
public interface IListViewBackend: ITableViewBackend
{
void SetSource (IListViewSource source, IBackend sourceBackend);
void SetSource (IListDataSource source, IBackend sourceBackend);
int[] SelectedRows { get; }
void SelectRow (int pos);
void UnselectRow (int pos);

Просмотреть файл

@ -28,15 +28,15 @@ using System;
namespace Xwt.Backends
{
public interface ITreeStoreBackend: ITreeViewSource, IBackend
public interface ITreeStoreBackend: ITreeDataSource, IBackend
{
void Initialize (Type[] columnTypes);
TreePosition InsertBefore (TreePosition pos);
TreePosition InsertAfter (TreePosition pos);
TreePosition AddChild (TreePosition pos);
void Remove (TreePosition pos);
TreePosition GetNext (TreePosition pos);
TreePosition GetPrevious (TreePosition pos);
TreePosition GetParent (TreePosition pos);
}
}

Просмотреть файл

@ -31,7 +31,7 @@ namespace Xwt.Backends
{
public interface ITreeViewBackend: ITableViewBackend
{
void SetSource (ITreeViewSource source, IBackend sourceBackend);
void SetSource (ITreeDataSource source, IBackend sourceBackend);
TreePosition[] SelectedItems { get; }
void SelectItem (TreePosition pos);
void UnselectItem (TreePosition pos);

Просмотреть файл

@ -139,6 +139,7 @@
<Compile Include="Xwt\ComboBox.cs" />
<Compile Include="Xwt\ItemCollection.cs" />
<Compile Include="Xwt.Backends\IComboBoxBackend.cs" />
<Compile Include="Xwt\Command.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>

Просмотреть файл

@ -24,13 +24,14 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using Xwt.Backends;
namespace Xwt
{
public class ComboBox: Widget
{
CellViewCollection views;
IListViewSource source;
IListDataSource source;
protected new class EventSink: Widget.EventSink, ICellContainer
{
@ -40,6 +41,10 @@ namespace Xwt
}
}
new IComboBoxBackend Backend {
get { return (IComboBoxBackend) base.Backend; }
}
public ComboBox ()
{
views = new CellViewCollection ((ICellContainer)WidgetEventSink);
@ -57,7 +62,7 @@ namespace Xwt
public ItemCollection Items {
get {
if (source == null)
source = new ItemCollection ();
ItemsSource = new ItemCollection ();
ItemCollection col = source as ItemCollection;
if (col == null)
throw new InvalidOperationException ("The Items collection is not available when a custom items source is set");
@ -65,9 +70,12 @@ namespace Xwt
}
}
public IListViewSource ItemsSource {
public IListDataSource ItemsSource {
get { return source; }
set { source = value; }
set {
source = value;
Backend.SetSource (source, source is XwtComponent ? GetBackend ((XwtComponent)source) : null);
}
}
public int SelectedIndex {

Просмотреть файл

@ -1,5 +1,5 @@
//
// ITreeViewSource.cs
// Command.cs
//
// Author:
// Lluis Sanchez <lluis@xamarin.com>
@ -23,19 +23,29 @@
// 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;
using Xwt.Drawing;
using System.Collections.ObjectModel;
using System.Collections.Generic;
namespace Xwt
{
public interface ITreeViewSource
public class Command
{
TreePosition GetChild (TreePosition pos, int index);
int GetChildrenCount (TreePosition pos);
object GetValue (TreePosition pos, int column);
void SetValue (TreePosition pos, int column, object value);
public Command (string id)
{
}
public static Command Ok = new Command ("Ok");
public static Command Cancel = new Command ("Cancel");
public static Command Yes = new Command ("Yes");
public static Command No = new Command ("No");
public static Command Close = new Command ("Close");
public static Command Delete = new Command ("Delete");
public static Command Add = new Command ("Add");
public static Command Remove = new Command ("Remove");
public static Command Clear = new Command ("Clear");
public static Command Copy = new Command ("Copy");
public static Command Save = new Command ("Save");
public static Command SaveAs = new Command ("SaveAs");
public static Command Stop = new Command ("Stop");
}
}

Просмотреть файл

@ -0,0 +1,70 @@
//
// IListViewSource.cs
//
// Author:
// Lluis Sanchez <lluis@xamarin.com>
//
// Copyright (c) 2011 Xamarin Inc
//
// 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:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// 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;
namespace Xwt
{
public interface IListDataSource
{
int RowCount { get; }
object GetValue (int row, int column);
void SetValue (int row, int column, object value);
Type[] ColumnTypes { get; }
event EventHandler<ListRowEventArgs> RowInserted;
event EventHandler<ListRowEventArgs> RowDeleted;
event EventHandler<ListRowEventArgs> RowChanged;
event EventHandler<ListRowOrderEventArgs> RowsReordered;
}
public class ListRowEventArgs: EventArgs
{
public ListRowEventArgs (int row)
{
Row = row;
}
public int Row {
get;
private set;
}
}
public class ListRowOrderEventArgs: ListRowEventArgs
{
public ListRowOrderEventArgs (int parentRow, int[] rows): base (parentRow)
{
ChildrenOrder = rows;
}
public int[] ChildrenOrder {
get;
private set;
}
}
}

Просмотреть файл

@ -0,0 +1,86 @@
//
// ITreeViewSource.cs
//
// Author:
// Lluis Sanchez <lluis@xamarin.com>
//
// Copyright (c) 2011 Xamarin Inc
//
// 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:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// 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;
using Xwt.Drawing;
using System.Collections.ObjectModel;
using System.Collections.Generic;
namespace Xwt
{
public interface ITreeDataSource
{
TreePosition GetParent (TreePosition pos);
TreePosition GetChild (TreePosition pos, int index);
int GetChildrenCount (TreePosition pos);
object GetValue (TreePosition pos, int column);
void SetValue (TreePosition pos, int column, object value);
Type[] ColumnTypes { get; }
event EventHandler<TreeNodeEventArgs> NodeInserted;
event EventHandler<TreeNodeChildEventArgs> NodeDeleted;
event EventHandler<TreeNodeEventArgs> NodeChanged;
event EventHandler<TreeNodeOrderEventArgs> NodesReordered;
}
public class TreeNodeEventArgs: EventArgs
{
public TreeNodeEventArgs (TreePosition node)
{
Node = node;
}
public TreePosition Node {
get;
private set;
}
}
public class TreeNodeChildEventArgs: TreeNodeEventArgs
{
public TreeNodeChildEventArgs (TreePosition parent, int childIndex): base (parent)
{
ChildIndex = childIndex;
}
public int ChildIndex {
get;
private set;
}
}
public class TreeNodeOrderEventArgs: TreeNodeEventArgs
{
public TreeNodeOrderEventArgs (TreePosition parentNode, int[] childrenOrder): base (parentNode)
{
ChildrenOrder = childrenOrder;
}
public int[] ChildrenOrder {
get;
private set;
}
}}

Просмотреть файл

@ -29,52 +29,74 @@ using System.Collections.ObjectModel;
namespace Xwt
{
public class ItemCollection: Collection<Object>, IListViewSource
public class ItemCollection: Collection<Object>, IListDataSource
{
internal ItemCollection ()
{
}
public event EventHandler<ListRowEventArgs> RowInserted;
public event EventHandler<ListRowEventArgs> RowDeleted;
public event EventHandler<ListRowEventArgs> RowChanged;
public event EventHandler<ListRowOrderEventArgs> RowsReordered;
protected override void InsertItem (int index, object item)
{
base.InsertItem (index, item);
if (RowInserted != null)
RowInserted (this, new ListRowEventArgs (index));
}
protected override void RemoveItem (int index)
{
base.RemoveItem (index);
if (RowDeleted != null)
RowDeleted (this, new ListRowEventArgs (index));
}
protected override void SetItem (int index, object item)
{
base.SetItem (index, item);
if (RowChanged != null)
RowChanged (this, new ListRowEventArgs (index));
}
protected override void ClearItems ()
{
int count = Count;
base.ClearItems ();
for (int n=count - 1; n >= 0; n--) {
if (RowDeleted != null)
RowDeleted (this, new ListRowEventArgs (n));
}
}
#region IListViewSource implementation
object IListViewSource.GetValue (int row, int column)
object IListDataSource.GetValue (int row, int column)
{
if (column != 0)
throw new InvalidOperationException ("Not data for column " + column);
return this [row];
}
void IListViewSource.SetValue (int row, int column, object value)
void IListDataSource.SetValue (int row, int column, object value)
{
if (column != 0)
throw new InvalidOperationException ("Not data for column " + column);
this [row] = value;
}
int IListViewSource.RowCount {
int IListDataSource.RowCount {
get {
return Count;
}
}
Type[] IListDataSource.ColumnTypes {
get {
return new Type[] { typeof(string) };
}
}
#endregion
}
}

Просмотреть файл

@ -31,7 +31,7 @@ using System.Collections.Generic;
namespace Xwt
{
public class ListStore: XwtComponent, IListViewSource
public class ListStore: XwtComponent, IListDataSource
{
DataField[] fields;
@ -62,7 +62,7 @@ namespace Xwt
public ListStore ()
{
}
public int RowCount {
get {
return Backend.RowCount;
@ -79,16 +79,39 @@ namespace Xwt
Backend.SetValue (row, column.Index, value);
}
object IListViewSource.GetValue (int row, int column)
object IListDataSource.GetValue (int row, int column)
{
return Backend.GetValue (row, column);
}
void IListViewSource.SetValue (int row, int column, object value)
void IListDataSource.SetValue (int row, int column, object value)
{
Backend.SetValue (row, column, value);
}
Type[] IListDataSource.ColumnTypes {
get {
return Backend.ColumnTypes;
}
}
event EventHandler<ListRowEventArgs> IListDataSource.RowInserted {
add { Backend.RowInserted += value; }
remove { Backend.RowInserted -= value; }
}
event EventHandler<ListRowEventArgs> IListDataSource.RowDeleted {
add { Backend.RowDeleted += value; }
remove { Backend.RowDeleted -= value; }
}
event EventHandler<ListRowEventArgs> IListDataSource.RowChanged {
add { Backend.RowChanged += value; }
remove { Backend.RowChanged -= value; }
}
event EventHandler<ListRowOrderEventArgs> IListDataSource.RowsReordered {
add { Backend.RowsReordered += value; }
remove { Backend.RowsReordered -= value; }
}
public int AddRow ()
{
return Backend.AddRow ();
@ -115,6 +138,11 @@ namespace Xwt
List<object[]> list = new List<object[]> ();
Type[] columnTypes;
public event EventHandler<ListRowEventArgs> RowInserted;
public event EventHandler<ListRowEventArgs> RowDeleted;
public event EventHandler<ListRowEventArgs> RowChanged;
public event EventHandler<ListRowOrderEventArgs> RowsReordered;
public void Initialize (object frontend)
{
}
@ -131,7 +159,15 @@ namespace Xwt
public void SetValue (int row, int column, object value)
{
list [row][column] = value;
list [row] [column] = value;
if (RowChanged != null)
RowChanged (this, new ListRowEventArgs (row));
}
public Type[] ColumnTypes {
get {
return columnTypes;
}
}
public int RowCount {
@ -144,13 +180,18 @@ namespace Xwt
{
object[] data = new object [columnTypes.Length];
list.Add (data);
return list.Count - 1;
int row = list.Count - 1;
if (RowInserted != null)
RowInserted (this, new ListRowEventArgs (row));
return row;
}
public int InsertRowAfter (int row)
{
object[] data = new object [columnTypes.Length];
list.Insert (row + 1, data);
if (RowInserted != null)
RowInserted (this, new ListRowEventArgs (row + 1));
return row + 1;
}
@ -158,12 +199,16 @@ namespace Xwt
{
object[] data = new object [columnTypes.Length];
list.Insert (row, data);
if (RowInserted != null)
RowInserted (this, new ListRowEventArgs (row));
return row;
}
public void RemoveRow (int row)
{
list.RemoveAt (row);
if (RowDeleted != null)
RowDeleted (this, new ListRowEventArgs (row));
}
public void EnableEvent (object eventId)

Просмотреть файл

@ -33,7 +33,7 @@ namespace Xwt
public class ListView: Widget, IColumnContainer
{
ListViewColumnCollection columns;
IListViewSource dataSource;
IListDataSource dataSource;
SelectionMode mode;
protected new class EventSink: Widget.EventSink, IListViewEventSink
@ -49,7 +49,7 @@ namespace Xwt
MapEvent (TableViewEvent.SelectionChanged, typeof(ListView), "OnSelectionChanged");
}
public ListView (IListViewSource source): this ()
public ListView (IListDataSource source): this ()
{
DataSource = source;
}
@ -80,7 +80,7 @@ namespace Xwt
}
}
public IListViewSource DataSource {
public IListDataSource DataSource {
get {
return dataSource;
}

Просмотреть файл

@ -32,7 +32,7 @@ using Xwt.Backends;
namespace Xwt
{
public class TreeStore: XwtComponent, ITreeViewSource
public class TreeStore: XwtComponent, ITreeDataSource
{
DataField[] fields;
@ -47,7 +47,7 @@ namespace Xwt
}
new ITreeStoreBackend Backend {
get { return (ITreeStoreBackend) base.Backend; }
get { return (ITreeStoreBackend)base.Backend; }
}
protected override IBackend OnCreateBackend ()
@ -82,25 +82,53 @@ namespace Xwt
return new TreeNavigator (Backend, pos);
}
TreePosition ITreeViewSource.GetChild (TreePosition pos, int index)
event EventHandler<TreeNodeEventArgs> ITreeDataSource.NodeInserted {
add { Backend.NodeInserted += value; }
remove { Backend.NodeInserted -= value; }
}
event EventHandler<TreeNodeChildEventArgs> ITreeDataSource.NodeDeleted {
add { Backend.NodeDeleted += value; }
remove { Backend.NodeDeleted -= value; }
}
event EventHandler<TreeNodeEventArgs> ITreeDataSource.NodeChanged {
add { Backend.NodeChanged += value; }
remove { Backend.NodeChanged -= value; }
}
event EventHandler<TreeNodeOrderEventArgs> ITreeDataSource.NodesReordered {
add { Backend.NodesReordered += value; }
remove { Backend.NodesReordered -= value; }
}
TreePosition ITreeDataSource.GetChild (TreePosition pos, int index)
{
return Backend.GetChild (pos, index);
}
int ITreeViewSource.GetChildrenCount (TreePosition pos)
TreePosition ITreeDataSource.GetParent (TreePosition pos)
{
return Backend.GetParent (pos);
}
int ITreeDataSource.GetChildrenCount (TreePosition pos)
{
return Backend.GetChildrenCount (pos);
}
object ITreeViewSource.GetValue (TreePosition pos, int column)
object ITreeDataSource.GetValue (TreePosition pos, int column)
{
return Backend.GetValue (pos, column);
}
void ITreeViewSource.SetValue (TreePosition pos, int column, object val)
void ITreeDataSource.SetValue (TreePosition pos, int column, object val)
{
Backend.SetValue (pos, column, val);
}
Type[] ITreeDataSource.ColumnTypes {
get {
return fields.Select (f => f.FieldType).ToArray ();
}
}
}
class DefaultTreeStoreBackend: ITreeStoreBackend
@ -142,6 +170,11 @@ namespace Xwt
int version;
int nextNodeId;
public event EventHandler<TreeNodeEventArgs> NodeInserted;
public event EventHandler<TreeNodeChildEventArgs> NodeDeleted;
public event EventHandler<TreeNodeEventArgs> NodeChanged;
public event EventHandler<TreeNodeOrderEventArgs> NodesReordered;
public void Initialize (object frontend)
{
}
@ -174,12 +207,14 @@ namespace Xwt
public void SetValue (TreePosition pos, int column, object value)
{
NodePosition n = GetPosition (pos);
Node node = n.ParentList[n.NodeIndex];
Node node = n.ParentList [n.NodeIndex];
if (node.Data == null) {
node.Data = new object [columnTypes.Length];
n.ParentList[n.NodeIndex] = node;
n.ParentList [n.NodeIndex] = node;
}
node.Data [column] = value;
if (NodeChanged != null)
NodeChanged (this, new TreeNodeEventArgs (pos));
}
public object GetValue (TreePosition pos, int column)
@ -246,7 +281,10 @@ namespace Xwt
np.NodeIndex++;
np.StoreVersion = version;
return new NodePosition () { ParentList = np.ParentList, NodeId = nn.NodeId, NodeIndex = np.NodeIndex - 1, StoreVersion = version };
var node = new NodePosition () { ParentList = np.ParentList, NodeId = nn.NodeId, NodeIndex = np.NodeIndex - 1, StoreVersion = version };
if (NodeInserted != null)
NodeInserted (this, new TreeNodeEventArgs (node));
return node;
}
public TreePosition InsertAfter (TreePosition pos)
@ -261,7 +299,10 @@ namespace Xwt
// Update the provided position is still valid
np.StoreVersion = version;
return new NodePosition () { ParentList = np.ParentList, NodeId = nn.NodeId, NodeIndex = np.NodeIndex + 1, StoreVersion = version };
var node = new NodePosition () { ParentList = np.ParentList, NodeId = nn.NodeId, NodeIndex = np.NodeIndex + 1, StoreVersion = version };
if (NodeInserted != null)
NodeInserted (this, new TreeNodeEventArgs (node));
return node;
}
public TreePosition AddChild (TreePosition pos)
@ -275,9 +316,8 @@ namespace Xwt
if (pos == null) {
list = rootNodes;
}
else {
Node n = np.ParentList[np.NodeIndex];
} else {
Node n = np.ParentList [np.NodeIndex];
if (n.Children == null) {
n.Children = new NodeList ();
n.Children.Parent = new NodePosition () { ParentList = np.ParentList, NodeId = n.NodeId, NodeIndex = np.NodeIndex, StoreVersion = version };
@ -292,7 +332,17 @@ namespace Xwt
if (np != null)
np.StoreVersion = version;
return new NodePosition () { ParentList = list, NodeId = nn.NodeId, NodeIndex = list.Count - 1, StoreVersion = version };
var node = new NodePosition () { ParentList = list, NodeId = nn.NodeId, NodeIndex = list.Count - 1, StoreVersion = version };
if (NodeInserted != null)
NodeInserted (this, new TreeNodeEventArgs (node));
return node;
}
public void Remove (TreePosition pos)
{
NodePosition np = GetPosition (pos);
np.ParentList.RemoveAt (np.NodeIndex);
version++;
}
public TreePosition GetParent (TreePosition pos)
@ -304,6 +354,12 @@ namespace Xwt
return new NodePosition () { ParentList = parent.ParentList, NodeId = parent.NodeId, NodeIndex = parent.NodeIndex, StoreVersion = version };
}
public Type[] ColumnTypes {
get {
return columnTypes;
}
}
public void EnableEvent (object eventId)
{
}

Просмотреть файл

@ -36,7 +36,7 @@ namespace Xwt
public class TreeView: Widget, IColumnContainer
{
ListViewColumnCollection columns;
ITreeViewSource dataSource;
ITreeDataSource dataSource;
SelectionMode mode;
protected new class EventSink: Widget.EventSink, ITreeViewEventSink
@ -73,7 +73,7 @@ namespace Xwt
columns.Attach (Backend);
}
public TreeView (ITreeViewSource source): this ()
public TreeView (ITreeDataSource source): this ()
{
DataSource = source;
}
@ -84,7 +84,7 @@ namespace Xwt
}
}
public ITreeViewSource DataSource {
public ITreeDataSource DataSource {
get {
return dataSource;
}