[dali_1.3.46] Merge branch 'devel/master' 79/191579/1
authorAnton Obzhirov <a.obzhirov@samsung.com>
Thu, 18 Oct 2018 13:27:32 +0000 (14:27 +0100)
committerAnton Obzhirov <a.obzhirov@samsung.com>
Thu, 18 Oct 2018 13:27:32 +0000 (14:27 +0100)
Change-Id: Ifc005a47542cd18c50d2ab3af8b816f915f634fe

16 files changed:
automated-tests/patch-coverage.pl
automated-tests/src/dali-toolkit/CMakeLists.txt
automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp
automated-tests/src/dali-toolkit/utc-Dali-LayoutingNesting.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-LayoutingResizePolicy.cpp [new file with mode: 0644]
dali-toolkit/devel-api/layouting/layout-group-impl.cpp
dali-toolkit/devel-api/layouting/layout-item-impl.cpp
dali-toolkit/devel-api/layouting/layout-item-impl.h
dali-toolkit/internal/controls/control/control-data-impl.cpp
dali-toolkit/internal/file.list
dali-toolkit/internal/layouting/layout-item-data-impl.h
dali-toolkit/internal/layouting/size-negotiation-mapper.cpp [new file with mode: 0644]
dali-toolkit/internal/layouting/size-negotiation-mapper.h [new file with mode: 0644]
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/dali-toolkit-version.cpp
packaging/dali-toolkit.spec

index c19953b..5e5e164 100755 (executable)
@@ -19,8 +19,10 @@ use strict;
 use Git;
 use Getopt::Long;
 use Error qw(:try);
+use HTML::Element;
 use Pod::Usage;
 use File::Basename;
+#use Data::Dumper;
 use File::stat;
 use Scalar::Util qw /looks_like_number/;
 use Cwd qw /getcwd/;
@@ -488,21 +490,17 @@ sub patch_html_output
 {
     my $filesref = shift;
 
-    open( my $filehandle, ">", $opt_output ) || die "Can't open $opt_output for writing:$!\n";
+    my $html = HTML::Element->new('html');
+    my $head = HTML::Element->new('head');
+    my $title = HTML::Element->new('title');
+    $title->push_content("Patch Coverage");
+    $head->push_content($title, "\n");
+    $html->push_content($head, "\n");
 
-    my $OUTPUT_FH = select;
-    select $filehandle;
-    print <<EOH;
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
-"http://www.w3.org/TR/REC-html40/loose.dtd">
-<html>
-<head>
-<title>Patch Coverage</title>
-</head>
-<body bgcolor="white">
-EOH
+    my $body = HTML::Element->new('body');
+    $body->attr('bgcolor', "white");
 
-    foreach my $file (keys(%$filesref))
+    foreach my $file (sort(keys(%$filesref)))
     {
         my ($name, $path, $suffix) = fileparse($file, qr{\.[^.]*$});
         next if($path !~ /^dali/);
@@ -510,33 +508,47 @@ EOH
         my $patchref = $filesref->{$file}->{"patch"};
         my $b_lines_ref = $filesref->{$file}->{"b_lines"};
         my $coverage_ref = $filesref->{$file}->{"coverage"};
-        print "<h2>$file</h2>\n";
 
+        my $header = HTML::Element->new('h2');
+        $header->push_content($file);
+        $body->push_content($header);
+        $body->push_content("\n");
         if($coverage_ref)
         {
             if( $coverage_ref->{"covered_lines"} > 0
                 ||
                 $coverage_ref->{"uncovered_lines"} > 0 )
             {
-                print "<p style=\"color:green;\">Covered: " .
-                    $coverage_ref->{"covered_lines"} . "<p>" .
-                    "<p style=\"color:red;\">Uncovered: " .
-                    $coverage_ref->{"uncovered_lines"} . "</span></p>";
+                my $para = HTML::Element->new('p');
+                my $covered = HTML::Element->new('span');
+                $covered->attr('style', "color:green;");
+                $covered->push_content("Covered: " . $coverage_ref->{"covered_lines"} );
+                $para->push_content($covered);
+
+                my $para2 = HTML::Element->new('p');
+                my $uncovered = HTML::Element->new('span');
+                $uncovered->attr('style', "color:red;");
+                $uncovered->push_content("Uncovered: " . $coverage_ref->{"uncovered_lines"} );
+                $para2->push_content($uncovered);
+                $body->push_content($para, $para2);
+            }
+            else
+            {
+                #print "coverage ref exists for $file:\n" . Data::Dumper::Dumper($coverage_ref) . "\n";
             }
         }
         else
         {
-            print "<p>";
-            my $span=0;
+            my $para = HTML::Element->new('p');
+            my $span = HTML::Element->new('span');
             if($suffix eq ".cpp" || $suffix eq ".c" || $suffix eq ".h")
             {
-                print "<span style=\"color:red;\">";
-                $span=1;
+                $span->attr('style', "color:red;");
             }
-            print "No coverage found";
-            print "</span>" if $span;
+            $span->push_content("No coverage found");
+            $para->push_content($span);
+            $body->push_content($para);
         }
-        print "</p>";
 
         for my $patch (@$patchref)
         {
@@ -545,53 +557,71 @@ EOH
             {
                 $hunkstr .= " - " . ($patch->[0]+$patch->[1]-1);
             }
-            print "<p style=\"font-weight:bold;\">" . $hunkstr . "</p>";
 
-            print "<pre>";
+            my $para = HTML::Element->new('p');
+            my $span = HTML::Element->new('span');
+            $span->attr('style', "font-weight:bold;");
+            $span->push_content($hunkstr);
+            $para->push_content($span);
+            $body->push_content($para);
+
+            my $codeHunk = HTML::Element->new('pre');
             for(my $i = 0; $i < $patch->[1]; $i++ )
             {
                 my $line = $i + $patch->[0];
                 my $num_line_digits=log($line)/log(10);
                 for $i (0..(6-$num_line_digits-1))
                 {
-                    print " ";
+                    $codeHunk->push_content(" ");
                 }
-                print "$line  ";
 
+                $codeHunk->push_content("$line  ");
+
+                my $srcLine = HTML::Element->new('span');
                 if($coverage_ref)
                 {
                     my $color;
+
                     if($coverage_ref->{"covered"}->{$line})
                     {
-                        print("<span style=\"color:green;\">");
+                        $srcLine->attr('style', "color:green;");
                     }
                     elsif($coverage_ref->{"uncovered"}->{$line})
                     {
-                        print("<span style=\"color:red;font-weight:bold;\">");
+                        $srcLine->attr('style', "color:red;font-weight:bold;");
                     }
                     else
                     {
-                        #print("<span style=\"color:black;font-weight:normal;\">");
+                        $srcLine->attr('style', "color:black;font-weight:normal;");
                     }
                     my $src=$coverage_ref->{"src"}->{$line};
                     chomp($src);
-                    #print $color, "$src\n", RESET;
-                    print "$src</span>\n";
+                    $srcLine->push_content($src);
                 }
                 else
                 {
                     # We don't have coverage data, so print it from the patch instead.
                     my $src = $b_lines_ref->{$line};
-                    print "$src\n";
+                    $srcLine->attr('style', "color:black;font-weight:normal;");
+                    $srcLine->push_content($src);
                 }
+                $codeHunk->push_content($srcLine, "\n");
             }
-            print "<\pre>\n";
+            $body->push_content($codeHunk, "\n");
         }
     }
+    $body->push_content(HTML::Element->new('hr'));
+    $html->push_content($body, "\n");
+
+    open( my $filehandle, ">", $opt_output ) || die "Can't open $opt_output for writing:$!\n";
 
-    print $filehandle "<hr>\n</body>\n</html>\n";
+    print $filehandle <<EOH;
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
+"http://www.w3.org/TR/REC-html40/loose.dtd">
+EOH
+;
+    print $filehandle $html->as_HTML();
     close $filehandle;
-    select $OUTPUT_FH;
 }
 
 
index f193458..7ad18b7 100755 (executable)
@@ -26,6 +26,8 @@ SET(TC_SOURCES
   utc-Dali-JsonParser.cpp
   utc-Dali-KeyInputFocusManager.cpp
   utc-Dali-Layouting.cpp
+  utc-Dali-LayoutingResizePolicy.cpp
+  utc-Dali-LayoutingNesting.cpp
   utc-Dali-PageTurnView.cpp
   utc-Dali-Scene3dView.cpp
   utc-Dali-Script.cpp
index f0540f4..49da596 100644 (file)
@@ -1663,6 +1663,7 @@ int UtcDaliLayouting_HboxLayout_ImageView(void)
   DALI_TEST_EQUALS( imageView.GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( 0.0f, 350.0f, 0.0f ), 0.0001f, TEST_LOCATION );
   DALI_TEST_EQUALS( imageView.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 100.0f, 100.0f, 0.0f ), 0.0001f, TEST_LOCATION );
 
+  tet_infoline("UtcDaliLayouting_HboxLayout - Change image (new size)");
   url = CreateImageURL( Vector4( 0, 255, 0, 255), ImageDimensions( 200, 200 ) );
   imageView.SetImage( url );
 
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-LayoutingNesting.cpp b/automated-tests/src/dali-toolkit/utc-Dali-LayoutingNesting.cpp
new file mode 100644 (file)
index 0000000..155b54a
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <toolkit-event-thread-callback.h>
+
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/layouting/absolute-layout.h>
+#include <dali-toolkit/devel-api/layouting/linear-layout.h>
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+#include <dali/devel-api/actors/actor-devel.h>
+
+#include <../custom-layout.h>
+
+#include <layout-utils.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+namespace
+{
+
+// Turns the given control into a Root layout control and adds it to the stage.
+void SetupRootLayoutControl( Control& rootControl )
+{
+  rootControl = Control::New();
+  auto absoluteLayout = AbsoluteLayout::New();
+  DevelControl::SetLayout( rootControl, absoluteLayout );
+  rootControl.SetName( "RootAbsoluteLayout" );
+  Stage stage = Stage::GetCurrent();
+  stage.Add( rootControl );
+}
+
+} // unnamed namespace
+
+void utc_dali_toolkit_layouting_nesting_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_toolkit_layouting_nesting_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+// Test nesting of Layouts and Controls
+
+int UtcDaliLayoutingNesting_01(void)
+{
+  /*
+
+  Root
+    |
+  Control (LinearLayout Horizontal)
+    |
+  Control (LayoutingRequired)
+    |
+  Control (LinearLayout Horizontal)
+    |
+  LeafControl
+
+  */
+
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliLayoutingNesting_01 - Nesting a LinearLayout (MATCH_PARENT) containing a leaf control within a LinearLayout");
+
+  Stage stage = Stage::GetCurrent();
+
+  auto rootControl = Control::New();
+  SetupRootLayoutControl( rootControl );
+
+  auto hbox = Control::New();
+  auto hboxLayout = LinearLayout::New();
+  hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+  DevelControl::SetLayout( hbox, hboxLayout );
+  hbox.SetName( "hBox" );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 480 );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 800 );
+
+
+  auto vbox = Control::New();
+  auto vboxLayout = LinearLayout::New();
+  vboxLayout.SetOrientation( LinearLayout::Orientation::VERTICAL );
+  DevelControl::SetLayout( vbox, vboxLayout );
+  vbox.SetName( "vBox" );
+  vbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  vbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  hbox.Add( vbox );
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 40, 40 ) );
+
+  for( auto&& iter : controls )
+  {
+    hbox.Add( iter );
+  }
+
+  rootControl.Add( hbox );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( hbox.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( vbox.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayoutingNesting_02(void)
+{
+  /*
+
+  Root
+    |
+  Control (LinearLayout Horizontal)
+    |
+  Control (LayoutingRequired)
+    |
+  Control (LinearLayout Horizontal)
+    |    |
+  LeafControl
+
+  */
+
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliLayoutingNesting_02 - Nesting a LinearLayout (MATCH_PARENT) containing a leaf control within a LinearLayout");
+  tet_infoline("Then change the parent's size and test child responded correctly");
+
+  Stage stage = Stage::GetCurrent();
+
+  auto rootControl = Control::New();
+  SetupRootLayoutControl( rootControl );
+
+  auto hbox = Control::New();
+  auto hboxLayout = LinearLayout::New();
+  hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+  DevelControl::SetLayout( hbox, hboxLayout );
+  hbox.SetName( "hBox" );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 480 );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, 800 );
+
+
+  auto vbox = Control::New();
+  auto vboxLayout = LinearLayout::New();
+  vboxLayout.SetOrientation( LinearLayout::Orientation::VERTICAL );
+  DevelControl::SetLayout( vbox, vboxLayout );
+  vbox.SetName( "vBox" );
+  vbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  vbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  hbox.Add( vbox );
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 40, 40 ) );
+
+  for( auto&& iter : controls )
+  {
+    hbox.Add( iter );
+  }
+
+  rootControl.Add( hbox );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( hbox.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( vbox.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, 400 );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+
+  DALI_TEST_EQUALS( hbox.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 400.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( vbox.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 400.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
\ No newline at end of file
diff --git a/automated-tests/src/dali-toolkit/utc-Dali-LayoutingResizePolicy.cpp b/automated-tests/src/dali-toolkit/utc-Dali-LayoutingResizePolicy.cpp
new file mode 100644 (file)
index 0000000..23923ce
--- /dev/null
@@ -0,0 +1,393 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <toolkit-event-thread-callback.h>
+
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/layouting/absolute-layout.h>
+#include <dali-toolkit/devel-api/layouting/linear-layout.h>
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+#include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
+#include <dali/devel-api/actors/actor-devel.h>
+
+#include <../custom-layout.h>
+
+#include <layout-utils.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+namespace
+{
+
+// Turns the given control into a Root layout control and adds it to the stage.
+void SetupRootLayoutControl( Control& rootControl )
+{
+  rootControl = Control::New();
+  auto absoluteLayout = AbsoluteLayout::New();
+  DevelControl::SetLayout( rootControl, absoluteLayout );
+  rootControl.SetName( "RootAbsoluteLayout" );
+  Stage stage = Stage::GetCurrent();
+  stage.Add( rootControl );
+}
+
+} // unnamed namespace
+
+void utc_dali_toolkit_layouting_resize_policy_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+
+void utc_dali_toolkit_layouting_resize_policy_cleanup(void)
+{
+  test_return_value = TET_PASS;
+}
+
+// Test setting of the MeasureSpecs with the legacy ResizePolicies
+
+int UtcDaliLayoutingResizePolicy_01(void)
+{
+  /*
+  Root
+    |
+  Control (LinearLayout Horizontal)
+    |
+  Control (LayoutingRequired)
+    |
+  Control (ResizePolicy::FILL_TO_PARENT)
+    |
+  LeafControl
+  */
+
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliLayoutingResizePolicy_01 - Set ResizePolicy FILL_TO_PARENT on Control");
+
+  Stage stage = Stage::GetCurrent();
+
+  auto rootControl = Control::New();
+  SetupRootLayoutControl( rootControl );
+
+  auto hbox = Control::New();
+  auto hboxLayout = LinearLayout::New();
+  hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+  DevelControl::SetLayout( hbox, hboxLayout );
+  hbox.SetName( "hBox" );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+  auto layoutingControl = Control::New();
+  layoutingControl.SetName( "layoutingRequiredControl" );
+  DevelControl::SetLayoutingRequired( layoutingControl, true );
+  layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  hbox.Add( layoutingControl );
+
+  auto control = Control::New();
+  control.SetName( "fillToParentControl" );
+  DevelControl::SetLayoutingRequired( control, true );
+  control.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+  layoutingControl.Add( control );
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 40, 40 ) );
+
+  for( auto&& iter : controls )
+  {
+    control.Add( iter );
+  }
+
+  rootControl.Add( hbox );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( DevelControl::IsLayoutingRequired( control ), true , 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( control.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 480.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliLayoutingResizePolicy_02(void)
+{
+  /*
+  Root
+    |
+  Control (LinearLayout Horizontal)
+    |
+  Control (LayoutingRequired)
+    |
+  Control (ResizePolicy::FIT_TO_CHILDREN)
+    |
+  LeafControl
+  */
+
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliLayoutingResizePolicy_02 - Set ResizePolicy FIT_TO_CHILDREN on Control");
+
+  Stage stage = Stage::GetCurrent();
+
+  auto rootControl = Control::New();
+  SetupRootLayoutControl( rootControl );
+
+  auto hbox = Control::New();
+  auto hboxLayout = LinearLayout::New();
+  hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+  DevelControl::SetLayout( hbox, hboxLayout );
+  hbox.SetName( "hBox" );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+  auto layoutingControl = Control::New();
+  layoutingControl.SetName( "layoutingRequiredControl" );
+  DevelControl::SetLayoutingRequired( layoutingControl, true );
+  layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  hbox.Add( layoutingControl );
+
+  auto control = Control::New();
+  control.SetName( "fitToChildrenControl" );
+  DevelControl::SetLayoutingRequired( control, true );
+  control.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
+  layoutingControl.Add( control );
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 40, 40 ) );
+
+  for( auto&& iter : controls )
+  {
+    control.Add( iter );
+  }
+
+  rootControl.Add( hbox );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( DevelControl::IsLayoutingRequired( control ), true , 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( control.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayoutingResizePolicy_03(void)
+{
+  /*
+  Root
+    |
+  Control (LinearLayout Horizontal)
+    |
+  Control (LayoutingRequired)
+    |
+  Control (ResizePolicy::SIZE_RELATIVE_TO_PARENT)
+    |
+  LeafControl
+  */
+
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliLayoutingResizePolicy_03 - Set ResizePolicy SIZE_RELATIVE_TO_PARENT on Control");
+
+  Stage stage = Stage::GetCurrent();
+
+  auto rootControl = Control::New();
+  SetupRootLayoutControl( rootControl );
+
+  auto hbox = Control::New();
+  auto hboxLayout = LinearLayout::New();
+  hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+  DevelControl::SetLayout( hbox, hboxLayout );
+  hbox.SetName( "hBox" );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+  auto layoutingControl = Control::New();
+  layoutingControl.SetName( "layoutingRequiredControl" );
+  DevelControl::SetLayoutingRequired( layoutingControl, true );
+  layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  hbox.Add( layoutingControl );
+
+  auto control = Control::New();
+  control.SetName( "fitToChildrenControl" );
+  DevelControl::SetLayoutingRequired( control, true );
+  control.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
+  control.SetSizeModeFactor( Vector3( 0.50f, 1.0f, 1.0f ) );
+  layoutingControl.Add( control );
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 40, 40 ) );
+
+  for( auto&& iter : controls )
+  {
+    control.Add( iter );
+  }
+
+  rootControl.Add( hbox );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( DevelControl::IsLayoutingRequired( control ), true , 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( control.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 240.0f, 800.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayoutingResizePolicy_04(void)
+{
+  /*
+  Root
+    |
+  Control (LinearLayout Horizontal)
+    |
+  Control (LayoutingRequired)
+    |
+  Control (ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT)
+    |
+  LeafControl
+  */
+
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliLayoutingResizePolicy_04 - Set ResizePolicy SIZE_FIXED_OFFSET_FROM_PARENT on Control");
+
+  Stage stage = Stage::GetCurrent();
+
+  auto rootControl = Control::New();
+  SetupRootLayoutControl( rootControl );
+
+  auto hbox = Control::New();
+  auto hboxLayout = LinearLayout::New();
+  hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+  DevelControl::SetLayout( hbox, hboxLayout );
+  hbox.SetName( "hBox" );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+  auto layoutingControl = Control::New();
+  layoutingControl.SetName( "layoutingRequiredControl" );
+  DevelControl::SetLayoutingRequired( layoutingControl, true );
+  layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  hbox.Add( layoutingControl );
+
+  auto control = Control::New();
+  control.SetName( "fitToChildrenControl" );
+  DevelControl::SetLayoutingRequired( control, true );
+  control.SetResizePolicy( ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS );
+  control.SetSizeModeFactor( Vector3( -100.0f, 10.0f, 0.0f ) );
+  layoutingControl.Add( control );
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 40, 40 ) );
+
+  for( auto&& iter : controls )
+  {
+    control.Add( iter );
+  }
+
+  rootControl.Add( hbox );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( DevelControl::IsLayoutingRequired( control ), true , 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( control.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 380.0f, 810.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliLayoutingResizePolicy_05(void)
+{
+  /*
+  Root
+    |
+  Control (LinearLayout Horizontal)
+    |
+  Control (LayoutingRequired)
+    |
+  Control (ResizePolicy::FIXED)
+    |
+  LeafControl
+  */
+
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliLayoutingResizePolicy_05 - Set ResizePolicy FIXED on Control");
+
+  Stage stage = Stage::GetCurrent();
+
+  auto rootControl = Control::New();
+  SetupRootLayoutControl( rootControl );
+
+  auto hbox = Control::New();
+  auto hboxLayout = LinearLayout::New();
+  hboxLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL );
+  DevelControl::SetLayout( hbox, hboxLayout );
+  hbox.SetName( "hBox" );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  hbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+
+  auto layoutingControl = Control::New();
+  layoutingControl.SetName( "layoutingRequiredControl" );
+  DevelControl::SetLayoutingRequired( layoutingControl, true );
+  layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  layoutingControl.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::MATCH_PARENT );
+  hbox.Add( layoutingControl );
+
+  auto control = Control::New();
+  control.SetName( "fitToChildrenControl" );
+  DevelControl::SetLayoutingRequired( control, true );
+  control.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
+  control.SetSize( Vector3( 300.0f, 300.0f, 0.0f ) );
+  layoutingControl.Add( control );
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 40, 40 ) );
+
+  for( auto&& iter : controls )
+  {
+    control.Add( iter );
+  }
+
+  rootControl.Add( hbox );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( DevelControl::IsLayoutingRequired( control ), true , 0.0001f, TEST_LOCATION );
+
+  DALI_TEST_EQUALS( control.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 300.0f, 300.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( 40.0f, 40.0f, 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
\ No newline at end of file
index 856ca18..cab70c3 100644 (file)
@@ -27,6 +27,7 @@
 #include <dali-toolkit/internal/layouting/layout-group-data-impl.h>
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
+#include <dali-toolkit/internal/layouting/size-negotiation-mapper.h>
 
 namespace
 {
@@ -344,6 +345,7 @@ void LayoutGroup::MeasureChild( LayoutItemPtr child,
   }
 #endif
 
+
   // Get last stored width and height specifications for the child
   auto desiredWidth = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
   auto desiredHeight = childOwner.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
@@ -561,6 +563,15 @@ void LayoutGroup::OnUnparent()
 {
   // Remove children
   RemoveAll();
+
+  auto control = Toolkit::Control::DownCast( GetOwner() );
+  if( control )
+  {
+    DevelActor::ChildAddedSignal( control ).Disconnect( mSlotDelegate, &LayoutGroup::ChildAddedToOwner );
+    DevelActor::ChildRemovedSignal( control ).Disconnect( mSlotDelegate, &LayoutGroup::ChildRemovedFromOwner );
+    DevelActor::ChildOrderChangedSignal( control ).Disconnect( mSlotDelegate, &LayoutGroup::ChildOrderChanged );
+    DevelHandle::PropertySetSignal( control ).Disconnect( mSlotDelegate, &LayoutGroup::OnOwnerPropertySet );
+  }
 }
 
 void LayoutGroup::RemoveChild( LayoutItem& item )
@@ -576,7 +587,9 @@ void LayoutGroup::ChildAddedToOwner( Actor child )
 
 #if defined(DEBUG_ENABLED)
   auto parent = Toolkit::Control::DownCast( GetOwner() );
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner control(%s) owner(%s)\n", control?control.GetName().c_str():"Invalid", parent?parent.GetName().c_str():"Invalid" );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner child control(%s) owner control(%s)\n",
+                                              control?control.GetName().c_str():"Invalid",
+                                              parent?parent.GetName().c_str():"Invalid" );
 #endif
 
   if( control ) // Can only support adding Controls, not Actors to layout
@@ -591,18 +604,21 @@ void LayoutGroup::ChildAddedToOwner( Actor child )
       // If control behaviour flag set to Layout then set a LayoutGroup.
       if( DevelControl::IsLayoutingRequired( control ) )
       {
-        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner Creating default LayoutGroup for control:%s\n", control?control.GetName().c_str():"Invalid" );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner Creating default LayoutGroup for control:%s\n",
+                                                    control?control.GetName().c_str():"Invalid" );
         childLayout = LayoutGroup::New( control );
       }
       else
       {
-        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner Creating default LayoutItem for control:%s\n", control?control.GetName().c_str():"Invalid" );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner Creating default LayoutItem for control:%s\n",
+                                                    control?control.GetName().c_str():"Invalid" );
         childLayout = LayoutItem::New( control );
+        childLayout->SetAnimateLayout( IsLayoutAnimated() ); // forces animation inheritance.
       }
-      childLayout->SetAnimateLayout( IsLayoutAnimated() ); // @todo this essentially forces animation inheritance. Bad?
 
-      DALI_LOG_STREAM( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner control:" <<  control.GetName() <<
-                       " desiredWidth: " <<  control.GetNaturalSize().width << " desiredHeight:"  << control.GetNaturalSize().height );
+      DALI_LOG_STREAM( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner child control:" <<  control.GetName() <<
+                       " desiredWidth: " <<  control.GetNaturalSize().width <<
+                       " desiredHeight:"  << control.GetNaturalSize().height );
 
       childControlDataImpl.SetLayout( *childLayout.Get() );
 
@@ -622,6 +638,7 @@ void LayoutGroup::ChildAddedToOwner( Actor child )
     }
     else
     {
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::ChildAddedToOwner child(%s) already has a Layout\n", control.GetName().c_str() );
       LayoutGroupPtr layoutGroup( dynamic_cast< LayoutGroup* >( childLayout.Get() ) );
       if( !layoutGroup )
       {
@@ -751,14 +768,47 @@ void LayoutGroup::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMea
       auto childLayout = GetChildAt( i );
       if( childLayout )
       {
-        auto childOwner = childLayout->GetOwner();
+        auto childControl = Toolkit::Control::DownCast(childLayout->GetOwner());
+
+        // If child control has children check if a ResizePolicy is set on it.  A LayoutItem could be a legacy container.
+        // A legacy container would need it's ResizePolicy to be applied as a MeasureSpec.
+
+        // Check below will be true for legacy containers and controls with layout required set.
+        // Other layouts will have their own OnMeasure (a checked requirement) hence not execute LayoutGroup::OnMeasure.
+        // Controls which have set layout required will not be legacy controls hence should not have a ResizePolicy set.
+        if( childControl.GetChildCount() > 0 )
+        {
+          // First pass, Static mappings that are not dependant on parent
+          SizeNegotiationMapper::SetLayoutParametersUsingResizePolicy( childControl, childLayout, Dimension::WIDTH );
+          SizeNegotiationMapper::SetLayoutParametersUsingResizePolicy( childControl, childLayout, Dimension::HEIGHT );
+        }
+
+        // Second pass, if any mappings were not possible due to parent size dependancies then calculate an exact desired size for child
+        if( true == childLayout->IsResizePolicyRequired() ) // No need to test child count as this flag would only be set if control had children.
+        {
+          // Get last stored width and height specifications for the child
+          LayoutLength desiredWidth = childControl.GetProperty<float>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
+          LayoutLength desiredHeight = childControl.GetProperty<float>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
+
+          DALI_LOG_INFO( gLogFilter, Debug::General, "LayoutGroup::MeasureChild Initial desired size pre ResizePolicy(%f,%f)\n", desiredWidth.AsInteger(), desiredHeight.AsInteger() );
+
+          childLayout->SetResizePolicyRequired( false ); // clear flag incase in case of changes before next Measure
+          SizeNegotiationMapper::GetSizeofChildForParentDependentResizePolicy( childControl, widthMeasureSpec, heightMeasureSpec, desiredWidth, desiredHeight );
+
+          // Parent dependant ResizePolicies become exact sizes so are now set on the child before it's measured.
+          childControl.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, desiredWidth.AsInteger() );
+          childControl.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, desiredHeight.AsInteger()  );
+
+          DALI_LOG_INFO( gLogFilter, Debug::General, " LayoutGroup::OnMeasure ResizePolicy Required resulting size(%f,%f)\n",  desiredWidth.AsInteger(), desiredHeight.AsInteger() );
+        }
 
         // Get size of child
         MeasureChild( childLayout, widthMeasureSpec, heightMeasureSpec );
         LayoutLength childWidth = childLayout->GetMeasuredWidth();
         LayoutLength childHeight = childLayout->GetMeasuredHeight();
+
         Extents childMargin = childLayout->GetMargin();
-        DALI_LOG_STREAM( gLogFilter, Debug::Verbose, "LayoutGroup::OnMeasure child width[" << childWidth << "] height[" << childHeight << "]\n" );
+        DALI_LOG_STREAM( gLogFilter, Debug::Verbose, "LayoutGroup::OnMeasure child " << childControl.GetName().c_str() << " width[" << childWidth << "] height[" << childHeight << "]\n" );
 
         layoutWidth = std::max( layoutWidth, childWidth + childMargin.start + childMargin.end );
         layoutHeight = std::max( layoutHeight, childHeight + childMargin.top + childMargin.bottom );
@@ -766,7 +816,7 @@ void LayoutGroup::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMea
       }
       else
       {
-          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::OnMeasure Not a layout\n" );
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "LayoutGroup::OnMeasure Not a layout\n" );
       }
     }
 
index d68e544..f70a5f1 100644 (file)
@@ -159,7 +159,11 @@ void LayoutItem::Measure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeasur
 
   const bool needsLayout = specChanged && ( !isSpecExactly || !matchesSpecSize );
 
-  DALI_LOG_STREAM( gLayoutFilter, Debug::General, "LayoutItem::Measure("<<widthMeasureSpec<<", "<<heightMeasureSpec<<") Owner:"<<Actor::DownCast(GetOwner()).GetName() <<"  forceLayout="<<forceLayout<<", specChanged="<<specChanged<<", isSpecExactly="<<isSpecExactly<<", matchesSpecSize="<<matchesSpecSize<<", needsLayout="<<needsLayout <<std::endl <<(forceLayout||needsLayout?"  Remeasuring":"  NoChange"));
+  DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::Measure("<<widthMeasureSpec<<", "<<heightMeasureSpec<<") Owner:"
+                                                  <<Actor::DownCast(GetOwner()).GetName() <<"  forceLayout="<<forceLayout
+                                                  <<", specChanged="<<specChanged<<", isSpecExactly="<<isSpecExactly
+                                                  <<", matchesSpecSize="<<matchesSpecSize
+                                                  <<", needsLayout="<<needsLayout <<(forceLayout||needsLayout?"  Remeasuring":"  NoChange"));
 
   if( forceLayout || needsLayout )
   {
@@ -266,6 +270,8 @@ LayoutLength LayoutItem::GetDefaultSize( LayoutLength size, MeasureSpec measureS
   auto specMode = measureSpec.GetMode();
   auto specSize = measureSpec.GetSize();
 
+  DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::GetDefaultSize MeasureSpec("<<measureSpec<< ") size:" << size << "\n" );
+
   switch (specMode)
   {
     case MeasureSpec::Mode::UNSPECIFIED:
@@ -275,8 +281,12 @@ LayoutLength LayoutItem::GetDefaultSize( LayoutLength size, MeasureSpec measureS
     }
     case MeasureSpec::Mode::AT_MOST:
     {
+      // 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.
       LayoutLength tmp = specSize;
-      if( size < tmp )
+
+      // Do not set size to 0, use specSize in this case as could be a legacy container
+      if( size < tmp && size > LayoutLength( 0 ) )
       {
         result = size;
       }
@@ -292,6 +302,7 @@ LayoutLength LayoutItem::GetDefaultSize( LayoutLength size, MeasureSpec measureS
       break;
     }
   }
+  DALI_LOG_STREAM( gLayoutFilter, Debug::General, "LayoutItem::GetDefaultSize setting default size:" << result << "\n" );
   return result;
 }
 
@@ -299,6 +310,7 @@ void LayoutItem::OnMeasure( MeasureSpec widthMeasureSpec, MeasureSpec heightMeas
 {
   DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::OnMeasure\n");
 
+  // GetDefaultSize will limit the MeasureSpec to the suggested minimumWidth and minimumHeight
   SetMeasuredDimensions( GetDefaultSize( GetSuggestedMinimumWidth(), widthMeasureSpec ),
                          GetDefaultSize( GetSuggestedMinimumHeight(), heightMeasureSpec ) );
 }
@@ -341,9 +353,28 @@ void LayoutItem::SetLayoutRequested()
   mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
 }
 
+bool LayoutItem::IsResizePolicyRequired() const
+{
+  return mImpl->GetPrivateFlag( Impl::PRIVATE_FLAG_USE_RESIZE_POLICY );
+}
+
+void LayoutItem::SetResizePolicyRequired( bool resizePolicyRequired )
+{
+  if( resizePolicyRequired )
+  {
+    mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_USE_RESIZE_POLICY );
+  }
+  else
+  {
+    mImpl->ClearPrivateFlag( Impl::PRIVATE_FLAG_USE_RESIZE_POLICY );
+  }
+}
+
 void LayoutItem::SetMeasuredDimensions( MeasuredSize measuredWidth, MeasuredSize measuredHeight )
 {
-  DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::SetMeasuredDimensions width(" << measuredWidth.GetSize() << ") height(" << measuredHeight.GetSize() << ") \n" );
+
+  DALI_LOG_STREAM( gLayoutFilter, Debug::Verbose, "LayoutItem::SetMeasuredDimensions width(" << measuredWidth.GetSize() << ") height(" << measuredHeight.GetSize() << ") Control:" <<
+                        ( ( Actor::DownCast( GetOwner()) ) ? Actor::DownCast(GetOwner()).GetName().c_str() : "Invalid Actor" ) << "\n" );
 
   mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_MEASURED_DIMENSION_SET );
   mImpl->mMeasuredWidth = measuredWidth;
index cfbe8ea..3850e5f 100644 (file)
@@ -188,6 +188,18 @@ public:
   void SetLayoutRequested();
 
   /**
+   * @brief Checks if the Resize policy is being used for this LayoutItem
+   * @return true is ResizePolicy is used
+   */
+  bool IsResizePolicyRequired() const;
+
+  /**
+   * @brief Sets if the ResizePolicy is needed or not for this LayoutItem
+   * @param[in] resizeRequired true or false flag
+   */
+  void SetResizePolicyRequired( bool resizeRequired );
+
+  /**
    * @brief Get the measured width (without any measurement flags).
    *
    * This method should be used only during measurement and layout calculations.
index 12f09c8..6468ad5 100755 (executable)
@@ -68,6 +68,7 @@ namespace
 
 #if defined(DEBUG_ENABLED)
 Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_CONTROL_VISUALS");
+Debug::Filter* gLogFilterLayout = Debug::Filter::New( Debug::NoLogging, false, "LOG_LAYOUT");
 #endif
 
 
@@ -1439,6 +1440,10 @@ Toolkit::Internal::LayoutItemPtr Control::Impl::GetLayout() const
 
 void Control::Impl::SetLayout( Toolkit::Internal::LayoutItem& layout )
 {
+  DALI_LOG_INFO( gLogFilterLayout, Debug::Verbose, "Control::SetLayout control:%s  existing layout:%s\n",
+                                   mControlImpl.Self().GetName().c_str(),
+                                   mLayout?"true":"false" );
+
   if( mLayout )
   {
     mLayout->Unparent();
index 547df3c..11faf72 100755 (executable)
@@ -20,6 +20,7 @@ toolkit_src_files = \
    $(toolkit_src_dir)/layouting/layout-group-data-impl.cpp \
    $(toolkit_src_dir)/layouting/layout-controller-debug.cpp \
    $(toolkit_src_dir)/layouting/layout-controller-impl.cpp \
+   $(toolkit_src_dir)/layouting/size-negotiation-mapper.cpp \
    $(toolkit_src_dir)/visuals/animated-image/animated-image-visual.cpp \
    $(toolkit_src_dir)/visuals/animated-image/image-cache.cpp \
    $(toolkit_src_dir)/visuals/animated-image/fixed-image-cache.cpp \
index a2d2855..2347d28 100644 (file)
@@ -57,6 +57,7 @@ public:
   static const int PRIVATE_FLAG_IS_LAID_OUT                   = 0x00000008;
   static const int PRIVATE_FLAG_MEASURE_NEEDED_BEFORE_LAYOUT  = 0x00000010; ///< Flag indicating that a call to measure() was skipped and should be done instead when layout() is invoked.
   static const int PRIVATE_FLAG_FORCE_SET_FRAME               = 0x00000020;
+  static const int PRIVATE_FLAG_USE_RESIZE_POLICY             = 0x00000040;
 
   int mViewFlags;
   int mPrivateFlags;
diff --git a/dali-toolkit/internal/layouting/size-negotiation-mapper.cpp b/dali-toolkit/internal/layouting/size-negotiation-mapper.cpp
new file mode 100644 (file)
index 0000000..a0f052a
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/layouting/size-negotiation-mapper.h>
+
+// EXTERNAL HEADER
+#include <dali/integration-api/debug.h>
+
+// INTERNAL HEADER
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/layouting/child-layout-data.h>
+#include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
+
+namespace
+{
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_LAYOUT" );
+#endif
+
+/**
+ * Set the width specification with the given layout params
+ */
+void SetWidthLayoutParams( Dali::Toolkit::Control control, int layoutParams )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy Setting WIDTH LayoutParam(%d) for %s\n",
+                                             layoutParams,
+                                             control.GetName().c_str() );
+  control.SetProperty( Dali::Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, layoutParams );
+}
+
+/**
+ * Set the height specification with the given layout params
+ */
+void SetHeightLayoutParams( Dali::Toolkit::Control control, int layoutParams )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy Setting HEIGHT LayoutParam(%d) for %s\n",
+                                             layoutParams,
+                                             control.GetName().c_str() );
+  control.SetProperty( Dali::Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, layoutParams );
+}
+
+/**
+ * Call SetResizePolicyRequired true on the layout belonging to the provided control
+ */
+void SetResizePolicyRequiredFlag( Dali::Toolkit::Internal::LayoutItemPtr layout )
+{
+  layout->SetResizePolicyRequired( true );
+}
+
+} // namspace
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+
+void SizeNegotiationMapper::SetLayoutParametersUsingResizePolicy( Toolkit::Control control, Toolkit::Internal::LayoutItemPtr layout, Dimension::Type dimension )
+{
+  // Get control's current width specification
+  int matchedLayoutParamWidth = control.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
+  int matchedLayoutParamHeight = control.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
+
+  // Get control's Resize Policy that should be mapped to a width specification
+  const ResizePolicy::Type resizePolicy = control.GetResizePolicy( dimension );
+
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy ResizePolicy for control:%s resizePolicy %d for dimension %d\n",
+                                              control?control.GetName().c_str():"Invalid",
+                                              resizePolicy,
+                                              dimension );
+
+  bool matchFound( false );
+
+  // Use the control's ResizePolicy to determine the new specification
+  switch( resizePolicy )
+  {
+    case ResizePolicy::USE_ASSIGNED_SIZE :
+    {
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy USE_ASSIGNED_SIZE\n");
+      // Set by legacy controls on their children. Will not be exposed to a Layout.
+      break;
+    }
+
+    case ResizePolicy::FIXED :
+    {
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy FIXED\n");
+      Vector3 controlSize = control.GetTargetSize();
+      matchedLayoutParamWidth = controlSize.width;
+      matchedLayoutParamHeight = controlSize.height;
+      matchFound = true;
+      break;
+    };
+    case ResizePolicy::USE_NATURAL_SIZE :
+    {
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy USE_NATURAL_SIZE\n");
+      // Default ResizePolicy for controls.
+      // LayoutGroups are containers, containers will not have a natural size.
+      break;
+    };
+    case ResizePolicy::FILL_TO_PARENT :
+    {
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy FILL_TO_PARENT\n");
+      matchedLayoutParamWidth = ChildLayoutData::MATCH_PARENT;
+      matchedLayoutParamHeight = ChildLayoutData::MATCH_PARENT;
+      matchFound = true;
+      break;
+    };
+    case ResizePolicy::SIZE_RELATIVE_TO_PARENT :
+    {
+      SetResizePolicyRequiredFlag( layout ); // Defer setting the exact size until the parent size is known.
+      break;
+    };
+    case ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT :
+    {
+      SetResizePolicyRequiredFlag( layout ); // Defer setting the exact size until the parent size is known.
+      break;
+    };
+    case ResizePolicy::FIT_TO_CHILDREN :
+    {
+      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsUsingResizePolicy FIT_TO_CHILDREN\n");
+      matchedLayoutParamWidth = ChildLayoutData::WRAP_CONTENT;
+      matchedLayoutParamHeight = ChildLayoutData::WRAP_CONTENT;
+      matchFound = true;
+      break;
+    };
+    case ResizePolicy::DIMENSION_DEPENDENCY :
+    {
+      // Not supported
+      break;
+    };
+  }
+
+  // Use the resize policy for the required dimensions only.
+  // Possible that only one dimension was set hence either the matchedLayoutParamWidth or
+  // matchedLayoutParamHeight should not be used.
+  if( matchFound )
+  {
+    if( dimension == Dimension::WIDTH )
+    {
+      SetWidthLayoutParams( control, matchedLayoutParamWidth );
+    }
+    else if( dimension == Dimension::HEIGHT )
+    {
+      SetHeightLayoutParams( control, matchedLayoutParamHeight );
+    }
+    else if( Dimension::ALL_DIMENSIONS )
+    {
+      SetWidthLayoutParams( control, matchedLayoutParamWidth );
+      SetHeightLayoutParams( control, matchedLayoutParamHeight );
+    }
+  }
+};
+
+void SizeNegotiationMapper::GetSizeofChildForParentDependentResizePolicy( Toolkit::Control control, const MeasureSpec parentWidthSpecification, const MeasureSpec parentHeightSpecification, LayoutLength& childWidth, LayoutLength& childHeight)
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "SizeNegotiationMapper::SetLayoutParamsForParentDependantResizePolicy ResizePolicy required for %s\n", control.GetName().c_str() );
+  ResizePolicy::Type widthResizePolicy = control.GetResizePolicy( Dimension::WIDTH );
+  ResizePolicy::Type heightResizePolicy = control.GetResizePolicy( Dimension::HEIGHT );
+  Vector3 sizeModeFactor = control.GetSizeModeFactor();
+
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::MeasureChild SetLayoutParamsForParentDependantResizePolicy for control:%s resizePolicy w:%d h:%d  modeFactor(%f,%f,%f)\n",
+                                              control?control.GetName().c_str():"Invalid",
+                                              widthResizePolicy, heightResizePolicy,
+                                              sizeModeFactor.x,
+                                              sizeModeFactor.y,
+                                              sizeModeFactor.z );
+
+  if( widthResizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT )
+  {
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsForParentDependantResizePolicy width SIZE_RELATIVE_TO_PARENT\n");
+    childWidth = parentWidthSpecification.GetSize().AsDecimal() * sizeModeFactor.x;
+  }
+  else if( widthResizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
+  {
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsForParentDependantResizePolicy width SIZE_FIXED_OFFSET_FROM_PARENT\n");
+    childWidth = parentWidthSpecification.GetSize().AsDecimal() + sizeModeFactor.x;
+  }
+
+  if( heightResizePolicy == ResizePolicy::SIZE_RELATIVE_TO_PARENT )
+  {
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsForParentDependantResizePolicy height  SIZE_RELATIVE_TO_PARENT\n");
+    childHeight = parentHeightSpecification.GetSize().AsDecimal() * sizeModeFactor.y;
+  }
+  else if( heightResizePolicy == ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT )
+  {
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "SizeNegotiationMapper::SetLayoutParamsForParentDependantResizePolicy height  SIZE_FIXED_OFFSET_FROM_PARENT\n");
+    childHeight = parentHeightSpecification.GetSize().AsDecimal() + sizeModeFactor.y;
+  }
+
+  // DIMENSION_DEPENDENCY not supported
+
+  DALI_LOG_INFO( gLogFilter, Debug::General, "SizeNegotiationMapper::SetLayoutParamsForParentDependantResizePolicy child size(%f,%f)\n",  childWidth.AsInteger(), childHeight.AsInteger() );
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
\ No newline at end of file
diff --git a/dali-toolkit/internal/layouting/size-negotiation-mapper.h b/dali-toolkit/internal/layouting/size-negotiation-mapper.h
new file mode 100644 (file)
index 0000000..d89996c
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef DALI_TOOLKIT_INTERNAL_LAYOUTING_SIZE_NEGOTIATION_MAPPER_IMPL_H
+#define DALI_TOOLKIT_INTERNAL_LAYOUTING_SIZE_NEGOTIATION_MAPPER_IMPL_H
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// EXTERNAL HEADERS
+#include <dali/public-api/actors/actor-enumerations.h>
+#include <dali-toolkit/public-api/controls/control.h>
+#include <dali-toolkit/devel-api/layouting/layout-item.h>
+
+namespace Dali
+{
+namespace Toolkit
+{
+namespace Internal
+{
+using LayoutItemPtr = IntrusivePtr<LayoutItem>;
+/**
+ *  @brief Maps ResizePolicies used in SizeNegotiation to the Layout system
+ *
+ */
+namespace SizeNegotiationMapper
+{
+/**
+ * @brief Sets the child layout parameters on the control by mapping it's ResizePolicy to a MeasureSpecification
+ * @param[out] control the control to set the layout params on
+ * @param[out] layout the layout for the given control
+ * @param[in] dimension the dimension or dimensions the resize policy applies to.
+ */
+void SetLayoutParametersUsingResizePolicy( Toolkit::Control control, Toolkit::Internal::LayoutItemPtr layout, const Dimension::Type dimension );
+
+/**
+ * @brief Sets the child layout parameters on the control using the a ResizePolicy that is dependant on it's parent
+ * @note This method should be used after a child has been parented and a parent measure spec is available.
+ * @param[out] control the control to set the layout params on
+ * @param[in] parentWidthSpecification the parent's width measure specification
+ * @param[in] parentHeightSpecification the parent's height measure specification
+ * @param[out] childWidth the resulting child width
+ * @param[out] childHeight the resulting child height
+ */
+void GetSizeofChildForParentDependentResizePolicy( Toolkit::Control control, const MeasureSpec parentWidthSpecification, const MeasureSpec parentHeightSpecification, LayoutLength& childWidth, LayoutLength& childHeight );
+
+} // namespace SizeNegotiationMapper
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+
+#endif // DALI_TOOLKIT_INTERNAL_LAYOUTING_SIZE_NEGOTIATION_MAPPER_IMPL_H
\ No newline at end of file
index 664c7e0..8f862f5 100755 (executable)
@@ -708,6 +708,7 @@ void Control::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dime
 
 Vector3 Control::GetNaturalSize()
 {
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::GetNaturalSize for %s\n", Self().GetName().c_str() );
   Toolkit::Visual::Base visual = mImpl->GetVisual( Toolkit::Control::Property::BACKGROUND );
   if( visual )
   {
index 9e3d094..8d8d1a9 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 3;
-const unsigned int TOOLKIT_MICRO_VERSION = 45;
+const unsigned int TOOLKIT_MICRO_VERSION = 46;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index a83597b..32a4005 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    1.3.45
+Version:    1.3.46
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT