*
*/
-
using System;
+using System.ComponentModel;
using System.Diagnostics;
+
using Tizen.NUI.BaseComponents;
-using System.ComponentModel;
namespace Tizen.NUI
{
[FlagsAttribute]
enum LayoutFlags : short
{
- None = 0,
- ForceLayout = 1,
- LayoutRequired = 2,
- MeasuredDimensionSet = 4
+ None = 0,
+ ForceLayout = 1,
+ LayoutRequired = 2,
+ MeasuredDimensionSet = 4
};
/// <summary>
{
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;
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
/// <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
/// [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;
}
OnUnparent();
// Remove myself from parent
- Parent?.Remove( this );
+ Parent?.Remove(this);
// Remove parent reference
Parent = null;
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>
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))
{
// 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)
/// <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))
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;
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>
{
get
{
- return ( Flags & LayoutFlags.ForceLayout) == LayoutFlags.ForceLayout;
+ return (Flags & LayoutFlags.ForceLayout) == LayoutFlags.ForceLayout;
}
}
/// 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 />
{
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);
}
}
{
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);
}
}
/// 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 />
/// 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.
/// <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;
}
/// <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;
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>
/// <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;
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))
// 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)
{
}
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;
}