Merge changes Ib7c620f5,I75f6d47b into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 5 Sep 2017 17:59:16 +0000 (17:59 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Tue, 5 Sep 2017 17:59:16 +0000 (17:59 +0000)
* changes:
  Add multiple thread support to TextureManager
  Fix potentially uninitialized variable.

18 files changed:
automated-tests/packaging/core-dali-toolkit-tests.spec
automated-tests/src/dali-toolkit-styling/default-theme.json
automated-tests/src/dali-toolkit-styling/utc-Dali-StyleManager.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-glyph-manager-impl.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-manager-impl.cpp
dali-toolkit/internal/text/rendering/atlas/atlas-manager-impl.h
dali-toolkit/internal/text/rendering/atlas/text-atlas-renderer.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/styles/1920x1080/dali-toolkit-default-theme.json
dali-toolkit/styles/480x800/dali-toolkit-default-theme.json
dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json
packaging/dali-toolkit.spec

index 046b020..b2570aa 100644 (file)
@@ -37,8 +37,6 @@ make %{?jobs:-j%jobs}
 rm -rf %{buildroot}
 cd automated-tests
 %make_install
-mkdir -p %{buildroot}/opt/usr/share/license
-cp %{_builddir}/%{name}-%{version}/LICENSE %{buildroot}/opt/usr/share/license/%{name}
 mkdir -p %{buildroot}/tmp/
 cp %{_builddir}/%{name}-%{version}/automated-tests/scripts/add_all_smack_rule.sh %{buildroot}/tmp/
 cp %{_builddir}/%{name}-%{version}/automated-tests/scripts/all_smack.rule %{buildroot}/tmp/
@@ -50,6 +48,6 @@ cp %{_builddir}/%{name}-%{version}/automated-tests/scripts/all_smack.rule %{buil
 
 %files
 /opt/usr/bin/*
-/opt/usr/share/license/%{name}
 /tmp/add_all_smack_rule.sh
 /tmp/all_smack.rule
+%license LICENSE
index 6b3ddd1..30edbfd 100644 (file)
@@ -1,7 +1,8 @@
 {
   "config":
   {
-    "alwaysShowFocus":false
+    "alwaysShowFocus":false,
+    "clearFocusOnEscape":true
   },
   "constants":
   {
index 20de8e8..e8348f1 100644 (file)
 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-base.h>
+#include <dali-toolkit/public-api/styling/style-manager.h>
+#include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
+#include <dali-toolkit/devel-api/styling/style-manager-devel.h>
+#include <dali/integration-api/events/key-event-integ.h>
 
 using namespace Dali;
 using namespace Dali::Toolkit;
@@ -1298,3 +1302,46 @@ int UtcDaliStyleManagerSetSubState02(void)
 
   END_TEST;
 }
+
+
+int UtcDaliStyleManagerConfigSectionTest(void)
+{
+  tet_infoline("Test that the properties in config section are works" );
+
+  const char* defaultTheme =
+    "{\n"
+    "  \"config\":\n"
+    "  {\n"
+    "    \"alwaysShowFocus\":false,\n"
+    "    \"clearFocusOnEscape\":false\n"
+    "  },\n"
+    "  \"styles\":\n"
+    "  {\n"
+    "  }\n"
+    "}\n";
+
+  Test::StyleMonitor::SetThemeFileOutput( DALI_STYLE_DIR "dali-toolkit-default-theme.json", defaultTheme );
+
+  ToolkitTestApplication application;
+
+  Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
+
+  Property::Map config = Toolkit::DevelStyleManager::GetConfigurations( styleManager );
+  bool alwaysShowFocus = config["alwaysShowFocus"].Get<bool>();
+  DALI_TEST_CHECK( !alwaysShowFocus );
+  bool clearFocusOnEscape = config["clearFocusOnEscape"].Get<bool>();
+  DALI_TEST_CHECK( !clearFocusOnEscape );
+
+  // For coverage
+  Toolkit::TextEditor editor = Toolkit::TextEditor::New();
+  editor.SetKeyboardFocusable( true );
+  Stage::GetCurrent().Add( editor );
+
+  Toolkit::KeyboardFocusManager::Get().SetCurrentFocusActor( editor );
+
+  application.ProcessEvent( Integration::KeyEvent( "", "", DALI_KEY_ESCAPE, 0, 0, Integration::KeyEvent::Down, "", DevelDevice::Class::NONE, DevelDevice::Subclass::NONE ) );
+  application.SendNotification();
+  application.Render();
+
+  END_TEST;
+}
index b764740..08b194f 100644 (file)
@@ -2502,3 +2502,54 @@ int utcDaliTextFieldSizeUpdate(void)
 
   END_TEST;
 }
+
+int utcDaliTextFieldExtremlyLargePointSize(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextFieldExtremlyLargePointSize");
+
+  TextField field = TextField::New();
+
+  field.SetProperty( TextField::Property::TEXT, "Text" );
+  field.SetSize( 300.f, 50.f );
+  field.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  field.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+  Stage::GetCurrent().Add( field );
+
+  try
+  {
+    field.SetProperty( TextField::Property::POINT_SIZE, 160.0f );
+    application.SendNotification();
+    DALI_TEST_CHECK( field );
+  }
+  catch (...)
+  {
+    tet_result(TET_FAIL);
+  }
+  END_TEST;
+}
+
+int UtcDaliTextFieldDefaultFontStylePropertyCoverage(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline("UtcDaliTextFieldFontStylePorpertyCoverage");
+  TextField field = TextField::New();
+  DALI_TEST_CHECK( field );
+  Stage::GetCurrent().Add( field );
+
+  Property::Map fontStyleMapGet;
+
+  fontStyleMapGet = field.GetProperty<Property::Map>( TextField::Property::FONT_STYLE );
+
+  Property::Value* weightValue = NULL;
+  Property::Value* widthValue = NULL;
+  Property::Value* slantValue = NULL;
+  weightValue = fontStyleMapGet.Find( "weight" );
+  widthValue = fontStyleMapGet.Find( "width" );
+  slantValue = fontStyleMapGet.Find( "slant" );
+  DALI_TEST_CHECK( !weightValue );
+  DALI_TEST_CHECK( !widthValue );
+  DALI_TEST_CHECK( !slantValue );
+
+  END_TEST;
+}
index d089d97..77005c0 100644 (file)
@@ -1478,7 +1478,7 @@ bool TextEditor::OnKeyEvent( const KeyEvent& event )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
 
-  if( Dali::DALI_KEY_ESCAPE == event.keyCode ) // Make a Dali key code for this
+  if( Dali::DALI_KEY_ESCAPE == event.keyCode && mController->ShouldClearFocusOnEscape() )
   {
     // Make sure ClearKeyInputFocus when only key is up
     if( event.state == KeyEvent::Up )
index 1ed87bd..d5ea993 100644 (file)
@@ -1526,7 +1526,7 @@ bool TextField::OnKeyEvent( const KeyEvent& event )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
 
-  if( Dali::DALI_KEY_ESCAPE == event.keyCode ) // Make a Dali key code for this
+  if( Dali::DALI_KEY_ESCAPE == event.keyCode && mController->ShouldClearFocusOnEscape() )
   {
     // Make sure ClearKeyInputFocus when only key is up
     if( event.state == KeyEvent::Up )
index 7e672bd..0d72be9 100644 (file)
@@ -49,6 +49,8 @@ void AtlasGlyphManager::Add( const Text::GlyphInfo& glyph,
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "Added glyph, font: %d index: %d\n", glyph.fontId, glyph.index );
 
+  // If glyph added to an existing or new atlas then a new glyph record is required.
+  // Check if an existing atlas will fit the image, create a new one if required.
   if ( mAtlasManager.Add( bitmap, slot ) )
   {
     // A new atlas was created so set the texture set details for the atlas
index 958749e..ba07cef 100644 (file)
@@ -42,6 +42,11 @@ namespace
   const uint32_t SINGLE_PIXEL_PADDING( 1u );
   const uint32_t DOUBLE_PIXEL_PADDING( SINGLE_PIXEL_PADDING << 1 );
   Toolkit::AtlasManager::AtlasSize EMPTY_SIZE;
+
+  bool IsBlockSizeSufficient( uint32_t width, uint32_t height, uint32_t requiredBlockWidth, uint32_t requiredBlockHeight )
+  {
+    return ( width + DOUBLE_PIXEL_PADDING <= requiredBlockWidth ) && ( height + DOUBLE_PIXEL_PADDING <= requiredBlockHeight );
+  }
 }
 
 AtlasManager::AtlasManager()
@@ -139,39 +144,46 @@ bool AtlasManager::Add( const PixelData& image,
   }
 
   // Search current atlases to see if there is a good match
-  while( !foundAtlas && index < mAtlasList.size() )
+  while( ( 0u == foundAtlas ) && ( index < mAtlasList.size() ) )
   {
     foundAtlas = CheckAtlas( index, width, height, pixelFormat );
     ++index;
   }
 
   // If we can't find a suitable atlas then check the policy to determine action
-  if ( !foundAtlas-- )
+  if ( 0u == foundAtlas )
   {
     if ( Toolkit::AtlasManager::FAIL_ON_ADD_CREATES == mAddFailPolicy )
     {
-      foundAtlas = CreateAtlas( mNewAtlasSize, pixelFormat );
-      if ( !foundAtlas-- )
+      if ( IsBlockSizeSufficient( width, height, mNewAtlasSize.mBlockWidth, mNewAtlasSize.mBlockHeight ) ) // Checks if image fits within the atlas blocks
       {
-        DALI_LOG_ERROR("Failed to create an atlas of %i x %i blocksize: %i x %i.\n",
-                       mNewAtlasSize.mWidth,
-                       mNewAtlasSize.mHeight,
-                       mNewAtlasSize.mBlockWidth,
-                       mNewAtlasSize.mBlockHeight );
-        return created;
+        foundAtlas = CreateAtlas( mNewAtlasSize, pixelFormat ); // Creating atlas with mNewAtlasSize, may not be the needed size!
+        if (  0u == foundAtlas )
+        {
+          DALI_LOG_ERROR("Failed to create an atlas of %i x %i blocksize: %i x %i.\n",
+                         mNewAtlasSize.mWidth,
+                         mNewAtlasSize.mHeight,
+                         mNewAtlasSize.mBlockWidth,
+                         mNewAtlasSize.mBlockHeight );
+          return false;
+        }
+        else
+        {
+          created = true;
+        }
       }
-      created = true;
-      foundAtlas = CheckAtlas( foundAtlas, width, height, pixelFormat );
     }
 
-    if ( !foundAtlas-- || Toolkit::AtlasManager::FAIL_ON_ADD_FAILS == mAddFailPolicy )
+    if ( (  0u == foundAtlas )  || Toolkit::AtlasManager::FAIL_ON_ADD_FAILS == mAddFailPolicy )
     {
-      // Haven't found an atlas for this image!!!!!!
+      // Haven't found an atlas for this image ( may have failed to add image to atlas )
       DALI_LOG_ERROR("Failed to create an atlas under current policy.\n");
-      return created;
+      return false;
     }
   }
 
+  foundAtlas--; // Atlas created successfully, decrement by 1 to get <vector> index (starts at 0 not 1)
+
   // Work out which the block we're going to use
   // Is there currently a next free block available ?
   if ( mAtlasList[ foundAtlas ].mAvailableBlocks )
@@ -188,7 +200,7 @@ bool AtlasManager::Add( const PixelData& image,
 
   desc.mImageWidth = width;
   desc.mImageHeight = height;
-  desc.mAtlasId = foundAtlas + 1u;
+  desc.mAtlasId = foundAtlas + 1u;  // Ids start from 1 not the 0 index
   desc.mCount = 1u;
 
   // See if there's a previously freed image ID that we can assign to this new image
@@ -211,7 +223,7 @@ bool AtlasManager::Add( const PixelData& image,
     mImageList[ imageId - 1u ] = desc;
     slot.mImageId = imageId;
   }
-  slot.mAtlasId = foundAtlas + 1u;
+  slot.mAtlasId = foundAtlas + 1u; // Ids start from 1 not the 0 index
 
   // Upload the buffer image into the atlas
   UploadImage( image, desc );
@@ -226,12 +238,13 @@ AtlasManager::SizeType AtlasManager::CheckAtlas( SizeType atlas,
   AtlasManager::SizeType result = 0u;
   if ( pixelFormat == mAtlasList[ atlas ].mPixelFormat )
   {
-    // Check to see if the image will fit in these blocks, if not we'll need to create a new atlas
-    if ( ( mAtlasList[ atlas ].mAvailableBlocks + mAtlasList[ atlas ].mFreeBlocksList.Size() )
-           && width + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mBlockWidth
-           && height + DOUBLE_PIXEL_PADDING <= mAtlasList[ atlas ].mSize.mBlockHeight )
+    // Check to see if the image will fit in these blocks
+
+    const SizeType availableBlocks = mAtlasList[ atlas ].mAvailableBlocks + mAtlasList[ atlas ].mFreeBlocksList.Size();
+
+    if ( availableBlocks && IsBlockSizeSufficient( width, height,mAtlasList[ atlas ].mSize.mBlockWidth, mAtlasList[ atlas ].mSize.mBlockHeight ) )
     {
-      result = atlas + 1u;
+      result = atlas + 1u; // Atlas ids start from 1 not 0
     }
   }
   return result;
index 863bba9..dc48498 100644 (file)
@@ -178,7 +178,7 @@ private:
   std::vector< AtlasDescriptor > mAtlasList;            // List of atlases created
   Vector< AtlasSlotDescriptor > mImageList;             // List of bitmaps stored in atlases
   Toolkit::AtlasManager::AtlasSize mNewAtlasSize;       // Atlas size to use in next creation
-  Toolkit::AtlasManager::AddFailPolicy mAddFailPolicy;  // Policy for faling to add an Image
+  Toolkit::AtlasManager::AddFailPolicy mAddFailPolicy;  // Policy for failing to add an Image
 
   SizeType CheckAtlas( SizeType atlas,
                        SizeType width,
index e9b876d..13eeae6 100644 (file)
@@ -315,25 +315,28 @@ struct AtlasRenderer::Impl
           lastUnderlinedFontId = glyph.fontId;
         } // underline
 
-        if( !mGlyphManager.IsCached( glyph.fontId, glyph.index, slot ) )
+        bool glyphNotCached = !mGlyphManager.IsCached( glyph.fontId, glyph.index, slot );  // Check FontGlyphRecord vector for entry with glyph index and fontId
+
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "AddGlyphs fontID[%u] glyphIndex[%u] [%s]\n", glyph.fontId, glyph.index, (glyphNotCached)?"not cached":"cached" );
+
+        if( glyphNotCached )
         {
-          // Select correct size for new atlas if needed....?
-          if( lastFontId != glyph.fontId )
+          MaxBlockSize& blockSize = mBlockSizes[currentBlockSize];
+
+          if ( lastFontId != glyph.fontId )
           {
             uint32_t index = 0u;
+            // Looks through all stored block sizes until finds the one which mataches required glyph font it.  Ensures new atlas block size will match existing for same font id.
+            // CalculateBlocksSize() above ensures a block size entry exists.
             for( std::vector<MaxBlockSize>::const_iterator it = mBlockSizes.begin(),
                    endIt = mBlockSizes.end();
                  it != endIt;
                  ++it, ++index )
             {
-              const MaxBlockSize& blockSize = *it;
-              if( blockSize.mFontId == glyph.fontId )
+              const MaxBlockSize& blockSizeEntry = *it;
+              if( blockSizeEntry.mFontId == glyph.fontId )
               {
-                currentBlockSize = index;
-                mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_WIDTH,
-                                               DEFAULT_ATLAS_HEIGHT,
-                                               blockSize.mNeededBlockWidth,
-                                               blockSize.mNeededBlockHeight );
+                blockSize = mBlockSizes[index];
               }
             }
           }
@@ -363,31 +366,27 @@ struct AtlasRenderer::Impl
 
           if( bitmap )
           {
-            MaxBlockSize& blockSize = mBlockSizes[currentBlockSize];
-
             // Ensure that the next image will fit into the current block size
-            bool setSize = false;
             if( bitmap.GetWidth() > blockSize.mNeededBlockWidth )
             {
-              setSize = true;
               blockSize.mNeededBlockWidth = bitmap.GetWidth();
             }
+
             if( bitmap.GetHeight() > blockSize.mNeededBlockHeight )
             {
-              setSize = true;
               blockSize.mNeededBlockHeight = bitmap.GetHeight();
             }
 
-            if( setSize )
-            {
-              mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_WIDTH,
-                                             DEFAULT_ATLAS_HEIGHT,
-                                             blockSize.mNeededBlockWidth,
-                                             blockSize.mNeededBlockHeight );
-            }
+            // If CheckAtlas in AtlasManager::Add can't fit the bitmap in the current atlas it will create a new atlas
+
+            // Setting the block size and size of new atlas does not mean a new one will be created. An existing atlas may still surffice.
+            mGlyphManager.SetNewAtlasSize( DEFAULT_ATLAS_WIDTH,
+                                           DEFAULT_ATLAS_HEIGHT,
+                                           blockSize.mNeededBlockWidth,
+                                           blockSize.mNeededBlockHeight );
 
             // Locate a new slot for our glyph
-            mGlyphManager.Add( glyph, bitmap, slot );
+            mGlyphManager.Add( glyph, bitmap, slot ); // slot will be 0 is glyph not added
           }
         }
         else
@@ -399,40 +398,44 @@ struct AtlasRenderer::Impl
         // Move the origin (0,0) of the mesh to the center of the actor
         const Vector2 position = *( positionsBuffer + i ) - halfTextSize - lineOffsetPosition;
 
-        // Generate mesh data for this quad, plugging in our supplied position
-        AtlasManager::Mesh2D newMesh;
-        mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh );
-        textCacheEntry.mFontId = glyph.fontId;
-        textCacheEntry.mImageId = slot.mImageId;
-        textCacheEntry.mIndex = glyph.index;
-        newTextCache.PushBack( textCacheEntry );
-
-        AtlasManager::Vertex2D* verticesBuffer = newMesh.mVertices.Begin();
-
-        // Get the color of the character.
-        const ColorIndex colorIndex = useDefaultColor ? 0u : *( colorIndicesBuffer + i );
-        const Vector4& color = ( useDefaultColor || ( 0u == colorIndex ) ) ? defaultColor : *( colorsBuffer + colorIndex - 1u );
-
-        for( unsigned int index = 0u, size = newMesh.mVertices.Count();
-             index < size;
-             ++index )
+        if ( 0u != slot.mImageId ) // invalid slot id, glyph has failed to be added to atlas
         {
-          AtlasManager::Vertex2D& vertex = *( verticesBuffer + index );
+          // Generate mesh data for this quad, plugging in our supplied position
+          AtlasManager::Mesh2D newMesh;
+          mGlyphManager.GenerateMeshData( slot.mImageId, position, newMesh );
+          textCacheEntry.mFontId = glyph.fontId;
+          textCacheEntry.mImageId = slot.mImageId;
+          textCacheEntry.mIndex = glyph.index;
+          newTextCache.PushBack( textCacheEntry );
+
+          AtlasManager::Vertex2D* verticesBuffer = newMesh.mVertices.Begin();
+
+          // Get the color of the character.
+          const ColorIndex colorIndex = useDefaultColor ? 0u : *( colorIndicesBuffer + i );
+          const Vector4& color = ( useDefaultColor || ( 0u == colorIndex ) ) ? defaultColor : *( colorsBuffer + colorIndex - 1u );
+
+          for( unsigned int index = 0u, size = newMesh.mVertices.Count();
+               index < size;
+               ++index )
+          {
+            AtlasManager::Vertex2D& vertex = *( verticesBuffer + index );
 
-          // Set the color of the vertex.
-          vertex.mColor = color;
-        }
+            // Set the color of the vertex.
+            vertex.mColor = color;
+          }
 
-        // Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas)
-        StitchTextMesh( meshContainer,
-                        newMesh,
-                        extents,
-                        position.y + glyph.yBearing,
-                        underlineGlyph,
-                        currentUnderlinePosition,
-                        currentUnderlineThickness,
-                        slot );
-        lastFontId = glyph.fontId;
+          // Find an existing mesh data object to attach to ( or create a new one, if we can't find one using the same atlas)
+          StitchTextMesh( meshContainer,
+                          newMesh,
+                          extents,
+                          position.y + glyph.yBearing,
+                          underlineGlyph,
+                          currentUnderlinePosition,
+                          currentUnderlineThickness,
+                          slot );
+
+          lastFontId = glyph.fontId; // Prevents searching for existing blocksizes when string of the same fontId.
+        }
       }
     } // glyphs
 
@@ -737,8 +740,9 @@ struct AtlasRenderer::Impl
            blockIt != blockEndIt;
            ++blockIt )
       {
-        if( (*blockIt).mFontId == fontId )
+        if( (*blockIt).mFontId == fontId )  // Different size fonts will have a different fontId
         {
+          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Text::AtlasRenderer::CalculateBlocksSize match found fontID(%u) glyphIndex(%u)\n", fontId, (*glyphIt).index );
           foundFont = true;
           break;
         }
@@ -753,7 +757,7 @@ struct AtlasRenderer::Impl
         maxBlockSize.mNeededBlockWidth = static_cast< uint32_t >( fontMetrics.height );
         maxBlockSize.mNeededBlockHeight = maxBlockSize.mNeededBlockWidth;
         maxBlockSize.mFontId = fontId;
-
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Text::AtlasRenderer::CalculateBlocksSize New font with no matched blocksize, setting blocksize[%u]\n", maxBlockSize.mNeededBlockWidth );
         mBlockSizes.push_back( maxBlockSize );
       }
     }
index 054f4a7..898e2c6 100644 (file)
@@ -27,6 +27,8 @@
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/text-model.h>
 #include <dali-toolkit/internal/text/text-view.h>
+#include <dali-toolkit/public-api/styling/style-manager.h>
+#include <dali-toolkit/devel-api/styling/style-manager-devel.h>
 
 namespace Dali
 {
@@ -320,7 +322,8 @@ struct Controller::Impl
     mAutoScrollDirectionRTL( false ),
     mUnderlineSetByString( false ),
     mShadowSetByString( false ),
-    mFontStyleSetByString( false )
+    mFontStyleSetByString( false ),
+    mShouldClearFocusOnEscape( true )
   {
     mModel = Model::New();
 
@@ -336,6 +339,17 @@ struct Controller::Impl
     // Set the text properties to default
     mModel->mVisualModel->SetUnderlineEnabled( false );
     mModel->mVisualModel->SetUnderlineHeight( 0.0f );
+
+    Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
+    if( styleManager )
+    {
+      bool temp;
+      Property::Map config = Toolkit::DevelStyleManager::GetConfigurations( styleManager );
+      if( config["clearFocusOnEscape"].Get( temp ) )
+      {
+        mShouldClearFocusOnEscape = temp;
+      }
+    }
   }
 
   ~Impl()
@@ -730,6 +744,7 @@ public:
   bool mUnderlineSetByString:1;            ///< Set when underline is set by string (legacy) instead of map
   bool mShadowSetByString:1;               ///< Set when shadow is set by string (legacy) instead of map
   bool mFontStyleSetByString:1;            ///< Set when font style is set by string (legacy) instead of map
+  bool mShouldClearFocusOnEscape:1;        ///< Whether text control should clear key input focus
 };
 
 } // namespace Text
index 8b0ee5b..258fea7 100644 (file)
@@ -686,7 +686,12 @@ void Controller::SetDefaultFontWeight( FontWeight weight )
 
 bool Controller::IsDefaultFontWeightDefined() const
 {
-  return mImpl->mFontDefaults->weightDefined;
+  if( NULL != mImpl->mFontDefaults )
+  {
+    return mImpl->mFontDefaults->weightDefined;
+  }
+
+  return false;
 }
 
 FontWeight Controller::GetDefaultFontWeight() const
@@ -752,7 +757,12 @@ void Controller::SetDefaultFontWidth( FontWidth width )
 
 bool Controller::IsDefaultFontWidthDefined() const
 {
-  return mImpl->mFontDefaults->widthDefined;
+  if( NULL != mImpl->mFontDefaults )
+  {
+    return mImpl->mFontDefaults->widthDefined;
+  }
+
+  return false;
 }
 
 FontWidth Controller::GetDefaultFontWidth() const
@@ -818,7 +828,11 @@ void Controller::SetDefaultFontSlant( FontSlant slant )
 
 bool Controller::IsDefaultFontSlantDefined() const
 {
-  return mImpl->mFontDefaults->slantDefined;
+  if( NULL != mImpl->mFontDefaults )
+  {
+    return mImpl->mFontDefaults->slantDefined;
+  }
+  return false;
 }
 
 FontSlant Controller::GetDefaultFontSlant() const
@@ -2222,13 +2236,10 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
       // Do nothing.
       return false;
     }
-    else if( Dali::DALI_KEY_ESCAPE == keyCode )
+    else if( Dali::DALI_KEY_ESCAPE == keyCode || Dali::DALI_KEY_BACK == keyCode )
     {
-      // Escape key is a special case which causes focus loss
-      KeyboardFocusLostEvent();
-
-      // Will request for relayout.
-      relayoutNeeded = true;
+      // Do nothing
+      return false;
     }
     else if( ( Dali::DALI_KEY_CURSOR_LEFT  == keyCode ) ||
              ( Dali::DALI_KEY_CURSOR_RIGHT == keyCode ) ||
@@ -3688,6 +3699,11 @@ void Controller::SetControlInterface( ControlInterface* controlInterface )
   mImpl->mControlInterface = controlInterface;
 }
 
+bool Controller::ShouldClearFocusOnEscape() const
+{
+  return mImpl->mShouldClearFocusOnEscape;
+}
+
 // private : Private contructors & copy operator.
 
 Controller::Controller()
index 5cb079c..9e193c7 100644 (file)
@@ -1180,6 +1180,13 @@ public: // Text-input Event Queuing.
    */
   void PasteClipboardItemEvent();
 
+  /**
+   * @brief Return true when text control should clear key input focus when escape key is pressed.
+   *
+   * @return Whether text control should clear key input focus or not when escape key is pressed.
+   */
+  bool ShouldClearFocusOnEscape() const;
+
 protected: // Inherit from Text::Decorator::ControllerInterface.
 
   /**
index aa4f80f..07f851c 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 54;
+const unsigned int TOOLKIT_MICRO_VERSION = 55;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index dd06d35..7d78ed4 100644 (file)
@@ -28,7 +28,8 @@
 {
   "config":
   {
-    "alwaysShowFocus":false
+    "alwaysShowFocus":false,
+    "clearFocusOnEscape":false
   },
   "styles":
   {
index 8612b3c..460d0f8 100644 (file)
@@ -28,7 +28,8 @@
 {
   "config":
   {
-    "alwaysShowFocus":false
+    "alwaysShowFocus":false,
+    "clearFocusOnEscape":true
   },
   "styles":
   {
index 0c48655..9390546 100644 (file)
@@ -28,7 +28,8 @@
 {
   "config":
   {
-    "alwaysShowFocus":false
+    "alwaysShowFocus":false,
+    "clearFocusOnEscape":true
   },
   "styles":
   {
index 10159cf..09b9373 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    The OpenGLES Canvas Core Library Toolkit
-Version:    1.2.54
+Version:    1.2.55
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-3-Clause and MIT