Merge "Fix focus issue after calling ClearFocus api" into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Wed, 1 Aug 2018 12:56:18 +0000 (12:56 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Wed, 1 Aug 2018 12:56:18 +0000 (12:56 +0000)
16 files changed:
automated-tests/src/dali-toolkit/utc-Dali-Builder.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
automated-tests/src/dali-toolkit/utc-Dali-Layouting.cpp
dali-toolkit/devel-api/builder/base64-encoding.cpp [new file with mode: 0644]
dali-toolkit/devel-api/builder/base64-encoding.h [new file with mode: 0644]
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/layouting/layout-group-impl.cpp
dali-toolkit/devel-api/layouting/layout-group-impl.h
dali-toolkit/devel-api/layouting/layout-item-impl.cpp
dali-toolkit/devel-api/layouting/layout-parent-impl.h
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/layouting/linear-layout-impl.cpp
dali-toolkit/internal/styling/style-manager-impl.cpp
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/third-party/base-n/basen.hpp [new file with mode: 0644]
packaging/dali-toolkit.spec

index 511d2ef..77439d4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * 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.
  */
 
 #include <iostream>
-#include <stdlib.h>
+#include <iterator>
+#include <vector>
+#include <algorithm>
+#include <cstdlib>
+
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/devel-api/builder/builder.h>
+#include <dali-toolkit/devel-api/builder/base64-encoding.h>
 #include <dali/integration-api/events/touch-event-integ.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include <test-button.h>
 #include <test-animation-data.h>
 
+
 #define STRINGIFY(A)#A
 
 using namespace Dali;
@@ -1851,3 +1857,256 @@ int UtcDaliBuilderConfigurationP(void)
 
   END_TEST;
 }
+
+
+int UtcDaliBase64EncodingP(void)
+{
+  std::vector<uint32_t> data = { 0, 1, 2, 3, 4, 5, std::numeric_limits<uint32_t>::min(), std::numeric_limits<uint32_t>::max()  };
+
+  Property::Value value;
+  EncodeBase64PropertyData( value, data );
+
+  std::cout << "Max uint32_t:" << std::numeric_limits<uint32_t>::max() << std::endl;
+  std::cout << "Input data:  ";
+  std::ostream_iterator<uint32_t> out_it (std::cout,", ");
+  std::copy ( data.begin(), data.end(), out_it );
+  std::cout << std::endl;
+
+  std::string output;
+  DALI_TEST_CHECK( value.Get( output ) );
+  DALI_TEST_EQUALS( output, "AAAAAAEAAAACAAAAAwAAAAQAAAAFAAAAAAAAAP////8", TEST_LOCATION );
+
+  std::cout << "Output data:  " << output << std::endl;
+
+  END_TEST;
+}
+
+int UtcDaliBase64EncodingN(void)
+{
+  tet_infoline( "Test encoding an empty vector returns empty string" );
+  std::vector<uint32_t> data;
+
+  Property::Value value;
+  EncodeBase64PropertyData( value, data );
+
+  std::string output;
+  DALI_TEST_CHECK( value.Get( output ) );
+  DALI_TEST_EQUALS( output.empty(), true, TEST_LOCATION );
+
+  END_TEST;
+}
+
+template <typename T>
+int b64l(std::vector<T>&data)
+{
+  auto lengthInBytes = 4*data.size();
+  return ceil( lengthInBytes * 1.33333f );
+}
+
+int UtcDaliBase64EncodingP02(void)
+{
+  tet_infoline( "Test encoding vectors of lengths m .. m+4 encode and decode back to the same length vectors" );
+
+  std::vector<uint32_t> testData;
+  for(int i=0; i<8; ++i ) // 8 chosen to stay within single string output
+  {
+    testData.push_back(i);
+  }
+  Property::Value value;
+  EncodeBase64PropertyData( value, testData );
+
+  std::string output;
+  DALI_TEST_CHECK( value.Get( output ) );
+  DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+  DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+  std::vector<uint32_t> outData;
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+  DALI_TEST_EQUALS( std::equal( testData.begin(), testData.end(), outData.begin()), true, TEST_LOCATION );
+
+  // n+1
+  testData.push_back( 12345 );
+  EncodeBase64PropertyData( value, testData );
+
+  DALI_TEST_CHECK( value.Get( output ) );
+  DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+  DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+  outData.clear();
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+  DALI_TEST_EQUALS( std::equal( testData.begin(), testData.end(), outData.begin()), true, TEST_LOCATION );
+
+  // n+2
+  testData.push_back( 67890 );
+  EncodeBase64PropertyData( value, testData );
+
+  DALI_TEST_CHECK( value.Get( output ) );
+  DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+  DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+  outData.clear();
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+  DALI_TEST_EQUALS( std::equal( testData.begin(), testData.end(), outData.begin()), true, TEST_LOCATION );
+
+  // n+3
+  testData.push_back( -1 );
+  EncodeBase64PropertyData( value, testData );
+
+  DALI_TEST_CHECK( value.Get( output ) );
+  DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+  DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+  outData.clear();
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+  DALI_TEST_EQUALS( std::equal( testData.begin(), testData.end(), outData.begin()), true, TEST_LOCATION );
+
+
+  END_TEST;
+}
+
+
+int UtcDaliBase64EncodingP03(void)
+{
+  tet_infoline( "Test encoding a vector of length 12 has output within single string" );
+
+  std::vector<uint32_t> testData;
+  for(int i=0; i<12; ++i )
+  {
+    testData.push_back(i);
+  }
+  Property::Value value;
+  EncodeBase64PropertyData( value, testData );
+
+  std::string output;
+  DALI_TEST_CHECK( value.Get( output ) );
+  DALI_TEST_EQUALS( output.empty(), false, TEST_LOCATION);
+  DALI_TEST_EQUALS( output.length(), b64l(testData), TEST_LOCATION );
+
+  std::vector<uint32_t> outData;
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliBase64EncodingP04(void)
+{
+  tet_infoline( "Test encoding a vector of length 13 has output split over 2 strings" );
+
+  std::vector<uint32_t> testData;
+  for(int i=0; i<13; ++i )
+  {
+    testData.push_back(i);
+  }
+  Property::Value value;
+  EncodeBase64PropertyData( value, testData );
+
+  auto array = value.GetArray();
+  DALI_TEST_CHECK( array );
+
+  DALI_TEST_EQUALS( array->Count(), 2, TEST_LOCATION );
+
+  std::vector<uint32_t> outData;
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliBase64EncodingP05(void)
+{
+  tet_infoline( "Test encoding a vector of length 24 has output split over 2 strings" );
+
+  std::vector<uint32_t> testData;
+  for(int i=0; i<24; ++i )
+  {
+    testData.push_back(i);
+  }
+  Property::Value value;
+  EncodeBase64PropertyData( value, testData );
+
+  auto array = value.GetArray();
+  DALI_TEST_CHECK( array );
+
+  DALI_TEST_EQUALS( array->Count(), 2, TEST_LOCATION );
+
+  std::vector<uint32_t> outData;
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliBase64EncodingP06(void)
+{
+  tet_infoline( "Test encoding a vector of arbitrary length decodes OK." );
+
+  std::vector<uint32_t> testData;
+  for(int i=0; i<97; ++i )
+  {
+    testData.push_back(i);
+  }
+  Property::Value value;
+  EncodeBase64PropertyData( value, testData );
+
+  auto array = value.GetArray();
+  DALI_TEST_CHECK( array );
+
+  std::vector<uint32_t> outData;
+  DecodeBase64PropertyData( value, outData );
+  DALI_TEST_EQUALS( testData.size(), outData.size(), TEST_LOCATION );
+
+  END_TEST;
+}
+
+
+int UtcDaliBase64DecodingN01(void)
+{
+  tet_infoline( "Test decoding empty string results in empty data" );
+
+  Property::Value value("");
+  std::vector<uint32_t> outputData;
+  DecodeBase64PropertyData( value, outputData);
+  DALI_TEST_EQUALS( outputData.size(), 0, TEST_LOCATION );
+  END_TEST;
+}
+
+
+int UtcDaliBase64DecodingN02(void)
+{
+  tet_infoline( "Test decoding array with non-string values results in empty data" );
+
+  Property::Array array;
+  array.Resize(2);
+  array[0] = "Stuff, things";
+  array[1] = 1;
+  Property::Value value(array);
+
+  std::vector<uint32_t> outputData;
+  DecodeBase64PropertyData( value, outputData);
+  DALI_TEST_EQUALS( outputData.size(), 0, TEST_LOCATION );
+  END_TEST;
+}
+
+int UtcDaliBase64DecodingP01(void)
+{
+  tet_infoline( "Test decoding string of known data gives expected result");
+
+  std::string testInput("//////7+/v4DAgEA");
+  std::vector<uint32_t> expectedResults = { 0xffffffff, 0xfefefefe, 0x00010203 };
+
+  std::vector<uint32_t> outputData;
+  DecodeBase64PropertyData(Property::Value(testInput), outputData);
+
+  DALI_TEST_EQUALS( std::equal( expectedResults.begin(), expectedResults.end(), outputData.begin() ), true,
+                    TEST_LOCATION );
+
+  END_TEST;
+}
index dcffb5b..77121d5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * 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.
@@ -1734,3 +1734,44 @@ int UtcDaliImageViewUsingAtlasAndGetNaturalSize(void)
   END_TEST;
 }
 
+int UtcDaliImageViewFillMode(void)
+{
+  ToolkitTestApplication application;
+
+  tet_infoline( "Create an ImageVisual without padding and set the fill-mode to fill" );
+  tet_infoline( "  There should be no need to change the transform, our size-policy should be relative and size shoudl be [1,1]");
+
+  ImageView imageView = ImageView::New();
+  Property::Map imageMap;
+  imageMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::Visual::IMAGE );
+  imageMap.Add( Toolkit::ImageVisual::Property::URL, gImage_600_RGB );
+  imageMap.Add( DevelVisual::Property::VISUAL_FITTING_MODE, DevelVisual::FittingMode::FILL );
+
+  imageView.SetProperty( Toolkit::ImageView::Property::IMAGE, imageMap );
+
+  Stage::GetCurrent().Add( imageView );
+
+  // Trigger a potential relayout
+  application.SendNotification();
+  application.Render();
+
+  Toolkit::Visual::Base visual = DevelControl::GetVisual( Toolkit::Internal::GetImplementation( imageView ), Toolkit::ImageView::Property::IMAGE );
+  Property::Map returnedMap;
+  visual.CreatePropertyMap( returnedMap );
+
+  Property::Value* value = returnedMap.Find( Toolkit::Visual::Property::TRANSFORM );
+  DALI_TEST_CHECK( value );
+  Property::Map* map = value->GetMap();
+  DALI_TEST_CHECK( map );
+
+  // If there's
+  value = map->Find( Toolkit::Visual::Transform::Property::SIZE );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get< Vector2 >(), Vector2::ONE, TEST_LOCATION ); // Relative size so will take up 100%
+
+  value = map->Find( Toolkit::Visual::Transform::Property::SIZE_POLICY );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get< int >() == Toolkit::Visual::Transform::Policy::RELATIVE );
+
+  END_TEST;
+}
index cd82d5e..29e3726 100644 (file)
@@ -26,6 +26,7 @@
 #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>
 
 using namespace Dali;
 using namespace Toolkit;
 
+void TestLayoutItemOrder( std::vector< Control >& controls, LayoutGroup& layoutGroup )
+{
+  for( auto&& iter : controls )
+  {
+    unsigned int siblingOrder = static_cast< unsigned int>( iter.GetProperty< int >( DevelActor::Property::SIBLING_ORDER ) );
+    DALI_TEST_EQUALS( layoutGroup.GetChildAt( siblingOrder ), DevelControl::GetLayout( iter ), TEST_LOCATION );
+  }
+}
+
 void utc_dali_toolkit_layouting_startup(void)
 {
   test_return_value = TET_UNDEF;
@@ -1511,6 +1521,95 @@ int UtcDaliLayouting_VboxLayout03(void)
   END_TEST;
 }
 
+int UtcDaliLayouting_VboxLayout_Padding(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliLayouting_VboxLayout_Padding - Adding Padding to the vbox");
+
+  // Adding padding to the layout should offset the positioning of the children.
+
+  const Extents LAYOUT_PADDING = Extents(5, 10, 20, 2 );
+  const Size CONTROL_SIZE = Size( 40, 40 );
+
+  Stage stage = Stage::GetCurrent();
+  // Create a root layout, ideally Dali would have a default layout in the root layer.
+  // Without this root layer the LinearLayout (or any other layout) will not
+  // honour WIDTH_SPECIFICATION or HEIGHT_SPECIFICATION settings.
+  // It uses the default stage size and ideally should have a layout added to it.
+  auto rootLayoutControl = Control::New();
+  rootLayoutControl.SetName( "AbsoluteLayout");
+  auto rootLayout = AbsoluteLayout::New();
+  DevelControl::SetLayout( rootLayoutControl, rootLayout );
+  rootLayoutControl.SetAnchorPoint( AnchorPoint::CENTER );
+  rootLayoutControl.SetParentOrigin( ParentOrigin::CENTER );
+  stage.Add( rootLayoutControl );
+
+  auto vbox = Control::New();
+  auto vboxLayout = LinearLayout::New();
+  vboxLayout.SetOrientation( LinearLayout::Orientation::VERTICAL );
+  DevelControl::SetLayout( vbox, vboxLayout );
+  vbox.SetName( "VBox");
+  vbox.SetProperty( Toolkit::Control::Property::PADDING, LAYOUT_PADDING );
+  vbox.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+  vbox.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, ChildLayoutData::WRAP_CONTENT );
+
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( CONTROL_SIZE.width, CONTROL_SIZE.height ) );
+  controls.push_back( CreateLeafControl( CONTROL_SIZE.width, CONTROL_SIZE.height ) );
+  controls.push_back( CreateLeafControl( CONTROL_SIZE.width, CONTROL_SIZE.height ) );
+  controls.push_back( CreateLeafControl( CONTROL_SIZE.width, CONTROL_SIZE.height ) );
+
+  for( auto&& iter : controls )
+  {
+    vbox.Add( iter );
+  }
+
+  vbox.SetParentOrigin( ParentOrigin::CENTER );
+  vbox.SetAnchorPoint( AnchorPoint::CENTER );
+  rootLayoutControl.Add( vbox );
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  // Extra update needed to Relayout one more time. Catches any position updates, false positive without this seen.
+  application.SendNotification();
+
+  // vbox centers elements horizontally, it fills test harness stage, which is 480x800.
+  tet_infoline("Test Child Actor Position");
+
+  auto controlYPosition = 0.0f;
+
+  controlYPosition = LAYOUT_PADDING.top;  // First child positioned at offset defined by the padding
+  DALI_TEST_EQUALS( controls[0].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( LAYOUT_PADDING.start,
+                                                                                            LAYOUT_PADDING.top,
+                                                                                            0.0f ), 0.0001f, TEST_LOCATION );
+
+  controlYPosition += CONTROL_SIZE.height; // Second child positioned is the position of the first child + the first child's height.
+  DALI_TEST_EQUALS( controls[1].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( LAYOUT_PADDING.start,
+                                                                                            controlYPosition,
+                                                                                            0.0f ),
+                                                                                            0.0001f, TEST_LOCATION );
+
+  controlYPosition += CONTROL_SIZE.height; // Third child positioned adjacent to second
+  DALI_TEST_EQUALS( controls[2].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( LAYOUT_PADDING.start,
+                                                                                            controlYPosition,
+                                                                                            0.0f ), 0.0001f, TEST_LOCATION );
+
+  controlYPosition += CONTROL_SIZE.height; // Forth passed adjacent to the third
+  DALI_TEST_EQUALS( controls[3].GetProperty<Vector3>( Actor::Property::POSITION ), Vector3( LAYOUT_PADDING.start,
+                                                                                            controlYPosition,
+                                                                                            0.0f ), 0.0001f, TEST_LOCATION );
+
+  auto totalControlsWidth = CONTROL_SIZE.width;
+  auto totalControlsHeight = CONTROL_SIZE.height * controls.size();
+
+  DALI_TEST_EQUALS( vbox.GetProperty<Vector3>( Actor::Property::SIZE ), Vector3( totalControlsWidth + LAYOUT_PADDING.start + LAYOUT_PADDING.end,
+                                                                                 totalControlsHeight + LAYOUT_PADDING.top + LAYOUT_PADDING.bottom,
+                                                                                 0.0f ), 0.0001f, TEST_LOCATION );
+
+  END_TEST;
+}
 
 
 int UtcDaliLayouting_RelayoutOnChildOrderChanged(void)
@@ -1692,6 +1791,9 @@ int UtcDaliLayouting_LayoutChildren01(void)
   DALI_TEST_EQUALS( hboxLayout.GetOwner(), empty, TEST_LOCATION );
   DALI_TEST_EQUALS( (void*)hboxImpl.GetParent(), (void*)nullptr, TEST_LOCATION );
 
+  // For coverage
+  hboxImpl.SetLayoutRequested();
+
   END_TEST;
 }
 
@@ -1798,10 +1900,10 @@ int UtcDaliLayouting_LayoutChildren04(void)
   END_TEST;
 }
 
-int UtcDaliLayouting_SetLayoutOrder(void)
+int UtcDaliLayouting_SetLayoutOrder01(void)
 {
   ToolkitTestApplication application;
-  tet_infoline(" UtcDaliLayouting_SetLayoutOrder - Call SetLayout after adding the control to the root layout");
+  tet_infoline(" UtcDaliLayouting_SetLayoutOrder01 - Call SetLayout after adding the control to the root layout");
 
   Stage stage = Stage::GetCurrent();
 
@@ -1838,3 +1940,91 @@ int UtcDaliLayouting_SetLayoutOrder(void)
 
   END_TEST;
 }
+
+int UtcDaliLayouting_SetLayoutOrder02(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_SetLayoutOrder02 - Test the layout item order and the control order");
+
+  Stage stage = Stage::GetCurrent();
+
+  auto rootControl = Control::New();
+  auto absoluteLayout = AbsoluteLayout::New();
+  DevelControl::SetLayout( rootControl, absoluteLayout );
+  rootControl.SetName( "AbsoluteLayout" );
+  stage.Add( rootControl );
+
+  auto hbox = Control::New();
+  auto hboxLayout = LinearLayout::New();
+  hbox.SetName( "HBox");
+
+  rootControl.Add( hbox );
+
+  DevelControl::SetLayout( hbox, hboxLayout );
+
+  // Add child controls
+  std::vector< Control > controls;
+  controls.push_back( CreateLeafControl( 100, 100 ) );  // 0
+  controls.push_back( CreateLeafControl( 100, 100 ) );  // 1
+  controls.push_back( CreateLeafControl( 100, 100 ) );  // 2
+
+  for( auto&& iter : controls )
+  {
+    hbox.Add( iter );
+  }
+
+  // Ensure layouting happens
+  application.SendNotification();
+  application.Render();
+
+  TestLayoutItemOrder( controls, hboxLayout );
+
+  tet_infoline("RaiseToTop");
+
+  controls[0].RaiseToTop(); // 1 2 0
+
+  TestLayoutItemOrder( controls, hboxLayout );
+
+  tet_infoline("LowerToBottom");
+
+  controls[2].LowerToBottom();  // 2 1 0
+
+  TestLayoutItemOrder( controls, hboxLayout );
+
+  tet_infoline("Remove / Add");
+
+  hbox.Remove( controls[2] );  // 1 0
+  hbox.Add( controls[2] );     // 1 0 2
+
+  TestLayoutItemOrder( controls, hboxLayout );
+
+  tet_infoline("SetLayout");
+
+  auto vboxLayout = LinearLayout::New();
+  DevelControl::SetLayout( controls[0], vboxLayout );
+
+  TestLayoutItemOrder( controls, hboxLayout );
+
+  tet_infoline("Raise");
+
+  controls[0].Raise();  // 1 2 0
+
+  TestLayoutItemOrder( controls, hboxLayout );
+
+  tet_infoline("Lower");
+
+  controls[2].Lower();   // 2 1 0
+
+  TestLayoutItemOrder( controls, hboxLayout );
+
+  tet_infoline("SetLayout again");
+
+  auto vboxLayout1 = LinearLayout::New();
+  DevelControl::SetLayout( controls[2], vboxLayout1 );
+
+  TestLayoutItemOrder( controls, hboxLayout );
+
+  DevelControl::SetLayout( controls[2], vboxLayout );
+
+  END_TEST;
+}
diff --git a/dali-toolkit/devel-api/builder/base64-encoding.cpp b/dali-toolkit/devel-api/builder/base64-encoding.cpp
new file mode 100644 (file)
index 0000000..2799430
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * 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 INCLUDES
+#include <sstream>
+#include <iterator>
+
+#include <dali/public-api/object/property-value.h>
+#include <dali/public-api/object/property-array.h>
+#include <dali-toolkit/devel-api/builder/base64-encoding.h>
+#include <dali-toolkit/third-party/base-n/basen.hpp>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace
+{
+const int MAX_PROPERTY_STRING_LENGTH(64); // Cuts larger strings into blocks of this size.
+
+bool GetStringFromProperty( const Property::Value& value, std::string& output )
+{
+  bool extracted = false;
+  if( value.Get( output ) )
+  {
+    extracted = true;
+  }
+  else
+  {
+    Property::Array* array = value.GetArray();
+    if( array )
+    {
+      const unsigned int arraySize = array->Size();
+      for( unsigned int i = 0; i < arraySize; ++i )
+      {
+        std::string element;
+        if( array->GetElementAt( i ).Get( element ) )
+        {
+          extracted = true;
+          output += element;
+        }
+        else
+        {
+          // If property in array is anything other than a string, then it is invalid so break and clear output.
+          output.clear();
+          extracted = false;
+          break;
+        }
+      }
+    }
+  }
+  return extracted;
+}
+
+}//anonymous namespace
+
+bool DecodeBase64PropertyData( const Property::Value& value, std::vector<uint32_t>& outputData )
+{
+  bool decoded = false;
+  std::string encodedString;
+
+
+  if( GetStringFromProperty( value, encodedString ) )
+  {
+    std::vector<unsigned char> outputTmpData;
+    outputTmpData.reserve( ceil( encodedString.size() * 0.75f ) );
+    bn::decode_b64( encodedString.begin(), encodedString.end(), std::back_inserter(outputTmpData) );
+
+    outputData.clear();
+    outputData.resize( outputTmpData.size() / sizeof(uint32_t) );
+    // Treat as a block of data
+    memcpy( &outputData[0], &outputTmpData[0], outputTmpData.size() );
+
+    decoded = true;
+  }
+  return decoded;
+}
+
+void EncodeBase64PropertyData( Property::Value& value, const std::vector<uint32_t>& inputData )
+{
+  std::ostringstream oss;
+
+  bn::encode_b64( reinterpret_cast<const char*>(&inputData[0]),
+                  reinterpret_cast<const char*>(&inputData[0]+inputData.size()),
+                  std::ostream_iterator<unsigned char>(oss, "") );
+
+
+  std::string encodedString = oss.str();
+  if( encodedString.length() > MAX_PROPERTY_STRING_LENGTH)
+  {
+    // cut string up into blocks of MAX_PROPERTY_STRING_LENGTH and store to an array
+    auto numStrings = encodedString.length() / MAX_PROPERTY_STRING_LENGTH +
+                      ((encodedString.length() % MAX_PROPERTY_STRING_LENGTH) != 0);
+
+    Property::Array array;
+    for(auto i=0u; i<numStrings; ++i)
+    {
+      array.PushBack( encodedString.substr( i*MAX_PROPERTY_STRING_LENGTH, MAX_PROPERTY_STRING_LENGTH));
+    }
+    value = array;
+  }
+  else
+  {
+    value = encodedString;
+  }
+}
+
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/devel-api/builder/base64-encoding.h b/dali-toolkit/devel-api/builder/base64-encoding.h
new file mode 100644 (file)
index 0000000..6a691a9
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef DALI_TOOLKIT_BASE64_ENCODING_H
+#define DALI_TOOLKIT_BASE64_ENCODING_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 INCLUDES
+#include <dali/public-api/object/property.h>
+#include <dali/public-api/common/vector-wrapper.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+/**
+ * @brief Parses a Property::STRING or Property::ARRAY of STRINGS to
+ * retrieve a block of uint32_t data.
+ *
+ * Data can be encoded using the base64 encoding scheme to allow it to be used
+ * in JSON (The property system maps to JSON types).
+ *
+ * @param[in] value The property value to decode
+ * @param[out] outputData The output data block
+ * @return True if a data block was decoded successfully.
+ */
+bool DecodeBase64PropertyData( const Property::Value& value, std::vector<uint32_t>& outputData );
+
+/**
+ * @brief Convert a block of uint32_t data into a Property::STRING or ARRAY of STRINGs
+ * encoded using base64. This allows the data to be mapped to JSON easily.
+ *
+ * @param[out] value The value to write data into (to avoid copying).
+ * @param[in] inputData The input
+ */
+void EncodeBase64PropertyData( Property::Value& value, const std::vector<uint32_t>& inputData );
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+
+#endif // DALI_TOOLKIT_BASE64_ENCODING_H
index 411afe1..e974720 100755 (executable)
@@ -1,6 +1,7 @@
 # Add local source files here
 
 devel_api_src_files = \
+  $(devel_api_src_dir)/builder/base64-encoding.cpp \
   $(devel_api_src_dir)/builder/builder.cpp \
   $(devel_api_src_dir)/builder/json-parser.cpp \
   $(devel_api_src_dir)/builder/tree-node.cpp \
@@ -73,6 +74,7 @@ devel_api_buttons_header_files = \
   $(devel_api_src_dir)/controls/buttons/toggle-button.h
 
 devel_api_builder_header_files = \
+  $(devel_api_src_dir)/builder/base64-encoding.h \
   $(devel_api_src_dir)/builder/builder.h \
   $(devel_api_src_dir)/builder/json-parser.h \
   $(devel_api_src_dir)/builder/tree-node.h
index f3856de..69d268d 100644 (file)
@@ -122,6 +122,104 @@ void LayoutGroup::Remove( LayoutItem& child )
   RequestLayout();
 }
 
+Toolkit::LayoutGroup::LayoutId LayoutGroup::Insert( LayoutItem& target, LayoutItem& child )
+{
+  LayoutParent* oldParent = child.GetParent();
+  if( oldParent )
+  {
+    LayoutGroupPtr parentGroup( dynamic_cast< LayoutGroup* >( oldParent ) );
+    if( parentGroup )
+    {
+      parentGroup->Remove( child );
+    }
+  }
+
+  // Find target position
+  std::vector< Impl::ChildLayout >::iterator position;
+  for( auto iter = mImpl->mChildren.begin(); iter != mImpl->mChildren.end(); ++iter )
+  {
+    if( iter->child.Get() == &target )
+    {
+      position = iter;
+      break;
+    }
+  }
+
+  Impl::ChildLayout childLayout;
+  childLayout.layoutId = mImpl->mNextLayoutId++;
+  childLayout.child = &child;
+  mImpl->mChildren.insert( position, childLayout );
+
+  child.SetParent( this );
+
+  auto owner = child.GetOwner();
+
+  // Inform deriving classes that this child has been added
+  OnChildAdd( *childLayout.child.Get() );
+
+  // Now listen to future changes to the child properties.
+  DevelHandle::PropertySetSignal(owner).Connect( this, &LayoutGroup::OnSetChildProperties );
+
+  RequestLayout();
+
+  return childLayout.layoutId;
+}
+
+Toolkit::LayoutGroup::LayoutId LayoutGroup::Move( LayoutItem& target, LayoutItem& child )
+{
+  // Remove child from the previous position
+  for( auto iter = mImpl->mChildren.begin() ; iter != mImpl->mChildren.end() ; ++iter )
+  {
+    if( iter->child.Get() == &child )
+    {
+      mImpl->mChildren.erase( iter );
+      break;
+    }
+  }
+
+  // Find target position
+  std::vector< Impl::ChildLayout >::iterator position;
+  for( auto iter = mImpl->mChildren.begin(); iter != mImpl->mChildren.end(); ++iter )
+  {
+    if( iter->child.Get() == &target )
+    {
+      position = iter;
+      break;
+    }
+  }
+
+  Impl::ChildLayout childLayout;
+  childLayout.layoutId = mImpl->mNextLayoutId++;
+  childLayout.child = &child;
+  mImpl->mChildren.insert( position, childLayout );
+
+  RequestLayout();
+
+  return childLayout.layoutId;
+}
+
+Toolkit::LayoutGroup::LayoutId LayoutGroup::MoveBack( LayoutItem& child )
+{
+  // Remove child from the previous position
+  for( auto iter = mImpl->mChildren.begin() ; iter != mImpl->mChildren.end() ; ++iter )
+  {
+    if( iter->child.Get() == &child )
+    {
+      mImpl->mChildren.erase( iter );
+      break;
+    }
+  }
+
+  Impl::ChildLayout childLayout;
+  childLayout.layoutId = mImpl->mNextLayoutId++;
+  childLayout.child = &child;
+  mImpl->mChildren.emplace_back( childLayout );
+
+  RequestLayout();
+
+  return childLayout.layoutId;
+}
+
 void LayoutGroup::RemoveAll()
 {
   for( auto iter = mImpl->mChildren.begin() ; iter != mImpl->mChildren.end() ; )
@@ -418,7 +516,30 @@ void LayoutGroup::OnInitialize()
         if( parentLayout )
         {
           Internal::LayoutGroup& parentLayoutImpl = GetImplementation( parentLayout );
-          parentLayoutImpl.Add( *this );
+
+          unsigned int count = parent.GetChildCount();
+          unsigned int index = static_cast< unsigned int >( control.GetProperty< int >( DevelActor::Property::SIBLING_ORDER ) );
+
+          // Find insertion position
+          while( ++index < count )
+          {
+            auto sibling = Toolkit::Control::DownCast( parent.GetChildAt( index ) );
+            if( sibling )
+            {
+              auto siblingLayout = DevelControl::GetLayout( sibling );
+              if( siblingLayout )
+              {
+                Internal::LayoutItem& siblingLayoutImpl = GetImplementation( siblingLayout );
+                parentLayoutImpl.Insert( siblingLayoutImpl, *this );
+                break;
+              }
+            }
+          }
+
+          if( index >= count )
+          {
+            parentLayoutImpl.Add( *this );
+          }
         }
       }
     }
@@ -509,13 +630,39 @@ void LayoutGroup::ChildRemovedFromOwner( Actor child )
   }
 }
 
-void LayoutGroup::ChildOrderChanged()
+void LayoutGroup::ChildOrderChanged( Actor child )
 {
-  RequestLayout();
-  // Force Children to be relaid out:
-  for( auto&& child : mImpl->mChildren )
+  Toolkit::Control childControl = Toolkit::Control::DownCast( child );
+  if( childControl )
   {
-    child.child->SetLayoutRequested();
+    Internal::Control& childControlImpl = GetImplementation( childControl );
+    Internal::Control::Impl& childControlDataImpl = Internal::Control::Impl::Get( childControlImpl );
+
+    auto childLayout = childControlDataImpl.GetLayout();
+    if( childLayout )
+    {
+      Toolkit::Control control = Toolkit::Control::DownCast( GetOwner() );
+      unsigned int count = control.GetChildCount();
+      unsigned int index = static_cast< unsigned int >( childControl.GetProperty< int >( DevelActor::Property::SIBLING_ORDER ) );
+
+      // Find insertion position
+      while( ++index < count )
+      {
+        auto sibling = Toolkit::Control::DownCast( control.GetChildAt( index ) );
+        if( sibling )
+        {
+          auto siblingLayout = DevelControl::GetLayout( sibling );
+          if( siblingLayout )
+          {
+            Internal::LayoutItem& siblingLayoutImpl = GetImplementation( siblingLayout );
+            Move( siblingLayoutImpl, *childLayout );
+            return;
+          }
+        }
+      }
+
+      MoveBack( *childLayout );
+    }
   }
 }
 
index 36e0312..3039125 100644 (file)
@@ -96,6 +96,26 @@ public:
   void Remove( LayoutItem& child ) override;
 
   /**
+   * @brief Insert a child to the parent
+   * @param[in] target The target item
+   * @param[in] child The item to insert to this layout parent
+   */
+  Toolkit::LayoutGroup::LayoutId Insert( LayoutItem& target, LayoutItem& child ) override;
+
+  /**
+   * @brief Move a child to another position
+   * @param[in] target The target item
+   * @param[in] child The item to move
+   */
+  Toolkit::LayoutGroup::LayoutId Move( LayoutItem& target, LayoutItem& child ) override;
+
+  /**
+   * @brief Move a child to back
+   * @param[in] child The item to move
+   */
+  Toolkit::LayoutGroup::LayoutId MoveBack( LayoutItem& child ) override;
+
+  /**
    * @brief Remove all layout children.
    *
    * @note This will not unparent owner's children
@@ -264,7 +284,7 @@ private:
   /**
    * Callback when child order is changed
    */
-  void ChildOrderChanged();
+  void ChildOrderChanged( Actor child );
 
   /**
    * Callback when an owner property is set. Triggers a relayout if it's a child property
index 4c1e6b9..a0350e3 100644 (file)
@@ -327,7 +327,7 @@ bool LayoutItem::IsLayoutRequested() const
 
 void LayoutItem::SetLayoutRequested()
 {
-  return mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
+  mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
 }
 
 void LayoutItem::SetMeasuredDimensions( MeasuredSize measuredWidth, MeasuredSize measuredHeight )
index 677a8ff..7c9414f 100644 (file)
@@ -52,6 +52,26 @@ public:
    */
   virtual void Remove( LayoutItem& item ) = 0;
 
+  /**
+   * @brief Insert a child to the parent
+   * @param[in] target The target item
+   * @param[in] item The item to insert to this layout parent
+   */
+  virtual Toolkit::LayoutGroup::LayoutId Insert( LayoutItem& target, LayoutItem& item ) = 0;
+
+  /**
+   * @brief Move a child to another position
+   * @param[in] target The target item
+   * @param[in] item The item to move
+   */
+  virtual Toolkit::LayoutGroup::LayoutId Move( LayoutItem& target, LayoutItem& item ) = 0;
+
+  /**
+   * @brief Move a child to back
+   * @param[in] item The item to move
+   */
+  virtual Toolkit::LayoutGroup::LayoutId MoveBack( LayoutItem& item ) = 0;
+
 protected:
   virtual ~LayoutParent()
   {
index 11d5389..f709559 100755 (executable)
@@ -271,45 +271,50 @@ void ImageView::OnRelayout( const Vector2& size, RelayoutContainer& container )
     Property::Map transformMap = Property::Map();
 
     Extents padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
+    const Visual::FittingMode fittingMode = Toolkit::GetImplementation(mVisual).GetFittingMode();
 
-    Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(
-          Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
-
-    if( Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection )
+    if( ( padding != Extents() ) || // If padding is not zero
+        ( fittingMode == Visual::FittingMode::FIT_KEEP_ASPECT_RATIO ) )
     {
-      std::swap( padding.start, padding.end );
-    }
+      Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(
+            Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
 
-    auto finalOffset = Vector2( padding.start, padding.top );
+      if( Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection )
+      {
+        std::swap( padding.start, padding.end );
+      }
 
-    // remove padding from the size to know how much is left for the visual
-    auto finalSize = size - Vector2( padding.start + padding.end, padding.top + padding.bottom );
+      auto finalOffset = Vector2( padding.start, padding.top );
 
-    // Should provide a transform that handles aspect ratio according to image size
-    if( Toolkit::GetImplementation(mVisual).GetFittingMode() == Visual::FittingMode::FIT_KEEP_ASPECT_RATIO )
-    {
-      auto availableVisualSize = finalSize;
+      // remove padding from the size to know how much is left for the visual
+      auto finalSize = size - Vector2( padding.start + padding.end, padding.top + padding.bottom );
 
-      Vector2 naturalSize;
-      mVisual.GetNaturalSize( naturalSize );
+      // Should provide a transform that handles aspect ratio according to image size
+      if( fittingMode == Visual::FittingMode::FIT_KEEP_ASPECT_RATIO )
+      {
+        auto availableVisualSize = finalSize;
 
-      // scale to fit the padded area
-      finalSize = naturalSize * std::min( ( naturalSize.width  ? ( availableVisualSize.width  / naturalSize.width  ) : 0 ),
-                                          ( naturalSize.height ? ( availableVisualSize.height / naturalSize.height ) : 0 ) );
+        Vector2 naturalSize;
+        mVisual.GetNaturalSize( naturalSize );
 
-      // calculate final offset within the padded area
-      finalOffset += ( availableVisualSize - finalSize ) * .5f;
-    }
+        // scale to fit the padded area
+        finalSize = naturalSize * std::min( ( naturalSize.width  ? ( availableVisualSize.width  / naturalSize.width  ) : 0 ),
+                                            ( naturalSize.height ? ( availableVisualSize.height / naturalSize.height ) : 0 ) );
 
-    // populate the transform map
-    transformMap.Add( Toolkit::Visual::Transform::Property::OFFSET, finalOffset )
-                .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY,
-                    Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
-                .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
-                .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN )
-                .Add( Toolkit::Visual::Transform::Property::SIZE, finalSize )
-                .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY,
-                    Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) );
+        // calculate final offset within the padded area
+        finalOffset += ( availableVisualSize - finalSize ) * .5f;
+      }
+
+      // populate the transform map
+      transformMap.Add( Toolkit::Visual::Transform::Property::OFFSET, finalOffset )
+                  .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY,
+                      Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
+                  .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
+                  .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN )
+                  .Add( Toolkit::Visual::Transform::Property::SIZE, finalSize )
+                  .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY,
+                      Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) );
+    }
 
     mVisual.SetTransformAndSize( transformMap, size );
   }
index 7b3720c..f989a54 100644 (file)
@@ -273,7 +273,7 @@ void LinearLayout::LayoutHorizontal( LayoutLength left, LayoutLength top, Layout
 
   Extents padding = GetPadding();
 
-  LayoutLength childTop( 0 );
+  LayoutLength childTop( padding.top );
   LayoutLength childLeft( padding.start );
 
   // Where bottom of child should go
@@ -433,7 +433,7 @@ void LinearLayout::LayoutVertical( LayoutLength left, LayoutLength top, LayoutLe
 {
   Extents padding = GetPadding();
 
-  LayoutLength childTop( 0 );
+  LayoutLength childTop( padding.top );
   LayoutLength childLeft( padding.start );
 
   // Where bottom of child should go
@@ -453,7 +453,7 @@ void LinearLayout::LayoutVertical( LayoutLength left, LayoutLength top, LayoutLe
       auto childMargin = childLayout->GetMargin();
 
       childTop += childMargin.top;
-      childLeft = ( childSpace - childWidth ) / 2 + childMargin.start - childMargin.end;
+      childLeft = LayoutLength( padding.start ) + ( childSpace - childWidth ) / 2 + childMargin.start - childMargin.end;
 
       childLayout->Layout( childLeft, childTop, childLeft + childWidth, childTop + childHeight );
       childTop += childHeight + childMargin.bottom + mCellPadding.height;
index df885d9..106ec54 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * 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.
@@ -45,6 +45,10 @@ const char* APPLICATION_RESOURCE_PATH_KEY = "APPLICATION_RESOURCE_PATH";
 
 const char* DEFAULT_PACKAGE_PATH = DALI_DATA_READ_ONLY_DIR "/toolkit/";
 
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_STYLE");
+#endif
+
 } // namespace
 
 namespace Dali
@@ -227,42 +231,52 @@ Toolkit::StyleManager::StyleChangedSignalType& StyleManager::ControlStyleChangeS
 void StyleManager::SetTheme( const std::string& themeFile )
 {
   bool themeLoaded = false;
+  bool loading = false;
 
-  if( mThemeFile.compare(DEFAULT_THEME) == 0 && mThemeBuilder )
+  // If we haven't loaded a theme, or the stored theme file is empty, or
+  // the previously loaded theme is different to the requested theme,
+  // first reset the builder and load the default theme.
+  if( ! mThemeBuilder || mThemeFile.empty() || mThemeFile.compare( themeFile ) != 0 )
   {
-    // We have already loaded the default theme into mThemeBuilder
-  }
-  else
-  {
-    // Reload the default theme
+    loading = true;
     mThemeBuilder = CreateBuilder( mThemeBuilderConstants );
-    themeLoaded = LoadJSON( mThemeBuilder, DEFAULT_THEME );
+    themeLoaded = LoadJSON( mThemeBuilder, DEFAULT_THEME ); // Sets themeLoaded to true if theme exists
   }
 
   if( themeFile.compare(DEFAULT_THEME) != 0 )
   {
     // The theme is different to the default: Merge it
-    themeLoaded = LoadJSON( mThemeBuilder, themeFile );
-    mThemeFile = themeFile;
+    loading = true;
+    themeLoaded |= LoadJSON( mThemeBuilder, themeFile );
   }
 
-  if( themeLoaded )
+  if( loading )
   {
-    if(mFeedbackStyle)
+    mThemeFile = themeFile;
+
+    if( themeLoaded )
     {
-      mFeedbackStyle->StyleChanged( mThemeFile, StyleChange::THEME_CHANGE );
-    }
+      // We've successfully loaded the theme file
+      if(mFeedbackStyle)
+      {
+        mFeedbackStyle->StyleChanged( mThemeFile, StyleChange::THEME_CHANGE );
+      }
 
-    EmitStyleChangeSignals(StyleChange::THEME_CHANGE);
-  }
-  else
-  {
-    mThemeBuilder.Reset();
+      EmitStyleChangeSignals(StyleChange::THEME_CHANGE);
+    }
+    else
+    {
+      // We tried to load a theme, but it failed. Ensure the builder is reset
+      mThemeBuilder.Reset();
+      mThemeFile.clear();
+    }
   }
 }
 
 const Property::Map StyleManager::GetConfigurations()
 {
+  DALI_LOG_STREAM( gLogFilter, Debug::Concise, "GetConfigurations()\n On entry, mThemeBuilder: " << (bool(mThemeBuilder)?"Created":"Empty") << "  mThemeFile: " << mThemeFile);
+
   Property::Map result;
   if( mThemeBuilder )
   {
@@ -270,6 +284,8 @@ const Property::Map StyleManager::GetConfigurations()
   }
   else
   {
+    DALI_LOG_STREAM( gLogFilter, Debug::Concise, "GetConfigurations()  Loading default theme" );
+
     bool themeLoaded = false;
 
     mThemeBuilder = CreateBuilder( mThemeBuilderConstants );
@@ -282,8 +298,12 @@ const Property::Map StyleManager::GetConfigurations()
     {
       result = mThemeBuilder.GetConfigurations();
     }
+    DALI_LOG_STREAM( gLogFilter, Debug::Concise, "  themeLoaded" << (themeLoaded?"success":"failure") );
   }
 
+  DALI_LOG_STREAM( gLogFilter, Debug::Concise, "GetConfigurations()\n On exit, result Count: " << (result.Count() != 0) );
+  DALI_LOG_STREAM( gLogFilter, Debug::Verbose, "          result: " << result );
+
   return result;
 }
 
index 70e33f9..b13f65b 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 = 33;
+const unsigned int TOOLKIT_MICRO_VERSION = 34;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
diff --git a/dali-toolkit/third-party/base-n/basen.hpp b/dali-toolkit/third-party/base-n/basen.hpp
new file mode 100644 (file)
index 0000000..3ed31e8
--- /dev/null
@@ -0,0 +1,289 @@
+/**
+ * base-n, 1.0
+ * Copyright (C) 2012 Andrzej Zawadzki (azawadzki@gmail.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+**/
+#ifndef BASEN_HPP
+#define BASEN_HPP
+
+#include <algorithm>
+#include <cctype>
+#include <cassert>
+#include <cstring>
+
+namespace bn
+{
+
+template<class Iter1, class Iter2>
+void encode_b16(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void encode_b32(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void encode_b64(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void decode_b16(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void decode_b32(Iter1 start, Iter1 end, Iter2 out);
+
+template<class Iter1, class Iter2>
+void decode_b64(Iter1 start, Iter1 end, Iter2 out);
+
+namespace impl
+{
+
+const int Error = -1;
+
+namespace {
+
+char extract_partial_bits(char value, size_t start_bit, size_t bits_count)
+{
+    assert(start_bit + bits_count < 8);
+    // shift extracted bits to the beginning of the byte
+    char t1 = value >> (8 - bits_count - start_bit);
+    // mask out bits on the left
+    char t2 = t1 & ~(0xff << bits_count);
+    return t2;
+}
+
+char extract_overlapping_bits(char previous, char next, size_t start_bit, size_t bits_count)
+{
+    assert(start_bit + bits_count < 16);
+    size_t bits_count_in_previous = 8 - start_bit;
+    size_t bits_count_in_next = bits_count - bits_count_in_previous;
+    char t1 = previous << bits_count_in_next;
+    char t2 = next >> (8 - bits_count_in_next) & ~(0xff << bits_count_in_next) ;
+    return (t1 | t2) & ~(0xff << bits_count);
+}
+
+}
+
+struct b16_conversion_traits
+{
+    static size_t group_length()
+    {
+       return 4;
+    }
+
+    static char encode(unsigned int index)
+    {
+        const char* const dictionary = "0123456789ABCDEF";
+        assert(index < strlen(dictionary));
+        return dictionary[index];
+    }
+
+    static char decode(char c)
+    {
+        if (c >= '0' && c <= '9') {
+            return c - '0';
+        } else if (c >= 'A' && c <= 'F') {
+            return c - 'A' + 10;
+        }
+        return Error;
+    }
+};
+
+struct b32_conversion_traits
+{
+    static size_t group_length()
+    {
+       return 5;
+    }
+
+    static char encode(unsigned int index)
+    {
+        const char * dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
+        assert(index < strlen(dictionary));
+        return dictionary[index];
+    }
+
+    static char decode(char c)
+    {
+        if (c >= 'A' && c <= 'Z') {
+            return c - 'A';
+        } else if (c >= '2' && c <= '7') {
+            return c - '2' + 26;
+        }
+        return Error;
+    }
+};
+
+struct b64_conversion_traits
+{
+    static size_t group_length()
+    {
+       return 6;
+    }
+
+    static char encode(unsigned int index)
+    {
+        const char* const dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+        assert(index < strlen(dictionary));
+        return dictionary[index];
+    }
+
+    static char decode(char c)
+    {
+        const int alph_len = 26;
+        if (c >= 'A' && c <= 'Z') {
+            return c - 'A';
+        } else if (c >= 'a' && c <= 'z') {
+            return c - 'a' + alph_len * 1;
+        } else if (c >= '0' && c <= '9') {
+            return c - '0' + alph_len * 2;
+        } else if (c == '+') {
+            return c - '+' + alph_len * 2 + 10;
+        } else if (c == '/') {
+            return c - '/' + alph_len * 2 + 11;
+        }
+        return Error;
+    }
+};
+
+template<class ConversionTraits, class Iter1, class Iter2>
+void decode(Iter1 start, Iter1 end, Iter2 out)
+{
+    Iter1 iter = start;
+    size_t output_current_bit = 0;
+    char buffer = 0;
+
+    while (iter != end) {
+        if (std::isspace(*iter)) {
+            ++iter;
+            continue;
+        }
+        char value = ConversionTraits::decode(*iter);
+        if (value == Error) {
+            // malformed data, but let's go on...
+            ++iter;
+            continue;
+        }
+        size_t bits_in_current_byte = std::min<size_t>(output_current_bit + ConversionTraits::group_length(), 8) - output_current_bit;
+        if (bits_in_current_byte == ConversionTraits::group_length()) {
+            // the value fits within current byte, so we can extract it directly
+            buffer |= value << (8 - output_current_bit - ConversionTraits::group_length());
+            output_current_bit += ConversionTraits::group_length();
+            // check if we filled up current byte completely; in such case we flush output and continue
+            if (output_current_bit == 8) {
+                *out++ = buffer;
+                buffer = 0;
+                output_current_bit = 0;
+            }
+        } else {
+            // the value spans across the current and the next byte
+            size_t bits_in_next_byte = ConversionTraits::group_length() - bits_in_current_byte;
+            // fill the current byte and flush it to our output
+            buffer |= value >> bits_in_next_byte;
+            *out++ = buffer;
+            buffer = 0;
+            // save the remainder of our value in the buffer; it will be flushed
+            // during next iterations
+            buffer |= value << (8 - bits_in_next_byte);
+            output_current_bit = bits_in_next_byte;
+        }
+        ++iter;
+    }
+}
+
+template<class ConversionTraits, class Iter1, class Iter2>
+void encode(Iter1 start, Iter1 end, Iter2 out)
+{
+    Iter1 iter = start;
+    size_t start_bit = 0;
+    bool has_backlog = false;
+    char backlog = 0;
+
+    while (has_backlog || iter != end) {
+        if (!has_backlog) {
+            if (start_bit + ConversionTraits::group_length() < 8) {
+                // the value fits within single byte, so we can extract it
+                // directly
+                char v = extract_partial_bits(*iter, start_bit, ConversionTraits::group_length());
+                *out++ = ConversionTraits::encode(v);
+                // since we know that start_bit + ConversionTraits::group_length() < 8 we don't need to go
+                // to the next byte
+                start_bit += ConversionTraits::group_length();
+            } else {
+                // our bits are spanning across byte border; we need to keep the
+                // starting point and move over to next byte.
+                backlog = *iter++;
+                has_backlog = true;
+            }
+        } else {
+            // encode value which is made from bits spanning across byte
+            // boundary
+            char v;
+            if (iter == end)
+                 v = extract_overlapping_bits(backlog, 0, start_bit, ConversionTraits::group_length());
+            else
+                 v = extract_overlapping_bits(backlog, *iter, start_bit, ConversionTraits::group_length());
+            *out++ = ConversionTraits::encode(v);
+            has_backlog = false;
+            start_bit = (start_bit + ConversionTraits::group_length()) % 8;
+        }
+    }
+}
+
+} // impl
+
+using namespace bn::impl;
+
+template<class Iter1, class Iter2>
+void encode_b16(Iter1 start, Iter1 end, Iter2 out)
+{
+    encode<b16_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void encode_b32(Iter1 start, Iter1 end, Iter2 out)
+{
+    encode<b32_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void encode_b64(Iter1 start, Iter1 end, Iter2 out)
+{
+    encode<b64_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void decode_b16(Iter1 start, Iter1 end, Iter2 out)
+{
+    decode<b16_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void decode_b32(Iter1 start, Iter1 end, Iter2 out)
+{
+    decode<b32_conversion_traits>(start, end, out);
+}
+
+template<class Iter1, class Iter2>
+void decode_b64(Iter1 start, Iter1 end, Iter2 out)
+{
+    decode<b64_conversion_traits>(start, end, out);
+}
+
+} // bn
+
+#endif // BASEN_HPP
index ab7c82f..82a9ed9 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    Dali 3D engine Toolkit
-Version:    1.3.33
+Version:    1.3.34
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT