diff options
| author | jpbruyere <jp.bruyere@hotmail.com> | 2016-09-06 17:55:41 +0200 |
|---|---|---|
| committer | jpbruyere <jp.bruyere@hotmail.com> | 2016-09-06 17:55:41 +0200 |
| commit | 39a9fa35ff36f8bcb3a88679e3658596d2e79b1c (patch) | |
| tree | 2266ea2ff2e0125c46e10b41613f624a1e2f20ac /src/GraphicObjects/TemplatedGroup.cs | |
| parent | 004ab2dee65d4b18e20d8999ff644dd197aa1cd8 (diff) | |
rebase master
Diffstat (limited to 'src/GraphicObjects/TemplatedGroup.cs')
| -rw-r--r-- | src/GraphicObjects/TemplatedGroup.cs | 256 |
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); + } } } |