Revert "[NUI] Correct the meaning of ExcludeLayouting. (#2256)"
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Layouting / LayoutItem.cs
index 487447f..7ba44af 100755 (executable)
  *
  */
 
-
 using System;
+using System.ComponentModel;
 using System.Diagnostics;
+
 using Tizen.NUI.BaseComponents;
-using System.ComponentModel;
 
 namespace Tizen.NUI
 {
@@ -27,10 +27,10 @@ namespace Tizen.NUI
     [FlagsAttribute]
     enum LayoutFlags : short
     {
-      None = 0,
-      ForceLayout = 1,
-      LayoutRequired = 2,
-      MeasuredDimensionSet = 4
+        None = 0,
+        ForceLayout = 1,
+        LayoutRequired = 2,
+        MeasuredDimensionSet = 4
     };
 
     /// <summary>
@@ -41,7 +41,7 @@ namespace Tizen.NUI
     {
         static bool LayoutDebugFrameData = false; // Debug flag
         private MeasureSpecification OldWidthMeasureSpec; // Store measure specification to compare against later
-        private MeasureSpecification OldHeightMeasureSpec;// Store measure specification to compare against later
+        private MeasureSpecification OldHeightMeasureSpec; // Store measure specification to compare against later
 
         private LayoutFlags Flags = LayoutFlags.None;
 
@@ -53,17 +53,18 @@ namespace Tizen.NUI
         private Extents _margin;
 
         private bool parentReplacement = false;
+        private bool setPositionByLayout = true;
 
         /// <summary>
         /// [Draft] Condition event that is causing this Layout to transition.
         /// </summary>
-        internal TransitionCondition ConditionForAnimation{get; set;}
+        internal TransitionCondition ConditionForAnimation { get; set; }
 
         /// <summary>
         /// [Draft] The View that this Layout has been assigned to.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
-        public View Owner{get; set;}  // Should not keep a View alive.
+        public View Owner { get; set; }  // Should not keep a View alive.
 
         /// <summary>
         /// [Draft] Use transition for layouting child
@@ -71,13 +72,27 @@ namespace Tizen.NUI
         /// <since_tizen> 6 </since_tizen>
         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
         [EditorBrowsable(EditorBrowsableState.Never)]
-         public bool LayoutWithTransition{get; set;}
+        public bool LayoutWithTransition { get; set; }
 
         /// <summary>
         /// [Draft] Set position by layouting result
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public bool SetPositionByLayout{get;set;} = true;
+        public bool SetPositionByLayout
+        {
+            get
+            {
+                return setPositionByLayout;
+            }
+            set
+            {
+                setPositionByLayout = value;
+                if (Owner != null && Owner.ExcludeLayouting != value)
+                {
+                    Owner.ExcludeLayouting = value;
+                }
+            }
+        }
 
         /// <summary>
         /// [Draft] Margin for this LayoutItem
@@ -126,7 +141,7 @@ namespace Tizen.NUI
         /// [Draft] Set parent to this layout.
         /// </summary>
         /// <param name="parent">Parent to set on this Layout.</param>
-        internal void SetParent( ILayoutParent parent)
+        internal void SetParent(ILayoutParent parent)
         {
             Parent = parent as LayoutGroup;
         }
@@ -140,7 +155,7 @@ namespace Tizen.NUI
             OnUnparent();
 
             // Remove myself from parent
-            Parent?.Remove( this );
+            Parent?.Remove(this);
 
             // Remove parent reference
             Parent = null;
@@ -152,9 +167,9 @@ namespace Tizen.NUI
         private void Initialize()
         {
             LayoutWithTransition = false;
-            _layoutPositionData = new LayoutData(this,TransitionCondition.Unspecified,0,0,0,0);
-            _padding = new Extents(0,0,0,0);
-            _margin = new Extents(0,0,0,0);
+            _layoutPositionData = new LayoutData(this, TransitionCondition.Unspecified, 0, 0, 0, 0);
+            _padding = new Extents(0, 0, 0, 0);
+            _margin = new Extents(0, 0, 0, 0);
         }
 
         /// <summary>
@@ -168,7 +183,7 @@ namespace Tizen.NUI
             OnAttachedToOwner();
             // Add layout to parent layout if a layout container
             View parent = Owner.GetParent() as View;
-            (parent?.Layout as LayoutGroup)?.Add( this );
+            (parent?.Layout as LayoutGroup)?.Add(this);
 
             // If Add or ChangeOnAdd then do not update condition
             if (ConditionForAnimation.Equals(TransitionCondition.Unspecified))
@@ -190,17 +205,17 @@ namespace Tizen.NUI
         {
             // Check if relayouting is required.
             bool specChanged = (widthMeasureSpec.Size != OldWidthMeasureSpec.Size) ||
-                               (heightMeasureSpec.Size != OldHeightMeasureSpec.Size) ||
-                               (widthMeasureSpec.Mode != OldWidthMeasureSpec.Mode) ||
-                               (heightMeasureSpec.Mode != OldHeightMeasureSpec.Mode);
+                (heightMeasureSpec.Size != OldHeightMeasureSpec.Size) ||
+                (widthMeasureSpec.Mode != OldWidthMeasureSpec.Mode) ||
+                (heightMeasureSpec.Mode != OldHeightMeasureSpec.Mode);
 
             bool isSpecExactly = (widthMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly) &&
-                                 (heightMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly);
+                (heightMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly);
 
             bool matchesSpecSize = (MeasuredWidth.Size == widthMeasureSpec.Size) &&
-                                   (MeasuredHeight.Size == heightMeasureSpec.Size);
+                (MeasuredHeight.Size == heightMeasureSpec.Size);
 
-            bool needsLayout = specChanged && ( !isSpecExactly || !matchesSpecSize);
+            bool needsLayout = specChanged && (!isSpecExactly || !matchesSpecSize);
             needsLayout = needsLayout || ((Flags & LayoutFlags.ForceLayout) == LayoutFlags.ForceLayout);
 
             if (needsLayout)
@@ -226,10 +241,40 @@ namespace Tizen.NUI
         /// <since_tizen> 6 </since_tizen>
         public void Layout(LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
         {
-            bool changed = SetFrame(left.AsRoundedValue(),
-                                    top.AsRoundedValue(),
-                                    right.AsRoundedValue(),
-                                    bottom.AsRoundedValue());
+            Layout(left, top, right, bottom, false);
+        }
+
+        /// <summary>
+        /// Assign a size and position to a layout and all of its descendants. <br />
+        /// This is the second phase of the layout mechanism.  (The first is measuring). In this phase, each parent
+        /// calls layout on all of its children to position them.  This is typically done using the child<br />
+        /// measurements that were stored in the measure pass.<br />
+        /// </summary>
+        /// <param name="left">Left position, relative to parent.</param>
+        /// <param name="top">Top position, relative to parent.</param>
+        /// <param name="right">Right position, relative to parent.</param>
+        /// <param name="bottom">Bottom position, relative to parent.</param>
+        /// <param name="independent">true, if this layout is not affected by parent layout.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Layout(LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom, bool independent)
+        {
+            bool changed = true;
+            if (!independent)
+            {
+                changed = SetFrame(left.AsRoundedValue(),
+                    top.AsRoundedValue(),
+                    right.AsRoundedValue(),
+                    bottom.AsRoundedValue());
+            }
+            else
+            {
+                // If height or width specification is not explicitly defined,
+                // the size of the owner view must be reset even the ExcludeLayouting is false.
+                if (Owner.HeightSpecification < 0 || Owner.WidthSpecification < 0)
+                {
+                    Owner.SetSize(right.AsRoundedValue() - left.AsRoundedValue(), bottom.AsRoundedValue() - top.AsRoundedValue());
+                }
+            }
 
             // Check if Measure needed before Layouting
             if (changed || ((Flags & LayoutFlags.LayoutRequired) == LayoutFlags.LayoutRequired))
@@ -258,31 +303,31 @@ namespace Tizen.NUI
             switch (specMode)
             {
                 case MeasureSpecification.ModeType.Unspecified:
-                {
-                    result = size;
-                    break;
-                }
-                case MeasureSpecification.ModeType.AtMost:
-                {
-                    // Ensure the default size does not exceed the spec size unless the default size is 0.
-                    // Another container could provide a default size of 0.
-
-                    // Do not set size to 0, use specSize in this case as could be a legacy container
-                    if( ( size.AsDecimal() < specSize.AsDecimal()) && ( size.AsDecimal() >  0) )
                     {
                         result = size;
+                        break;
                     }
-                    else
+                case MeasureSpecification.ModeType.AtMost:
                     {
-                        result = specSize;
+                        // Ensure the default size does not exceed the spec size unless the default size is 0.
+                        // Another container could provide a default size of 0.
+
+                        // Do not set size to 0, use specSize in this case as could be a legacy container
+                        if ((size.AsDecimal() < specSize.AsDecimal()) && (size.AsDecimal() > 0))
+                        {
+                            result = size;
+                        }
+                        else
+                        {
+                            result = specSize;
+                        }
+                        break;
                     }
-                    break;
-                }
                 case MeasureSpecification.ModeType.Exactly:
-                {
-                    result = specSize;
-                    break;
-                }
+                    {
+                        result = specSize;
+                        break;
+                    }
             }
 
             return result;
@@ -308,13 +353,13 @@ namespace Tizen.NUI
             Flags = Flags | LayoutFlags.ForceLayout;
             if (Parent != null)
             {
-                 LayoutGroup layoutGroup =  Parent as LayoutGroup;
-                 if(! layoutGroup.LayoutRequested)
-                 {
+                LayoutGroup layoutGroup =  Parent as LayoutGroup;
+                if (layoutGroup != null && !layoutGroup.LayoutRequested)
+                {
                     layoutGroup.RequestLayout();
-                 }
+                }
             }
-                       
+
         }
 
         /// <summary>
@@ -325,7 +370,7 @@ namespace Tizen.NUI
         {
             get
             {
-                return ( Flags & LayoutFlags.ForceLayout) == LayoutFlags.ForceLayout;
+                return (Flags & LayoutFlags.ForceLayout) == LayoutFlags.ForceLayout;
             }
         }
 
@@ -349,14 +394,14 @@ namespace Tizen.NUI
         /// This method should be used only during measurement and layout calculations.<br />
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
-        public MeasuredSize MeasuredWidth{ get; set; } = new MeasuredSize( new LayoutLength(-3), MeasuredSize.StateType.MeasuredSizeOK);
+        public MeasuredSize MeasuredWidth { get; set; } = new MeasuredSize(new LayoutLength(-3), MeasuredSize.StateType.MeasuredSizeOK);
 
         /// <summary>
         /// Get the measured height (without any measurement flags).<br />
         /// This method should be used only during measurement and layout calculations.<br />
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
-        public MeasuredSize MeasuredHeight{ get; set; } = new MeasuredSize( new LayoutLength(-3), MeasuredSize.StateType.MeasuredSizeOK);
+        public MeasuredSize MeasuredHeight { get; set; } = new MeasuredSize(new LayoutLength(-3), MeasuredSize.StateType.MeasuredSizeOK);
 
         /// <summary>
         /// Returns the suggested minimum width that the layout should use.<br />
@@ -367,8 +412,16 @@ namespace Tizen.NUI
         {
             get
             {
-                int naturalWidth = Owner.NaturalSize2D.Width;
-                return new LayoutLength(Math.Max( MinimumWidth.AsDecimal(), naturalWidth ));
+                float maximumWidth = Owner.MaximumSize.Width;
+                float minimumWidth = Owner.MinimumSize.Width;
+
+                float baseHeight = Owner.MaximumSize.Height > 0 ? Math.Min(Owner.MaximumSize.Height, Owner.NaturalSize.Height) : Owner.NaturalSize.Height;
+                float baseWidth = Owner.GetWidthForHeight(baseHeight);
+
+                float result = minimumWidth > 0 ? Math.Max(baseWidth, minimumWidth) : baseWidth;
+                result = maximumWidth > 0 ? Math.Min(result, maximumWidth) : result;
+
+                return new LayoutLength(result);
             }
         }
 
@@ -381,8 +434,16 @@ namespace Tizen.NUI
         {
             get
             {
-                int naturalHeight = Owner.NaturalSize2D.Height;
-                return new LayoutLength(Math.Max( MinimumHeight.AsDecimal(), naturalHeight ));
+                float maximumHeight = Owner.MaximumSize.Height;
+                float minimumHeight = Owner.MinimumSize.Height;
+
+                float baseWidth = Owner.MaximumSize.Width > 0 ? Math.Min(Owner.MaximumSize.Width, Owner.NaturalSize.Width) : Owner.NaturalSize.Width;
+                float baseHeight = Owner.GetHeightForWidth(baseWidth);
+
+                float result = minimumHeight > 0 ? Math.Max(baseHeight, minimumHeight) : baseHeight;
+                result = maximumHeight > 0 ? Math.Min(result, maximumHeight) : result;
+
+                return new LayoutLength(result);
             }
         }
 
@@ -394,7 +455,7 @@ namespace Tizen.NUI
         /// 2. If the owner's View.WidthSpecification is set to View.LayoutParamPolicies.WrapContent, then the view's width is set based on the suggested minimum width. (@see GetSuggestedMinimumWidth()).<br />
         /// 3. If the owner's View.WidthSpecification is set to View.LayoutParamPolicies.MatchParent, then the parent width takes precedence over the minimum width.<br />
         /// </summary>
-        internal LayoutLength MinimumWidth {get; set;}
+        internal LayoutLength MinimumWidth { get; set; }
 
         /// <summary>
         /// Sets the minimum height of the layout.<br />
@@ -404,7 +465,7 @@ namespace Tizen.NUI
         /// 2. If the owner's View.HeightSpecification is set to View.LayoutParamPolicies.WrapContent, then the view's height is set based on the suggested minimum height. (@see GetSuggestedMinimumHeight()).<br />
         /// 3. If the owner's View.HeightSpecification is set to View.LayoutParamPolicies.MatchParent, then the parent height takes precedence over the minimum height.<br />
         /// </summary>
-        internal LayoutLength MinimumHeight {get; set;}
+        internal LayoutLength MinimumHeight { get; set; }
 
         ///<summary>
         /// Utility to reconcile a desired size and state, with constraints imposed by a MeasureSpecification.
@@ -414,34 +475,34 @@ namespace Tizen.NUI
         /// <param name="childMeasuredState"> Size information bit mask for the layout's children.</param>
         /// <returns> A measured size, which may indicate that it is too small. </returns>
         /// <since_tizen> 6 </since_tizen>
-        protected MeasuredSize ResolveSizeAndState( LayoutLength size, MeasureSpecification measureSpecification, MeasuredSize.StateType childMeasuredState )
+        protected MeasuredSize ResolveSizeAndState(LayoutLength size, MeasureSpecification measureSpecification, MeasuredSize.StateType childMeasuredState)
         {
             var specMode = measureSpecification.Mode;
             LayoutLength specSize = measureSpecification.Size;
-            MeasuredSize result = new MeasuredSize( size, childMeasuredState );
+            MeasuredSize result = new MeasuredSize(size, childMeasuredState);
 
-            switch( specMode )
+            switch (specMode)
             {
                 case MeasureSpecification.ModeType.AtMost:
-                {
-                    if (specSize.AsRoundedValue() < size.AsRoundedValue())
                     {
-                        result = new MeasuredSize( specSize, MeasuredSize.StateType.MeasuredSizeTooSmall);
+                        if (specSize.AsRoundedValue() < size.AsRoundedValue())
+                        {
+                            result = new MeasuredSize(specSize, MeasuredSize.StateType.MeasuredSizeTooSmall);
+                        }
+                        break;
                     }
-                    break;
-                }
 
                 case MeasureSpecification.ModeType.Exactly:
-                {
-                    result.Size = specSize;
-                    break;
-                }
+                    {
+                        result.Size = specSize;
+                        break;
+                    }
 
                 case MeasureSpecification.ModeType.Unspecified:
                 default:
-                {
-                    break;
-                }
+                    {
+                        break;
+                    }
             }
             return result;
         }
@@ -452,7 +513,7 @@ namespace Tizen.NUI
         /// <param name="measuredWidth">The measured width of this layout.</param>
         /// <param name="measuredHeight">The measured height of this layout.</param>
         /// <since_tizen> 6 </since_tizen>
-        protected void SetMeasuredDimensions( MeasuredSize measuredWidth, MeasuredSize measuredHeight )
+        protected void SetMeasuredDimensions(MeasuredSize measuredWidth, MeasuredSize measuredHeight)
         {
             MeasuredWidth = measuredWidth;
             MeasuredHeight = measuredHeight;
@@ -474,8 +535,8 @@ namespace Tizen.NUI
         protected virtual void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
         {
             // GetDefaultSize will limit the MeasureSpec to the suggested minimumWidth and minimumHeight
-            SetMeasuredDimensions( GetDefaultSize( SuggestedMinimumWidth, widthMeasureSpec ),
-                                   GetDefaultSize( SuggestedMinimumHeight, heightMeasureSpec ) );
+            SetMeasuredDimensions(GetDefaultSize(SuggestedMinimumWidth, widthMeasureSpec),
+                                   GetDefaultSize(SuggestedMinimumHeight, heightMeasureSpec));
         }
 
         /// <summary>
@@ -488,36 +549,30 @@ namespace Tizen.NUI
         /// <param name="right">Right position, relative to parent.</param>
         /// <param name="bottom">Bottom position, relative to parent.</param>
         /// <since_tizen> 6 </since_tizen>
-        protected virtual void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom)
-        {
-        }
+        protected virtual void OnLayout(bool changed, LayoutLength left, LayoutLength top, LayoutLength right, LayoutLength bottom) { }
 
         /// <summary>
         /// Virtual method to allow derived classes to remove any children before it is removed from
         /// its parent.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
-        protected virtual void OnUnparent()
-        {
-        }
+        protected virtual void OnUnparent() { }
 
         /// <summary>
         /// Virtual method called when this Layout is attached to it's owner.
         /// Allows derived layouts to take ownership of child Views and connect to any Owner signals required.
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
-        protected virtual void OnAttachedToOwner()
-        {
-        }
+        protected virtual void OnAttachedToOwner() { }
 
         private bool SetFrame(float left, float top, float right, float bottom)
         {
             bool changed = false;
 
-            if ( _layoutPositionData.Left != left ||
+            if (_layoutPositionData.Left != left ||
                  _layoutPositionData.Right != right ||
                  _layoutPositionData.Top != top ||
-                 _layoutPositionData.Bottom != bottom  )
+                 _layoutPositionData.Bottom != bottom)
             {
                 changed = true;
 
@@ -525,7 +580,7 @@ namespace Tizen.NUI
                 float oldHeight = _layoutPositionData.Bottom - _layoutPositionData.Top;
                 float newWidth = right - left;
                 float newHeight = bottom - top;
-                bool sizeChanged = ( newWidth != oldWidth ) || ( newHeight != oldHeight );
+                bool sizeChanged = (newWidth != oldWidth) || (newHeight != oldHeight);
 
                 // Set condition to layout changed as currently unspecified. Add, Remove would have specified a condition.
                 if (ConditionForAnimation.Equals(TransitionCondition.Unspecified))
@@ -536,11 +591,11 @@ namespace Tizen.NUI
                 // Store new layout position data
                 _layoutPositionData = new LayoutData(this, ConditionForAnimation, left, top, right, bottom);
 
-                Debug.WriteLineIf( LayoutDebugFrameData, "LayoutItem FramePositionData View:" + _layoutPositionData.Item.Owner.Name +
+                Debug.WriteLineIf(LayoutDebugFrameData, "LayoutItem FramePositionData View:" + _layoutPositionData.Item.Owner.Name +
                                                          " left:" + _layoutPositionData.Left +
                                                          " top:" + _layoutPositionData.Top +
                                                          " right:" + _layoutPositionData.Right +
-                                                         " bottom:" + _layoutPositionData.Bottom );
+                                                         " bottom:" + _layoutPositionData.Bottom);
 
                 if (Owner.Parent != null && Owner.Parent.Layout != null && Owner.Parent.Layout.LayoutWithTransition)
                 {
@@ -548,14 +603,13 @@ namespace Tizen.NUI
                 }
                 else
                 {
-                    Owner.SetSize(right - left, bottom - top, Owner.Position.Z);
-                    if(SetPositionByLayout)
+                    if (Owner.Position != null)
                     {
-                        Owner.SetPosition(left, top, Owner.Position.Z);
+                        Owner.SetSize(right - left, bottom - top);
+                        Owner.SetPosition(left, top);
                     }
                 }
 
-
                 // Reset condition for animation ready for next transition when required.
                 ConditionForAnimation = TransitionCondition.Unspecified;
             }