From 5aea8651b674c26b9395d1b1077a287a1e885b58 Mon Sep 17 00:00:00 2001 From: jpbruyere Date: Wed, 25 Jan 2017 09:25:14 +0100 Subject: [PATCH] CrowThread;AlwaysOnTop win;GTree explorer; --- Crow.csproj | 1 + src/CrowThread.cs | 58 ++++++++++++++++++++++++++++ src/GraphicObjects/GenericStack.cs | 1 + src/GraphicObjects/GraphicObject.cs | 10 +++-- src/GraphicObjects/Popper.cs | 7 ++-- src/GraphicObjects/TemplatedGroup.cs | 18 ++++----- src/GraphicObjects/TreeView.cs | 27 ++++++++++++- src/Interface.cs | 33 +++++++++++----- 8 files changed, 128 insertions(+), 27 deletions(-) create mode 100644 src/CrowThread.cs diff --git a/Crow.csproj b/Crow.csproj index 13a0a351..25e7f10d 100644 --- a/Crow.csproj +++ b/Crow.csproj @@ -153,6 +153,7 @@ + diff --git a/src/CrowThread.cs b/src/CrowThread.cs new file mode 100644 index 00000000..dfdeda00 --- /dev/null +++ b/src/CrowThread.cs @@ -0,0 +1,58 @@ +// +// CrowThread.cs +// +// Author: +// Jean-Philippe Bruyère +// +// 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 . +using System; +using System.Threading; + +namespace Crow +{ + /// + /// Thread monitored by current interface with Finished event when state==Stopped + /// + 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); + } + } +} + diff --git a/src/GraphicObjects/GenericStack.cs b/src/GraphicObjects/GenericStack.cs index a2d78d88..0636c14e 100644 --- a/src/GraphicObjects/GenericStack.cs +++ b/src/GraphicObjects/GenericStack.cs @@ -29,6 +29,7 @@ namespace Crow return; _spacing = value; NotifyValueChanged ("Spacing", Spacing); + RegisterForLayouting (LayoutingType.Sizing|LayoutingType.ArrangeChildren); } } [XmlAttributeAttribute()][DefaultValue(Orientation.Horizontal)] diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index 070a221a..1e8bfcf9 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -507,8 +507,10 @@ namespace Crow 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); @@ -1200,8 +1202,8 @@ namespace Crow 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) { diff --git a/src/GraphicObjects/Popper.cs b/src/GraphicObjects/Popper.cs index 38621337..84088355 100644 --- a/src/GraphicObjects/Popper.cs +++ b/src/GraphicObjects/Popper.cs @@ -219,16 +219,17 @@ namespace Crow 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); } } diff --git a/src/GraphicObjects/TemplatedGroup.cs b/src/GraphicObjects/TemplatedGroup.cs index ee799fd0..a1941f06 100644 --- a/src/GraphicObjects/TemplatedGroup.cs +++ b/src/GraphicObjects/TemplatedGroup.cs @@ -40,6 +40,7 @@ namespace Crow #region events public event EventHandler SelectedItemChanged; + public event EventHandler Loaded; #endregion IList data; @@ -47,7 +48,7 @@ namespace Crow Color selBackground, selForeground; int itemPerPage = 50; - Thread loadingThread = null; + CrowThread loadingThread = null; volatile bool cancelLoading = false; #region Templating @@ -141,8 +142,8 @@ namespace Crow 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); @@ -310,13 +311,8 @@ namespace Crow } } 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) { @@ -374,6 +370,8 @@ namespace Crow } } 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 (); diff --git a/src/GraphicObjects/TreeView.cs b/src/GraphicObjects/TreeView.cs index 4fa881b4..d4354b65 100644 --- a/src/GraphicObjects/TreeView.cs +++ b/src/GraphicObjects/TreeView.cs @@ -48,7 +48,6 @@ namespace Crow NotifyValueChanged ("IsRoot", isRoot); } } - [XmlIgnore]public override object SelectedItem { get { return selectedItemContainer == null ? @@ -84,6 +83,32 @@ namespace Crow 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; + } + } + } } } diff --git a/src/Interface.cs b/src/Interface.cs index 6b859dbe..565e6ab4 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -142,6 +142,7 @@ namespace Crow public static Dictionary Instantiators = new Dictionary(); public bool DesignMode = false; public int TopWindows = 0;//window always on top count + public List CrowThreads = new List();//used to monitor thread finished #endregion #region Private Fields @@ -302,7 +303,7 @@ namespace Crow /// Widget is focused and button is down or another perif action is occuring /// , it can not lose focus while Active - public GraphicObject activeWidget + public GraphicObject ActiveWidget { get { return _activeWidget; } set @@ -394,6 +395,13 @@ namespace Crow _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; @@ -535,14 +543,15 @@ namespace Crow #region GraphicTree handling /// Add widget to the Graphic tree of this interface and register it for layouting - 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); @@ -554,12 +563,18 @@ namespace Crow GraphicTree.Remove (g); } /// Put widget on top of other root widgets - 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); } } @@ -634,10 +649,10 @@ namespace Crow 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; } @@ -717,7 +732,7 @@ namespace Crow } _activeWidget.onMouseUp (_activeWidget, e); - activeWidget = null; + ActiveWidget = null; return true; } public bool ProcessMouseButtonDown(int button) -- 2.47.3