From cb91338f8038afbade79f12e04d0294b94f75228 Mon Sep 17 00:00:00 2001 From: jpbruyere Date: Sat, 6 Feb 2016 15:46:32 +0100 Subject: [PATCH] simpler layouting queue test --- Crow.csproj | 1 - Crow.sln | 3 - Crow.userprefs | 44 +++++--- MonoDevelop.GOLib/MonoDevelop.GOLib.csproj | 10 ++ Tests/Interfaces/0.crow | 27 ++--- src/GraphicObjects/ComboBox.cs | 6 +- src/GraphicObjects/GenericStack.cs | 29 +++--- src/GraphicObjects/GraphicObject.cs | 111 +++++++++------------ src/GraphicObjects/Grid.cs | 23 +++-- src/GraphicObjects/ILayoutable.cs | 4 +- src/Interface.cs | 5 +- src/LayoutingQueueItem.cs | 5 +- src/OpenTKGameWindow.cs | 22 ++-- 13 files changed, 137 insertions(+), 153 deletions(-) diff --git a/Crow.csproj b/Crow.csproj index 3b142f75..f4474492 100644 --- a/Crow.csproj +++ b/Crow.csproj @@ -102,7 +102,6 @@ - diff --git a/Crow.sln b/Crow.sln index 794d208c..4f8d22f9 100644 --- a/Crow.sln +++ b/Crow.sln @@ -24,15 +24,12 @@ Global {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release|Linux_x86.ActiveCfg = Release|Any CPU {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release|Linux_x86.Build.0 = Release|Any CPU {7BAE4448-E8F4-48B3-BB11-FA78E7F4506B}.Debug|Linux_x86.ActiveCfg = Debug|Any CPU - {7BAE4448-E8F4-48B3-BB11-FA78E7F4506B}.Debug|Linux_x86.Build.0 = Debug|Any CPU {7BAE4448-E8F4-48B3-BB11-FA78E7F4506B}.Release|Linux_x86.ActiveCfg = Release|Any CPU - {7BAE4448-E8F4-48B3-BB11-FA78E7F4506B}.Release|Linux_x86.Build.0 = Release|Any CPU {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Debug|Linux_x86.ActiveCfg = Debug|Any CPU {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Debug|Linux_x86.Build.0 = Debug|Any CPU {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Release|Linux_x86.ActiveCfg = Release|Any CPU {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Release|Linux_x86.Build.0 = Release|Any CPU {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Debug|Linux_x86.ActiveCfg = Debug|Any CPU - {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Debug|Linux_x86.Build.0 = Debug|Any CPU {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Release|Linux_x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution diff --git a/Crow.userprefs b/Crow.userprefs index d17e4d36..1b24c0fa 100644 --- a/Crow.userprefs +++ b/Crow.userprefs @@ -1,18 +1,38 @@  - - + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MonoDevelop.GOLib/MonoDevelop.GOLib.csproj b/MonoDevelop.GOLib/MonoDevelop.GOLib.csproj index fdf16c93..3fa91fbb 100644 --- a/MonoDevelop.GOLib/MonoDevelop.GOLib.csproj +++ b/MonoDevelop.GOLib/MonoDevelop.GOLib.csproj @@ -33,6 +33,11 @@ prompt 4 false + + + + + none @@ -40,6 +45,11 @@ prompt 4 false + + + + + diff --git a/Tests/Interfaces/0.crow b/Tests/Interfaces/0.crow index 3fbc5e5f..1b4bc645 100755 --- a/Tests/Interfaces/0.crow +++ b/Tests/Interfaces/0.crow @@ -1,21 +1,8 @@  - - - - - - - - - - - - - \ No newline at end of file + + + + + + + \ No newline at end of file diff --git a/src/GraphicObjects/ComboBox.cs b/src/GraphicObjects/ComboBox.cs index 181131b4..aee7da9b 100644 --- a/src/GraphicObjects/ComboBox.cs +++ b/src/GraphicObjects/ComboBox.cs @@ -164,11 +164,7 @@ namespace Crow } } - public override void UpdateLayout (LayoutingType layoutType) - { - CheckPendingChildrenAddition (); - base.UpdateLayout (layoutType); - } + internal void CheckPendingChildrenAddition() { if (pendingChildrenAddition == null) diff --git a/src/GraphicObjects/GenericStack.cs b/src/GraphicObjects/GenericStack.cs index c49c5307..5de21fac 100644 --- a/src/GraphicObjects/GenericStack.cs +++ b/src/GraphicObjects/GenericStack.cs @@ -109,19 +109,11 @@ namespace Crow } bmp = null; } + + public override bool UpdateLayout (LayoutingType layoutType) + { + RegisteredLayoutings &= (~layoutType); - public override void EnqueueForLayouting () - { - if (Parent == null) - return; - - base.EnqueueForLayouting (); - - if (RegisteredLayoutings.HasFlag(LayoutingType.PositionChildren)) - Interface.LayoutingQueue.Enqueue (LayoutingType.PositionChildren, this); - } - public override void UpdateLayout (LayoutingType layoutType) - { if (layoutType == LayoutingType.PositionChildren) { //allow 1 child to have size to 0 if stack has fixed or streched size, //this child will occupy remaining space @@ -165,13 +157,18 @@ namespace Crow } } } - } + } + ComputeChildrenPositions (); + //if no layouting remains in queue for item, registre for redraw - if (RegisteredLQINodes.Count () <= 0 && bmp==null) + if (RegisteredLayoutings == LayoutingType.None && bmp==null) this.RegisterForRedraw (); - }else - base.UpdateLayout(layoutType); + + return true; + } + + return base.UpdateLayout(layoutType); } public override void OnLayoutChanges (LayoutingType layoutType) { diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index 1f437021..4d00b99a 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -64,6 +64,7 @@ namespace Crow #endregion #region private fields + LayoutingType registeredLayoutings = LayoutingType.None; ILayoutable _parent; string _name = "unamed"; Fill _background = Color.Transparent; @@ -111,8 +112,7 @@ namespace Crow #endregion #region ILayoutable - - public List> RegisteredLQINodes { get; } = new List>(); + [XmlIgnore]public LayoutingType RegisteredLayoutings { get { return registeredLayoutings; } set { registeredLayoutings = value; } } //TODO: it would save the recurent cost of a cast in event bubbling if parent type was GraphicObject // or we could add to the interface the mouse events /// @@ -501,21 +501,14 @@ namespace Crow protected virtual Size measureRawSize () { return Bounds.Size; } - - void deleteLQI(int lt){ - LinkedListNode[] lqis = this.RegisteredLQINodes.Where (n => (lt & (int)n.Value.LayoutType) > 0).ToArray (); - for (int i = 0; i < lqis.Length; i++) { - Interface.LayoutingQueue.Remove (lqis [i]); - RegisteredLQINodes.Remove (lqis [i]); - } - } - public LayoutingType RegisteredLayoutings = 0; - + public virtual void RegisterForLayouting(LayoutingType layoutType){ + //dont set position for stretched item if (Width == 0) layoutType &= (~LayoutingType.X); if (Height == 0) layoutType &= (~LayoutingType.Y); + //Prevent child repositionning in a stack //TODO:this should be done inside GenericStack GenericStack gs = Parent as GenericStack; @@ -525,66 +518,36 @@ namespace Crow else layoutType &= (~LayoutingType.Y); } + + //prevent queueing same LayoutingType for this + layoutType &= (~RegisteredLayoutings); + if (layoutType == LayoutingType.None) return; - if (RegisteredLayoutings == LayoutingType.None) - Interface.RegisteredGOForLayouting.Enqueue (this); - RegisteredLayoutings |= (LayoutingType)layoutType; - } - /// clear current layoutingQueue items for object and - /// trigger a new layouting pass for a layoutType - public virtual void EnqueueForLayouting() - { - if (Parent == null) - return; + #if DEBUG_LAYOUTING - Debug.WriteLine ("RegisterForLayouting => {1}->{0}", RegisteredLayoutings.ToString(), this.ToString()); + Debug.WriteLine ("RegisterForLayouting => {1}->{0}", layoutType, this.ToString()); #endif - //deleteLQI (RegisteredLayoutings); - if (RegisteredLayoutings.HasFlag(LayoutingType.Width)) { - if (Bounds.Width == 0) //stretch in parent - Interface.LayoutingQueue.EnqueueAfterParentSizing (LayoutingType.Width, this); - else if (Bounds.Width < 0) //fit - Interface.LayoutingQueue.EnqueueBeforeParentSizing (LayoutingType.Width, this); - else - RegisteredLQINodes.Add( - Interface.LayoutingQueue.AddFirst ( - new LayoutingQueueItem (LayoutingType.Width, this))); - } - - if (RegisteredLayoutings.HasFlag(LayoutingType.Height)) { - if (Bounds.Height == 0) //stretch in parent - Interface.LayoutingQueue.EnqueueAfterParentSizing (LayoutingType.Height, this); - else if (Bounds.Height < 0) //fit - Interface.LayoutingQueue.EnqueueBeforeParentSizing (LayoutingType.Height, this); - else{ - RegisteredLQINodes.Add( - Interface.LayoutingQueue.AddFirst ( - new LayoutingQueueItem (LayoutingType.Height, this))); - - } - } - - if (RegisteredLayoutings.HasFlag(LayoutingType.X)) - //for x positionning, sizing of parent and this have to be done - Interface.LayoutingQueue.EnqueueAfterThisAndParentSizing (LayoutingType.X, this); - - if (RegisteredLayoutings.HasFlag(LayoutingType.Y)) - //for x positionning, sizing of parent and this have to be done - Interface.LayoutingQueue.EnqueueAfterThisAndParentSizing (LayoutingType.Y, this); + if (layoutType.HasFlag (LayoutingType.Width)) + Interface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this)); + if (layoutType.HasFlag (LayoutingType.Height)) + Interface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this)); + if (layoutType.HasFlag (LayoutingType.X)) + Interface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this)); + if (layoutType.HasFlag (LayoutingType.Y)) + Interface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this)); + if (layoutType.HasFlag (LayoutingType.PositionChildren)) + Interface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.PositionChildren, this)); } - /// trigger dependant sizing component update public virtual void OnLayoutChanges(LayoutingType layoutType) { - if (Parent==null) - return; #if DEBUG_LAYOUTING Debug.WriteLine ("Layout change: " + this.ToString () + ":" + LastSlots.ToString() + "=>" + Slot.ToString ()); #endif - + switch (layoutType) { case LayoutingType.Width: if (Width != 0 && Parent.getBounds().Width >=0) //update position in parent @@ -597,13 +560,23 @@ namespace Crow } LayoutChanged.Raise (this, new LayoutingEventArgs (layoutType)); } + /// Update layout component, this is where the computation of alignement /// and size take place - public virtual void UpdateLayout (LayoutingType layoutType) - { + /// true, if layouting was possible, false if conditions were not + /// met and LQI has to be re-queued + public virtual bool UpdateLayout (LayoutingType layoutType) + { + //unset bit, it would be reset if LQI is re-queued + registeredLayoutings &= (~layoutType); + switch (layoutType) { case LayoutingType.X: if (Bounds.X == 0) { + + if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Width)) + return false; + switch (HorizontalAlignment) { case HorizontalAlignment.Left: Slot.X = 0; @@ -629,8 +602,12 @@ namespace Crow break; case LayoutingType.Y: if (Bounds.Y == 0) { + + if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Height)) + return false; + switch (VerticalAlignment) { - case VerticalAlignment.Top: + case VerticalAlignment.Top://this could be processed even if parent Height is not known Slot.Y = 0; break; case VerticalAlignment.Bottom: @@ -662,6 +639,8 @@ namespace Crow Slot.Width = Width; else if (Width < 0) Slot.Width = measureRawSize ().Width; + else if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Width)) + return false; else Slot.Width = Parent.ClientRectangle.Width; @@ -689,6 +668,8 @@ namespace Crow Slot.Height = Height; else if (Height < 0) Slot.Height = measureRawSize ().Height; + else if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Width)) + return false; else Slot.Height = Parent.ClientRectangle.Height; @@ -698,7 +679,6 @@ namespace Crow else if (Slot.Height > MaximumSize.Height && MaximumSize.Height > 0) Slot.Height = MaximumSize.Height; - if (LastSlots.Height == Slot.Height) break; @@ -709,9 +689,12 @@ namespace Crow LastSlots.Height = Slot.Height; break; } + //if no layouting remains in queue for item, registre for redraw - if (this.RegisteredLQINodes.Count () <= 0 && bmp == null) + if (this.registeredLayoutings == LayoutingType.None && bmp == null) this.RegisterForRedraw (); + + return true; } #endregion diff --git a/src/GraphicObjects/Grid.cs b/src/GraphicObjects/Grid.cs index 171abd61..fc3d8988 100644 --- a/src/GraphicObjects/Grid.cs +++ b/src/GraphicObjects/Grid.cs @@ -125,22 +125,23 @@ namespace Crow } } - public override void EnqueueForLayouting () - { - base.EnqueueForLayouting (); - if (RegisteredLayoutings.HasFlag(LayoutingType.PositionChildren)) - Interface.LayoutingQueue.Enqueue (LayoutingType.PositionChildren, this); - } - public override void UpdateLayout (LayoutingType layoutType) - { + public override bool UpdateLayout (LayoutingType layoutType) + { + RegisteredLayoutings &= (~layoutType); + if (layoutType == LayoutingType.PositionChildren) { + ComputeChildrenPositions (); + //if no layouting remains in queue for item, registre for redraw - if (RegisteredLQINodes.Count () <= 0 && bmp==null) + if (RegisteredLayoutings == LayoutingType.None && bmp==null) this.RegisterForRedraw (); - }else - base.UpdateLayout(layoutType); + + return true; + } + + return base.UpdateLayout(layoutType); } #endregion diff --git a/src/GraphicObjects/ILayoutable.cs b/src/GraphicObjects/ILayoutable.cs index 01d62365..b9a97b0e 100644 --- a/src/GraphicObjects/ILayoutable.cs +++ b/src/GraphicObjects/ILayoutable.cs @@ -13,9 +13,9 @@ namespace Crow IGOLibHost HostContainer { get; } - List> RegisteredLQINodes { get; } + LayoutingType RegisteredLayoutings { get; set; } void RegisterForLayouting(LayoutingType layoutType); - void UpdateLayout(LayoutingType layoutType); + bool UpdateLayout(LayoutingType layoutType); Rectangle ContextCoordinates(Rectangle r); diff --git a/src/Interface.cs b/src/Interface.cs index cf86ecf3..5ecd7a88 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -53,12 +53,9 @@ namespace Crow /// Threshold to catch borders for sizing public static int BorderThreshold = 5; - public static LayoutingQueue LayoutingQueue = new LayoutingQueue (); - public static Queue RegisteredGOForLayouting = new Queue(); + public static Queue LayoutingQueue = new Queue(); #region Load/Save - //internal static List Bindings; - public static void Save (string file, T graphicObject) { diff --git a/src/LayoutingQueueItem.cs b/src/LayoutingQueueItem.cs index 8fbd95ca..d5ad7fcc 100644 --- a/src/LayoutingQueueItem.cs +++ b/src/LayoutingQueueItem.cs @@ -46,6 +46,7 @@ namespace Crow { LayoutType = _layoutType; GraphicObject = _graphicObject; + GraphicObject.RegisteredLayoutings |= LayoutType; } public void ProcessLayouting() @@ -53,12 +54,14 @@ namespace Crow #if DEBUG_LAYOUTING Debug.WriteLine ("Layouting => " + this.ToString ()); #endif + try { if (GraphicObject.Parent == null){ Debug.WriteLine("ERROR: processLayouting, no parent for: " + GraphicObject.ToString()); return; } - GraphicObject.UpdateLayout (LayoutType); + if (!GraphicObject.UpdateLayout (LayoutType)) + Interface.LayoutingQueue.Enqueue(this); } catch (Exception ex) { Debug.WriteLine ("Layouting error: " + ex.ToString ()); } diff --git a/src/OpenTKGameWindow.cs b/src/OpenTKGameWindow.cs index bb5b67e6..12099e48 100644 --- a/src/OpenTKGameWindow.cs +++ b/src/OpenTKGameWindow.cs @@ -261,16 +261,9 @@ namespace Crow #endif //Debug.WriteLine ("======= Layouting queue start ======="); - while (Interface.RegisteredGOForLayouting.Count > 0){ - while (Interface.RegisteredGOForLayouting.Count > 0){ - GraphicObject go = Interface.RegisteredGOForLayouting.Dequeue (); - go.EnqueueForLayouting (); - go.RegisteredLayoutings = LayoutingType.None; - } - while (Interface.LayoutingQueue.First != null) { - LayoutingQueueItem lqi = Interface.LayoutingQueue.Dequeue (); - lqi.ProcessLayouting (); - } + while (Interface.LayoutingQueue.Count > 0) { + LayoutingQueueItem lqi = Interface.LayoutingQueue.Dequeue (); + lqi.ProcessLayouting (); } #if MEASURE_TIME @@ -551,11 +544,12 @@ namespace Crow #endregion #region ILayoutable implementation - - //TODO:uneeded list, should be removed - public List> RegisteredLQINodes { get; } = new List>(); + public LayoutingType RegisteredLayoutings { + get { return LayoutingType.None; } + set { throw new NotImplementedException (); } + } public void RegisterForLayouting (LayoutingType layoutType) { throw new NotImplementedException (); } - public void UpdateLayout (LayoutingType layoutType) { throw new NotImplementedException (); } + public bool UpdateLayout (LayoutingType layoutType) { throw new NotImplementedException (); } public Rectangle ContextCoordinates (Rectangle r) { return r; -- 2.47.3