diff options
| author | jpbruyere <jp.bruyere@hotmail.com> | 2016-02-07 17:08:39 +0100 |
|---|---|---|
| committer | jpbruyere <jp.bruyere@hotmail.com> | 2016-02-07 17:08:39 +0100 |
| commit | 31a67ec22a1d083ffaee818ad18b6b1ab26426fb (patch) | |
| tree | 83102735e34afe6bea2e6d1bbd94ecb68e7fae2c /src/GraphicObjects | |
| parent | 96eae258f27ffbaadb5eafb0e7f8750c210c523a (diff) | |
| parent | b4da579b1bf48573c90b2a8a0d12d883fa71e773 (diff) | |
Merge SimplerLayoutingQueue
Diffstat (limited to 'src/GraphicObjects')
| -rw-r--r-- | src/GraphicObjects/ComboBox.cs | 8 | ||||
| -rw-r--r-- | src/GraphicObjects/GenericStack.cs | 173 | ||||
| -rw-r--r-- | src/GraphicObjects/GraphicObject.cs | 201 | ||||
| -rw-r--r-- | src/GraphicObjects/Grid.cs | 31 | ||||
| -rw-r--r-- | src/GraphicObjects/Group.cs | 104 | ||||
| -rw-r--r-- | src/GraphicObjects/ILayoutable.cs | 6 | ||||
| -rw-r--r-- | src/GraphicObjects/Label.cs | 2 | ||||
| -rw-r--r-- | src/GraphicObjects/ListBox.cs | 2 | ||||
| -rw-r--r-- | src/GraphicObjects/Popper.cs | 8 | ||||
| -rw-r--r-- | src/GraphicObjects/PrivateContainer.cs | 36 | ||||
| -rw-r--r-- | src/GraphicObjects/Scroller.cs | 2 | ||||
| -rw-r--r-- | src/GraphicObjects/Slider.cs | 4 | ||||
| -rw-r--r-- | src/GraphicObjects/Spinner.cs | 17 | ||||
| -rw-r--r-- | src/GraphicObjects/TextBox.cs | 4 | ||||
| -rw-r--r-- | src/GraphicObjects/TextRun.cs | 2 |
15 files changed, 328 insertions, 272 deletions
diff --git a/src/GraphicObjects/ComboBox.cs b/src/GraphicObjects/ComboBox.cs index ed979d75..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) @@ -281,7 +277,7 @@ namespace Crow { IsPopped = false; } - void _overlay_LayoutChanged (object sender, LayoutChangeEventArgs e) + void _overlay_LayoutChanged (object sender, LayoutingEventArgs e) { ILayoutable tc = Overlay.Parent as ILayoutable; if (tc == null) diff --git a/src/GraphicObjects/GenericStack.cs b/src/GraphicObjects/GenericStack.cs index 92e944bb..d2338362 100644 --- a/src/GraphicObjects/GenericStack.cs +++ b/src/GraphicObjects/GenericStack.cs @@ -31,13 +31,13 @@ namespace Crow public override T addChild<T> (T child) { T tmp = base.addChild (child); - this.RegisterForLayouting ((int)LayoutingType.PositionChildren); + this.RegisterForLayouting (LayoutingType.PositionChildren); return tmp; } public override void removeChild (GraphicObject child) { base.removeChild (child); - this.RegisterForLayouting ((int)LayoutingType.PositionChildren); + this.RegisterForLayouting (LayoutingType.PositionChildren); } #region Public Properties @@ -66,14 +66,18 @@ namespace Crow Size tmp = new Size (); if (Orientation == Orientation.Horizontal) { - foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) { + foreach (GraphicObject c in Children) { + if (!c.Visible) + continue; tmp.Width += c.Slot.Width + Spacing; tmp.Height = Math.Max (tmp.Height, Math.Max(c.Slot.Bottom, c.Slot.Height)); } if (tmp.Width > 0) tmp.Width -= Spacing; } else { - foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) { + foreach (GraphicObject c in Children) { + if (!c.Visible) + continue; tmp.Width = Math.Max (tmp.Width, Math.Max(c.Slot.Right, c.Slot.Width)); tmp.Height += c.Slot.Height + Spacing; } @@ -93,84 +97,147 @@ namespace Crow #endif int d = 0; if (Orientation == Orientation.Horizontal) { - foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) { + foreach (GraphicObject c in Children) { + if (!c.Visible) + continue; c.Slot.X = d; d += c.Slot.Width + Spacing; - c.RegisterForLayouting ((int)LayoutingType.Y); + c.RegisterForLayouting (LayoutingType.Y); } } else { - foreach (GraphicObject c in Children.Where(ch=>ch.Visible)) { + foreach (GraphicObject c in Children) { + if (!c.Visible) + continue; c.Slot.Y = d; d += c.Slot.Height + Spacing; - c.RegisterForLayouting ((int)LayoutingType.X); + c.RegisterForLayouting (LayoutingType.X); } } + bmp = null; } + + public override bool UpdateLayout (LayoutingType layoutType) + { + RegisteredLayoutings &= (~layoutType); - public override void RegisterForLayouting (int layoutType) - { - if (Parent == null) - return; + LayoutingType childSizeToCheck; + if (Orientation == Orientation.Horizontal) + childSizeToCheck = LayoutingType.Width; + else + childSizeToCheck = LayoutingType.Height; - base.RegisterForLayouting (layoutType); + foreach (GraphicObject g in Children) { + if (!g.Visible) + continue; + if (g.RegisteredLayoutings.HasFlag (childSizeToCheck)) + return false; + } - if ((layoutType & (int)LayoutingType.PositionChildren) > 0) - 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 if (Orientation == Orientation.Horizontal) { if (Width >= 0) { - GraphicObject[] gobjs = Children.Where (c => c.Width == 0 && c.Visible).ToArray(); - if (gobjs.Length > 1) - throw new Exception ("Only one child in stack may have size to stretched"); - else if (gobjs.Length == 1) { - int sz = Children.Where(ch=>ch.Visible).Except (gobjs).Sum (g => g.Slot.Width); - if (sz < Slot.Width) { - gobjs [0].Slot.Width = Slot.Width - sz - (Children.Count-1) * Spacing - 2 * Margin; - int idx = Children.IndexOf (gobjs [0]); - if (idx > 0 && idx < Children.Count - 1) - gobjs [0].Slot.Width -= Spacing; - if (gobjs [0].LastSlots.Width != gobjs [0].Slot.Width) { - gobjs [0].bmp = null; - gobjs [0].OnLayoutChanges (LayoutingType.Width); - gobjs [0].LastSlots.Width = gobjs [0].Slot.Width; - } + GraphicObject stretchedGO = null; + int tmpWidth = Slot.Width; + int cptChildren = 0; + for (int i = 0; i < Children.Count; i++) { + if (!Children [i].Visible) + continue; + cptChildren++; + if (Children [i].Width == 0) { + if (stretchedGO != null) + throw new Exception ("Only one child in stack may have size to stretched"); + stretchedGO = Children [i]; + if (i < Children.Count - 1) + tmpWidth -= Spacing; + continue; + } + tmpWidth -= Children[i].Slot.Width + Spacing; + } + if (stretchedGO != null) { + tmpWidth += (Spacing - 2 * Margin); + if (tmpWidth < MinimumSize.Width) + tmpWidth = MinimumSize.Width; + else if (tmpWidth > MaximumSize.Width && MaximumSize.Width > 0) + tmpWidth = MaximumSize.Width; + if (stretchedGO.LastSlots.Width != tmpWidth) { + stretchedGO.Slot.Width = tmpWidth; + stretchedGO.bmp = null; + stretchedGO.OnLayoutChanges (LayoutingType.Width); + stretchedGO.LastSlots.Width = stretchedGO.Slot.Width; } } } } else { if (Height >= 0) { - GraphicObject[] gobjs = Children.Where(ch=>ch.Visible).Where (c => c.Height == 0).ToArray(); - if (gobjs.Length > 1) - throw new Exception ("Only one child in stack may have size to stretched"); - else if (gobjs.Length == 1) { - int sz = Children.Where(ch=>ch.Visible).Except (gobjs).Sum (g => g.Slot.Height); - if (sz < Slot.Height) { - gobjs [0].Slot.Height = Slot.Height - sz- (Children.Count-1) * Spacing - 2 * Margin; - int idx = Children.IndexOf (gobjs [0]); - if (idx > 0 && idx < Children.Count - 1) - gobjs [0].Slot.Height -= Spacing; - if (gobjs [0].LastSlots.Height != gobjs [0].Slot.Height) { - gobjs [0].bmp = null; - gobjs [0].OnLayoutChanges (LayoutingType.Height); - gobjs [0].LastSlots.Height = gobjs [0].Slot.Height; - } + GraphicObject stretchedGO = null; + int tmpHeight = Slot.Height; + int cptChildren = 0; + for (int i = 0; i < Children.Count; i++) { + if (!Children [i].Visible) + continue; + cptChildren++; + if (Children [i].Height == 0) { + if (stretchedGO != null) + throw new Exception ("Only one child in stack may have size to stretched"); + stretchedGO = Children [i]; + if (i < Children.Count - 1) + tmpHeight -= Spacing; + continue; + } + tmpHeight -= Children[i].Slot.Height + Spacing; + } + if (stretchedGO != null) { + tmpHeight += (Spacing - 2 * Margin); + if (tmpHeight < MinimumSize.Height) + tmpHeight = MinimumSize.Height; + else if (tmpHeight > MaximumSize.Height && MaximumSize.Height > 0) + tmpHeight = MaximumSize.Height; + if (stretchedGO.LastSlots.Height != tmpHeight) { + stretchedGO.Slot.Height = tmpHeight; + stretchedGO.bmp = null; + stretchedGO.OnLayoutChanges (LayoutingType.Height); + stretchedGO.LastSlots.Height = stretchedGO.Slot.Height; } } } - } + } + 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 OnChildLayoutChanges (object sender, LayoutingEventArgs arg) + { + base.OnChildLayoutChanges (sender, arg); + + GraphicObject g = sender as GraphicObject; + switch (arg.LayoutType) { + case LayoutingType.Width: + if (Orientation == Orientation.Horizontal) { + if (this.Bounds.Width < 0) + this.RegisterForLayouting (LayoutingType.Width); + this.RegisterForLayouting (LayoutingType.PositionChildren); + } + break; + case LayoutingType.Height: + if (Orientation == Orientation.Vertical) { + if (this.Bounds.Height < 0) + this.RegisterForLayouting (LayoutingType.Height); + this.RegisterForLayouting (LayoutingType.PositionChildren); + } + break; + } + } #endregion diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index f6963cb5..88af16dd 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,11 +112,7 @@ namespace Crow #endregion #region ILayoutable - /// <summary> - /// Keep ref's of LQI in queue per GraphicObject, to prevent searching in - /// the double linked list which would be very slow. - /// </summary> - public List<LinkedListNode<LayoutingQueueItem>> RegisteredLQINodes { get; } = new List<LinkedListNode<LayoutingQueueItem>>(); + [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 /// <summary> @@ -177,7 +174,7 @@ namespace Crow public event EventHandler<KeyboardKeyEventArgs> KeyUp; public event EventHandler Focused; public event EventHandler Unfocused; - public event EventHandler<LayoutChangeEventArgs> LayoutChanged; + public event EventHandler<LayoutingEventArgs> LayoutChanged; #endregion #region public properties @@ -222,7 +219,7 @@ namespace Crow Bounds.X = value; NotifyValueChanged ("Left", Bounds.X); - this.RegisterForLayouting ((int)LayoutingType.X); + this.RegisterForLayouting (LayoutingType.X); } } [XmlAttributeAttribute()][DefaultValue(0)] @@ -234,7 +231,7 @@ namespace Crow Bounds.Y = value; NotifyValueChanged ("Top", Bounds.Y); - this.RegisterForLayouting ((int)LayoutingType.Y); + this.RegisterForLayouting (LayoutingType.Y); } } [XmlAttributeAttribute()][DefaultValue(0)] @@ -246,7 +243,7 @@ namespace Crow Bounds.Width = value; NotifyValueChanged ("Width", Bounds.Width); - this.RegisterForLayouting ((int)LayoutingType.Width); + this.RegisterForLayouting (LayoutingType.Width); } } [XmlAttributeAttribute()][DefaultValue(0)] @@ -258,7 +255,7 @@ namespace Crow Bounds.Height = value; NotifyValueChanged ("Height", Bounds.Height); - this.RegisterForLayouting ((int)LayoutingType.Height); + this.RegisterForLayouting (LayoutingType.Height); } } [XmlAttributeAttribute()][DefaultValue(false)] @@ -374,7 +371,7 @@ namespace Crow if (this.Contains (HostContainer.hoverWidget)) HostContainer.hoverWidget = null; if (Parent is GenericStack) - Parent.RegisterForLayouting ((int)LayoutingType.Sizing | (int)LayoutingType.PositionChildren); + Parent.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.PositionChildren); NotifyValueChanged ("Visible", _isVisible); } @@ -389,7 +386,7 @@ namespace Crow get { return _maximumSize; } set { _maximumSize = value; } } - [XmlAttributeAttribute()][DefaultValue("0;0")] + [XmlAttributeAttribute()][DefaultValue("1;1")] public virtual Size MinimumSize { get { return _minimumSize; } set { _minimumSize = value; } @@ -472,7 +469,7 @@ namespace Crow public virtual void registerClipRect() { HostContainer.redrawClip.AddRectangle (ScreenCoordinates(Slot)); - //this clipping should take only last painted slots in ancestor tree which + //this clipping should take only last painted slots on each level in ancestor tree which //is not the case for now. HostContainer.redrawClip.AddRectangle (ScreenCoordinates(LastPaintedSlot)); } @@ -504,124 +501,83 @@ namespace Crow protected virtual Size measureRawSize () { return Bounds.Size; } - /// <summary> - /// Delete all ref's to this LQI (local and inQueue) - /// </summary> - void deleteLQI(int lt){ - int i = 0; - while (i < RegisteredLQINodes.Count) { - if (((int)RegisteredLQINodes [i].Value.LayoutType & lt) > 0) { - Interface.LayoutingQueue.Remove (RegisteredLQINodes [i]); - RegisteredLQINodes.RemoveAt (i); - } else - i++; - } - } - /// <summary> clear current layoutingQueue items for object and - /// trigger a new layouting pass for a layoutType </summary> - public virtual void RegisterForLayouting(int layoutType) - { + + public virtual void RegisterForLayouting(LayoutingType layoutType){ if (Parent == null) return; - #if DEBUG_LAYOUTING - Debug.WriteLine ("RegisterForLayouting => {1}->{0}", layoutType, this.ToString()); - #endif + //dont set position for stretched item + if (Width == 0) + layoutType &= (~LayoutingType.X); + if (Height == 0) + layoutType &= (~LayoutingType.Y); - deleteLQI (layoutType); - if ((layoutType & (int)LayoutingType.Width) > 0) { - 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))); + //Prevent child repositionning in a stack + //TODO:this should be done inside GenericStack + GenericStack gs = Parent as GenericStack; + if (gs != null) { + if (gs.Orientation == Orientation.Horizontal) + layoutType &= (~LayoutingType.X); + else + layoutType &= (~LayoutingType.Y); } - if ((layoutType & (int)LayoutingType.Height) > 0) { - 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))); - - } - } + //prevent queueing same LayoutingType for this + layoutType &= (~RegisteredLayoutings); - if ((layoutType & (int)LayoutingType.X) > 0) - //for x positionning, sizing of parent and this have to be done - Interface.LayoutingQueue.EnqueueAfterThisAndParentSizing (LayoutingType.X, this); + if (layoutType == LayoutingType.None) + return; - if ((layoutType & (int)LayoutingType.Y) > 0) - //for x positionning, sizing of parent and this have to be done - Interface.LayoutingQueue.EnqueueAfterThisAndParentSizing (LayoutingType.Y, this); - } + #if DEBUG_LAYOUTING + Debug.WriteLine ("RegisterForLayouting => {1}->{0}", layoutType, this.ToString()); + #endif + //enqueue LQI LayoutingTypes separately + 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)); + } /// <summary> trigger dependant sizing component update </summary> 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 (Parent.getBounds ().Width < 0) { - Group gw = Parent as Group; - if (gw != null) { - if (Slot.Width > gw.maxChildrenWidth) - gw.maxChildrenWidth = Slot.Width; - } - this.Parent.RegisterForLayouting ((int)LayoutingType.Width); - }else if (Width != 0) //update position in parent - this.RegisterForLayouting ((int)LayoutingType.X); - GenericStack gsw = Parent as GenericStack; - if (gsw == null) - break; - if ((Parent as GenericStack).Orientation == Orientation.Horizontal) { -// ulong idx = (ulong)gsw.Children.IndexOf (this); -// if (idx < gsw.stackingUpdateStartIndex) -// gsw.stackingUpdateStartIndex = idx; - this.Parent.RegisterForLayouting ((int)LayoutingType.PositionChildren); - } + case LayoutingType.Width: + this.RegisterForLayouting (LayoutingType.X); break; case LayoutingType.Height: - if (Parent.getBounds ().Height < 0) { - Group gh = Parent as Group; - if (gh != null) { - if (Slot.Width > gh.maxChildrenHeight) - gh.maxChildrenHeight = Slot.Height; - } - this.Parent.RegisterForLayouting ((int)LayoutingType.Height); - }else if (Height != 0) //update position in parent - this.RegisterForLayouting ((int)LayoutingType.Y); - GenericStack gsh = Parent as GenericStack; - if (gsh==null) - break; - if (gsh.Orientation == Orientation.Vertical) { -// ulong idx = (ulong)gsh.Children.IndexOf (this); -// if (idx < gsh.stackingUpdateStartIndex) -// gsh.stackingUpdateStartIndex = idx; - this.Parent.RegisterForLayouting ((int)LayoutingType.PositionChildren); - } + this.RegisterForLayouting (LayoutingType.Y); break; } - LayoutChanged.Raise (this, new LayoutChangeEventArgs (layoutType)); + LayoutChanged.Raise (this, new LayoutingEventArgs (layoutType)); } + /// <summary> Update layout component, this is where the computation of alignement /// and size take place </summary> - public virtual void UpdateLayout (LayoutingType layoutType) - { + /// <returns><c>true</c>, if layouting was possible, <c>false</c> if conditions were not + /// met and LQI has to be re-queued</returns> + 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; @@ -647,8 +603,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: @@ -680,6 +640,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; @@ -707,6 +669,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; @@ -716,7 +680,6 @@ namespace Crow else if (Slot.Height > MaximumSize.Height && MaximumSize.Height > 0) Slot.Height = MaximumSize.Height; - if (LastSlots.Height == Slot.Height) break; @@ -727,9 +690,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 @@ -763,7 +729,6 @@ namespace Crow onDraw (gr); } draw.Flush (); - //draw.WriteToPng ("/mnt/data/test.png"); } } /// <summary> Chained painting routine on the parent context of the actual cached version @@ -909,8 +874,7 @@ namespace Crow #if DEBUG_BINDING Debug.WriteLine ("ResolveBinding => " + this.ToString ()); #endif - - Dictionary<object,List<Binding>> resolved = new Dictionary<object, List<Binding>>(); + List<Binding> resolved = new List<Binding> (); foreach (Binding b in Bindings) { if (!string.IsNullOrEmpty (b.DynMethodId)) continue; @@ -934,12 +898,7 @@ namespace Crow addHandler.Invoke (this, new object[] { del }); continue; } - List<Binding> bindings = null; - if (!resolved.TryGetValue (b.Target.Instance, out bindings)) { - bindings = new List<Binding> (); - resolved [b.Target.Instance] = bindings; - } - bindings.Add (b); + resolved.Add (b); } MethodInfo stringEquals = typeof(string).GetMethod @@ -955,8 +914,8 @@ namespace Crow //group;only one dynMethods by target (valuechanged event source) //changed value name tested in switch - //IEnumerable<Binding[]> groupedByTarget = resolved.GroupBy (g => g.Target.Instance, g => g, (k, g) => g.ToArray ()); - foreach (List<Binding> grouped in resolved.Values) { + IEnumerable<Binding[]> groupedByTarget = resolved.GroupBy (g => g.Target.Instance, g => g, (k, g) => g.ToArray ()); + foreach (Binding[] grouped in groupedByTarget) { int i = 0; Type targetType = grouped[0].Target.Instance.GetType(); @@ -980,8 +939,8 @@ namespace Crow il = dm.GetILGenerator(256); endMethod = il.DefineLabel(); - jumpTable = new System.Reflection.Emit.Label[grouped.Count]; - for (i = 0; i < grouped.Count; i++) + jumpTable = new System.Reflection.Emit.Label[grouped.Length]; + for (i = 0; i < grouped.Length; i++) jumpTable [i] = il.DefineLabel (); il.DeclareLocal(typeof(string)); il.DeclareLocal(typeof(object)); diff --git a/src/GraphicObjects/Grid.cs b/src/GraphicObjects/Grid.cs index 1981fc60..fc3d8988 100644 --- a/src/GraphicObjects/Grid.cs +++ b/src/GraphicObjects/Grid.cs @@ -32,13 +32,13 @@ namespace Crow public override T addChild<T> (T child) { T tmp = base.addChild (child); - this.RegisterForLayouting ((int)LayoutingType.PositionChildren); + this.RegisterForLayouting (LayoutingType.PositionChildren); return tmp; } public override void removeChild (GraphicObject child) { base.removeChild (child); - this.RegisterForLayouting ((int)LayoutingType.PositionChildren); + this.RegisterForLayouting (LayoutingType.PositionChildren); } #region Public Properties @@ -59,7 +59,7 @@ namespace Crow _columnCount = value; NotifyValueChanged ("ColumnCount", ColumnCount); - this.RegisterForLayouting ((int)LayoutingType.PositionChildren); + this.RegisterForLayouting (LayoutingType.PositionChildren); } } [XmlAttributeAttribute()][DefaultValue(1)] @@ -73,7 +73,7 @@ namespace Crow _rowCount = value; NotifyValueChanged ("RowCount", RowCount); - this.RegisterForLayouting ((int)LayoutingType.PositionChildren); + this.RegisterForLayouting (LayoutingType.PositionChildren); } } public virtual int CaseWidth { @@ -125,22 +125,23 @@ namespace Crow } } - public override void RegisterForLayouting (int layoutType) - { - base.RegisterForLayouting (layoutType); - if ((layoutType & (int)LayoutingType.PositionChildren) > 0) - 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/Group.cs b/src/GraphicObjects/Group.cs index 7f952ac1..8737b866 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -14,9 +14,7 @@ namespace Crow { #region CTOR public Group() - : base() - { - } + : base(){} #endregion #region EVENT HANDLERS @@ -25,6 +23,8 @@ namespace Crow internal int maxChildrenWidth = 0; internal int maxChildrenHeight = 0; + internal GraphicObject largestChild = null; + internal GraphicObject tallestChild = null; bool _multiSelect = false; List<GraphicObject> children = new List<GraphicObject>(); @@ -33,7 +33,6 @@ namespace Crow public virtual List<GraphicObject> Children { get { return children; } - set { children = value; } } [XmlAttributeAttribute()][DefaultValue(false)] public bool MultiSelect @@ -48,26 +47,28 @@ namespace Crow GraphicObject g = child as GraphicObject; Children.Add(g); g.Parent = this as GraphicObject; - g.RegisterForLayouting ((int)LayoutingType.Sizing); + g.RegisterForLayouting (LayoutingType.Sizing); + g.LayoutChanged += OnChildLayoutChanges; return (T)child; } public virtual void removeChild(GraphicObject child) - { + { + child.LayoutChanged -= OnChildLayoutChanges; child.ClearBinding (); child.Parent = null; Children.Remove(child); - this.RegisterForLayouting ((int)LayoutingType.Sizing); + this.RegisterForLayouting (LayoutingType.Sizing); } public virtual void ClearChildren() { - int lim = children.Count; - for (int i = 0; i < lim; i++) { - GraphicObject g = Children [0]; + while(children.Count > 0){ + GraphicObject g = children[children.Count-1]; + g.LayoutChanged -= OnChildLayoutChanges; g.ClearBinding (); g.Parent = null; - Children.Remove(g); + Children.RemoveAt(children.Count-1); } - this.RegisterForLayouting ((int)LayoutingType.Sizing); + this.RegisterForLayouting (LayoutingType.Sizing); ChildrenCleared.Raise (this, new EventArgs ()); } public void putWidgetOnTop(GraphicObject w) @@ -86,7 +87,7 @@ namespace Crow Children.Insert(0, w); } } - + #region GraphicObject overrides [XmlIgnore]public override bool DrawingIsValid { get { @@ -136,40 +137,73 @@ namespace Crow { base.OnLayoutChanges (layoutType); - GenericStack gs = this as GenericStack; //position smaller objects in group when group size is fit switch (layoutType) { case LayoutingType.Width: - if (gs != null) { - if (gs.Orientation == Orientation.Horizontal) { - this.RegisterForLayouting ((int)LayoutingType.PositionChildren); - break; - } - } - foreach (GraphicObject c in Children.Where(ch => ch.Visible)) { - if (c.getBounds ().Width == 0) - c.RegisterForLayouting ((int)LayoutingType.Width); - else - c.RegisterForLayouting ((int)LayoutingType.X); + foreach (GraphicObject c in Children) { + if (!c.Visible) + continue; + c.RegisterForLayouting (LayoutingType.X | LayoutingType.Width); } break; case LayoutingType.Height: - if (gs != null) { - if (gs.Orientation == Orientation.Vertical) { - this.RegisterForLayouting ((int)LayoutingType.PositionChildren); - break; + foreach (GraphicObject c in Children) { + if (!c.Visible) + continue; + c.RegisterForLayouting (LayoutingType.Y | LayoutingType.Height); } + break; + } + } + public virtual void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) + { + GraphicObject g = sender as GraphicObject; + switch (arg.LayoutType) { + case LayoutingType.X: + break; + case LayoutingType.Y: + break; + case LayoutingType.Width: + if (g.Slot.Width > maxChildrenWidth) { + maxChildrenWidth = g.Slot.Width; + largestChild = g; + if (this.Bounds.Width < 0) + this.RegisterForLayouting (LayoutingType.Width); + } else if (g == largestChild) { + //search for the new largest child + largestChild = null; + maxChildrenWidth = 0; + for (int i = 0; i < children.Count; i++) { + if (children [i].Slot.Width > maxChildrenWidth) { + maxChildrenWidth = children [i].Slot.Width; + largestChild = children [i]; + } } + if (this.Bounds.Width < 0) + this.RegisterForLayouting (LayoutingType.Width); } - foreach (GraphicObject c in Children.Where(ch => ch.Visible)) { - if (c.getBounds ().Height == 0) - c.RegisterForLayouting ((int)LayoutingType.Height); - else - c.RegisterForLayouting ((int)LayoutingType.Y); + break; + case LayoutingType.Height: + if (g.Slot.Height > maxChildrenHeight) { + maxChildrenHeight = g.Slot.Height; + tallestChild = g; + if (this.Bounds.Height < 0) + this.RegisterForLayouting (LayoutingType.Height); + } else if (g == tallestChild) { + //search for the new tallest child + tallestChild = null; + maxChildrenHeight = 0; + for (int i = 0; i < children.Count; i++) { + if (children [i].Slot.Height > maxChildrenHeight) { + maxChildrenHeight = children [i].Slot.Height; + tallestChild = children [i]; + } + } + if (this.Bounds.Height < 0) + this.RegisterForLayouting (LayoutingType.Height); } break; } } - public override Rectangle ContextCoordinates(Rectangle r){ return r + ClientRectangle.Position; } diff --git a/src/GraphicObjects/ILayoutable.cs b/src/GraphicObjects/ILayoutable.cs index 7bb30bce..b9a97b0e 100644 --- a/src/GraphicObjects/ILayoutable.cs +++ b/src/GraphicObjects/ILayoutable.cs @@ -13,9 +13,9 @@ namespace Crow IGOLibHost HostContainer { get; } - List<LinkedListNode<LayoutingQueueItem>> RegisteredLQINodes { get; } - void RegisterForLayouting(int layoutType); - void UpdateLayout(LayoutingType layoutType); + LayoutingType RegisteredLayoutings { get; set; } + void RegisterForLayouting(LayoutingType layoutType); + bool UpdateLayout(LayoutingType layoutType); Rectangle ContextCoordinates(Rectangle r); diff --git a/src/GraphicObjects/Label.cs b/src/GraphicObjects/Label.cs index d8d214c7..08e7211a 100644 --- a/src/GraphicObjects/Label.cs +++ b/src/GraphicObjects/Label.cs @@ -105,7 +105,7 @@ namespace Crow lines = getLines; this.registerForGraphicUpdate (); - this.RegisterForLayouting ((int)LayoutingType.Sizing); + this.RegisterForLayouting (LayoutingType.Sizing); NotifyValueChanged ("Text", _text); } } diff --git a/src/GraphicObjects/ListBox.cs b/src/GraphicObjects/ListBox.cs index 788d835f..dfa248cf 100644 --- a/src/GraphicObjects/ListBox.cs +++ b/src/GraphicObjects/ListBox.cs @@ -100,9 +100,9 @@ namespace Crow foreach (var item in data) { ms.Seek(0,SeekOrigin.Begin); GraphicObject g = Interface.Load (ms, t); - g.DataSource = item; g.MouseClick += itemClick; _list.addChild (g); + g.DataSource = item; } ms.Dispose (); diff --git a/src/GraphicObjects/Popper.cs b/src/GraphicObjects/Popper.cs index a7e1290c..528022e7 100644 --- a/src/GraphicObjects/Popper.cs +++ b/src/GraphicObjects/Popper.cs @@ -60,13 +60,13 @@ namespace Crow IsPopped = false; } - void _content_LayoutChanged (object sender, LayoutChangeEventArgs e) + void _content_LayoutChanged (object sender, LayoutingEventArgs e) { ILayoutable tc = Content.Parent as ILayoutable; if (tc == null) return; Rectangle r = this.ScreenCoordinates (this.Slot); - if (((int)e.LayoutType & (int)LayoutingType.Width) > 0) { + if (e.LayoutType.HasFlag(LayoutingType.Width)) { if (Content.Slot.Width < tc.ClientRectangle.Width) { if (r.Left + Content.Slot.Width > tc.ClientRectangle.Right) Content.Left = tc.ClientRectangle.Right - Content.Slot.Width; @@ -75,7 +75,7 @@ namespace Crow } else Content.Left = 0; } - if (((int)e.LayoutType & (int)LayoutingType.Height) > 0) { + if (e.LayoutType.HasFlag(LayoutingType.Height)) { if (Content.Slot.Height < tc.ClientRectangle.Height) { if (r.Bottom + Content.Slot.Height > tc.ClientRectangle.Bottom) Content.Top = r.Top - Content.Slot.Height; @@ -166,7 +166,7 @@ namespace Crow if (Content.Parent == null) tc.AddWidget (Content); tc.PutOnTop (Content); - _content_LayoutChanged (this, new LayoutChangeEventArgs (LayoutingType.Sizing)); + _content_LayoutChanged (this, new LayoutingEventArgs (LayoutingType.Sizing)); } Pop.Raise (this, e); } diff --git a/src/GraphicObjects/PrivateContainer.cs b/src/GraphicObjects/PrivateContainer.cs index f4190f9b..9f787eac 100644 --- a/src/GraphicObjects/PrivateContainer.cs +++ b/src/GraphicObjects/PrivateContainer.cs @@ -52,7 +52,8 @@ namespace Crow { if (child != null) { - this.RegisterForLayouting ((int)LayoutingType.Sizing); + child.LayoutChanged -= OnChildLayoutChanges; + this.RegisterForLayouting (LayoutingType.Sizing); child.Parent = null; } @@ -60,7 +61,8 @@ namespace Crow if (child != null) { child.Parent = this; - child.RegisterForLayouting ((int)LayoutingType.Sizing); + child.LayoutChanged += OnChildLayoutChanges; + child.RegisterForLayouting (LayoutingType.Sizing); } return (T)_child; @@ -101,22 +103,36 @@ namespace Crow switch (layoutType) { case LayoutingType.Width: if (child != null) { - if (child.getBounds ().Width == 0) - child.RegisterForLayouting ((int)LayoutingType.Width); - else - child.RegisterForLayouting ((int)LayoutingType.X); + if (child.Visible) + child.RegisterForLayouting (LayoutingType.X | LayoutingType.Width); } break; case LayoutingType.Height: if (child != null) { - if (child.getBounds ().Height == 0) - child.RegisterForLayouting ((int)LayoutingType.Height); - else - child.RegisterForLayouting ((int)LayoutingType.Y); + if (child.Visible) + child.RegisterForLayouting (LayoutingType.Y | LayoutingType.Height); } break; } } + public virtual void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) + { + GraphicObject g = sender as GraphicObject; + switch (arg.LayoutType) { + case LayoutingType.X: + break; + case LayoutingType.Y: + break; + case LayoutingType.Width: + if (this.Bounds.Width < 0) + this.RegisterForLayouting (LayoutingType.Width); + break; + case LayoutingType.Height: + if (this.Bounds.Height < 0) + this.RegisterForLayouting (LayoutingType.Height); + break; + } + } public override Rectangle ContextCoordinates (Rectangle r) { diff --git a/src/GraphicObjects/Scroller.cs b/src/GraphicObjects/Scroller.cs index b2a09db5..5188baf8 100644 --- a/src/GraphicObjects/Scroller.cs +++ b/src/GraphicObjects/Scroller.cs @@ -100,7 +100,7 @@ namespace Crow : base(){} #region GraphicObject Overrides - void OnChildLayoutChanges (object sender, LayoutChangeEventArgs arg) + void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) { int maxScroll = MaximumScroll; if (_verticalScrolling) { diff --git a/src/GraphicObjects/Slider.cs b/src/GraphicObjects/Slider.cs index 495683d2..a9bb5b8e 100644 --- a/src/GraphicObjects/Slider.cs +++ b/src/GraphicObjects/Slider.cs @@ -58,7 +58,7 @@ namespace Crow if (_cursorSize == value) return; _cursorSize = value; - RegisterForLayouting ((int)LayoutingType.Sizing); + RegisterForLayouting (LayoutingType.Sizing); registerForGraphicUpdate (); NotifyValueChanged ("CursorSize", _cursorSize); } @@ -72,7 +72,7 @@ namespace Crow return; _orientation = value; - RegisterForLayouting ((int)LayoutingType.All); + RegisterForLayouting (LayoutingType.All); NotifyValueChanged ("Orientation", _orientation); } } diff --git a/src/GraphicObjects/Spinner.cs b/src/GraphicObjects/Spinner.cs index a44abb13..49d323e0 100644 --- a/src/GraphicObjects/Spinner.cs +++ b/src/GraphicObjects/Spinner.cs @@ -35,29 +35,12 @@ namespace Crow { } - #region implemented abstract members of TemplatedControl - - protected override void loadTemplate (GraphicObject template = null) - { - base.loadTemplate (template); - } - - #endregion - void onUp (object sender, MouseButtonEventArgs e) { -// decimal tmp = 0; -// if (!decimal.TryParse (labCpt.Text, out tmp)) -// return; - Value += this.SmallIncrement; } void onDown (object sender, MouseButtonEventArgs e) { -// decimal tmp = 0; -// if (!decimal.TryParse (labCpt.Text, out tmp)) -// return; - Value -= this.SmallIncrement; } diff --git a/src/GraphicObjects/TextBox.cs b/src/GraphicObjects/TextBox.cs index 143d148f..91122523 100644 --- a/src/GraphicObjects/TextBox.cs +++ b/src/GraphicObjects/TextBox.cs @@ -199,9 +199,9 @@ namespace Crow break; } if (Width < 0) - RegisterForLayouting ((int)LayoutingType.Width); + RegisterForLayouting (LayoutingType.Width); if (Height < 0) - RegisterForLayouting ((int)LayoutingType.Height); + RegisterForLayouting (LayoutingType.Height); registerForGraphicUpdate(); } #endregion diff --git a/src/GraphicObjects/TextRun.cs b/src/GraphicObjects/TextRun.cs index bee580b3..76dde9a8 100644 --- a/src/GraphicObjects/TextRun.cs +++ b/src/GraphicObjects/TextRun.cs @@ -60,7 +60,7 @@ namespace Crow return; registerForGraphicUpdate(); - this.RegisterForLayouting ((int)LayoutingType.Sizing); + this.RegisterForLayouting (LayoutingType.Sizing); _text = value; |