aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/GraphicObjects/TemplatedGroup.cs
diff options
context:
space:
mode:
authorjpbruyere <jp.bruyere@hotmail.com>2016-09-06 17:55:41 +0200
committerjpbruyere <jp.bruyere@hotmail.com>2016-09-06 17:55:41 +0200
commit39a9fa35ff36f8bcb3a88679e3658596d2e79b1c (patch)
tree2266ea2ff2e0125c46e10b41613f624a1e2f20ac /src/GraphicObjects/TemplatedGroup.cs
parent004ab2dee65d4b18e20d8999ff644dd197aa1cd8 (diff)
rebase master
Diffstat (limited to 'src/GraphicObjects/TemplatedGroup.cs')
-rw-r--r--src/GraphicObjects/TemplatedGroup.cs256
1 files changed, 244 insertions, 12 deletions
diff --git a/src/GraphicObjects/TemplatedGroup.cs b/src/GraphicObjects/TemplatedGroup.cs
index 0d48b9eb..500e5ea6 100644
--- a/src/GraphicObjects/TemplatedGroup.cs
+++ b/src/GraphicObjects/TemplatedGroup.cs
@@ -23,6 +23,9 @@ using System.Xml.Serialization;
using System.Xml;
using System.Reflection;
using System.Collections.Generic;
+using System.ComponentModel;
+using System.Collections;
+using System.Threading;
namespace Crow
{
@@ -33,8 +36,127 @@ namespace Crow
#endregion
protected Group items;
+ string _itemTemplate;
+
+ #region events
+ public event EventHandler<SelectionChangeEventArgs> SelectedItemChanged;
+ #endregion
+
+ Group _list;
+ IList data;
+ int _selectedIndex;
+ Color selBackground, selForeground;
+
+ int itemPerPage = 50;
+ Thread loadingThread = null;
+ volatile bool cancelLoading = false;
+
+ #region Templating
+ //TODO: dont instantiate ItemTemplates if not used
+ //but then i should test if null in msil gen
+ public Dictionary<string, ItemTemplate> ItemTemplates = new Dictionary<string, Crow.ItemTemplate>();
+
+ [XmlAttributeAttribute][DefaultValue("#Crow.Templates.ItemTemplate.goml")]
+ public string ItemTemplate {
+ get { return _itemTemplate; }
+ set {
+ if (value == _itemTemplate)
+ return;
+
+ _itemTemplate = value;
+
+ //TODO:reload list with new template?
+ NotifyValueChanged("ItemTemplate", _itemTemplate);
+ }
+ }
+ protected override void loadTemplate(GraphicObject template = null)
+ {
+ base.loadTemplate (template);
+
+ items = this.child.FindByName ("ItemsContainer") as Group;
+ if (items == null)
+ throw new Exception ("TemplatedGroup template Must contain a Group named 'ItemsContainer'");
+ if (items.Children.Count == 0)
+ NotifyValueChanged ("HasChildren", false);
+ else
+ NotifyValueChanged ("HasChildren", true);
+ }
+ #endregion
public virtual List<GraphicObject> Items{ get { return items.Children; }}
+ [XmlAttributeAttribute][DefaultValue(-1)]public int SelectedIndex{
+ get { return _selectedIndex; }
+ set {
+ if (value == _selectedIndex)
+ return;
+
+ _selectedIndex = value;
+
+ NotifyValueChanged ("SelectedIndex", _selectedIndex);
+ NotifyValueChanged ("SelectedItem", SelectedItem);
+ SelectedItemChanged.Raise (this, new SelectionChangeEventArgs (SelectedItem));
+ }
+ }
+ [XmlIgnore]public virtual object SelectedItem{
+ get { return data == null ? null : _selectedIndex < 0 ? null : data[_selectedIndex]; }
+ }
+
+ [XmlAttributeAttribute]public IList Data {
+ get { return data; }
+ set {
+ if (value == data)
+ return;
+
+ cancelLoadingThread ();
+
+ data = value;
+
+ NotifyValueChanged ("Data", data);
+
+ lock (CurrentInterface.UpdateMutex)
+ ClearItems ();
+
+ if (data == null)
+ return;
+
+ loadingThread = new Thread (loading);
+ loadingThread.IsBackground = true;
+ loadingThread.Start ();
+ //loadPage(1);
+
+ NotifyValueChanged ("SelectedIndex", _selectedIndex);
+ NotifyValueChanged ("SelectedItem", SelectedItem);
+ SelectedItemChanged.Raise (this, new SelectionChangeEventArgs (SelectedItem));
+ }
+ }
+
+ [XmlAttributeAttribute][DefaultValue("SteelBlue")]//DeepJungleGreen
+ public virtual Color SelectionBackground {
+ get { return selBackground; }
+ set {
+ if (value == selBackground)
+ return;
+ selBackground = value;
+ NotifyValueChanged ("SelectionBackground", selBackground);
+ RegisterForRedraw ();
+ }
+ }
+ [XmlAttributeAttribute][DefaultValue("White")]
+ public virtual Color SelectionForeground {
+ get { return selForeground; }
+ set {
+ if (value == selForeground)
+ return;
+ selForeground = value;
+ NotifyValueChanged ("SelectionForeground", selForeground);
+ RegisterForRedraw ();
+ }
+ }
+
+ protected void raiseSelectedItemChanged(){
+ SelectedItemChanged.Raise (this, new SelectionChangeEventArgs (SelectedItem));
+ }
+
public virtual void AddItem(GraphicObject g){
items.AddChild (g);
@@ -53,18 +175,6 @@ namespace Crow
NotifyValueChanged ("HasChildren", false);
}
- protected override void loadTemplate(GraphicObject template = null)
- {
- base.loadTemplate (template);
-
- items = this.child.FindByName ("ItemsContainer") as Group;
- if (items == null)
- throw new Exception ("TemplatedGroup template Must contain a Group named 'ItemsContainer'");
- if (items.Children.Count == 0)
- NotifyValueChanged ("HasChildren", false);
- else
- NotifyValueChanged ("HasChildren", true);
- }
#region GraphicObject overrides
public override GraphicObject FindByName (string nameToFind)
@@ -160,5 +270,127 @@ namespace Crow
throw new NotImplementedException ();
}
#endregion
+
+ void loading(){
+ if (ItemTemplates == null)
+ ItemTemplates = new Dictionary<string, ItemTemplate> ();
+ if (!ItemTemplates.ContainsKey ("default"))
+ ItemTemplates ["default"] = Interface.GetItemTemplate (ItemTemplate);
+
+ for (int i = 1; i <= (data.Count / itemPerPage) + 1; i++) {
+ if (cancelLoading)
+ return;
+ loadPage (i);
+ }
+ }
+ void cancelLoadingThread(){
+ if (loadingThread == null)
+ return;
+ if (!loadingThread.IsAlive)
+ return;
+ cancelLoading = true;
+ loadingThread.Join ();
+ cancelLoading = false;
+ }
+ void loadPage(int pageNum)
+ {
+ #if DEBUG_LOAD
+ Stopwatch loadingTime = new Stopwatch ();
+ loadingTime.Start ();
+ #endif
+
+ Group page = items.Clone () as Group;
+
+ page.Name = "page" + pageNum;
+
+// //reset size to fit in the dir of the stacking
+// //because items total size is forced to approx size
+// if (_gsList.Orientation == Orientation.Horizontal) {
+// page.Width = Measure.Fit;
+ page.BindMember ("Height", "../HeightPolicy");
+ page.BindMember ("Width", "../WidthPolicy");
+// } else {
+// page.Height = Measure.Fit;
+// page.BindMember ("Width", "../WidthPolicy");
+// }
+
+ for (int i = (pageNum - 1) * itemPerPage; i < pageNum * itemPerPage; i++) {
+ if (i >= data.Count)
+ break;
+ if (cancelLoading)
+ return;
+
+ loadItem (i, page);
+
+ //g.LogicalParent = this;
+ }
+
+ lock (CurrentInterface.LayoutMutex)
+ items.AddChild (page);
+
+ #if DEBUG_LOAD
+ loadingTime.Stop ();
+ Debug.WriteLine("Listbox {2} Loading: {0} ticks \t, {1} ms",
+ loadingTime.ElapsedTicks,
+ loadingTime.ElapsedMilliseconds, this.ToString());
+ #endif
+ }
+ protected void loadItem(int i, Group page){
+ GraphicObject g = null;
+ ItemTemplate iTemp = null;
+ Type dataType = data [i].GetType ();
+
+ if (ItemTemplates.ContainsKey (dataType.FullName))
+ iTemp = ItemTemplates [dataType.FullName];
+ else
+ iTemp = ItemTemplates ["default"];
+
+ lock (CurrentInterface.LayoutMutex) {
+ g = iTemp.CreateInstance(CurrentInterface);
+ page.AddChild (g);
+ g.DataSource = data [i];
+ }
+
+ registerItemClick (g);
+
+ if (iTemp.Expand != null && g is Expandable) {
+ (g as Expandable).Expand += iTemp.Expand;
+ }
+ }
+ protected virtual void registerItemClick(GraphicObject g){
+ g.MouseClick += itemClick;
+ }
+// protected void _list_LayoutChanged (object sender, LayoutingEventArgs e)
+// {
+// #if DEBUG_LAYOUTING
+// Debug.WriteLine("list_LayoutChanged");
+// #endif
+// if (_gsList.Orientation == Orientation.Horizontal) {
+// if (e.LayoutType == LayoutingType.Width)
+// _gsList.Width = approxSize;
+// } else if (e.LayoutType == LayoutingType.Height)
+// _gsList.Height = approxSize;
+// }
+ int approxSize
+ {
+ get {
+ if (data == null)
+ return -1;
+ GenericStack page1 = items.FindByName ("page1") as GenericStack;
+ if (page1 == null)
+ return -1;
+
+ return page1.Orientation == Orientation.Horizontal ?
+ data.Count < itemPerPage ?
+ -1:
+ (int)Math.Ceiling ((double)page1.Slot.Width / (double)itemPerPage * (double)(data.Count+1)):
+ data.Count < itemPerPage ?
+ -1:
+ (int)Math.Ceiling ((double)page1.Slot.Height / (double)itemPerPage * (double)(data.Count+1));
+ }
+ }
+ internal virtual void itemClick(object sender, MouseButtonEventArgs e){
+ SelectedIndex = data.IndexOf((sender as GraphicObject).DataSource);
+ }
}
}