<Compile Include="src\IML\EventBinding.cs" />
<Compile Include="src\PerformanceMeasure.cs" />
<Compile Include="src\IML\BindingMember.cs" />
+ <Compile Include="src\CrowThread.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
--- /dev/null
+//
+// CrowThread.cs
+//
+// Author:
+// Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2017 jp
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+using System;
+using System.Threading;
+
+namespace Crow
+{
+ /// <summary>
+ /// Thread monitored by current interface with Finished event when state==Stopped
+ /// </summary>
+ public class CrowThread {
+ Thread thread;
+ public event EventHandler Finished;
+ public GraphicObject Host;
+ public CrowThread (GraphicObject host, ThreadStart start){
+ thread = new Thread (start);
+ thread.IsBackground = true;
+ Host = host;
+ lock (Host.CurrentInterface.CrowThreads)
+ Host.CurrentInterface.CrowThreads.Add (this);
+ }
+ public void CheckState(){
+ if (thread.ThreadState != ThreadState.Stopped)
+ return;
+ Finished.Raise (Host, null);
+ lock (Host.CurrentInterface.CrowThreads)
+ Host.CurrentInterface.CrowThreads.Remove (this);
+ }
+ public void Start() { thread.Start();}
+ public void Cancel(){
+ if (thread.IsAlive){
+ //cancelLoading = true;
+ thread.Join ();
+ //cancelLoading = false;
+ }
+ Host.CurrentInterface.CrowThreads.Remove (this);
+ }
+ }
+}
+
return;
_spacing = value;
NotifyValueChanged ("Spacing", Spacing);
+ RegisterForLayouting (LayoutingType.Sizing|LayoutingType.ArrangeChildren);
}
}
[XmlAttributeAttribute()][DefaultValue(Orientation.Horizontal)]
isVisible = value;
//ensure main win doesn't keep hidden childrens ref
- if (!isVisible && this.Contains (CurrentInterface.HoverWidget))
- CurrentInterface.HoverWidget = null;
+ if (CurrentInterface.HoverWidget != null) {
+ if (!isVisible && this.Contains (CurrentInterface.HoverWidget))
+ CurrentInterface.HoverWidget = null;
+ }
if (isVisible)
RegisterForLayouting (LayoutingType.Sizing);
currentInterface.clickTimer.Restart();
CurrentInterface.eligibleForDoubleClick = null;
- if (CurrentInterface.activeWidget == null)
- CurrentInterface.activeWidget = this;
+ if (CurrentInterface.ActiveWidget == null)
+ CurrentInterface.ActiveWidget = this;
if (this.Focusable && !Interface.FocusOnHover) {
BubblingMouseButtonEventArg be = e as BubblingMouseButtonEventArg;
if (be.Focused == null) {
if (Content != null) {
Content.Visible = true;
if (Content.Parent == null)
- CurrentInterface.AddWidget (Content);
- CurrentInterface.PutOnTop (Content);
+ CurrentInterface.AddWidget (Content, true);
+ CurrentInterface.PutOnTop (Content, true);
_content_LayoutChanged (this, new LayoutingEventArgs (LayoutingType.Sizing));
}
Pop.Raise (this, e);
}
public virtual void onUnpop(object sender, EventArgs e)
{
- if (Content != null)
+ if (Content != null) {
Content.Visible = false;
+ }
Unpop.Raise (this, e);
}
}
#region events
public event EventHandler<SelectionChangeEventArgs> SelectedItemChanged;
+ public event EventHandler Loaded;
#endregion
IList data;
Color selBackground, selForeground;
int itemPerPage = 50;
- Thread loadingThread = null;
+ CrowThread loadingThread = null;
volatile bool cancelLoading = false;
#region Templating
if (data == null)
return;
- loadingThread = new Thread (loading);
- loadingThread.IsBackground = true;
+ loadingThread = new CrowThread (this, loading);
+ loadingThread.Finished += (object sender, EventArgs e) => (sender as TemplatedGroup).Loaded.Raise (sender, e);
loadingThread.Start ();
//loadPage(1);
}
}
void cancelLoadingThread(){
- if (loadingThread == null)
- return;
- if (!loadingThread.IsAlive)
- return;
- cancelLoading = true;
- loadingThread.Join ();
- cancelLoading = false;
+ if (loadingThread != null)
+ loadingThread.Cancel ();
}
void loadPage(int pageNum)
{
}
}
protected void loadItem(int i, Group page){
+ if (data [i] == null)//TODO:surely a threading sync problem
+ return;
GraphicObject g = null;
ItemTemplate iTemp = null;
Type dataType = data [i].GetType ();
NotifyValueChanged ("IsRoot", isRoot);
}
}
-
[XmlIgnore]public override object SelectedItem {
get {
return selectedItemContainer == null ?
NotifyValueChanged ("SelectedItem", SelectedItem);
raiseSelectedItemChanged ();
}
+
+ void onExpandAll_MouseClick (object sender, MouseButtonEventArgs e)
+ {
+ ExpandAll ();
+ }
+
+ public void ExpandAll(){
+ foreach (Group grp in items.Children) {
+ foreach (GraphicObject go in grp.Children) {
+ Expandable exp = go as Expandable;
+ if (exp == null)
+ continue;
+ TreeView subTV = exp.FindByName ("List") as TreeView;
+ if (subTV == null)
+ continue;
+ EventHandler handler = null;
+ handler = delegate(object sender, EventArgs e) {
+ TreeView tv = sender as TreeView;
+ tv.Loaded -= handler;
+ tv.ExpandAll ();
+ };
+ subTV.Loaded += handler;
+ exp.IsExpanded = true;
+ }
+ }
+ }
}
}
public static Dictionary<String, Instantiator> Instantiators = new Dictionary<string, Instantiator>();
public bool DesignMode = false;
public int TopWindows = 0;//window always on top count
+ public List<CrowThread> CrowThreads = new List<CrowThread>();//used to monitor thread finished
#endregion
#region Private Fields
/// <summary>Widget is focused and button is down or another perif action is occuring
/// , it can not lose focus while Active</summary>
- public GraphicObject activeWidget
+ public GraphicObject ActiveWidget
{
get { return _activeWidget; }
set
_focusedWidget.onKeyDown (this, lastKeyDownEvt);
}
}
+ CrowThread[] tmpThreads;
+ lock (CrowThreads) {
+ tmpThreads = new CrowThread[CrowThreads.Count];
+ Array.Copy (CrowThreads.ToArray (), tmpThreads, CrowThreads.Count);
+ }
+ for (int i = 0; i < tmpThreads.Length; i++)
+ tmpThreads [i].CheckState ();
if (!Monitor.TryEnter (UpdateMutex))
return;
#region GraphicTree handling
/// <summary>Add widget to the Graphic tree of this interface and register it for layouting</summary>
- public void AddWidget(GraphicObject g)
+ public void AddWidget(GraphicObject g, bool topMost = false)
{
g.Parent = this;
int ptr = TopWindows;
if (g is Window) {
if ((g as Window).AlwaysOnTop)
ptr = 0;
- }
+ } else if (topMost)
+ ptr = 0;
GraphicTree.Insert (ptr, g);
g.RegisteredLayoutings = LayoutingType.None;
g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
GraphicTree.Remove (g);
}
/// <summary> Put widget on top of other root widgets</summary>
- public void PutOnTop(GraphicObject g)
+ public void PutOnTop(GraphicObject g, bool topMost = false)
{
- if (GraphicTree.IndexOf(g) > TopWindows)
+ int ptr = TopWindows;
+ if (g is Window) {
+ if ((g as Window).AlwaysOnTop)
+ ptr = 0;
+ } else if (topMost)
+ ptr = 0;
+ if (GraphicTree.IndexOf(g) > ptr)
{
GraphicTree.Remove(g);
- GraphicTree.Insert(TopWindows, g);
+ GraphicTree.Insert(ptr, g);
EnqueueForRepaint (g);
}
}
MouseMoveEventArgs e = new MouseMoveEventArgs (x, y, deltaX, deltaY);
e.Mouse = Mouse;
- if (activeWidget != null) {
+ if (ActiveWidget != null) {
//TODO, ensure object is still in the graphic tree
//send move evt even if mouse move outside bounds
- activeWidget.onMouseMove (this, e);
+ ActiveWidget.onMouseMove (this, e);
return true;
}
}
_activeWidget.onMouseUp (_activeWidget, e);
- activeWidget = null;
+ ActiveWidget = null;
return true;
}
public bool ProcessMouseButtonDown(int button)