[NUI] Apply Padding and Margin on CollectionView and Layouter with styles (#2883)
authorSangHyeon Jade Lee <sh10233.lee@samsung.com>
Tue, 13 Apr 2021 10:23:53 +0000 (19:23 +0900)
committerhuiyueun <35286162+huiyueun@users.noreply.github.com>
Tue, 20 Apr 2021 06:13:00 +0000 (15:13 +0900)
now you can define the padding in layouter independently,
and each item's padding and margin will be respected.

src/Tizen.NUI.Components/Controls/RecyclerView/CollectionView.cs
src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultLinearItem.cs
src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultTitleItem.cs
src/Tizen.NUI.Components/Controls/RecyclerView/Item/RecyclerViewItem.cs
src/Tizen.NUI.Components/Controls/RecyclerView/Layouter/GridLayouter.cs
src/Tizen.NUI.Components/Controls/RecyclerView/Layouter/ItemsLayouter.cs
src/Tizen.NUI.Components/Controls/RecyclerView/Layouter/LinearLayouter.cs
src/Tizen.NUI.Components/Theme/DefaultThemeCommon.cs

index 2a0bf2e..51105ec 100755 (executable)
@@ -263,6 +263,15 @@ namespace Tizen.NUI.Components
                 }
 
                 needInitalizeLayouter = true;
+
+                var styleName = "Tizen.NUI.Components." + (itemsLayouter is LinearLayouter? "LinearLayouter" : (itemsLayouter is GridLayouter ? "GridLayouter" : "ItemsLayouter"));
+                using (ViewStyle layouterStyle = ThemeManager.GetStyle(styleName))
+                {
+                    if (layouterStyle != null)
+                    {
+                        itemsLayouter.Padding = new Extents(layouterStyle.Padding);
+                    }
+                }
                 Init();
             }
         }
@@ -632,23 +641,17 @@ namespace Tizen.NUI.Components
         /// <summary>
         /// Scroll to specific item's aligned position with or without animation.
         /// </summary>
-        /// <param name="item">Target item of dataset.</param>
+        /// <param name="index">Target item index of dataset.</param>
         /// <param name="animate">Boolean flag of animation.</param>
         /// <param name="align">Align state of item. see details in ItemScrollTo.</param>
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public virtual void ScrollTo(object item, bool animate = false, ItemScrollTo align = ItemScrollTo.Nearest)
+        public virtual void ScrollTo(int index, bool animate = false, ItemScrollTo align = ItemScrollTo.Nearest)
         {
-            if (item == null) throw new ArgumentNullException(nameof(item));
             if (ItemsLayouter == null) throw new Exception("Item Layouter must exist.");
 
-            if (InternalItemSource.GetPosition(item) == -1)
-            {
-                throw new Exception("ScrollTo parameter item is not a member of ItemsSource");
-            }
-
             float scrollPos, curPos, curSize, curItemSize;
-            (float x, float y) = ItemsLayouter.GetItemPosition(item);
-            (float width, float height) = ItemsLayouter.GetItemSize(item);
+            (float x, float y) = ItemsLayouter.GetItemPosition(index);
+            (float width, float height) = ItemsLayouter.GetItemSize(index);
             if (ScrollingDirection == Direction.Horizontal)
             {
                 scrollPos = x;
@@ -698,6 +701,28 @@ namespace Tizen.NUI.Components
             base.ScrollTo(scrollPos, animate);
         }
 
+        /// <summary>
+        /// Apply style to CollectionView
+        /// </summary>
+        /// <param name="viewStyle">The style to apply.</param>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override void ApplyStyle(ViewStyle viewStyle)
+        {
+            base.ApplyStyle(viewStyle);
+            if (viewStyle != null)
+            {
+                //Extension = RecyclerViewItemStyle.CreateExtension();
+            }
+            if (itemsLayouter != null)
+            {
+                string styleName = "Tizen.NUI.Compoenents." + (itemsLayouter is LinearLayouter? "LinearLayouter" : (itemsLayouter is GridLayouter ? "GridLayouter" : "ItemsLayouter"));
+                using (ViewStyle layouterStyle = ThemeManager.GetStyle(styleName))
+                {
+                    itemsLayouter.Padding = new Extents(layouterStyle.Padding);
+                }
+            }
+        }
+
         // Realize and Decorate the item.
         internal override RecyclerViewItem RealizeItem(int index)
         {
index d3627f6..cb5ace2 100755 (executable)
@@ -256,7 +256,6 @@ namespace Tizen.NUI.Components
         [EditorBrowsable(EditorBrowsableState.Never)]
         public override void ApplyStyle(ViewStyle viewStyle)
         {
-
             base.ApplyStyle(viewStyle);
             if (viewStyle != null && viewStyle is DefaultLinearItemStyle defaultStyle)
             {
@@ -271,12 +270,9 @@ namespace Tizen.NUI.Components
                 if (itemSeperator != null)
                 {
                     itemSeperator.ApplyStyle(defaultStyle.Seperator);
-                    //FIXME : currently margin is not applied by ApplyStyle automatically.
-                    itemSeperator.Margin = defaultStyle.Seperator.Margin;
+                    //FIXME : currently padding and margin are not applied by ApplyStyle automatically as missing binding features.
+                    itemSeperator.Margin = new Extents(defaultStyle.Seperator.Margin);
                 }
-                //FIXME : currently padding is not applied by ApplyStyle automatically.
-                Extents padding = defaultStyle.Padding;
-                Padding = padding;
             }
         }
 
index fe77c68..8236a63 100755 (executable)
@@ -195,12 +195,9 @@ namespace Tizen.NUI.Components
                 if (itemSeperator != null)
                 {
                     itemSeperator.ApplyStyle(defaultStyle.Seperator);
-                    //FIXME : currently margin is not applied by ApplyStyle automatically.
-                    itemSeperator.Margin = defaultStyle.Seperator.Margin;
+                    //FIXME : currently padding and margin are not applied by ApplyStyle automatically as missing binding features.
+                    itemSeperator.Margin = new Extents(defaultStyle.Seperator.Margin);
                 }
-                //FIXME : currently padding is not applied by ApplyStyle automatically.
-                Extents padding = defaultStyle.Padding;
-                Padding = padding;
             }
         }
 
index 53c6265..61501f0 100755 (executable)
@@ -282,6 +282,9 @@ namespace Tizen.NUI.Components
             if (viewStyle != null)
             {
                 //Extension = RecyclerViewItemStyle.CreateExtension();
+                //FIXME : currently padding and margin are not applied by ApplyStyle automatically as missing binding features.               
+                Padding = new Extents(viewStyle.Padding);
+                Margin = new Extents(viewStyle.Margin);
             }
 
             styleApplied = true;
index 8f6123f..1f7e4e4 100755 (executable)
@@ -27,17 +27,21 @@ namespace Tizen.NUI.Components
     public class GridLayouter : ItemsLayouter
     {
         private CollectionView colView;
-        private Size2D sizeCandidate;
+        private (float Width, float Height) sizeCandidate;
         private int spanSize = 1;
         private float align = 0.5f;
         private bool hasHeader;
+        private Extents headerMargin;
         private float headerSize;
+        private Extents footerMargin;
         private bool hasFooter;
         private float footerSize;
         private bool isGrouped;
         private readonly List<GroupInfo> groups = new List<GroupInfo>();
         private float groupHeaderSize;
+        private Extents groupHeaderMargin;
         private float groupFooterSize;
+        private Extents groupFooterMargin;
         private GroupInfo Visited;
 
         /// <summary>
@@ -70,17 +74,21 @@ namespace Tizen.NUI.Components
             RecyclerViewItem footer = colView?.Footer;
             float width, height;
             int count = colView.InternalItemSource.Count;
-            int pureCount = count - (header ? 1 : 0) - (footer ? 1 : 0);
+            int pureCount = count - (header? 1 : 0) - (footer? 1 : 0);
 
             // 2. Get the header / footer and size deligated item and measure the size.
             if (header != null)
             {
                 MeasureChild(colView, header);
 
-                width = header.Layout != null ? header.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
-                height = header.Layout != null ? header.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
+                width = header.Layout != null? header.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
+                height = header.Layout != null? header.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
 
-                headerSize = IsHorizontal ? width : height;
+                Extents itemMargin = header.Margin;
+                headerSize = IsHorizontal?
+                                width + itemMargin.Start + itemMargin.End:
+                                height + itemMargin.Top + itemMargin.Bottom;
+                headerMargin = new Extents(itemMargin);
                 hasHeader = true;
 
                 colView.UnrealizeItem(header);
@@ -90,17 +98,21 @@ namespace Tizen.NUI.Components
             {
                 MeasureChild(colView, footer);
 
-                width = footer.Layout != null ? footer.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
-                height = footer.Layout != null ? footer.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
+                width = footer.Layout != null? footer.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
+                height = footer.Layout != null? footer.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
 
-                footerSize = IsHorizontal ? width : height;
+                Extents itemMargin = footer.Margin;
+                footerSize = IsHorizontal?
+                                width + itemMargin.Start + itemMargin.End:
+                                height + itemMargin.Top + itemMargin.Bottom;
+                footerMargin = new Extents(itemMargin);
                 footer.Index = count - 1;
                 hasFooter = true;
 
                 colView.UnrealizeItem(footer);
             }
 
-            int firstIndex = header ? 1 : 0;
+            int firstIndex = header? 1 : 0;
 
             if (colView.IsGrouped)
             {
@@ -132,7 +144,11 @@ namespace Tizen.NUI.Components
                         }
                         //Console.WriteLine("[NUI] GroupHeader Size {0} :{0}", width, height);
                         // pick the StepCandidate.
-                        groupHeaderSize = IsHorizontal ? width : height;
+                        Extents itemMargin = groupHeader.Margin;
+                        groupHeaderSize = IsHorizontal?
+                                            width + itemMargin.Start + itemMargin.End:
+                                            height + itemMargin.Top + itemMargin.Bottom;
+                        groupHeaderMargin = new Extents(itemMargin);
                         colView.UnrealizeItem(groupHeader);
                     }
                 }
@@ -165,8 +181,12 @@ namespace Tizen.NUI.Components
                             height = groupFooter.Layout.MeasuredHeight.Size.AsRoundedValue();
                         }
                         // pick the StepCandidate.
-                        groupFooterSize = IsHorizontal ? width : height;
-
+                        Extents itemMargin = groupFooter.Margin;
+                        groupFooterSize = IsHorizontal?
+                                            width + itemMargin.Start + itemMargin.End:
+                                            height + itemMargin.Top + itemMargin.Bottom;
+                        groupFooterMargin = new Extents(itemMargin);
+                    
                         colView.UnrealizeItem(groupFooter);
                     }
                 }
@@ -192,7 +212,7 @@ namespace Tizen.NUI.Components
                 firstIndex++;
             }
 
-            sizeCandidate = new Size2D(0, 0);
+            sizeCandidate = (0, 0);
             if (!failed)
             {
                 // Get Size Deligate. FIXME if group exist index must be changed.
@@ -219,11 +239,16 @@ namespace Tizen.NUI.Components
                 //Console.WriteLine("[NUI] item Size {0} :{1}", width, height);
 
                 // pick the StepCandidate.
-                StepCandidate = IsHorizontal ? width : height;
-                spanSize = IsHorizontal ? Convert.ToInt32(Math.Truncate((double)(colView.Size.Height / height))) :
-                                        Convert.ToInt32(Math.Truncate((double)(colView.Size.Width / width)));
+                Extents itemMargin = sizeDeligate.Margin;
+                width = width + itemMargin.Start + itemMargin.End;
+                height = height + itemMargin.Top + itemMargin.Bottom;
+                StepCandidate = IsHorizontal? width : height;
+                CandidateMargin = new Extents(itemMargin);
+                spanSize = IsHorizontal?
+                            Convert.ToInt32(Math.Truncate((double)((colView.Size.Height - Padding.Top - Padding.Bottom) / height))) :
+                            Convert.ToInt32(Math.Truncate((double)((colView.Size.Width - Padding.Start - Padding.End) / width)));
 
-                sizeCandidate = new Size2D(Convert.ToInt32(width), Convert.ToInt32(height));
+                sizeCandidate = (width, height);
 
                 colView.UnrealizeItem(sizeDeligate);
             }
@@ -293,6 +318,10 @@ namespace Tizen.NUI.Components
                 if (hasFooter) ScrollContentSize += footerSize;
             }
 
+            ScrollContentSize = IsHorizontal?
+                                ScrollContentSize + Padding.Start + Padding.End:
+                                ScrollContentSize + Padding.Top + Padding.Bottom;
+
             if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
             else colView.ContentContainer.SizeHeight = ScrollContentSize;
 
@@ -319,7 +348,7 @@ namespace Tizen.NUI.Components
             bool IsHorizontal = (colView.ScrollingDirection == ScrollableBase.Direction.Horizontal);
 
             (float X, float Y) visibleArea = (PrevScrollPosition,
-                PrevScrollPosition + (IsHorizontal ? colView.Size.Width : colView.Size.Height)
+                PrevScrollPosition + (IsHorizontal? colView.Size.Width : colView.Size.Height)
             );
 
             //Console.WriteLine("[NUI] itemsView [{0},{1}] [{2},{3}]", colView.Size.Width, colView.Size.Height, colView.ContentContainer.Size.Width, colView.ContentContainer.Size.Height);
@@ -359,47 +388,26 @@ namespace Tizen.NUI.Components
                 if (item == null) item = colView.RealizeItem(i);
                 VisibleItems.Add(item);
 
+                //item Position without Padding and Margin.
                 (float x, float y) = GetItemPosition(i);
-                // 5. Placing item.
+                // 5. Placing item with Padding and Margin.
                 item.Position = new Position(x, y);
-                //Console.WriteLine("[NUI] ["+item.Index+"] ["+item.Position.X+", "+item.Position.Y+" ==== \n");
-            }
-            //Console.WriteLine("Realize Done");
-        }
-
-        /// <Inheritdoc/>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public override (float X, float Y) GetItemPosition(object item)
-        {
-            if (item == null) throw new ArgumentNullException(nameof(item));
-            if (colView == null) return (0, 0);
-
-            return GetItemPosition(colView.InternalItemSource.GetPosition(item));
-        }
-
-        /// <Inheritdoc/>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public override (float X, float Y) GetItemSize(object item)
-        {
-            if (item == null) throw new ArgumentNullException(nameof(item));
-            if (sizeCandidate == null) return (0, 0);
-
-            if (isGrouped)
-            {
-                int index = colView.InternalItemSource.GetPosition(item);
-                float view = (IsHorizontal ? colView.Size.Height : colView.Size.Width);
-
-                if (colView.InternalItemSource.IsGroupHeader(index))
+                
+                //Linear Item need to be resized!
+                if (item.IsHeader || item.IsFooter || item.isGroupHeader || item.isGroupFooter)
                 {
-                    return (IsHorizontal ? (groupHeaderSize, view) : (view, groupHeaderSize));
-                }
-                else if (colView.InternalItemSource.IsGroupFooter(index))
-                {
-                    return (IsHorizontal ? (groupFooterSize, view) : (view, groupFooterSize));
+                    if (IsHorizontal && item.HeightSpecification == LayoutParamPolicies.MatchParent)
+                    {
+                        item.Size = new Size(item.Size.Width, Container.Size.Height - Padding.Top - Padding.Bottom - item.Margin.Top - item.Margin.Bottom);
+                    }
+                    else if (!IsHorizontal && item.WidthSpecification == LayoutParamPolicies.MatchParent)
+                    {
+                        item.Size = new Size(Container.Size.Width - Padding.Start - Padding.End - item.Margin.Start - item.Margin.End, item.Size.Height);
+                    }
                 }
+                //Console.WriteLine("[NUI] ["+item.Index+"] ["+item.Position.X+", "+item.Position.Y+" ==== \n");
             }
-
-            return (sizeCandidate.Width, sizeCandidate.Height);
+            //Console.WriteLine("Realize Done");
         }
 
         /// <inheritdoc/>
@@ -482,7 +490,7 @@ namespace Tizen.NUI.Components
             (int start, int end) found = (0, 0);
 
             // Header is Showing
-            if (hasHeader && visibleArea.X < headerSize)
+            if (hasHeader && visibleArea.X < headerSize + (IsHorizontal? Padding.Start : Padding.Top))
             {
                 found.start = 0;
             }
@@ -539,7 +547,7 @@ namespace Tizen.NUI.Components
                 if (found.start < 0) found.start = 0;
             }
 
-            if (hasFooter && visibleArea.Y > ScrollContentSize - footerSize)
+            if (hasFooter && visibleArea.Y > ScrollContentSize - footerSize - (IsHorizontal? Padding.End : Padding.Bottom))
             {
                 found.end = MaxIndex + 1;
             }
@@ -599,19 +607,27 @@ namespace Tizen.NUI.Components
             return found;
         }
 
-        private (float X, float Y) GetItemPosition(int index)
+        internal override (float X, float Y) GetItemPosition(int index)
         {
             float xPos, yPos;
-            if (sizeCandidate == null) return (0, 0);
+            int spaceStartX = Padding.Start;
+            int spaceStartY = Padding.Top;
+            int emptyArea = IsHorizontal?
+                            (int)(colView.Size.Height - Padding.Top - Padding.Bottom - (sizeCandidate.Height * spanSize)) :
+                            (int)(colView.Size.Width - Padding.Start - Padding.End - (sizeCandidate.Width * spanSize));
 
             if (hasHeader && index == 0)
             {
-                return (0, 0);
+                return (spaceStartX + headerMargin.Start, spaceStartY + headerMargin.Top);
             }
             if (hasFooter && index == colView.InternalItemSource.Count - 1)
             {
-                xPos = IsHorizontal ? ScrollContentSize - footerSize : 0;
-                yPos = IsHorizontal ? 0 : ScrollContentSize - footerSize;
+                xPos = IsHorizontal?
+                        ScrollContentSize - Padding.End - footerSize + footerMargin.Start:
+                        spaceStartX;
+                yPos = IsHorizontal?
+                        spaceStartY:
+                        ScrollContentSize - Padding.Bottom - footerSize + footerMargin.Top;
                 return (xPos, yPos);
             }
             if (isGrouped)
@@ -619,26 +635,42 @@ namespace Tizen.NUI.Components
                 GroupInfo myGroup = GetGroupInfo(index);
                 if (colView.InternalItemSource.IsGroupHeader(index))
                 {
-                    xPos = IsHorizontal ? myGroup.GroupPosition : 0;
-                    yPos = IsHorizontal ? 0 : myGroup.GroupPosition;
+                    spaceStartX+= groupHeaderMargin.Start;
+                    spaceStartY+= groupHeaderMargin.Top;
+                    xPos = IsHorizontal?
+                            myGroup.GroupPosition + groupHeaderMargin.Start:
+                            spaceStartX;
+                    yPos = IsHorizontal?
+                            spaceStartY:
+                            myGroup.GroupPosition + groupHeaderMargin.Top;
                 }
                 else if (colView.InternalItemSource.IsGroupFooter(index))
                 {
-                    xPos = IsHorizontal ? myGroup.GroupPosition + myGroup.GroupSize - groupFooterSize : 0;
-                    yPos = IsHorizontal ? 0 : myGroup.GroupPosition + myGroup.GroupSize - groupFooterSize;
+                    spaceStartX+= groupFooterMargin.Start;
+                    spaceStartY+= groupFooterMargin.Top;
+                    xPos = IsHorizontal?
+                            myGroup.GroupPosition + myGroup.GroupSize - groupFooterSize + groupFooterMargin.Start:
+                            spaceStartX;
+                    yPos = IsHorizontal?
+                            spaceStartY:
+                            myGroup.GroupPosition + myGroup.GroupSize - groupFooterSize + groupFooterMargin.Top;
                 }
                 else
                 {
                     int pureIndex = index - myGroup.StartIndex - 1;
                     int division = pureIndex / spanSize;
                     int remainder = pureIndex % spanSize;
-                    int emptyArea = IsHorizontal ? (int)(colView.Size.Height - (sizeCandidate.Height * spanSize)) :
-                                                    (int)(colView.Size.Width - (sizeCandidate.Width * spanSize));
                     if (division < 0) division = 0;
                     if (remainder < 0) remainder = 0;
-
-                    xPos = IsHorizontal ? division * sizeCandidate.Width + myGroup.GroupPosition + groupHeaderSize : emptyArea * align + remainder * sizeCandidate.Width;
-                    yPos = IsHorizontal ? emptyArea * align + remainder * sizeCandidate.Height : division * sizeCandidate.Height + myGroup.GroupPosition + groupHeaderSize;
+                    spaceStartX+= CandidateMargin.Start;
+                    spaceStartY+= CandidateMargin.Top;
+
+                    xPos = IsHorizontal?
+                            (division * sizeCandidate.Width) + myGroup.GroupPosition + groupHeaderSize + CandidateMargin.Start:
+                            (emptyArea * align) + (remainder * sizeCandidate.Width) + spaceStartX;
+                    yPos = IsHorizontal?
+                            (emptyArea * align) + (remainder * sizeCandidate.Height) + spaceStartY:
+                            (division * sizeCandidate.Height) + myGroup.GroupPosition + groupHeaderSize + CandidateMargin.Top;
                 }
             }
             else
@@ -647,18 +679,28 @@ namespace Tizen.NUI.Components
                 // int convert must be truncate value.
                 int division = pureIndex / spanSize;
                 int remainder = pureIndex % spanSize;
-                int emptyArea = IsHorizontal ? (int)(colView.Size.Height - (sizeCandidate.Height * spanSize)) :
-                                                (int)(colView.Size.Width - (sizeCandidate.Width * spanSize));
                 if (division < 0) division = 0;
                 if (remainder < 0) remainder = 0;
-
-                xPos = IsHorizontal ? division * sizeCandidate.Width + (hasHeader ? headerSize : 0) : emptyArea * align + remainder * sizeCandidate.Width;
-                yPos = IsHorizontal ? emptyArea * align + remainder * sizeCandidate.Height : division * sizeCandidate.Height + (hasHeader ? headerSize : 0);
+                spaceStartX+= CandidateMargin.Start;
+                spaceStartY+= CandidateMargin.Top;
+
+                xPos = IsHorizontal?
+                        (division * sizeCandidate.Width) + (hasHeader? headerSize : 0) + spaceStartX:
+                        (emptyArea * align) + (remainder * sizeCandidate.Width) + spaceStartX;
+                yPos = IsHorizontal?
+                        (emptyArea * align) + (remainder * sizeCandidate.Height) + spaceStartY:
+                        (division * sizeCandidate.Height) + (hasHeader? headerSize : 0) + spaceStartY;
             }
 
             return (xPos, yPos);
         }
 
+        internal override (float Width, float Height) GetItemSize(int index)
+        {            
+            return (sizeCandidate.Width - CandidateMargin.Start - CandidateMargin.End,
+                    sizeCandidate.Height - CandidateMargin.Top - CandidateMargin.Bottom);
+        }
+
         private RecyclerViewItem GetVisibleItem(int index)
         {
             foreach (RecyclerViewItem item in VisibleItems)
index 7d20b06..afc5abb 100755 (executable)
@@ -28,6 +28,26 @@ namespace Tizen.NUI.Components
     public abstract class ItemsLayouter : ICollectionChangedNotifier, IDisposable
     {
         private bool disposed = false;
+        private Extents padding = new Extents(0, 0, 0, 0);
+
+        /// <summary>
+        /// Padding for ContentContainer of RecyclerView.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public Extents Padding {
+            get
+            {
+                return padding;
+            }
+            set
+            {
+                padding = value;
+                if (ItemsView?.ContentContainer != null)
+                {
+                    ItemsView.Padding = padding;
+                }
+            }
+        }
 
         /// <summary>
         /// Container which contains ViewItems.
@@ -78,6 +98,12 @@ namespace Tizen.NUI.Components
         protected float StepCandidate { get; set; }
 
         /// <summary>
+        /// Candidate item's Margin for scroll size measure.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected Extents CandidateMargin { get; set; }
+
+        /// <summary>
         /// Content size of scrollable.
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
@@ -132,30 +158,6 @@ namespace Tizen.NUI.Components
         }
 
         /// <summary>
-        /// Position of layouting item.
-        /// </summary>
-        /// <param name="item">item of dataset.</param>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public virtual (float X, float Y) GetItemPosition(object item)
-        {
-            if (item == null) throw new ArgumentNullException(nameof(item));
-            // Layouting Items in scrollPosition.
-            return (0, 0);
-        }
-
-        /// <summary>
-        /// Size of layouting item.
-        /// </summary>
-        /// <param name="item">item of dataset.</param>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public virtual (float X, float Y) GetItemSize(object item)
-        {
-            if (item == null) throw new ArgumentNullException(nameof(item));
-            // Layouting Items in scrollPosition.
-            return (0, 0);
-        }
-
-        /// <summary>
         /// This is called to find out how much container size can be.
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
@@ -307,12 +309,12 @@ namespace Tizen.NUI.Components
             // but in some multiple-line TextLabel can be long enough to over the it's parent size.
 
             MeasureSpecification childWidthMeasureSpec = LayoutGroup.GetChildMeasureSpecification(
-                        new MeasureSpecification(new LayoutLength(parent.Size.Width), MeasureSpecification.ModeType.Exactly),
+                        new MeasureSpecification(new LayoutLength(parent.Size.Width - parent.Padding.Start - parent.Padding.End - child.Margin.Start - child.Margin.End), MeasureSpecification.ModeType.Exactly),
                         new LayoutLength(0),
                         new LayoutLength(child.WidthSpecification));
 
             MeasureSpecification childHeightMeasureSpec = LayoutGroup.GetChildMeasureSpecification(
-                        new MeasureSpecification(new LayoutLength(parent.Size.Height), MeasureSpecification.ModeType.Exactly),
+                        new MeasureSpecification(new LayoutLength(parent.Size.Height - parent.Padding.Top - parent.Padding.Bottom - child.Margin.Top - child.Margin.Bottom), MeasureSpecification.ModeType.Exactly),
                         new LayoutLength(0),
                         new LayoutLength(child.HeightSpecification));
 
@@ -343,7 +345,21 @@ namespace Tizen.NUI.Components
             }
 
             disposed = true;
-            if (disposing) Clear();
+            if (disposing)
+            {
+                Clear();
+                padding.Dispose();
+            }
+        }
+
+        internal virtual (float X, float Y) GetItemPosition(int index)
+        {
+            return (0, 0);
+        }
+
+        internal virtual (float Width, float Height) GetItemSize(int index)
+        {
+            return (0, 0);
         }
     }
 }
index dd3af25..1f0196f 100755 (executable)
@@ -32,12 +32,16 @@ namespace Tizen.NUI.Components
         private CollectionView colView;
         private bool hasHeader;
         private float headerSize;
+        private Extents headerMargin;
         private bool hasFooter;
         private float footerSize;
+        private Extents footerMargin;
         private bool isGrouped;
         private readonly List<GroupInfo> groups = new List<GroupInfo>();
         private float groupHeaderSize;
+        private Extents groupHeaderMargin;
         private float groupFooterSize;
+        private Extents groupFooterMargin;
         private GroupInfo Visited;
 
         /// <summary>
@@ -76,10 +80,14 @@ namespace Tizen.NUI.Components
             {
                 MeasureChild(colView, header);
 
-                width = header.Layout != null ? header.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
-                height = header.Layout != null ? header.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
+                width = header.Layout != null? header.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
+                height = header.Layout != null? header.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
 
-                headerSize = IsHorizontal ? width : height;
+                Extents itemMargin = header.Margin;
+                headerSize = IsHorizontal?
+                                width + itemMargin.Start + itemMargin.End:
+                                height + itemMargin.Top + itemMargin.Bottom;
+                headerMargin = new Extents(itemMargin);
                 hasHeader = true;
 
                 colView.UnrealizeItem(header);
@@ -90,10 +98,14 @@ namespace Tizen.NUI.Components
             {
                 MeasureChild(colView, footer);
 
-                width = footer.Layout != null ? footer.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
-                height = footer.Layout != null ? footer.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
+                width = footer.Layout != null? footer.Layout.MeasuredWidth.Size.AsRoundedValue() : 0;
+                height = footer.Layout != null? footer.Layout.MeasuredHeight.Size.AsRoundedValue() : 0;
 
-                footerSize = IsHorizontal ? width : height;
+                Extents itemMargin = footer.Margin;
+                footerSize = IsHorizontal?
+                                width + itemMargin.Start + itemMargin.End:
+                                height + itemMargin.Top + itemMargin.Bottom;
+                footerMargin = new Extents(itemMargin);
                 footer.Index = count - 1;
                 hasFooter = true;
 
@@ -102,9 +114,9 @@ namespace Tizen.NUI.Components
             else hasFooter = false;
 
             //No Internal Source exist.
-            if (count == (hasHeader ? (hasFooter ? 2 : 1) : 0)) return;
+            if (count == (hasHeader? (hasFooter? 2 : 1) : 0)) return;
 
-            int firstIndex = hasHeader ? 1 : 0;
+            int firstIndex = hasHeader? 1 : 0;
 
             if (colView.IsGrouped)
             {
@@ -134,9 +146,12 @@ namespace Tizen.NUI.Components
                             width = groupHeader.Layout.MeasuredWidth.Size.AsRoundedValue();
                             height = groupHeader.Layout.MeasuredHeight.Size.AsRoundedValue();
                         }
-                        //Console.WriteLine("[NUI] GroupHeader Size {0} :{0}", width, height);
                         // pick the StepCandidate.
-                        groupHeaderSize = IsHorizontal ? width : height;
+                        Extents itemMargin = groupHeader.Margin;
+                        groupHeaderSize = IsHorizontal?
+                                            width + itemMargin.Start + itemMargin.End:
+                                            height + itemMargin.Top + itemMargin.Bottom;
+                        groupHeaderMargin = new Extents(itemMargin);
                         colView.UnrealizeItem(groupHeader);
                     }
                 }
@@ -169,8 +184,11 @@ namespace Tizen.NUI.Components
                             height = groupFooter.Layout.MeasuredHeight.Size.AsRoundedValue();
                         }
                         // pick the StepCandidate.
-                        groupFooterSize = IsHorizontal ? width : height;
-
+                        Extents itemMargin = groupFooter.Margin;
+                        groupFooterSize = IsHorizontal?
+                                            width + itemMargin.Start + itemMargin.End:
+                                            height + itemMargin.Top + itemMargin.Bottom;
+                        groupFooterMargin = new Extents(itemMargin);  
                         colView.UnrealizeItem(groupFooter);
                     }
                 }
@@ -220,15 +238,18 @@ namespace Tizen.NUI.Components
                     width = sizeDeligate.Layout.MeasuredWidth.Size.AsRoundedValue();
                     height = sizeDeligate.Layout.MeasuredHeight.Size.AsRoundedValue();
                 }
-                //Console.WriteLine("[NUI] Layout Size {0} :{0}", width, height);
                 // pick the StepCandidate.
-                StepCandidate = IsHorizontal ? width : height;
+                Extents itemMargin = sizeDeligate.Margin;
+                StepCandidate = IsHorizontal?
+                                width + itemMargin.Start + itemMargin.End:
+                                height + itemMargin.Top + itemMargin.Bottom;
+                CandidateMargin = new Extents(itemMargin);  
                 if (StepCandidate == 0) StepCandidate = 1; //????
 
                 colView.UnrealizeItem(sizeDeligate);
             }
 
-            float Current = 0.0F;
+            float Current = IsHorizontal? Padding.Start : Padding.Top;
             IGroupableItemSource source = colView.InternalItemSource;
             GroupInfo currentGroup = null;
             for (int i = 0; i < count; i++)
@@ -304,7 +325,7 @@ namespace Tizen.NUI.Components
                 }
             }
 
-            ScrollContentSize = Current;
+            ScrollContentSize = Current + (IsHorizontal? Padding.End : Padding.Bottom);
             if (IsHorizontal) colView.ContentContainer.SizeWidth = ScrollContentSize;
             else colView.ContentContainer.SizeHeight = ScrollContentSize;
 
@@ -332,14 +353,14 @@ namespace Tizen.NUI.Components
             {
                 for (int i = ItemSizeChanged; i <= LastIndex; i++)
                     UpdatePosition(i);
-                ScrollContentSize = ItemPosition[LastIndex - 1] + GetItemSize(LastIndex);
+                ScrollContentSize = ItemPosition[LastIndex - 1] + GetItemStepSize(LastIndex) + (IsHorizontal? Padding.End : Padding.Bottom);
             }
 
             int prevFirstVisible = FirstVisible;
             int prevLastVisible = LastVisible;
 
             (float X, float Y) visibleArea = (PrevScrollPosition,
-                PrevScrollPosition + (IsHorizontal ? colView.Size.Width : colView.Size.Height)
+                PrevScrollPosition + (IsHorizontal? colView.Size.Width : colView.Size.Height)
             );
 
             // 1. Set First/Last Visible Item Index. 
@@ -371,65 +392,56 @@ namespace Tizen.NUI.Components
                     if (item) continue;
                 }
                 if (item == null) item = colView.RealizeItem(i);
-
                 VisibleItems.Add(item);
 
                 // 5. Placing item.
                 float posX = 0F, posY = 0F;
+                int spaceStartX = Padding.Start + item.Margin.Start;
+                int spaceStartY = Padding.Top + item.Margin.Top;
+
                 if (isGrouped)
                 {
                     //isHeader?
                     if (colView.Header == item)
                     {
-                        posX = 0F;
-                        posY = 0F;
+                        posX = spaceStartX;
+                        posY = spaceStartY;
                     }
                     else if (colView.Footer == item)
                     {
-                        posX = (IsHorizontal ? ScrollContentSize - item.SizeWidth : 0F);
-                        posY = (IsHorizontal ? 0F : ScrollContentSize - item.SizeHeight);
+                        posX = (IsHorizontal? ScrollContentSize - footerSize - Padding.End + footerMargin.Start : spaceStartX);
+                        posY = (IsHorizontal? spaceStartY : ScrollContentSize - footerSize - Padding.Bottom - footerMargin.Top);
                     }
                     else
                     {
                         GroupInfo gInfo = GetGroupInfo(i);
-                        posX = (IsHorizontal ? gInfo.GroupPosition + gInfo.ItemPosition[i - gInfo.StartIndex] : 0F);
-                        posY = (IsHorizontal ? 0F : gInfo.GroupPosition + gInfo.ItemPosition[i - gInfo.StartIndex]);
+                        posX = (IsHorizontal?
+                                item.Margin.Start + gInfo.GroupPosition + gInfo.ItemPosition[i - gInfo.StartIndex]:
+                                spaceStartX);
+                        posY = (IsHorizontal?
+                                spaceStartY:
+                                item.Margin.Top + gInfo.GroupPosition + gInfo.ItemPosition[i - gInfo.StartIndex]);
                     }
                 }
                 else
                 {
-                    posX = (IsHorizontal ? ItemPosition[i] : 0F);
-                    posY = (IsHorizontal ? 0F : ItemPosition[i]);
+                    posX = (IsHorizontal? ItemPosition[i] + item.Margin.Start : spaceStartX);
+                    posY = (IsHorizontal? spaceStartY : ItemPosition[i] + item.Margin.Top);
                 }
 
                 item.Position = new Position(posX, posY);
-                //Console.WriteLine("[NUI] ["+item+"]["+item.Index+"] :: ["+item.Position.X+", "+item.Position.Y+"] ==== \n");
+            
+                if (IsHorizontal && item.HeightSpecification == LayoutParamPolicies.MatchParent)
+                {
+                    item.Size = new Size(item.Size.Width, Container.Size.Height - Padding.Top - Padding.Bottom - item.Margin.Top - item.Margin.Bottom);
+                }
+                else if (!IsHorizontal && item.WidthSpecification == LayoutParamPolicies.MatchParent)
+                {
+                    item.Size = new Size(Container.Size.Width - Padding.Start - Padding.End - item.Margin.Start - item.Margin.End, item.Size.Height);
+                }
             }
         }
 
-        /// <Inheritdoc/>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public override (float X, float Y) GetItemPosition(object item)
-        {
-            if (item == null) throw new ArgumentNullException(nameof(item));
-            // Layouting Items in scrollPosition.
-            float pos = ItemPosition[colView.InternalItemSource.GetPosition(item)];
-
-            return (IsHorizontal ? (pos, 0.0F) : (0.0F, pos));
-        }
-
-        /// <Inheritdoc/>
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public override (float X, float Y) GetItemSize(object item)
-        {
-            if (item == null) throw new ArgumentNullException(nameof(item));
-            // Layouting Items in scrollPosition.
-            float size = GetItemSize(colView.InternalItemSource.GetPosition(item));
-            float view = (IsHorizontal ? colView.Size.Height : colView.Size.Width);
-
-            return (IsHorizontal ? (size, view) : (view, size));
-        }
-
         /// <inheritdoc/>
         [EditorBrowsable(EditorBrowsableState.Never)]
         public override void NotifyItemSizeChanged(RecyclerViewItem item)
@@ -453,7 +465,7 @@ namespace Tizen.NUI.Components
                 PrevSize = ItemPosition[item.Index + 1] - ItemPosition[item.Index];
             }
 
-            CurrentSize = (IsHorizontal ? item.Size.Width : item.Size.Height);
+            CurrentSize = (IsHorizontal? item.Size.Width : item.Size.Height);
 
             if (CurrentSize != PrevSize)
             {
@@ -498,22 +510,22 @@ namespace Tizen.NUI.Components
             {
                 case View.FocusDirection.Left:
                     {
-                        targetSibling = IsHorizontal ? currentFocusedView.SiblingOrder - 1 : targetSibling;
+                        targetSibling = IsHorizontal? currentFocusedView.SiblingOrder - 1 : targetSibling;
                         break;
                     }
                 case View.FocusDirection.Right:
                     {
-                        targetSibling = IsHorizontal ? currentFocusedView.SiblingOrder + 1 : targetSibling;
+                        targetSibling = IsHorizontal? currentFocusedView.SiblingOrder + 1 : targetSibling;
                         break;
                     }
                 case View.FocusDirection.Up:
                     {
-                        targetSibling = IsHorizontal ? targetSibling : currentFocusedView.SiblingOrder - 1;
+                        targetSibling = IsHorizontal? targetSibling : currentFocusedView.SiblingOrder - 1;
                         break;
                     }
                 case View.FocusDirection.Down:
                     {
-                        targetSibling = IsHorizontal ? targetSibling : currentFocusedView.SiblingOrder + 1;
+                        targetSibling = IsHorizontal? targetSibling : currentFocusedView.SiblingOrder + 1;
                         break;
                     }
             }
@@ -534,14 +546,14 @@ namespace Tizen.NUI.Components
         [EditorBrowsable(EditorBrowsableState.Never)]
         protected override (int start, int end) FindVisibleItems((float X, float Y) visibleArea)
         {
-            int MaxIndex = colView.InternalItemSource.Count - 1 - (hasFooter ? 1 : 0);
+            int MaxIndex = colView.InternalItemSource.Count - 1 - (hasFooter? 1 : 0);
             int adds = 5;
             int skipGroup = -2;
             (int start, int end) found = (0, 0);
 
             // 1. Find the start index.
             // Header is Showing
-            if (hasHeader && visibleArea.X <= headerSize)
+            if (hasHeader && visibleArea.X <= headerSize + (IsHorizontal? Padding.Start: Padding.Top))
             {
                 found.start = 0;
             }
@@ -585,7 +597,7 @@ namespace Tizen.NUI.Components
                 }
                 else
                 {
-                    float visibleAreaX = visibleArea.X - (hasHeader ? headerSize : 0);
+                    float visibleAreaX = visibleArea.X - (hasHeader? headerSize : 0);
                     found.start = (Convert.ToInt32(Math.Abs(visibleAreaX / StepCandidate)) - adds);
                 }
 
@@ -633,7 +645,7 @@ namespace Tizen.NUI.Components
                 }
                 else
                 {
-                    float visibleAreaY = visibleArea.Y - (hasHeader ? headerSize : 0);
+                    float visibleAreaY = visibleArea.Y - (hasHeader? headerSize : 0);
                     found.end = (Convert.ToInt32(Math.Abs(visibleAreaY / StepCandidate)) + adds);
                     if (hasHeader) found.end += 1;
                 }
@@ -642,7 +654,78 @@ namespace Tizen.NUI.Components
             return found;
         }
 
-        private float GetItemSize(int index)
+        // Item position excluding margins.
+        internal override (float X, float Y) GetItemPosition(int index)
+        {
+            int spaceStartX = Padding.Start;
+            int spaceStartY = Padding.Top;
+            if (colView.InternalItemSource.IsHeader(index))
+            {
+                return (spaceStartX + headerMargin.Start, spaceStartY + headerMargin.Top);
+            }
+            else if (colView.InternalItemSource.IsFooter(index))
+            {
+                return ((IsHorizontal? ScrollContentSize - footerSize - Padding.End + footerMargin.Start : spaceStartX + footerMargin.Start),
+                        (IsHorizontal? spaceStartY + footerMargin.Top : ScrollContentSize - footerSize - Padding.Bottom + footerMargin.Top));
+            }
+            else if (isGrouped)
+            {
+                GroupInfo gInfo = GetGroupInfo(index);
+                return ((IsHorizontal?
+                            CandidateMargin.Start + gInfo.GroupPosition + gInfo.ItemPosition[index - gInfo.StartIndex]:
+                            spaceStartX),
+                        (IsHorizontal?
+                            spaceStartY:
+                            CandidateMargin.Top + gInfo.GroupPosition + gInfo.ItemPosition[index - gInfo.StartIndex]));
+            }
+            else
+            {
+                return ((IsHorizontal? ItemPosition[index] + CandidateMargin.Start : spaceStartX + CandidateMargin.Start),
+                        (IsHorizontal? spaceStartY + CandidateMargin.Top : ItemPosition[index] + CandidateMargin.Top));
+            }
+        }
+
+        // Item size excluding margins. this size is approximated size.
+        internal override (float Width, float Height) GetItemSize(int index)
+        {
+            if (colView.InternalItemSource.IsHeader(index))
+            {
+                return ((IsHorizontal? (int)headerSize : (int)(colView.Size.Width) - Padding.Start - Padding.End)
+                        - headerMargin.Start - headerMargin.End,
+                        (IsHorizontal? (int)colView.Size.Height - Padding.Top - Padding.Bottom: (int)headerSize)
+                        - headerMargin.Top - headerMargin.Bottom);
+            }
+            else if (colView.InternalItemSource.IsFooter(index))
+            {
+                return ((IsHorizontal? (int)footerSize : (int)(colView.Size.Width) - Padding.Start - Padding.End)
+                        - footerMargin.Start - footerMargin.End,
+                        (IsHorizontal? (int)colView.Size.Height - Padding.Top - Padding.Bottom: (int)footerSize)
+                        - footerMargin.Top - footerMargin.Bottom);
+            }
+            else if (colView.InternalItemSource.IsGroupHeader(index))
+            {
+                return ((IsHorizontal? (int)groupHeaderSize : (int)(colView.Size.Width) - Padding.Start - Padding.End)
+                        - groupHeaderMargin.Start - groupHeaderMargin.End,
+                        (IsHorizontal? (int)colView.Size.Height - Padding.Top - Padding.Bottom: (int)groupHeaderSize)
+                        - groupHeaderMargin.Top - groupHeaderMargin.Bottom);
+            }
+            else if (colView.InternalItemSource.IsGroupFooter(index))
+            {
+                return ((IsHorizontal? (int)groupFooterSize : (int)(colView.Size.Width) - Padding.Start - Padding.End)
+                        - groupFooterMargin.Start - groupFooterMargin.End,
+                        (IsHorizontal? (int)colView.Size.Height - Padding.Top - Padding.Bottom: (int)groupFooterSize)
+                        - groupFooterMargin.Top - groupFooterMargin.Bottom);
+            }
+            else
+            {
+                return ((IsHorizontal? (int)StepCandidate : (int)(colView.Size.Width) - Padding.Start - Padding.End)
+                        - CandidateMargin.Start - CandidateMargin.End,
+                        (IsHorizontal? (int)colView.Size.Height - Padding.Top - Padding.Bottom: (int)StepCandidate)
+                        - CandidateMargin.Top - CandidateMargin.Bottom);
+            }            
+        }
+
+        private float GetItemStepSize(int index)
         {
             if (colView.SizingStrategy == ItemSizingStrategy.MeasureAll)
             {
@@ -650,12 +733,17 @@ namespace Tizen.NUI.Components
             }
             else
             {
-                if (index == 0 && hasHeader)
+                if (colView.InternalItemSource.IsHeader(index))
                     return headerSize;
-                if (index == colView.InternalItemSource.Count - 1 && hasFooter)
+                else if (colView.InternalItemSource.IsFooter(index))
                     return footerSize;
-                return StepCandidate;
-            }
+                else if (colView.InternalItemSource.IsGroupHeader(index))
+                    return groupHeaderSize;
+                else if (colView.InternalItemSource.IsGroupFooter(index))
+                    return groupFooterSize;
+                else
+                    return StepCandidate;
+            }            
         }
 
         private void UpdatePosition(int index)
@@ -672,7 +760,7 @@ namespace Tizen.NUI.Components
                     //Do Something
                 }
 
-            ItemPosition[index] = ItemPosition[index - 1] + GetItemSize(index - 1);
+            ItemPosition[index] = ItemPosition[index - 1] + GetItemStepSize(index - 1);
         }
 
         private RecyclerViewItem GetVisibleItem(int index)
index 7d8e14c..0e79362 100755 (executable)
@@ -254,6 +254,21 @@ namespace Tizen.NUI.Components
                 ThumbHorizontalImageUrl = FrameworkInformation.ResourcePath + "nui_component_default_scroll_hbar.#.png",
             });
 
+            theme.AddStyleWithoutClone("Tizen.NUI.Components.LinearLayouter", new ViewStyle()
+            {
+                Padding = new Extents(64, 64, 0, 0)
+            });
+
+            theme.AddStyleWithoutClone("Tizen.NUI.Components.GridLayouter", new ViewStyle()
+            {
+                Padding = new Extents(0, 0, 0, 0),
+            });
+
+            theme.AddStyleWithoutClone("Tizen.NUI.Components.ItemsLayouter", new ViewStyle()
+            {
+                Padding = new Extents(0, 0, 0, 0),
+            });
+
             theme.AddStyleWithoutClone("Tizen.NUI.Components.RecyclerViewItem", new RecyclerViewItemStyle()
             {
                 BackgroundColor = new Selector<Color>()
@@ -269,6 +284,7 @@ namespace Tizen.NUI.Components
             {
                 SizeHeight = 108,
                 Padding = new Extents(64, 64, 18, 17),
+                Margin = new Extents(0, 0, 0, 0),
                 BackgroundColor = new Selector<Color>()
                 {
                     Normal = new Color(1, 1, 1, 1),
@@ -307,7 +323,8 @@ namespace Tizen.NUI.Components
             });
             theme.AddStyleWithoutClone("Tizen.NUI.Components.DefaultGridItem", new DefaultGridItemStyle()
             {
-                Padding = new Extents(5, 5, 5, 5),
+                Padding = new Extents(0, 0, 0, 0),
+                Margin = new Extents(5, 5, 5, 5),
                 Caption = new TextLabelStyle()
                 {
                     SizeHeight = 60,
@@ -324,6 +341,7 @@ namespace Tizen.NUI.Components
             {
                 SizeHeight = 60,
                 Padding = new Extents(64, 64, 12, 12),
+                Margin = new Extents(0, 0, 0, 0),
                 BackgroundColor = new Selector<Color>()
                 {
                     Normal = new Color("#EEEEF1FF"),