[dali_1.1.30] Merge branch 'devel/master' 76/66176/1
authorAdam Bialogonski <adam.b@samsung.com>
Fri, 15 Apr 2016 14:00:16 +0000 (15:00 +0100)
committerAdam Bialogonski <adam.b@samsung.com>
Fri, 15 Apr 2016 14:00:16 +0000 (15:00 +0100)
Change-Id: I33ce19ae36aafe268989ff40230611c11ddca4d8

74 files changed:
automated-tests/src/dali-toolkit-internal/utc-Dali-LogicalModel.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Segmentation.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-VisualModel.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-text-model.cpp
automated-tests/src/dali-toolkit/utc-Dali-EffectsView.cpp
automated-tests/src/dali-toolkit/utc-Dali-PageTurnView.cpp
dali-toolkit/devel-api/controls/effects-view/effects-view.cpp
dali-toolkit/devel-api/controls/effects-view/effects-view.h
dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp
dali-toolkit/internal/controls/bloom-view/bloom-view-impl.h
dali-toolkit/internal/controls/buttons/button-impl.cpp
dali-toolkit/internal/controls/buttons/button-impl.h
dali-toolkit/internal/controls/buttons/check-box-button-impl.cpp
dali-toolkit/internal/controls/buttons/check-box-button-impl.h
dali-toolkit/internal/controls/buttons/push-button-impl.cpp
dali-toolkit/internal/controls/buttons/push-button-impl.h
dali-toolkit/internal/controls/buttons/radio-button-impl.cpp
dali-toolkit/internal/controls/buttons/radio-button-impl.h
dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp
dali-toolkit/internal/controls/effects-view/effects-view-impl.h
dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.cpp
dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.h
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/controls/magnifier/magnifier-impl.cpp
dali-toolkit/internal/controls/page-turn-view/page-turn-book-spine-effect.h
dali-toolkit/internal/controls/page-turn-view/page-turn-effect.cpp
dali-toolkit/internal/controls/page-turn-view/page-turn-effect.h
dali-toolkit/internal/controls/page-turn-view/page-turn-landscape-view-impl.cpp
dali-toolkit/internal/controls/page-turn-view/page-turn-landscape-view-impl.h
dali-toolkit/internal/controls/page-turn-view/page-turn-portrait-view-impl.cpp
dali-toolkit/internal/controls/page-turn-view/page-turn-portrait-view-impl.h
dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.cpp
dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.h
dali-toolkit/internal/controls/popup/popup-impl.cpp
dali-toolkit/internal/controls/popup/popup-impl.h
dali-toolkit/internal/controls/renderers/image/image-renderer.cpp
dali-toolkit/internal/controls/renderers/renderer-factory-cache.cpp
dali-toolkit/internal/controls/renderers/renderer-factory-cache.h
dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp
dali-toolkit/internal/controls/shadow-view/shadow-view-impl.cpp
dali-toolkit/internal/controls/shadow-view/shadow-view-impl.h
dali-toolkit/internal/controls/table-view/table-view-impl.cpp
dali-toolkit/internal/controls/table-view/table-view-impl.h
dali-toolkit/internal/controls/tool-bar/tool-bar-impl.cpp
dali-toolkit/internal/controls/tool-bar/tool-bar-impl.h
dali-toolkit/internal/filters/blur-two-pass-filter.cpp
dali-toolkit/internal/filters/blur-two-pass-filter.h
dali-toolkit/internal/filters/emboss-filter.cpp
dali-toolkit/internal/filters/emboss-filter.h
dali-toolkit/internal/filters/image-filter.cpp
dali-toolkit/internal/filters/image-filter.h
dali-toolkit/internal/filters/spread-filter.cpp
dali-toolkit/internal/filters/spread-filter.h
dali-toolkit/internal/text/logical-model-impl.cpp
dali-toolkit/internal/text/logical-model-impl.h
dali-toolkit/internal/text/paragraph-run.h [new file with mode: 0644]
dali-toolkit/internal/text/segmentation.cpp
dali-toolkit/internal/text/segmentation.h
dali-toolkit/internal/text/shaper.cpp
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/text/text-definitions.h
dali-toolkit/internal/text/text-run-container.h
dali-toolkit/internal/text/visual-model-impl.cpp
dali-toolkit/internal/text/visual-model-impl.h
dali-toolkit/internal/transition-effects/cube-transition-effect-impl.cpp
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/controls/control-impl.h
dali-toolkit/public-api/controls/page-turn-view/page-factory.h
dali-toolkit/public-api/dali-toolkit-version.cpp
docs/content/shared-javascript-and-cpp-documentation/creating-custom-controls.md
packaging/dali-toolkit.spec

index 9ec9930..fa28d61 100644 (file)
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 
 #include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/internal/text/text-run-container.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include <toolkit-text-model.h>
 
@@ -39,6 +40,26 @@ using namespace Text;
 
 namespace
 {
+struct CreateParagraphData
+{
+  std::string    description;                    ///< Description of the test.
+  std::string    text;                           ///< Input text.
+  CharacterIndex index;                          ///< The first character index.
+  Length         numberOfCharacters;             ///< The number of characters.
+  unsigned int   numberOfParagraphs;             ///< The expected number of paragraphs.
+  unsigned int*  indices;                        ///< The expected paragraph info indices.
+  unsigned int*  numberOfCharactersPerParagraph; ///< The expected number of characters of each paragraph.
+};
+
+struct FindParagraphData
+{
+  std::string    description;        ///< Description of the test.
+  std::string    text;               ///< Input text.
+  CharacterIndex index;              ///< The first character index.
+  Length         numberOfCharacters; ///< The number of characters.
+  unsigned int   numberOfParagraphs; ///< The expected number of paragraphs.
+  unsigned int*  paragraphs;         ///< The expected paragraph info.
+};
 
 struct SetVisualToLogicalMapData
 {
@@ -51,6 +72,109 @@ struct SetVisualToLogicalMapData
   unsigned int* visualToLogical;            ///< The expected visual to logical conversion table.
 };
 
+bool CreateParagraphTest( const CreateParagraphData& data )
+{
+  // 1) Create the model.
+  LogicalModelPtr logicalModel = LogicalModel::New();
+  VisualModelPtr visualModel = VisualModel::New();
+  Size textArea(100.f, 60.f);
+  Size layoutSize;
+
+  Vector<FontDescriptionRun> fontDescriptionRuns;
+  LayoutOptions options;
+  CreateTextModel( data.text,
+                   textArea,
+                   fontDescriptionRuns,
+                   options,
+                   layoutSize,
+                   logicalModel,
+                   visualModel );
+
+  // 2) Clear the paragraphs.
+  Vector<ParagraphRun>& paragraphs = logicalModel->mParagraphInfo;
+  ClearCharacterRuns( data.index,
+                      data.index + data.numberOfCharacters - 1u,
+                      paragraphs );
+
+  // 3) Call the LogicalModel::CreateParagraphInfo() method
+  logicalModel->CreateParagraphInfo( data.index,
+                                     data.numberOfCharacters );
+
+  // 4) Compare the results.
+  if( data.numberOfParagraphs != paragraphs.Count() )
+  {
+    std::cout << "  Different number of paragraphs : " << paragraphs.Count() << ", expected : " << data.numberOfParagraphs << std::endl;
+    return false;
+  }
+
+  unsigned int index = 0u;
+  for( Vector<ParagraphRun>::ConstIterator it = paragraphs.Begin(),
+         endIt = paragraphs.End();
+       it != endIt;
+       ++it, ++index )
+  {
+    const ParagraphRun& paragraph( *it );
+
+    if( data.indices[index] != paragraph.characterRun.characterIndex )
+    {
+      std::cout << "  Different character index for paragraph : " << index << ", " << paragraph.characterRun.characterIndex << ", expected : " << data.indices[index] << std::endl;
+      return false;
+    }
+    if( data.numberOfCharactersPerParagraph[index] != paragraph.characterRun.numberOfCharacters )
+    {
+      std::cout << "  Different number of characters for paragraph : " << index << ", " << paragraph.characterRun.numberOfCharacters << ", expected : " << data.numberOfCharactersPerParagraph[index] << std::endl;
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool FindParagraphTest( const FindParagraphData& data )
+{
+  // 1) Create the model.
+  LogicalModelPtr logicalModel = LogicalModel::New();
+  VisualModelPtr visualModel = VisualModel::New();
+  Size textArea(100.f, 60.f);
+  Size layoutSize;
+
+  Vector<FontDescriptionRun> fontDescriptionRuns;
+  LayoutOptions options;
+  CreateTextModel( data.text,
+                   textArea,
+                   fontDescriptionRuns,
+                   options,
+                   layoutSize,
+                   logicalModel,
+                   visualModel );
+
+  // 2) Find the paragraphs.
+  Vector<ParagraphRunIndex> paragraphs;
+  logicalModel->FindParagraphs( data.index, data.numberOfCharacters, paragraphs );
+
+  // 3) compare the results.
+  if( data.numberOfParagraphs != paragraphs.Count() )
+  {
+    return false;
+  }
+
+  unsigned int index = 0u;
+  for( Vector<ParagraphRunIndex>::ConstIterator it = paragraphs.Begin(),
+         endIt = paragraphs.End();
+       it != endIt;
+       ++it, ++index )
+  {
+    const ParagraphRunIndex paragraphIndex = *it;
+
+    if( paragraphIndex != data.paragraphs[index] )
+    {
+      return false;
+    }
+  }
+
+  return true;
+}
+
 bool SetVisualToLogicalMapTest( const SetVisualToLogicalMapData& data )
 {
   std::cout << "  testing : " << data.description << std::endl;
@@ -106,10 +230,158 @@ bool SetVisualToLogicalMapTest( const SetVisualToLogicalMapData& data )
 } // namespace
 
 //////////////////////////////////////////////////////////
+//
+// UtcDaliCreateParagraph
+// UtcDaliFindParagraph
+// UtcDaliSetVisualToLogicalMap
+//
+//////////////////////////////////////////////////////////
 
-int UtcDaliSetVisualToLogicalMap(void)
+int UtcDaliCreateParagraph(void)
 {
   ToolkitTestApplication application;
+  tet_infoline(" UtcDaliCreateParagraph");
+
+  unsigned int paragraphsIndices01[] = { 0u };
+  unsigned int paragraphsNumberOfCharacters01[] = { 0u };
+  unsigned int paragraphsIndices02[] = { 0u, 12u, 17u };
+  unsigned int paragraphsNumberOfCharacters02[] = { 12u, 5u, 1u };
+  unsigned int paragraphsIndices03[] = { 0u, 12u, 17u, 34u };
+  unsigned int paragraphsNumberOfCharacters03[] = { 12u, 5u, 17u ,1u };
+
+  struct CreateParagraphData data[] =
+  {
+    {
+      "Zero characters",
+      "",
+      0u,
+      0u,
+      0u,
+      paragraphsIndices01,
+      paragraphsNumberOfCharacters01,
+    },
+    {
+      "Some paragraphs",
+      "Hello world\ndemo\n\n",
+      0u,
+      18u,
+      3u,
+      paragraphsIndices02,
+      paragraphsNumberOfCharacters02,
+    },
+    {
+      "Some paragraphs. Update the initial paragraphs.",
+      "Hello world\ndemo\nhello world demo\n\n",
+      0u,
+      17u,
+      4u,
+      paragraphsIndices03,
+      paragraphsNumberOfCharacters03,
+    },
+    {
+      "Some paragraphs. Update the mid paragraphs.",
+      "Hello world\ndemo\nhello world demo\n\n",
+      12u,
+      5u,
+      4u,
+      paragraphsIndices03,
+      paragraphsNumberOfCharacters03,
+    },
+    {
+      "Some paragraphs. Update the final paragraphs.",
+      "Hello world\ndemo\nhello world demo\n\n",
+      17u,
+      18u,
+      4u,
+      paragraphsIndices03,
+      paragraphsNumberOfCharacters03,
+    },
+  };
+  const unsigned int numberOfTests = 5u;
+
+  for( unsigned int index = 0u; index < numberOfTests; ++index )
+  {
+    // ToolkitTestApplication application;
+    if( !CreateParagraphTest( data[index] ) )
+    {
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliFindParagraph(void)
+{
+  tet_infoline(" UtcDaliFindParagraph");
+
+  unsigned int paragraphs01[] = {};
+  unsigned int paragraphs02[] = { 0u, 1u, 2u };
+  unsigned int paragraphs03[] = { 0u };
+  unsigned int paragraphs04[] = { 1u };
+  unsigned int paragraphs05[] = { 0u, 1u, 2u };
+
+  struct FindParagraphData data[] =
+  {
+    {
+      "Zero characters",
+      "",
+      0u,
+      100u,
+      0u,
+      paragraphs01,
+    },
+    {
+      "Some paragraphs",
+      "Hello world\ndemo\n\n",
+      0u,
+      18u,
+      3u,
+      paragraphs02
+    },
+    {
+      "Some paragraphs",
+      "Hello world\ndemo\n\n",
+      0u,
+      12u,
+      1u,
+      paragraphs03
+    },
+    {
+      "Some paragraphs",
+      "Hello world\ndemo\n\n",
+      12u,
+      5u,
+      1u,
+      paragraphs04
+    },
+    {
+      "Some paragraphs",
+      "Hello world\ndemo\n\n",
+      3u,
+      15u,
+      3u,
+      paragraphs05
+    },
+  };
+  const unsigned int numberOfTests = 5u;
+
+  for( unsigned int index = 0u; index < numberOfTests; ++index )
+  {
+    ToolkitTestApplication application;
+    if( !FindParagraphTest( data[index] ) )
+    {
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliSetVisualToLogicalMap(void)
+{
   tet_infoline(" UtcDaliSetVisualToLogicalMap");
 
   unsigned int* visualToLogical01 = NULL;
@@ -210,6 +482,7 @@ int UtcDaliSetVisualToLogicalMap(void)
 
   for( unsigned int index = 0u; index < numberOfTests; ++index )
   {
+    ToolkitTestApplication application;
     if( !SetVisualToLogicalMapTest( data[index] ) )
     {
       tet_result(TET_FAIL);
index 0023240..5366164 100644 (file)
@@ -62,13 +62,31 @@ bool LineBreakInfoTest( const BreakInfoData& data )
 
   utf32.Resize( numberOfCharacters );
 
-  // 2) Set the line break info.
+  // 2) Set the line break info for the whole text.
   Vector<LineBreakInfo> lineBreakInfo;
   lineBreakInfo.Resize( numberOfCharacters );
 
-  SetLineBreakInfo( utf32, lineBreakInfo );
+  SetLineBreakInfo( utf32,
+                    0u,
+                    numberOfCharacters,
+                    lineBreakInfo );
+
+  // 3) Update the word text info if it's requested for part of the text.
+  if( ( 0u != data.index ) &&
+      ( numberOfCharacters != data.numberOfCharacters ) )
+  {
+    // Clear part of the line break info.
+    lineBreakInfo.Erase( lineBreakInfo.Begin() + data.index,
+                         lineBreakInfo.Begin() + data.index + data.numberOfCharacters );
 
-  // 3) compare the results
+    // Update the word line info.
+    SetLineBreakInfo( utf32,
+                      data.index,
+                      data.numberOfCharacters,
+                      lineBreakInfo );
+  }
+
+  // 4) compare the results
   std::ostringstream breakInfo;
 
   for( unsigned int index = 0u; index < numberOfCharacters; ++index )
@@ -78,8 +96,11 @@ bool LineBreakInfoTest( const BreakInfoData& data )
 
   if( data.breakInfo != breakInfo.str() )
   {
-    std::cout << "  expected : [" << data.breakInfo << "]" << std::endl;
-    std::cout << "       got : [" << breakInfo.str() << "]" << std::endl;
+    std::cout << "                text : [" << data.text << "]" << std::endl;
+    std::cout << "               index : " <<  data.index << std::endl;
+    std::cout << "  numberOfCharacters : " <<  data.numberOfCharacters << std::endl;
+    std::cout << "            expected : [" << data.breakInfo << "]" << std::endl;
+    std::cout << "                 got : [" << breakInfo.str() << "]" << std::endl;
     return false;
   }
 
@@ -149,7 +170,6 @@ bool WordBreakInfoTest( const BreakInfoData& data )
 
 int UtcDaliTextSegnemtationSetLineBreakInfo(void)
 {
-  ToolkitTestApplication application;
   tet_infoline(" UtcDaliTextSegnemtationSetLineBreakInfo");
 
   struct BreakInfoData data[] =
@@ -177,6 +197,51 @@ int UtcDaliTextSegnemtationSetLineBreakInfo(void)
       "222222122222221221222212212221222222122222222220",
     },
     {
+      "Latin script. Update initial paragraphs.",
+      "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
+      "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
+      "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
+      "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
+      "Quidam corpora at duo. An eos possim scripserit?",
+      0u,
+      141u,
+      "22222122222122222122212222212222212222222222122122221222221222222222122122220"
+      "2221221222212222222122222222221222222122222222122222222122212220"
+      "221222122222122222221222222222122212222221222222212220"
+      "22122222212222222122222222222122221222122222122222222222122222222222212220"
+      "222222122222221221222212212221222222122222222220",
+    },
+    {
+      "Latin script. Update mid paragraphs.",
+      "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
+      "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
+      "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
+      "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
+      "Quidam corpora at duo. An eos possim scripserit?",
+      141u,
+      128u,
+      "22222122222122222122212222212222212222222222122122221222221222222222122122220"
+      "2221221222212222222122222222221222222122222222122222222122212220"
+      "221222122222122222221222222222122212222221222222212220"
+      "22122222212222222122222222222122221222122222122222222222122222222222212220"
+      "222222122222221221222212212221222222122222222220",
+    },
+    {
+      "Latin script. Update final paragraphs.",
+      "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
+      "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
+      "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
+      "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
+      "Quidam corpora at duo. An eos possim scripserit?",
+      195u,
+      122u,
+      "22222122222122222122212222212222212222222222122122221222221222222222122122220"
+      "2221221222212222222122222222221222222122222222122222222122212220"
+      "221222122222122222221222222222122212222221222222212220"
+      "22122222212222222122222222222122221222122222122222222222122222222222212220"
+      "222222122222221221222212212221222222122222222220",
+    },
+    {
       "Japanese script",
       "韓国側は北朝鮮当局を通じて米ドルで賃金を支払う。\n"
       "国際社会から様々な経済制裁を受ける北朝鮮にとっては出稼ぎ労働などと並んで重要な外貨稼ぎの手段となっている。\n"
@@ -199,10 +264,11 @@ int UtcDaliTextSegnemtationSetLineBreakInfo(void)
       "21111112112111111111111211121111111111120",
     }
   };
-  const unsigned int numberOfTests = 4u;
+  const unsigned int numberOfTests = 7u;
 
   for( unsigned int index = 0u; index < numberOfTests; ++index )
   {
+    ToolkitTestApplication application;
     if( !LineBreakInfoTest( data[index] ) )
     {
       tet_result(TET_FAIL);
@@ -215,7 +281,6 @@ int UtcDaliTextSegnemtationSetLineBreakInfo(void)
 
 int UtcDaliTextSegnemtationSetWordBreakInfo(void)
 {
-  ToolkitTestApplication application;
   tet_infoline(" UtcDaliTextSegnemtationSetWordBreakInfo");
 
   struct BreakInfoData data[] =
@@ -380,6 +445,7 @@ int UtcDaliTextSegnemtationSetWordBreakInfo(void)
 
   for( unsigned int index = 0u; index < numberOfTests; ++index )
   {
+    ToolkitTestApplication application;
     if( !WordBreakInfoTest( data[index] ) )
     {
       tet_result(TET_FAIL);
index fdde254..fe6d4cb 100644 (file)
@@ -84,10 +84,12 @@ bool SetGlyphsPerCharacterTest( const SetGlyphsPerCharacterData& data )
   Vector<GlyphIndex>& charactersToGlyph = visualModel->mCharactersToGlyph;
   Vector<Length>& glyphsPerCharacter = visualModel->mGlyphsPerCharacter;
 
+  GlyphIndex startGlyphIndex = 0u;
   if( 0u != charactersToGlyph.Count() )
   {
     // The number of glyphs to be removed.
     const Length numberOfGlyphs = charactersToGlyph[data.startIndex + data.numberOfCharacters - 1u] + glyphsPerCharacter[data.startIndex + data.numberOfCharacters - 1u] - charactersToGlyph[data.startIndex];
+    startGlyphIndex = charactersToGlyph[data.startIndex];
 
     charactersToGlyph.Erase( charactersToGlyph.Begin() + data.startIndex,
                              charactersToGlyph.Begin() + data.startIndex + data.numberOfCharacters );
@@ -106,6 +108,7 @@ bool SetGlyphsPerCharacterTest( const SetGlyphsPerCharacterData& data )
 
   // 3) Call the CreateGlyphsPerCharacterTable() function
   visualModel->CreateGlyphsPerCharacterTable( data.startIndex,
+                                              startGlyphIndex,
                                               data.numberOfCharacters );
 
   // 4) Compare the results.
@@ -160,10 +163,12 @@ bool SetCharacterToGlyphTest( const SetCharacterToGlyphData& data )
   Vector<GlyphIndex>& charactersToGlyph = visualModel->mCharactersToGlyph;
   Vector<Length>& glyphsPerCharacter = visualModel->mGlyphsPerCharacter;
 
+  GlyphIndex startGlyphIndex = 0u;
   if( 0u != charactersToGlyph.Count() )
   {
     // The number of glyphs to be removed.
     const Length numberOfGlyphs = charactersToGlyph[data.startIndex + data.numberOfCharacters - 1u] + glyphsPerCharacter[data.startIndex + data.numberOfCharacters - 1u] - charactersToGlyph[data.startIndex];
+    startGlyphIndex = charactersToGlyph[data.startIndex];
 
     charactersToGlyph.Erase( charactersToGlyph.Begin() + data.startIndex,
                              charactersToGlyph.Begin() + data.startIndex + data.numberOfCharacters );
@@ -180,6 +185,7 @@ bool SetCharacterToGlyphTest( const SetCharacterToGlyphData& data )
 
   // 3) Call the CreateCharacterToGlyphTable() function
   visualModel->CreateCharacterToGlyphTable( data.startIndex,
+                                            startGlyphIndex,
                                             data.numberOfCharacters );
 
   // 4) Compare the results.
index 7b0ca45..c4dac4e 100644 (file)
@@ -122,12 +122,12 @@ void DummyControlImplOverride::OnPinch(const PinchGesture& pinch) { pinchCalled
 void DummyControlImplOverride::OnPan(const PanGesture& pan) { panCalled = true; }
 void DummyControlImplOverride::OnTap(const TapGesture& tap) { tapCalled = true; }
 void DummyControlImplOverride::OnLongPress(const LongPressGesture& longPress) { longPressCalled = true; }
-void DummyControlImplOverride::OnStageConnection( int depth ) { stageConnectionCalled = true; }
-void DummyControlImplOverride::OnStageDisconnection() { stageDisconnectionCalled = true; }
+void DummyControlImplOverride::OnStageConnection( int depth ) { Control::OnStageConnection( depth ); stageConnectionCalled = true; }
+void DummyControlImplOverride::OnStageDisconnection() { stageDisconnectionCalled = true; Control::OnStageDisconnection(); }
 void DummyControlImplOverride::OnChildAdd(Actor& child) { childAddCalled = true; }
 void DummyControlImplOverride::OnChildRemove(Actor& child) { childRemoveCalled = true; }
-void DummyControlImplOverride::OnSizeSet(const Vector3& targetSize) { sizeSetCalled = true; }
-void DummyControlImplOverride::OnSizeAnimation(Animation& animation, const Vector3& targetSize) { sizeAnimationCalled = true; }
+void DummyControlImplOverride::OnSizeSet(const Vector3& targetSize) { Control::OnSizeSet( targetSize ); sizeSetCalled = true; }
+void DummyControlImplOverride::OnSizeAnimation(Animation& animation, const Vector3& targetSize) { Control::OnSizeAnimation( animation, targetSize ); sizeAnimationCalled = true; }
 bool DummyControlImplOverride::OnTouchEvent(const TouchEvent& event) { touchEventCalled = true; return false; }
 bool DummyControlImplOverride::OnHoverEvent(const HoverEvent& event) { hoverEventCalled = true; return false; }
 bool DummyControlImplOverride::OnWheelEvent(const WheelEvent& event) { wheelEventCalled = true; return false; }
index 5bde6be..aff7eb7 100644 (file)
@@ -116,7 +116,10 @@ void CreateTextModel( const std::string& text,
   Vector<LineBreakInfo>& lineBreakInfo = logicalModel->mLineBreakInfo;
   lineBreakInfo.Resize( numberOfCharacters );
 
-  SetLineBreakInfo( utf32Characters, lineBreakInfo );
+  SetLineBreakInfo( utf32Characters,
+                    0u,
+                    numberOfCharacters,
+                    lineBreakInfo );
 
   if( 0u == numberOfCharacters )
   {
@@ -184,6 +187,10 @@ void CreateTextModel( const std::string& text,
                         numberOfCharacters,
                         bidirectionalInfo );
 
+  // Create the paragraph info.
+  logicalModel->CreateParagraphInfo( 0u,
+                                     numberOfCharacters );
+
   // 6) Set character directions.
   Vector<CharacterDirection>& characterDirections = logicalModel->mCharacterDirections;
   if( 0u != bidirectionalInfo.Count() )
@@ -232,8 +239,8 @@ void CreateTextModel( const std::string& text,
              newParagraphGlyphs );
 
   // Create the 'number of glyphs' per character and the glyph to character conversion tables.
-  visualModel->CreateGlyphsPerCharacterTable( 0u, numberOfCharacters );
-  visualModel->CreateCharacterToGlyphTable( 0u, numberOfCharacters );
+  visualModel->CreateGlyphsPerCharacterTable( 0u, 0u, numberOfCharacters );
+  visualModel->CreateCharacterToGlyphTable( 0u, 0u, numberOfCharacters );
 
   const Length numberOfGlyphs = glyphs.Count();
 
index a6be471..09b51f2 100644 (file)
@@ -42,11 +42,15 @@ int UtcDaliEffectsViewNew(void)
   EffectsView view;
   DALI_TEST_CHECK( !view );
 
-  view = EffectsView::New();
+  view = EffectsView::New( EffectsView::DROP_SHADOW );
   DALI_TEST_CHECK( view );
 
   Stage::GetCurrent().Add( view );
 
+  view.Reset();
+  view = EffectsView::New( EffectsView::EMBOSS );
+  DALI_TEST_CHECK( view );
+
   application.SendNotification();
   application.Render();
 
@@ -57,7 +61,7 @@ int UtcDaliEffectsViewCopyAndAssignment(void)
 {
   ToolkitTestApplication application;
 
-  EffectsView view = EffectsView::New();
+  EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW );
   DALI_TEST_CHECK( view );
 
   EffectsView copy( view );
@@ -80,7 +84,7 @@ int UtcDaliEffectsViewDownCast(void)
 {
   ToolkitTestApplication application;
 
-  BaseHandle view = EffectsView::New();
+  BaseHandle view = EffectsView::New( EffectsView::EMBOSS );
   DALI_TEST_CHECK( EffectsView::DownCast( view ) );
 
   BaseHandle empty;
@@ -92,131 +96,92 @@ int UtcDaliEffectsViewDownCast(void)
   END_TEST;
 }
 
-int UtcDaliEffectsViewSetGetTypeP(void)
+// Positive test case for a method
+int UtcDaliEffectsViewAddRemove(void)
 {
   ToolkitTestApplication application;
+  tet_infoline("UtcDaliGaussianBlurViewAddRemove");
 
-  EffectsView view = EffectsView::New();
-  DALI_TEST_CHECK( view.GetType() == EffectsView::INVALID_TYPE );
+  EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW );
+  DALI_TEST_CHECK( view );
 
-  view.SetType( EffectsView::DROP_SHADOW );
-  DALI_TEST_CHECK( view.GetType() == EffectsView::DROP_SHADOW );
+  Actor actor = Actor::New();
+  DALI_TEST_CHECK( !actor.OnStage() );
 
-  view.SetType( EffectsView::EMBOSS );
-  DALI_TEST_CHECK( view.GetType() == EffectsView::EMBOSS );
 
-  END_TEST;
-}
+  view.SetParentOrigin(ParentOrigin::CENTER);
+  view.SetSize(Stage::GetCurrent().GetSize());
+  view.Add(actor);
+  Stage::GetCurrent().Add(view);
 
-int UtcDaliEffectsViewSetTypeN(void)
-{
-  ToolkitTestApplication application;
+  DALI_TEST_CHECK( actor.OnStage() );
+  DALI_TEST_CHECK( actor.GetParent() );
+  DALI_TEST_CHECK( actor.GetParent() != view );
 
-  EffectsView view;
-  try
-  {
-    view.SetType( EffectsView::DROP_SHADOW );
-    DALI_TEST_CHECK( false ); // Should not get here
-  }
-  catch( ... )
-  {
-    DALI_TEST_CHECK( true );
-  }
+  view.Remove(actor);
 
+  DALI_TEST_CHECK( !actor.OnStage() );
   END_TEST;
 }
 
-int UtcDaliEffectsViewGetTypeN(void)
+int UtcDaliEffectsViewGetTypeP(void)
 {
   ToolkitTestApplication application;
 
-  EffectsView view;
-  try
-  {
-    EffectsView::EffectType type = view.GetType();
-    (void) type;
-    DALI_TEST_CHECK( false ); // Should not get here
-  }
-  catch( ... )
-  {
-    DALI_TEST_CHECK( true );
-  }
+  EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW );
+  DALI_TEST_CHECK( view.GetType() == EffectsView::DROP_SHADOW );
+
+  view.Reset();
+  view = EffectsView::New( EffectsView::EMBOSS );
+  DALI_TEST_CHECK( view.GetType() == EffectsView::EMBOSS );
 
   END_TEST;
 }
 
-int UtcDaliEffectsViewEnableP(void)
+int UtcDaliEffectsViewOnStage(void)
 {
   ToolkitTestApplication application;
 
-  EffectsView view = EffectsView::New();
+  EffectsView view = EffectsView::New(EffectsView::EMBOSS);
+  view.SetSize(100.f, 100.f);
   Stage stage = Stage::GetCurrent();
   DALI_TEST_CHECK( stage.GetRenderTaskList().GetTaskCount() == 1 );
 
-  view.Enable();
+  stage.Add( view );
+  application.SendNotification();
+  application.Render();
   DALI_TEST_CHECK( stage.GetRenderTaskList().GetTaskCount() > 1 );
 
   END_TEST;
 }
 
-int UtcDaliEffectsViewEnableN(void)
+int UtcDaliEffectsViewOffStage(void)
 {
   ToolkitTestApplication application;
 
-  EffectsView view;
-  try
-  {
-    view.Enable();
-    DALI_TEST_CHECK( false ); // Should not get here
-  }
-  catch( ... )
-  {
-    DALI_TEST_CHECK( true );
-  }
-
-  END_TEST;
-}
-
-int UtcDaliEffectsViewDisableP(void)
-{
-  ToolkitTestApplication application;
-
-  EffectsView view = EffectsView::New();
+  EffectsView view = EffectsView::New(EffectsView::DROP_SHADOW);
+  view.SetSize(100.f, 100.f);
   Stage stage = Stage::GetCurrent();
   DALI_TEST_CHECK( stage.GetRenderTaskList().GetTaskCount() == 1 );
 
-  view.Enable();
+  stage.Add( view );
+  application.SendNotification();
+  application.Render();
   DALI_TEST_CHECK( stage.GetRenderTaskList().GetTaskCount() > 1 );
 
-  view.Disable();
+  stage.Remove( view );
+  application.SendNotification();
+  application.Render();
   DALI_TEST_CHECK( stage.GetRenderTaskList().GetTaskCount() == 1 );
 
   END_TEST;
 }
 
-int UtcDaliEffectsViewDisableN(void)
-{
-  ToolkitTestApplication application;
-
-  EffectsView view;
-  try
-  {
-    view.Disable();
-    DALI_TEST_CHECK( false ); // Should not get here
-  }
-  catch( ... )
-  {
-    DALI_TEST_CHECK( true );
-  }
-
-  END_TEST;
-}
-
 int UtcDaliEffectsViewRefreshP(void)
 {
   ToolkitTestApplication application;
 
-  EffectsView view = EffectsView::New();
+  EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW );
   try
   {
     view.Refresh();
@@ -252,7 +217,7 @@ int UtcDaliEffectsViewSetPixelFormatP(void)
 {
   ToolkitTestApplication application;
 
-  EffectsView view = EffectsView::New();
+  EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW );
   try
   {
     view.SetPixelFormat( Pixel::RGBA8888 );
@@ -284,179 +249,90 @@ int UtcDaliEffectsViewSetPixelFormatN(void)
   END_TEST;
 }
 
-int UtcDaliEffectsViewSetGetOutputImage(void)
-{
-  ToolkitTestApplication application;
-
-  EffectsView view = EffectsView::New();
-  FrameBufferImage image = FrameBufferImage::New();
-  DALI_TEST_CHECK( image );
-
-  view.SetOutputImage( image );
-  DALI_TEST_CHECK( view.GetOutputImage() == image );
-
-  // Replace with another image
-  FrameBufferImage image2 = FrameBufferImage::New();
-  DALI_TEST_CHECK( image2 );
-  view.SetOutputImage( image2 );
-  DALI_TEST_CHECK( view.GetOutputImage() == image2 );
-
-  // Remove output image
-  view.SetOutputImage( FrameBufferImage() );
-  DALI_TEST_CHECK( ! view.GetOutputImage() );
-
-  END_TEST;
-}
-
-int UtcDaliEffectsViewSetOutputImageN(void)
-{
-  ToolkitTestApplication application;
-
-  EffectsView view;
-  try
-  {
-    view.SetOutputImage( FrameBufferImage::New() );
-    DALI_TEST_CHECK( false ); // Should not get here
-  }
-  catch( ... )
-  {
-    DALI_TEST_CHECK( true );
-  }
-
-  END_TEST;
-}
-
-int UtcDaliEffectsViewGetOutputImageN(void)
+int UtcDaliEffectsViewSizeProperty(void)
 {
   ToolkitTestApplication application;
 
-  EffectsView view;
-  try
-  {
-    FrameBufferImage image = view.GetOutputImage();
-    (void)image;
-    DALI_TEST_CHECK( false ); // Should not get here
-  }
-  catch( ... )
-  {
-    DALI_TEST_CHECK( true );
-  }
-
-  END_TEST;
-}
+  EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW );
 
-int UtcDaliEffectsViewGetEffectSizePropertyIndexP(void)
-{
-  ToolkitTestApplication application;
+  Property::Index idx = view.GetPropertyIndex( "effectSize" );
+  DALI_TEST_EQUALS( idx, (Property::Index)EffectsView::Property::EFFECT_SIZE, TEST_LOCATION );
 
-  EffectsView view = EffectsView::New();
-  DALI_TEST_CHECK( Property::INVALID_INDEX != view.GetEffectSizePropertyIndex() );
+  view.SetProperty( idx, 5 );
+  Property::Value value = view.GetProperty( EffectsView::Property::EFFECT_SIZE );
+  int size;
+  DALI_TEST_CHECK( value.Get(size) );
+  DALI_TEST_CHECK( size == 5 );
 
   END_TEST;
 }
 
-int UtcDaliEffectsViewGetEffectSizePropertyIndexN(void)
+int UtcDaliEffectsViewOffsetProperty(void)
 {
   ToolkitTestApplication application;
 
-  EffectsView view;
-  try
-  {
-    Property::Index index = view.GetEffectSizePropertyIndex();
-    (void)index;
-    DALI_TEST_CHECK( false ); // Should not get here
-  }
-  catch( ... )
-  {
-    DALI_TEST_CHECK( true );
-  }
-
-  END_TEST;
-}
-
-int UtcDaliEffectsViewGetEffectStrengthPropertyIndexP(void)
-{
-  ToolkitTestApplication application;
-
-  EffectsView view = EffectsView::New();
-  DALI_TEST_CHECK( Property::INVALID_INDEX != view.GetEffectStrengthPropertyIndex() );
-
-  END_TEST;
-}
-
-int UtcDaliEffectsViewGetEffectStrengthPropertyIndexN(void)
-{
-  ToolkitTestApplication application;
-
-  EffectsView view;
-  try
-  {
-    Property::Index index = view.GetEffectStrengthPropertyIndex();
-    (void)index;
-    DALI_TEST_CHECK( false ); // Should not get here
-  }
-  catch( ... )
-  {
-    DALI_TEST_CHECK( true );
-  }
-
-  END_TEST;
-}
-
-int UtcDaliEffectsViewGetEffectOffsetPropertyIndexP(void)
-{
-  ToolkitTestApplication application;
-
-  EffectsView view = EffectsView::New();
-  DALI_TEST_CHECK( Property::INVALID_INDEX != view.GetEffectOffsetPropertyIndex() );
+  EffectsView view = EffectsView::New( EffectsView::EMBOSS );
+  Stage::GetCurrent().Add( view );
 
-  END_TEST;
-}
+  Property::Value value = view.GetProperty( EffectsView::Property::EFFECT_OFFSET );
+  Vector3 offsetValue;
+  DALI_TEST_CHECK( value.Get(offsetValue) );
+  DALI_TEST_EQUALS( offsetValue, Vector3::ZERO, TEST_LOCATION );
 
-int UtcDaliEffectsViewGetEffectOffsetPropertyIndexN(void)
-{
-  ToolkitTestApplication application;
+  Vector3 offsetSet( 2.f, 3.f, 4.f );
+  view.SetProperty( EffectsView::Property::EFFECT_OFFSET, offsetSet);
+  application.SendNotification();
+  application.Render(0);
+  value = view.GetProperty( EffectsView::Property::EFFECT_OFFSET );
+  value.Get(offsetValue);
+  DALI_TEST_EQUALS( offsetValue, offsetSet, TEST_LOCATION );
+
+  Vector3 offsetAnimate( 4.f, 6.f, 8.f );
+  float durationSeconds(0.05f);
+  Animation animation = Animation::New( durationSeconds );
+  animation.AnimateTo( Property(view,EffectsView::Property::EFFECT_OFFSET ), offsetAnimate );
+  animation.Play();
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*1000.0f) + 1u/*just beyond the animation duration*/);
 
-  EffectsView view;
-  try
-  {
-    Property::Index index = view.GetEffectOffsetPropertyIndex();
-    (void)index;
-    DALI_TEST_CHECK( false ); // Should not get here
-  }
-  catch( ... )
-  {
-    DALI_TEST_CHECK( true );
-  }
+  value = view.GetProperty( EffectsView::Property::EFFECT_OFFSET );
+  value.Get(offsetValue);
+  DALI_TEST_EQUALS( offsetValue, offsetAnimate, TEST_LOCATION );
 
   END_TEST;
 }
 
-int UtcDaliEffectsViewGetEffectColorPropertyIndexP(void)
+int UtcDaliEffectsViewColorProperty(void)
 {
   ToolkitTestApplication application;
 
-  EffectsView view = EffectsView::New();
-  DALI_TEST_CHECK( Property::INVALID_INDEX != view.GetEffectColorPropertyIndex() );
+  EffectsView view = EffectsView::New( EffectsView::DROP_SHADOW );
+  Stage::GetCurrent().Add( view );
 
-  END_TEST;
-}
+  Property::Value value = view.GetProperty( EffectsView::Property::EFFECT_COLOR );
+  Vector4 colorValue;
+  DALI_TEST_CHECK( value.Get(colorValue) );
+  DALI_TEST_EQUALS( colorValue, Color::WHITE, TEST_LOCATION );
 
-int UtcDaliEffectsViewGetEffectColorPropertyIndexN(void)
-{
-  ToolkitTestApplication application;
+  Vector4 colorSet( 0.2f, 0.3f, 0.4f, 0.5f );
+  view.SetProperty( EffectsView::Property::EFFECT_COLOR, colorSet);
+  application.SendNotification();
+  application.Render(0);
+  value = view.GetProperty( EffectsView::Property::EFFECT_COLOR );
+  value.Get(colorValue);
+  DALI_TEST_EQUALS( colorValue, colorSet, TEST_LOCATION );
+
+  Vector4 colorAnimate( 0.5f, 0.6f, 0.8f, 1.f );
+  float durationSeconds(0.05f);
+  Animation animation = Animation::New( durationSeconds );
+  animation.AnimateTo( Property(view,EffectsView::Property::EFFECT_COLOR ), colorAnimate );
+  animation.Play();
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>(durationSeconds*1000.0f) + 1u/*just beyond the animation duration*/);
 
-  EffectsView view;
-  try
-  {
-    Property::Index index = view.GetEffectColorPropertyIndex();
-    (void)index;
-    DALI_TEST_CHECK( false ); // Should not get here
-  }
-  catch( ... )
-  {
-    DALI_TEST_CHECK( true );
-  }
+  value = view.GetProperty( EffectsView::Property::EFFECT_COLOR );
+  value.Get(colorValue);
+  DALI_TEST_EQUALS( colorValue, colorAnimate, TEST_LOCATION );
 
   END_TEST;
 }
@@ -465,7 +341,7 @@ int UtcDaliEffectsViewGetSetBackgroundColor(void)
 {
   ToolkitTestApplication application;
 
-  EffectsView view = EffectsView::New();
+  EffectsView view = EffectsView::New(EffectsView::DROP_SHADOW);
   view.SetBackgroundColor( Color::RED );
   DALI_TEST_CHECK( Color::RED == view.GetBackgroundColor() );
 
@@ -516,25 +392,22 @@ int UtcDaliEffectsViewSetRefreshOnDemandP(void)
 {
   ToolkitTestApplication application;
 
-  EffectsView view = EffectsView::New();
-  FrameBufferImage image = FrameBufferImage::New();
-  view.SetOutputImage( image );
-  view.Enable();
+  EffectsView view = EffectsView::New(EffectsView::DROP_SHADOW);
+  view.SetSize(100.f, 100.f);
 
   Stage stage = Stage::GetCurrent();
   stage.Add( view );
+  application.SendNotification();
+  application.Render();
 
   RenderTaskList renderTaskList = stage.GetRenderTaskList();
   DALI_TEST_CHECK( renderTaskList.GetTask( 1 ).GetRefreshRate() == RenderTask::REFRESH_ALWAYS );
-  DALI_TEST_CHECK( renderTaskList.GetTask( 2 ).GetRefreshRate() == RenderTask::REFRESH_ALWAYS );
 
   view.SetRefreshOnDemand( true );
   DALI_TEST_CHECK( renderTaskList.GetTask( 1 ).GetRefreshRate() == RenderTask::REFRESH_ONCE );
-  DALI_TEST_CHECK( renderTaskList.GetTask( 2 ).GetRefreshRate() == RenderTask::REFRESH_ONCE );
 
   view.SetRefreshOnDemand( false );
   DALI_TEST_CHECK( renderTaskList.GetTask( 1 ).GetRefreshRate() == RenderTask::REFRESH_ALWAYS );
-  DALI_TEST_CHECK( renderTaskList.GetTask( 2 ).GetRefreshRate() == RenderTask::REFRESH_ALWAYS );
 
   END_TEST;
 }
@@ -563,23 +436,16 @@ int UtcDaliEffectsViewSizeSet(void)
   Stage stage = Stage::GetCurrent();
 
   {
-    EffectsView view = EffectsView::New();
+    EffectsView view = EffectsView::New(EffectsView::DROP_SHADOW);
     view.SetSize( 200.0f, 200.0f, 0.0f );
     stage.Add( view );
-    view.Enable();
     application.SendNotification();
     application.Render();
-    view.Disable();
-    application.SendNotification();
-    application.Render();
-
     DALI_TEST_EQUALS( view.GetCurrentSize(), Vector3( 200.0f, 200.0f, 0.0f ), TEST_LOCATION );
   }
 
   {
-    EffectsView view = EffectsView::New();
-    view.SetOutputImage( FrameBufferImage::New( 200, 200 ) );
-    view.SetType( EffectsView::EMBOSS );
+    EffectsView view = EffectsView::New(EffectsView::EMBOSS);
     view.SetSize( 200.0f, 200.0f, 0.0f );
     stage.Add( view );
     application.SendNotification();
@@ -589,8 +455,7 @@ int UtcDaliEffectsViewSizeSet(void)
   }
 
   {
-    EffectsView view = EffectsView::New();
-    view.SetType( EffectsView::DROP_SHADOW );
+    EffectsView view = EffectsView::New(EffectsView::DROP_SHADOW);
     view.SetSize( 200.0f, 200.0f, 0.0f );
     stage.Add( view );
     application.SendNotification();
index cb6eefa..1142c4c 100644 (file)
@@ -21,6 +21,7 @@
 #include <sstream>
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali/integration-api/events/pan-gesture-event.h>
+#include <dali/public-api/images/buffer-image.h>
 #include <dali-toolkit/public-api/controls/page-turn-view/page-factory.h>
 #include <dali-toolkit/public-api/controls/page-turn-view/page-turn-landscape-view.h>
 #include <dali-toolkit/public-api/controls/page-turn-view/page-turn-portrait-view.h>
@@ -193,7 +194,6 @@ public:
   TestPageFactory(ToolkitTestApplication& application)
   : mApplication( application )
   {
-    mSourceActors.resize(TOTAL_PAGE_NUMBER);
     mTotalPageNumber = TOTAL_PAGE_NUMBER;
   }
 
@@ -207,40 +207,17 @@ public:
   }
 
   /**
-   * Create an image actor to represent a page.
+   * Create an image to represent a page content.
    * @param[in] pageId The ID of the page to create.
-   * @return An image actor, or an uninitialized pointer if the ID is out of range.
+   * @return An image, or an empty handle if the ID is out of range.
    */
-  virtual Actor NewPage( unsigned int pageId )
+  virtual Image NewPage( unsigned int pageId )
   {
-    if(!mSourceActors[pageId])
-    {
-      Actor actor = CreateSolidColorImageActor(mApplication, Color::BLUE,IMAGE_WIDTH,IMAGE_HEIGHT);
-      actor.SetName( static_cast<std::ostringstream*>( &(std::ostringstream() << pageId) )->str()  );
-
-      actor.SetParentOrigin( ParentOrigin::CENTER );
-      actor.SetAnchorPoint( AnchorPoint::CENTER );
-
-      ImageActor backPageActor = CreateSolidColorImageActor(mApplication, Color::BLUE,IMAGE_WIDTH,IMAGE_HEIGHT);
-      backPageActor.SetParentOrigin( ParentOrigin::CENTER );
-      backPageActor.SetAnchorPoint( AnchorPoint::CENTER );
-      actor.Add( backPageActor );
-
-      mSourceActors[pageId] = actor;
-    }
-
-    return mSourceActors[pageId];
-  }
-
-  void DeletePage( unsigned int pageId )
-  {
-    mSourceActors.erase( mSourceActors.begin() + pageId );
-    mTotalPageNumber--;
+    return BufferImage::WHITE();
   }
 
 private:
   ToolkitTestApplication& mApplication;
-  std::vector<Actor>      mSourceActors;
   unsigned int            mTotalPageNumber;
 };
 
@@ -706,3 +683,11 @@ int UtcDaliPageTurnLanscapeViewSignals(void)
   DALI_TEST_EQUALS( landscapeView.GetProperty(PageTurnView::Property::CURRENT_PAGE_ID).Get<int>(), 0, TEST_LOCATION );
   END_TEST;
 }
+
+int UtcDaliPageImageFactoryGetExtention(void)
+{
+  ToolkitTestApplication application;
+  TestPageFactory factory(application);
+  DALI_TEST_CHECK( factory.GetExtension() == NULL );
+  END_TEST;
+}
index d1757d7..2abab5a 100644 (file)
@@ -27,9 +27,11 @@ namespace Dali
 namespace Toolkit
 {
 
-EffectsView EffectsView::New()
+EffectsView EffectsView::New( EffectType type )
 {
-  return Internal::EffectsView::New();
+  EffectsView effectsView = Internal::EffectsView::New();
+  GetImpl(effectsView).SetType( type );
+  return effectsView;
 }
 
 EffectsView::EffectsView()
@@ -59,26 +61,11 @@ EffectsView::~EffectsView()
 {
 }
 
-void EffectsView::SetType( EffectsView::EffectType type )
-{
-  GetImpl(*this).SetType( type );
-}
-
 EffectsView::EffectType EffectsView::GetType() const
 {
   return GetImpl(*this).GetType();
 }
 
-void EffectsView::Enable()
-{
-  GetImpl(*this).Enable();
-}
-
-void EffectsView::Disable()
-{
-  GetImpl(*this).Disable();
-}
-
 void EffectsView::Refresh()
 {
   GetImpl(*this).Refresh();
@@ -94,36 +81,6 @@ void EffectsView::SetPixelFormat( Pixel::Format pixelFormat )
   GetImpl(*this).SetPixelFormat( pixelFormat );
 }
 
-void EffectsView::SetOutputImage( FrameBufferImage image )
-{
-  GetImpl(*this).SetOutputImage( image );
-}
-
-FrameBufferImage EffectsView::GetOutputImage()
-{
-  return GetImpl(*this).GetOutputImage();
-}
-
-Property::Index EffectsView::GetEffectSizePropertyIndex() const
-{
-  return GetImpl(*this).GetEffectSizePropertyIndex();
-}
-
-Property::Index EffectsView::GetEffectStrengthPropertyIndex() const
-{
-  return GetImpl(*this).GetEffectStrengthPropertyIndex();
-}
-
-Property::Index EffectsView::GetEffectOffsetPropertyIndex() const
-{
-  return GetImpl(*this).GetEffectOffsetPropertyIndex();
-}
-
-Property::Index EffectsView::GetEffectColorPropertyIndex() const
-{
-  return GetImpl(*this).GetEffectColorPropertyIndex();
-}
-
 void EffectsView::SetBackgroundColor( const Vector4& color )
 {
   GetImpl(*this).SetBackgroundColor(color);
index 2255e1f..b734b41 100644 (file)
@@ -42,7 +42,7 @@ class EffectsView;
  *
  * Example usage: Applying an emboss effect
  * ...
- * EffectsView effectsView = EffectsView::New();
+ * EffectsView effectsView = EffectsView::New( Toolkit::EffectsView::EMBOSS );
  *
  * // set position and format
  * effectsView.SetParentOrigin( ParentOrigin::CENTER );
@@ -50,22 +50,15 @@ class EffectsView;
  * effectsView.SetPixelFormat( Pixel::RGBA8888 );
  *
  * // set effect type and properties
- * effectsView.SetType( Toolkit::EffectsView::EMBOSS );
  * effectsView.SetProperty( effectsView.GetEffectSizePropertyIndex(), static_cast< float >( shadowSize ) );
  * effectsView.SetProperty( effectsView.GetEffectOffsetPropertyIndex(), Vector3( shadowDistance.x, shadowDistance.y, 0.0f ) );
  * effectsView.SetProperty( effectsView.GetEffectColorPropertyIndex(), shadowColor );
  *
- * // Render result to an offscreen
- * effectsView.SetOutputImage( image );
- *
  * // Render once
  * effectsView.SetRefreshOnDemand( true );
  *
  * // optionally set a clear color
  * effectsView.SetBackgroundColor( Vector4( 0.0f, 0.0f, 0.0f, 0.0f ) );
- *
- * // start effect processing
- * effectsView.Enable();
  */
 class DALI_IMPORT_API EffectsView : public Control
 {
@@ -78,12 +71,42 @@ public:
     INVALID_TYPE
   };
 
+  /**
+   * @brief The start and end property ranges for this control.
+   */
+  enum PropertyRange
+  {
+    PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,  ///< @SINCE_1_0.0
+    PROPERTY_END_INDEX =   PROPERTY_START_INDEX + 1000,              ///< Reserve property indices @SINCE_1_0.0
+
+    ANIMATABLE_PROPERTY_START_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX,        ///< @SINCE_1_1.18
+    ANIMATABLE_PROPERTY_END_INDEX =   ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 1000  ///< Reserve animatable property indices, @SINCE_1_1.18
+  };
+
+  /**
+   * @brief An enumeration of properties belonging to the EffectsView class.
+   */
+  struct Property
+  {
+    enum
+    {
+      // Event side properties
+      EFFECT_SIZE = PROPERTY_START_INDEX,              ///< name "effectSize", type INTEGER
+
+      // Animatable properties
+      EFFECT_OFFSET = ANIMATABLE_PROPERTY_START_INDEX, ///< name "effectOffset", type VECTOR3
+      EFFECT_COLOR,                                    ///< name "effectColor", type VECTOR4
+    };
+  };
+
 public:
 
   /**
    * Create an EffectsView object with default configuration
+   * @param[in] type The type of effect to be performed by the EffectView.
+   *                 A member of the EffectType enumeration.
    */
-  static EffectsView New();
+  static EffectsView New( EffectType type );
 
   /**
    * Create an uninitialized EffectsView. Only derived versions can be instantiated.
@@ -119,29 +142,12 @@ public:
 public:
 
   /**
-   * Set the effect type
-   * @param[in] type The type of effect to be performed by the EffectView.
-   *                 A member of the EffectType enumeration.
-   */
-  void SetType( EffectType type );
-
-  /**
    * Get the effect type
    * @return The type of effect performed by the EffectView. A member of the EffectType enumeration.
    */
   EffectType GetType() const;
 
   /**
-   * Enable the effect
-   */
-  void Enable();
-
-  /**
-   * Disable the effect
-   */
-  void Disable();
-
-  /**
    * Refresh/Redraw the effect
    */
   void Refresh();
@@ -160,42 +166,6 @@ public:
    void SetPixelFormat( Pixel::Format pixelFormat );
 
    /**
-    * Set the FrameBufferImage that will receive the final output of the EffectsView.
-    * @param[in] image User supplied FrameBufferImage that will receive the final output of the EffectsView.
-    */
-   void SetOutputImage( FrameBufferImage image );
-
-   /**
-    * Get the FrameBufferImage that holds the final output of the EffectsView.
-    * @return The FrameBufferImage that holds the final output of the EffectsView.
-    */
-   FrameBufferImage GetOutputImage();
-
-   /**
-    * Get the property index to the effect size
-    * @return The property index to the effect size
-    */
-   Dali::Property::Index GetEffectSizePropertyIndex() const;
-
-   /**
-    * Get the property index to the effect strength
-    * @return The property index to the effect strength
-    */
-   Dali::Property::Index GetEffectStrengthPropertyIndex() const;
-
-   /**
-    * Get the property index to the Vector3 specifying the effect offset (eg drop shadow offset)
-    * @return The property index to the Vector3 specifying the effect offset
-    */
-   Dali::Property::Index GetEffectOffsetPropertyIndex() const;
-
-   /**
-    * Get the property index to the effect color (eg shadow color)
-    * @return The property index to the effect color
-    */
-   Dali::Property::Index GetEffectColorPropertyIndex() const;
-
-   /**
     * Set background color for the view. The background will be filled with this color.
     * @param[in] color The background color.
     */
index 4d088d1..474a16e 100644 (file)
@@ -290,6 +290,8 @@ void BloomView::OnInitialize()
 
 void BloomView::OnSizeSet(const Vector3& targetSize)
 {
+  Control::OnSizeSet( targetSize );
+
   mTargetSize = Vector2(targetSize);
   mChildrenRoot.SetSize(targetSize);
   mCompositeImageActor.SetSize(targetSize);
@@ -313,17 +315,21 @@ void BloomView::OnSizeSet(const Vector3& targetSize)
   }
 }
 
-void BloomView::OnControlChildAdd( Actor& child )
+void BloomView::OnChildAdd( Actor& child )
 {
+  Control::OnChildAdd( child );
+
   if( child != mChildrenRoot && child != mInternalRoot)
   {
     mChildrenRoot.Add( child );
   }
 }
 
-void BloomView::OnControlChildRemove( Actor& child )
+void BloomView::OnChildRemove( Actor& child )
 {
   mChildrenRoot.Remove( child );
+
+  Control::OnChildRemove( child );
 }
 
 void BloomView::AllocateResources()
index ea3f7e5..14e1d3c 100644 (file)
@@ -85,14 +85,14 @@ private:
   virtual void OnSizeSet(const Vector3& targetSize);
 
   /**
-   * @copydoc Control::OnControlChildAdd()
+   * @copydoc Control::OnChildAdd()
    */
-  virtual void OnControlChildAdd( Actor& child );
+  virtual void OnChildAdd( Actor& child );
 
   /**
-   * @copydoc Control::OnControlChildRemove()
+   * @copydoc Control::OnChildRemove()
    */
-  virtual void OnControlChildRemove( Actor& child );
+  virtual void OnChildRemove( Actor& child );
 
   void AllocateResources();
   void CreateRenderTasks();
index 3132b20..6df5fcf 100644 (file)
@@ -823,22 +823,6 @@ bool Button::DoClickAction( const Property::Map& attributes )
   return false;
 }
 
-void Button::OnButtonStageDisconnection()
-{
-  if( ButtonDown == mState )
-  {
-    if( !mTogglableButton )
-    {
-      Released();
-
-      if( mAutoRepeating )
-      {
-        mAutoRepeatingTimer.Reset();
-      }
-    }
-  }
-}
-
 void Button::OnButtonDown()
 {
   if( !mTogglableButton )
@@ -1030,8 +1014,6 @@ void Button::OnInitialize()
   mTapDetector.Attach( self );
   mTapDetector.DetectedSignal().Connect(this, &Button::OnTap);
 
-  OnButtonInitialize();
-
   self.SetKeyboardFocusable( true );
 }
 
@@ -1049,10 +1031,24 @@ bool Button::OnKeyboardEnter()
   return ret;
 }
 
-void Button::OnControlStageDisconnection()
+void Button::OnStageDisconnection()
 {
-  OnButtonStageDisconnection(); // Notification for derived classes.
+  if( ButtonDown == mState )
+  {
+    if( !mTogglableButton )
+    {
+      Released();
+
+      if( mAutoRepeating )
+      {
+        mAutoRepeatingTimer.Reset();
+      }
+    }
+  }
+
   mState = ButtonUp;
+
+  Control::OnStageDisconnection();
 }
 
 void Button::OnTap(Actor actor, const TapGesture& tap)
index 7adb67c..6f1e313 100644 (file)
@@ -335,12 +335,6 @@ private:
   bool DoClickAction( const Property::Map& attributes );
 
   /**
-   * This method is called after the button initialization.
-   * Could be reimplemented in subclasses to provide specific behaviour.
-   */
-  virtual void OnButtonInitialize() { }
-
-  /**
    * This method is called when the label is set.
    * @param[in] noPadding Used to bypass padding if the label is to be treated generically.
    */
@@ -407,12 +401,6 @@ private:
   virtual void OnTouchPointInterrupted();
 
   /**
-   * This method is called when the button is removed from the stage.
-   * Could be reimplemented in subclasses to provide specific behaviour.
-   */
-  virtual void OnButtonStageDisconnection();
-
-  /**
    * This method is called when the \e selected property is changed.
    */
   virtual void OnSelected() {}
@@ -483,17 +471,16 @@ public:
    */
   static Property::Value GetProperty( BaseObject* object, Property::Index propertyIndex );
 
-protected: // From CustomActorImpl
+protected: // From Control
 
   /**
-   * @copydoc Dali::CustomActorImpl::OnTouchEvent( const TouchEvent& event )
+   * @copydoc Dali::Control::OnTouchEvent( const TouchEvent& event )
    */
   virtual bool OnTouchEvent( const TouchEvent& event );
 
-private: // From Control
-
   /**
    * @copydoc Toolkit::Control::OnInitialize()
+   * @note If overridden by deriving button classes, then an up-call to Button::OnInitialize MUST be made at the start.
    */
   virtual void OnInitialize();
 
@@ -508,10 +495,10 @@ private: // From Control
   virtual bool OnKeyboardEnter();
 
   /**
-   * Callback received when the button is disconnected from the stage.
-   * It resets the button status.
+   * @copydoc Toolkit::Control::OnStageDisconnection()
+   * @note If overridden by deriving button classes, then an up-call to Button::OnStageDisconnection MUST be made at the end.
    */
-  void OnControlStageDisconnection();
+  void OnStageDisconnection();
 
 private:
 
index 79ef935..6607c5c 100644 (file)
@@ -97,8 +97,10 @@ void CheckBoxButton::SetTickUVEffect()
   }
 }
 
-void CheckBoxButton::OnButtonInitialize()
+void CheckBoxButton::OnInitialize()
 {
+  Button::OnInitialize();
+
   // Wrap around all children
   Self().SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
 
index e80b838..7e9d314 100644 (file)
@@ -73,9 +73,9 @@ private: // From Button
 
 
   /**
-   * @copydoc Toolkit::Internal::Button::OnButtonInitialize
+   * @copydoc Toolkit::Internal::Button::OnInitialize
    */
-  virtual void OnButtonInitialize();
+  virtual void OnInitialize();
 
   /**
    * @copydoc Toolkit::Internal::Button::OnLabelSet
index 50d85e5..9a47206 100644 (file)
@@ -127,8 +127,10 @@ PushButton::~PushButton()
 {
 }
 
-void PushButton::OnButtonInitialize()
+void PushButton::OnInitialize()
 {
+  Button::OnInitialize();
+
   // Push button requires the Leave event.
   Actor self = Self();
   self.SetLeaveRequired( true );
index 44e447c..a003e6d 100644 (file)
@@ -96,9 +96,9 @@ public:
 private: // From Button
 
   /**
-   * @copydoc Toolkit::Internal::Button::OnButtonInitialize
+   * @copydoc Toolkit::Internal::Button::OnInitialize
    */
-  virtual void OnButtonInitialize();
+  virtual void OnInitialize();
 
   /**
    * @copydoc Toolkit::Internal::Button::OnLabelSet
index e980ec9..142dba1 100644 (file)
@@ -74,8 +74,10 @@ RadioButton::~RadioButton()
 {
 }
 
-void RadioButton::OnButtonInitialize()
+void RadioButton::OnInitialize()
 {
+  Button::OnInitialize();
+
   Actor self = Self();
 
   // Wrap size of radio button around all its children
index 34130ae..630e1a3 100644 (file)
@@ -64,9 +64,9 @@ private:
 private: // From Button
 
   /**
-   * @copydoc Toolkit::Internal::Button::OnButtonInitialize
+   * @copydoc Toolkit::Internal::Button::OnInitialize
    */
-  virtual void OnButtonInitialize();
+  virtual void OnInitialize();
 
   /**
    * @copydoc Toolkit::Internal::Button::OnButtonUp
index 8d1a3b3..d65b8fd 100644 (file)
 #include <dali/public-api/animation/constraint.h>
 #include <dali/public-api/animation/constraints.h>
 #include <dali/public-api/common/stage.h>
+#include <dali/public-api/object/property-map.h>
 #include <dali/public-api/object/type-registry.h>
 #include <dali/devel-api/object/type-registry-helper.h>
 #include <dali/public-api/render-tasks/render-task-list.h>
 
 // INTERNAL INCLUDES
-#include "../../filters/blur-two-pass-filter.h"
-#include "../../filters/emboss-filter.h"
-#include "../../filters/spread-filter.h"
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/internal/filters/blur-two-pass-filter.h>
+#include <dali-toolkit/internal/filters/emboss-filter.h>
+#include <dali-toolkit/internal/filters/spread-filter.h>
 
 namespace Dali
 {
@@ -45,10 +47,13 @@ namespace
 
 Dali::BaseHandle Create()
 {
-  return Toolkit::EffectsView::New();
+  return EffectsView::New();
 }
 
 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::EffectsView, Toolkit::Control, Create )
+DALI_PROPERTY_REGISTRATION( Toolkit, EffectsView, "effectSize", INTEGER, EFFECT_SIZE )
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, EffectsView, "effectOffset", VECTOR3, EFFECT_OFFSET )
+DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, EffectsView, "effectColor", Color::WHITE, EFFECT_COLOR )
 DALI_TYPE_REGISTRATION_END()
 
 const Pixel::Format EFFECTS_VIEW_DEFAULT_PIXEL_FORMAT = Pixel::RGBA8888;
@@ -56,23 +61,36 @@ const float         ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f;
 const Vector4       EFFECTS_VIEW_DEFAULT_BACKGROUND_COLOR( 1.0f, 1.0f, 1.0f, 0.0 );
 const bool          EFFECTS_VIEW_REFRESH_ON_DEMAND(false);
 
-// Custom properties
-const char* const   EFFECT_SIZE_PROPERTY_NAME = "EffectSize";
-const char* const   EFFECT_STRENGTH_PROPERTY_NAME = "EffectStrength";
-const char* const   EFFECT_OFFSET_PROPERTY_NAME = "EffectOffset";
-const char* const   EFFECT_COLOR_PROPERTY_NAME = "EffectColor";
-
-const float         EFFECT_SIZE_DEFAULT( 1.0f );
-const float         EFFECT_STRENGTH_DEFAULT( 0.5f );
-const Vector3       EFFECT_OFFSET_DEFAULT( 0.0f, 0.0f, 0.0f );
-const Vector4       EFFECT_COLOR_DEFAULT( Color::WHITE );
-
-const char* const EFFECTS_VIEW_FRAGMENT_SOURCE =
-    "void main()\n"
-    "{\n"
-    "  gl_FragColor = uColor;\n"
-    "  gl_FragColor.a *= texture2D( sTexture, vTexCoord).a;\n"
-    "}\n";
+const char* EFFECTS_VIEW_VERTEX_SOURCE = DALI_COMPOSE_SHADER(
+  attribute mediump vec2 aPosition;\n
+  varying mediump vec2 vTexCoord;\n
+  uniform mediump mat4 uMvpMatrix;\n
+  uniform mediump vec3 uSize;\n
+  uniform mediump vec3 effectOffset;\n
+  \n
+  void main()\n
+  {\n
+    mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
+    vertexPosition.xyz *= uSize;\n
+    vertexPosition.xyz += effectOffset;\n
+    vertexPosition = uMvpMatrix * vertexPosition;\n
+    \n
+    vTexCoord = aPosition + vec2(0.5);\n
+    gl_Position = vertexPosition;\n
+  }\n
+);
+
+const char* EFFECTS_VIEW_FRAGMENT_SOURCE = DALI_COMPOSE_SHADER(
+  varying mediump vec2 vTexCoord;\n
+  uniform sampler2D sTexture;\n
+  uniform lowp vec4 effectColor;\n
+  \n
+  void main()\n
+  {\n
+     gl_FragColor = effectColor;\n
+     gl_FragColor.a *= texture2D( sTexture, vTexCoord).a;\n
+  }\n
+);
 
 const float BLUR_KERNEL0[] = { 12.0f/16.0f,
                                2.0f/16.0f, 2.0f/16.0f };
@@ -113,17 +131,15 @@ Toolkit::EffectsView EffectsView::New()
 
 EffectsView::EffectsView()
 : Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ),
-  mEffectType( Toolkit::EffectsView::INVALID_TYPE ),
-  mPixelFormat( EFFECTS_VIEW_DEFAULT_PIXEL_FORMAT ),
-  mSpread(0.0f),
+  mChildrenRoot(Actor::New()),
   mBackgroundColor( EFFECTS_VIEW_DEFAULT_BACKGROUND_COLOR ),
   mTargetSize( Vector2::ZERO ),
   mLastSize( Vector2::ZERO ),
-  mRefreshOnDemand(EFFECTS_VIEW_REFRESH_ON_DEMAND),
-  mEffectSizePropertyIndex(Property::INVALID_INDEX),
-  mEffectStrengthPropertyIndex(Property::INVALID_INDEX),
-  mEffectOffsetPropertyIndex(Property::INVALID_INDEX),
-  mEffectColorPropertyIndex(Property::INVALID_INDEX)
+  mEffectSize(0),
+  mEffectType( Toolkit::EffectsView::INVALID_TYPE ),
+  mPixelFormat( EFFECTS_VIEW_DEFAULT_PIXEL_FORMAT ),
+  mEnabled( false ),
+  mRefreshOnDemand(EFFECTS_VIEW_REFRESH_ON_DEMAND)
 {
 }
 
@@ -136,24 +152,25 @@ void EffectsView::SetType( Toolkit::EffectsView::EffectType type )
 {
   if( mEffectType != type )
   {
-    mEffectType = type;
-
     RemoveFilters();
 
-    switch( mEffectType )
+    Actor self = Self();
+    Property::Map rendererMap;
+    rendererMap.Insert( "rendererType", "image" );
+
+    switch( type )
     {
       case Toolkit::EffectsView::DROP_SHADOW:
       {
-        mFilters.push_back( new SpreadFilter );
-        mFilters.push_back( new BlurTwoPassFilter );
+        mFilters.PushBack( new SpreadFilter );
+        mFilters.PushBack( new BlurTwoPassFilter );
         break;
       }
       case Toolkit::EffectsView::EMBOSS:
       {
-        mFilters.push_back( new SpreadFilter );
-        mFilters.push_back( new EmbossFilter );
-        mFilters.push_back( new BlurTwoPassFilter );
-        mActorPostFilter.RemoveShaderEffect();
+        mFilters.PushBack( new SpreadFilter );
+        mFilters.PushBack( new EmbossFilter );
+        mFilters.PushBack( new BlurTwoPassFilter );
         break;
       }
       default:
@@ -161,6 +178,14 @@ void EffectsView::SetType( Toolkit::EffectsView::EffectType type )
         break;
       }
     }
+
+    Property::Map customShader;
+    customShader[ "vertexShader" ] = EFFECTS_VIEW_VERTEX_SOURCE;
+    customShader[ "fragmentShader" ] = EFFECTS_VIEW_FRAGMENT_SOURCE;
+    rendererMap[ "shader" ] = customShader;
+    Toolkit::RendererFactory::Get().ResetRenderer( mRendererPostFilter, self, rendererMap );
+
+    mEffectType = type;
   }
 }
 
@@ -174,6 +199,7 @@ void EffectsView::Enable()
   // make sure resources are allocated and start the render tasks processing
   AllocateResources();
   CreateRenderTasks();
+  mEnabled = true;
 }
 
 void EffectsView::Disable()
@@ -181,6 +207,7 @@ void EffectsView::Disable()
   // stop render tasks processing
   // Note: render target resources are automatically freed since we set the Image::Unused flag
   RemoveRenderTasks();
+  mEnabled = false;
 }
 
 void EffectsView::Refresh()
@@ -200,176 +227,128 @@ void EffectsView::SetPixelFormat( Pixel::Format pixelFormat )
   mPixelFormat = pixelFormat;
 }
 
-void EffectsView::SetOutputImage( FrameBufferImage image )
-{
-  CustomActor self = Self();
-
-  if( mImageForResult != image )
-  {
-    if( !image )
-    {
-      if( mImageForResult )
-      {
-        self.Remove( mActorForResult );
-        mActorForResult.Reset();
-
-        self.Add( mActorPostFilter );
-        self.Add( mActorForChildren );
-      }
-    }
-    else
-    {
-      if( mImageForResult )
-      {
-        self.Remove( mActorForResult );
-      }
-      mActorForResult = Actor::New();
-      mActorForResult.SetParentOrigin( ParentOrigin::CENTER );
-      mActorForResult.SetSize( mTargetSize );
-      mActorForResult.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
-
-      Self().Add( mActorForResult );
-      mActorForResult.Add( mActorPostFilter );
-      mActorForResult.Add( mActorForChildren );
-    }
-    mImageForResult = image;
-  }
-}
-
-FrameBufferImage EffectsView::GetOutputImage()
-{
-  return mImageForResult;
-}
-
-Property::Index EffectsView::GetEffectSizePropertyIndex() const
-{
-  return mEffectSizePropertyIndex;
-}
-
-Property::Index EffectsView::GetEffectStrengthPropertyIndex() const
-{
-  return mEffectStrengthPropertyIndex;
-}
-
-Property::Index EffectsView::GetEffectOffsetPropertyIndex() const
+void EffectsView::SetBackgroundColor( const Vector4& color )
 {
-  return mEffectOffsetPropertyIndex;
+  mBackgroundColor = color;
 }
 
-Property::Index EffectsView::GetEffectColorPropertyIndex() const
+Vector4 EffectsView::GetBackgroundColor() const
 {
-  return mEffectColorPropertyIndex;
+  return mBackgroundColor;
 }
 
-void EffectsView::SetupProperties()
+void EffectsView::SetEffectSize( int effectSize )
 {
-  CustomActor self = Self();
+  mEffectSize = effectSize;
 
-  // Register a property that the user can control the drop shadow offset
-  mEffectSizePropertyIndex     = self.RegisterProperty(EFFECT_SIZE_PROPERTY_NAME, EFFECT_SIZE_DEFAULT, Property::READ_WRITE);
-  mEffectStrengthPropertyIndex = self.RegisterProperty(EFFECT_STRENGTH_PROPERTY_NAME, EFFECT_STRENGTH_DEFAULT, Property::READ_WRITE);
-  mEffectOffsetPropertyIndex   = self.RegisterProperty(EFFECT_OFFSET_PROPERTY_NAME, EFFECT_OFFSET_DEFAULT);
-  mEffectColorPropertyIndex    = self.RegisterProperty(EFFECT_COLOR_PROPERTY_NAME, EFFECT_COLOR_DEFAULT);
-
-  Constraint positionConstraint = Constraint::New<Vector3>( mActorPostFilter, Actor::Property::POSITION, EqualToConstraint() );
-  positionConstraint.AddSource( Source( self, mEffectOffsetPropertyIndex ) );
-  positionConstraint.Apply();
+  if( mEnabled )
+  {
+    const size_t numFilters( mFilters.Size() );
+    for( size_t i = 0; i < numFilters; ++i )
+    {
+      mFilters[i]->Disable();
+    }
 
-  Constraint colorConstraint = Constraint::New<Vector4>( mActorPostFilter, Actor::Property::COLOR, EqualToConstraint() );
-  colorConstraint.AddSource( Source( self, mEffectColorPropertyIndex ) );
-  colorConstraint.Apply();
-}
+    SetupFilters();
 
-void EffectsView::SetBackgroundColor( const Vector4& color )
-{
-  mBackgroundColor = color;
+    for( size_t i = 0; i < numFilters; ++i )
+    {
+      mFilters[i]->Enable();
+    }
+  }
 }
 
-Vector4 EffectsView::GetBackgroundColor() const
+int EffectsView::GetEffectSize()
 {
-  return mBackgroundColor;
+  return mEffectSize;
 }
 
 // From Control
 void EffectsView::OnInitialize()
 {
-  //////////////////////////////////////////////////////
-  // Create cameras
-  mCameraForChildren = CameraActor::New();
-  mCameraForChildren.SetParentOrigin(ParentOrigin::CENTER);
-
-  mActorForChildren = ImageActor::New();
-  mActorForChildren.SetParentOrigin( ParentOrigin::CENTER );
-  mActorForChildren.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
-
-  mActorPostFilter = ImageActor::New();
-  mActorPostFilter.SetParentOrigin( ParentOrigin::CENTER );
-  mActorPostFilter.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
-  mActorPostFilter.SetShaderEffect( ShaderEffect::New( "", EFFECTS_VIEW_FRAGMENT_SOURCE ) );
-
-  // Connect to actor tree
-  Self().Add( mActorPostFilter );
-  Self().Add( mActorForChildren );
-  Self().Add( mCameraForChildren );
-
-  SetupProperties();
+  CustomActor self = Self();
+  mChildrenRoot.SetParentOrigin( ParentOrigin::CENTER );
+  self.Add( mChildrenRoot );
 }
 
 void EffectsView::OnSizeSet(const Vector3& targetSize)
 {
+  Control::OnSizeSet( targetSize );
+
   mTargetSize = Vector2(targetSize);
 
   // if we are already on stage, need to update render target sizes now to reflect the new size of this actor
-  if(Self().OnStage())
+  if(mEnabled)
   {
-    AllocateResources();
+    if( mLastSize != Vector2::ZERO )
+    {
+      Disable();
+    }
+    Enable();
   }
 
-  if( mActorForResult )
+  mChildrenRoot.SetSize( targetSize );
+}
+
+void EffectsView::OnStageConnection( int depth )
+{
+  Control::OnStageConnection( depth );
+
+  Enable();
+
+  Actor self = Self();
+  if( mRendererPostFilter )
   {
-    mActorForResult.SetSize( targetSize );
+    mRendererPostFilter.SetOnStage( self );
   }
-  if( mActorForChildren )
+  if( mRendererForChildren )
   {
-    mActorForChildren.SetSize( targetSize );
+    mRendererForChildren.SetOnStage( self );
   }
-  if( mActorPostFilter )
+}
+
+void EffectsView::OnStageDisconnection()
+{
+  Disable();
+
+  const size_t numFilters( mFilters.Size() );
+  for( size_t i = 0; i < numFilters; ++i )
   {
-    mActorPostFilter.SetSize( targetSize );
+    mFilters[i]->Disable();
   }
 
-  // Children render camera must move when EffectsView object is resized.
-  // This is since we cannot change render target size - so we need to remap the child actors' rendering
-  // accordingly so they still exactly fill the render target.
-  // Note that this means the effective resolution of the child render changes as the EffectsView object
-  // changes size, this is the trade off for not being able to modify render target size
-  // Change camera z position based on EffectsView actor height
-  if( mCameraForChildren )
+  Actor self = Self();
+  if( mRendererPostFilter )
   {
-    const float cameraPosScale( 0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f) );
-    mCameraForChildren.SetZ( targetSize.height * cameraPosScale );
+    mRendererPostFilter.SetOffStage( self );
   }
-
-  const size_t numFilters( mFilters.size() );
-  for( size_t i = 0; i < numFilters; ++i )
+  if( mRendererForChildren )
   {
-    mFilters[i]->SetSize( mTargetSize );
+    mRendererForChildren.SetOffStage( self );
   }
 
+  Control::OnStageDisconnection();
 }
 
-void EffectsView::OnStageDisconnection()
+void EffectsView::OnChildAdd( Actor& child )
 {
-  const size_t numFilters( mFilters.size() );
-  for( size_t i = 0; i < numFilters; ++i )
+  Control::OnChildAdd( child );
+
+  if( child != mChildrenRoot && child != mCameraForChildren )
   {
-    mFilters[i]->Disable();
+    mChildrenRoot.Add( child );
   }
 }
 
+void EffectsView::OnChildRemove( Actor& child )
+{
+  mChildrenRoot.Remove( child );
+
+  Control::OnChildRemove( child );
+}
+
 void EffectsView::SetupFilters()
 {
-  int effectSize = static_cast< int >( Self().GetProperty( mEffectSizePropertyIndex ).Get<float>() );
   switch( mEffectType )
   {
     case Toolkit::EffectsView::DROP_SHADOW:
@@ -377,23 +356,23 @@ void EffectsView::SetupFilters()
       SpreadFilter* spreadFilter = static_cast< SpreadFilter* >( mFilters[0] );
       spreadFilter->SetInputImage( mImageForChildren );
       spreadFilter->SetOutputImage( mImagePostFilter );
-      spreadFilter->SetRootActor( Self() );
+      spreadFilter->SetRootActor( mChildrenRoot );
       spreadFilter->SetBackgroundColor( mBackgroundColor );
       spreadFilter->SetPixelFormat( mPixelFormat );
       spreadFilter->SetSize( mTargetSize );
-      spreadFilter->SetSpread( effectSize );
+      spreadFilter->SetSpread( mEffectSize );
 
       BlurTwoPassFilter* blurFilter = static_cast< BlurTwoPassFilter* >( mFilters[1] );
       blurFilter->SetInputImage( mImagePostFilter );
       blurFilter->SetOutputImage( mImagePostFilter );
-      blurFilter->SetRootActor( Self() );
+      blurFilter->SetRootActor( mChildrenRoot );
       blurFilter->SetBackgroundColor( mBackgroundColor );
       blurFilter->SetPixelFormat( mPixelFormat );
       blurFilter->SetSize( mTargetSize );
 
       const float* kernel(NULL);
       size_t kernelSize(0);
-      switch( effectSize )
+      switch( mEffectSize )
       {
         case 4:  {  kernel = BLUR_KERNEL4; kernelSize = sizeof(BLUR_KERNEL4)/sizeof(BLUR_KERNEL4[0]); break; }
         case 3:  {  kernel = BLUR_KERNEL3; kernelSize = sizeof(BLUR_KERNEL3)/sizeof(BLUR_KERNEL3[0]); break; }
@@ -410,16 +389,16 @@ void EffectsView::SetupFilters()
       SpreadFilter* spreadFilter = static_cast< SpreadFilter* >( mFilters[0] );
       spreadFilter->SetInputImage( mImageForChildren );
       spreadFilter->SetOutputImage( mImagePostFilter );
-      spreadFilter->SetRootActor( Self() );
+      spreadFilter->SetRootActor( mChildrenRoot );
       spreadFilter->SetBackgroundColor( mBackgroundColor );
       spreadFilter->SetPixelFormat( Pixel::RGBA8888 );
       spreadFilter->SetSize( mTargetSize );
-      spreadFilter->SetSpread( effectSize );
+      spreadFilter->SetSpread( mEffectSize );
 
       EmbossFilter* embossFilter = static_cast< EmbossFilter* >( mFilters[1] );
       embossFilter->SetInputImage( mImagePostFilter );
       embossFilter->SetOutputImage( mImagePostFilter );
-      embossFilter->SetRootActor( Self() );
+      embossFilter->SetRootActor( mChildrenRoot );
       embossFilter->SetBackgroundColor( mBackgroundColor );
       embossFilter->SetPixelFormat( Pixel::RGBA8888 );
       embossFilter->SetSize( mTargetSize );
@@ -427,7 +406,7 @@ void EffectsView::SetupFilters()
       BlurTwoPassFilter* blurFilter = static_cast< BlurTwoPassFilter* >( mFilters[2] );
       blurFilter->SetInputImage( mImagePostFilter );
       blurFilter->SetOutputImage( mImagePostFilter );
-      blurFilter->SetRootActor( Self() );
+      blurFilter->SetRootActor( mChildrenRoot );
       blurFilter->SetBackgroundColor( Vector4( 0.5f, 0.5f, 0.5f, 0.0 ) );
       blurFilter->SetPixelFormat( Pixel::RGBA8888 );
       blurFilter->SetSize( mTargetSize );
@@ -446,14 +425,18 @@ void EffectsView::AllocateResources()
   if(mTargetSize != mLastSize)
   {
     mLastSize = mTargetSize;
-
     SetupCameras();
 
+    Toolkit::RendererFactory rendererFactory = Toolkit::RendererFactory::Get();
+    Actor self = Self();
+
     mImageForChildren = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Dali::Image::UNUSED );
-    mActorForChildren.SetImage(mImageForChildren);
+    rendererFactory.ResetRenderer(mRendererForChildren, self, mImageForChildren);
+    mRendererForChildren.SetDepthIndex( DepthIndex::CONTENT+1 );
 
     mImagePostFilter = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Dali::Image::UNUSED );
-    mActorPostFilter.SetImage(mImagePostFilter);
+    rendererFactory.ResetRenderer(mRendererPostFilter, self, mImagePostFilter);
+    mRendererPostFilter.SetDepthIndex( DepthIndex::CONTENT );
 
     SetupFilters();
   }
@@ -461,26 +444,39 @@ void EffectsView::AllocateResources()
 
 void EffectsView::SetupCameras()
 {
-  const float cameraPosScale( 0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f) );
-
-  // Create and place a camera for the children render, corresponding to its render target size
-  mCameraForChildren.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
-  // TODO: how do we pick a reasonable value for near clip? Needs to relate to normal camera the user renders with, but we don't have a handle on it
-  mCameraForChildren.SetNearClippingPlane(1.0f);
-  mCameraForChildren.SetAspectRatio(mTargetSize.width / mTargetSize.height);
-  mCameraForChildren.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
-  mCameraForChildren.SetPosition(0.0f, 0.0f, mTargetSize.height * cameraPosScale);
-  mCameraForChildren.SetZ( mTargetSize.height * cameraPosScale );
+  if( !mCameraForChildren )
+  {
+    // Create a camera for the children render, corresponding to its render target size
+    mCameraForChildren = CameraActor::New(mTargetSize);
+    mCameraForChildren.SetParentOrigin(ParentOrigin::CENTER);
+    mCameraForChildren.SetInvertYAxis( true );
+    Self().Add( mCameraForChildren );
+  }
+  else
+  {
+    // place the camera for the children render, corresponding to its render target size
+    const float cameraPosScale( 0.5f / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f) );
+    mCameraForChildren.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
+    mCameraForChildren.SetNearClippingPlane(1.0f);
+    mCameraForChildren.SetAspectRatio(mTargetSize.width / mTargetSize.height);
+    mCameraForChildren.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
+    mCameraForChildren.SetPosition(0.0f, 0.0f, mTargetSize.height * cameraPosScale);
+    mCameraForChildren.SetZ( mTargetSize.height * cameraPosScale );
+  }
 }
 
 void EffectsView::CreateRenderTasks()
 {
+  if( mTargetSize == Vector2::ZERO )
+  {
+    return;
+  }
   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
 
   // create render task to render our child actors to offscreen buffer
   mRenderTaskForChildren = taskList.CreateTask();
   mRenderTaskForChildren.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
-  mRenderTaskForChildren.SetSourceActor( Self() );
+  mRenderTaskForChildren.SetSourceActor( mChildrenRoot );
   mRenderTaskForChildren.SetExclusive(true);
   mRenderTaskForChildren.SetInputEnabled( false );
   mRenderTaskForChildren.SetClearColor( mBackgroundColor );
@@ -489,35 +485,25 @@ void EffectsView::CreateRenderTasks()
   mRenderTaskForChildren.SetCameraActor(mCameraForChildren); // use camera that covers render target exactly
 
   // Enable image filters
-  const size_t numFilters( mFilters.size() );
+  const size_t numFilters( mFilters.Size() );
   for( size_t i = 0; i < numFilters; ++i )
   {
     mFilters[i]->Enable();
   }
-
-  // create render task to render result of the image filters to the final offscreen
-  if( mImageForResult )
-  {
-    mRenderTaskForResult = taskList.CreateTask();
-    mRenderTaskForResult.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
-    mRenderTaskForResult.SetSourceActor( mActorForResult );
-    mRenderTaskForResult.SetExclusive(true);
-    mRenderTaskForResult.SetInputEnabled( false );
-    mRenderTaskForResult.SetClearColor( mBackgroundColor );
-    mRenderTaskForResult.SetClearEnabled( true );
-    mRenderTaskForResult.SetTargetFrameBuffer( mImageForResult );
-    mRenderTaskForResult.SetCameraActor(mCameraForChildren); // use camera that covers render target exactly
-  }
 }
 
 void EffectsView::RemoveRenderTasks()
 {
+  if( mTargetSize == Vector2::ZERO )
+  {
+    return;
+  }
+
   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
 
   taskList.RemoveTask(mRenderTaskForChildren);
-  taskList.RemoveTask(mRenderTaskForResult);
 
-  const size_t numFilters( mFilters.size() );
+  const size_t numFilters( mFilters.Size() );
   for( size_t i = 0; i < numFilters; ++i )
   {
     mFilters[i]->Disable();
@@ -533,12 +519,7 @@ void EffectsView::RefreshRenderTasks()
     mRenderTaskForChildren.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
   }
 
-  if( mRenderTaskForResult )
-  {
-    mRenderTaskForResult.SetRefreshRate( mRefreshOnDemand ? RenderTask::REFRESH_ONCE : RenderTask::REFRESH_ALWAYS );
-  }
-
-  const size_t numFilters( mFilters.size() );
+  const size_t numFilters( mFilters.Size() );
   for( size_t i = 0; i < numFilters; ++i )
   {
     mFilters[i]->Refresh();
@@ -547,12 +528,63 @@ void EffectsView::RefreshRenderTasks()
 
 void EffectsView::RemoveFilters()
 {
-  const size_t numFilters( mFilters.size() );
+  const size_t numFilters( mFilters.Size() );
   for( size_t i = 0; i < numFilters; ++i )
   {
     delete mFilters[i];
   }
-  mFilters.clear();
+  mFilters.Release();
+}
+
+void EffectsView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+  Toolkit::EffectsView effectsView = Toolkit::EffectsView::DownCast( Dali::BaseHandle( object ) );
+
+  if ( effectsView )
+  {
+    switch ( index )
+    {
+      case Toolkit::EffectsView::Property::EFFECT_SIZE:
+      {
+        int effectSize;
+        if( value.Get( effectSize ) )
+        {
+          GetImpl( effectsView ).SetEffectSize( effectSize );
+        }
+        break;
+      }
+      default:
+      {
+        break;
+      }
+    }
+  }
+}
+
+Property::Value EffectsView::GetProperty( BaseObject* object, Property::Index propertyIndex )
+{
+  Property::Value value;
+
+  Toolkit::EffectsView imageview = Toolkit::EffectsView::DownCast( Dali::BaseHandle( object ) );
+
+  if ( imageview )
+  {
+    EffectsView& impl = GetImpl( imageview );
+    switch ( propertyIndex )
+    {
+      case Toolkit::EffectsView::Property::EFFECT_SIZE:
+      {
+         value = impl.GetEffectSize();
+        break;
+      }
+      default:
+      {
+        break;
+      }
+    }
+  }
+
+  return value;
 }
 
 } // namespace Internal
index a39a1f7..bf6569d 100644 (file)
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/actors/camera-actor.h>
-#include <dali/public-api/actors/image-actor.h>
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/render-tasks/render-task.h>
-#include <dali/public-api/shader-effects/shader-effect.h>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/devel-api/controls/effects-view/effects-view.h>
+#include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/gaussian-blur-view/gaussian-blur-view.h>
+#include <dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h>
 
 namespace Dali
 {
@@ -80,12 +79,6 @@ public:
   /// @copydoc Dali::Toolkit::EffectsView::GetType
   Toolkit::EffectsView::EffectType GetType() const;
 
-  /// @copydoc Dali::Toolkit::EffectsView::Enable
-  void Enable();
-
-  /// @copydoc Dali::Toolkit::EffectsView::Disable
-  void Disable();
-
   /// @copydoc Dali::Toolkit::EffectsView::Refresh
   void Refresh();
 
@@ -95,40 +88,46 @@ public:
   /// @copydoc Dali::Toolkit::EffectsView::SetPixelFormat
   void SetPixelFormat( Pixel::Format pixelFormat );
 
-  /// @copydoc Dali::Toolkit::EffectsView::SetOutputImage
-  void SetOutputImage( FrameBufferImage image );
-
-  /// @copydoc Dali::Toolkit::EffectsView::GetOutputImage
-  FrameBufferImage GetOutputImage();
-
-  /// @copydoc Dali::Toolkit::EffectsView::GetEffectSizePropertyIndex
-  Property::Index GetEffectSizePropertyIndex() const;
-
-  /// @copydoc Dali::Toolkit::EffectsView::GetEffectStrengthPropertyIndex
-  Property::Index GetEffectStrengthPropertyIndex() const;
-
-  /// @copydoc Dali::Toolkit::EffectsView::GetEffectOffsetPropertyIndex
-  Property::Index GetEffectOffsetPropertyIndex() const;
-
-  /// @copydoc Dali::Toolkit::EffectsView::GetEffectColorPropertyIndex
-  Property::Index GetEffectColorPropertyIndex() const;
-
   /// @copydoc Dali::Toolkit::EffectsView::SetBackgroundColor(const Vector4&)
   void SetBackgroundColor( const Vector4& color );
 
   /// @copydoc Dali::Toolkit::GaussianBlurView::GetBackgroundColor
   Vector4 GetBackgroundColor() const;
 
-private:
   /**
-   * Register and setup indices for EffectsView properties
+   * Set the effect size which decides the size of filter kernel.
+   * @param[in] effectSize The effect size.
+   */
+  void SetEffectSize( int effectSize );
+
+  /**
+   * Get the effect size.
+   * @return The effect size.
+   */
+  int GetEffectSize();
+
+  // Properties
+  /**
+   * Called when a property of an object of this type is set.
+   * @param[in] object The object whose property is set.
+   * @param[in] index The property index.
+   * @param[in] value The new property value.
+   */
+  static void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value );
+
+
+  /**
+   * Called to retrieve a property of an object of this type.
+   * @param[in] object The object whose property is to be retrieved.
+   * @param[in] index The property index.
+   * @return The current value of the property.
    */
-  void SetupProperties();
+  static Property::Value GetProperty( BaseObject* object, Property::Index propertyIndex );
 
 private: // From Control
 
   /**
-   * @copydoc Toolkit::Control::OnInitialize()
+   * @copydoc Toolkit::Internal::Control::OnInitialize()
    */
   virtual void OnInitialize();
 
@@ -137,12 +136,37 @@ private: // From Control
    */
   virtual void OnSizeSet( const Vector3& targetSize );
 
+  /**
+   * @copydoc Toolkit::Internal::Control::OnStageConnection
+   */
+  virtual void OnStageConnection( int depth );
+
+  /**
+   * @copydoc Toolkit::Internal::Control::OnStageDisconnection
+   */
+  virtual void OnStageDisconnection();
+
+  /**
+   * @copydoc Toolkit::Internal::Control::OnChildAdd
+   */
+  virtual void OnChildAdd( Actor& child );
+
+  /**
+   * @copydoc Toolkit::Internal::Control::OnChildRemove
+   */
+  virtual void OnChildRemove( Actor& child );
+
 private:
 
   /**
-   * Callback received when the control is disconnected from the stage.
+   * Enable the effect when the control is set on stage
    */
-  void OnStageDisconnection();
+  void Enable();
+
+  /**
+   * Disable the effect when the control is set off stage
+   */
+  void Disable();
 
   /**
    * Setup image filters
@@ -188,21 +212,14 @@ private:
   EffectsView& operator = ( const EffectsView& );
 
 private: // attributes/properties
-  Toolkit::EffectsView::EffectType mEffectType;
 
   /////////////////////////////////////////////////////////////
   // for rendering all user added children to offscreen target
   FrameBufferImage mImageForChildren;
-  ImageActor mActorForChildren;
+  Toolkit::ControlRenderer mRendererForChildren;
   RenderTask mRenderTaskForChildren;
   CameraActor mCameraForChildren;
-
-  /////////////////////////////////////////////////////////////
-  Pixel::Format mPixelFormat;     ///< pixel format used by render targets
-
-  /////////////////////////////////////////////////////////////
-  // downsampling is used for the separated blur passes to get increased blur with the same number of samples and also to make rendering quicker
-  float mSpread;
+  Actor mChildrenRoot; // for creating a subtree for all user added child actors
 
   /////////////////////////////////////////////////////////////
   // background fill color
@@ -212,40 +229,23 @@ private: // attributes/properties
   // for checking if we need to reallocate render targets
   Vector2 mTargetSize;
   Vector2 mLastSize;
-
-  bool mRefreshOnDemand;
-
-  /////////////////////////////////////////////////////////////
-  // horizontal spread objects
-  FrameBufferImage mImageForHorzSpread;
-  ImageActor mActorForHorzSpread;
-  RenderTask mRenderTaskForHorzSpread;
-
-  /////////////////////////////////////////////////////////////
-  // vertical spread objects
-  FrameBufferImage mImageForVertSpread;
-  ImageActor mActorForVertSpread;
-  RenderTask mRenderTaskForVertSpread;
-
-  CameraActor mCameraForSpread;
-
   /////////////////////////////////////////////////////////////
   // post blur image
   FrameBufferImage mImagePostFilter;
-  ImageActor mActorPostFilter;
+  Toolkit::ControlRenderer mRendererPostFilter;
+
+  Vector<ImageFilter*> mFilters;
 
   /////////////////////////////////////////////////////////////
-  // final image
-  FrameBufferImage mImageForResult;
-  Actor mActorForResult;
-  RenderTask mRenderTaskForResult;
+  // downsampling is used for the separated blur passes to get increased blur with the same number of samples and also to make rendering quicker
+  int mEffectSize;
 
-  Property::Index mEffectSizePropertyIndex;
-  Property::Index mEffectStrengthPropertyIndex;
-  Property::Index mEffectOffsetPropertyIndex;
-  Property::Index mEffectColorPropertyIndex;
+  /////////////////////////////////////////////////////////////
+  Toolkit::EffectsView::EffectType mEffectType;
+  Pixel::Format mPixelFormat;     ///< pixel format used by render targets
 
-  std::vector<ImageFilter*> mFilters;
+  bool mEnabled:1;
+  bool mRefreshOnDemand:1;
 }; // class EffectsView
 
 } // namespace Internal
index 8a608f1..6081c0b 100644 (file)
@@ -331,6 +331,8 @@ void GaussianBlurView::OnInitialize()
 
 void GaussianBlurView::OnSizeSet(const Vector3& targetSize)
 {
+  Control::OnSizeSet( targetSize );
+
   mTargetSize = Vector2(targetSize);
 
   mChildrenRoot.SetSize(targetSize);
@@ -357,17 +359,21 @@ void GaussianBlurView::OnSizeSet(const Vector3& targetSize)
   }
 }
 
-void GaussianBlurView::OnControlChildAdd( Actor& child )
+void GaussianBlurView::OnChildAdd( Actor& child )
 {
+  Control::OnChildAdd( child );
+
   if( child != mChildrenRoot && child != mInternalRoot)
   {
     mChildrenRoot.Add( child );
   }
 }
 
-void GaussianBlurView::OnControlChildRemove( Actor& child )
+void GaussianBlurView::OnChildRemove( Actor& child )
 {
   mChildrenRoot.Remove( child );
+
+  Control::OnChildRemove( child );
 }
 
 void GaussianBlurView::AllocateResources()
index 1d8332e..9b6d564 100644 (file)
@@ -99,14 +99,14 @@ private:
   virtual void OnSizeSet(const Vector3& targetSize);
 
   /**
-   * @copydoc Control::OnControlChildAdd()
+   * @copydoc Control::OnChildAdd()
    */
-  virtual void OnControlChildAdd( Actor& child );
+  virtual void OnChildAdd( Actor& child );
 
   /**
-   * @copydoc Control::OnControlChildRemove()
+   * @copydoc Control::OnChildRemove()
    */
-  virtual void OnControlChildRemove( Actor& child );
+  virtual void OnChildRemove( Actor& child );
 
   void SetBlurBellCurveWidth(float blurBellCurveWidth);
   float CalcGaussianWeight(float x);
index f7c36a7..3eb0144 100644 (file)
@@ -246,6 +246,8 @@ void ImageView::OnStageDisconnection()
 
 void ImageView::OnSizeSet( const Vector3& targetSize )
 {
+  Control::OnSizeSet( targetSize );
+
   if( mRenderer )
   {
     Vector2 size( targetSize );
index 796e7bb..dfc7e1b 100644 (file)
@@ -280,6 +280,8 @@ void Magnifier::SetFrameVisibility(bool visible)
 
 void Magnifier::OnSizeSet(const Vector3& targetSize)
 {
+  Control::OnSizeSet( targetSize );
+
   // TODO: Once Camera/CameraActor properties function as proper animatable properties
   // this code can disappear.
   // whenever the size of the magnifier changes, the field of view needs to change
index efe112c..f9e87fb 100644 (file)
@@ -18,8 +18,7 @@
  *
  */
 
-// EXTERNAL INCLUDES
-#include <dali/public-api/shader-effects/shader-effect.h>
+#define DALI_COMPOSE_SHADER(STR) #STR
 
 namespace Dali
 {
@@ -42,50 +41,68 @@ namespace Internal
  *
  * Animatable/Constrainable uniforms:
  *  "uSpineShadowParameter" - The two parameters are the major&minor radius (in pixels) to form an ellipse shape. The top-left
- *                            quarter of this ellipse is used to calculate spine normal for simulating shadow
- *  "uIsBackImageVisible"   - Set whether the current page is with its backside visible. Need to pass the parameter as true for
- *                            the page which is turned over but still visible in Landscape
- *  "uPageWidth"            - The page width of the PageTurnBookSpineEffect
+ *                            quarter of this ellipse is used to calculate spine normal for simulating shadow *
+ *  "uTextureWidth" - 1.0 for single sided page,
+ *                    2.0 for double sided image which has left half part as page front side and right half part as page back side.
  *
- * @return A handle to a newly allocated ShaderEffect
+ * @return The newly created Property::Map with the page turn book spine effect
  **/
-inline ShaderEffect CreatePageTurnBookSpineEffect()
+inline Property::Map CreatePageTurnBookSpineEffect()
 {
+  const char* vertexSource = DALI_COMPOSE_SHADER(
+      precision mediump float;\n
+      attribute mediump vec2 aPosition;\n
+      uniform mediump mat4 uMvpMatrix;\n
+      uniform vec3 uSize;\n
+      uniform float uTextureWidth;\n
+      varying vec2 vTexCoord;\n
+      void main()\n
+      {\n
+        mediump vec4 vertexPosition = vec4(aPosition*uSize.xy, 0.0, 1.0);\n
+        gl_Position = uMvpMatrix * vertexPosition;\n
+        vTexCoord = aPosition + vec2(0.5);\n
+        vTexCoord.x /= uTextureWidth;
+      }\n);
+
   // the simplified version of the fragment shader of page turn effect
-  std::string fragmentSource = DALI_COMPOSE_SHADER(
+  const char* fragmentSource = DALI_COMPOSE_SHADER(
       precision mediump float;\n
-      uniform float uIsBackImageVisible;\n
-      uniform float uPageWidth;\n
+      varying mediump vec2 vTexCoord;\n
+      uniform vec3 uSize;\n
       uniform vec2 uSpineShadowParameter;\n
+      uniform sampler2D sTexture;\n
+      uniform lowp vec4 uColor;\n
+
       void main()\n
       {\n
-      // flip the image horizontally by changing the x component of the texture coordinate
-        if( uIsBackImageVisible == 1.0 )\n
-          gl_FragColor = texture2D( sTexture, vec2( sTextureRect.p+sTextureRect.s-vTexCoord.x, vTexCoord.y ) ) * uColor; \n
-        else\n
-        gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
-      // display book spine, a stripe of shadowed texture
-        float pixelPos = (vTexCoord.x-sTextureRect.s)*uPageWidth; \n
-        if(pixelPos < uSpineShadowParameter.x) \n
+        if( gl_FrontFacing )\n // display front side
+        {\n
+          gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
+        }\n
+        else\n // display back side, flip the image horizontally by changing the x component of the texture coordinate
+        {\n
+          gl_FragColor = texture2D( sTexture, vec2( 1.0 - vTexCoord.x, vTexCoord.y ) ) * uColor;\n
+        }\n
+        // display book spine, a stripe of shadowed texture
+        float pixelPos = vTexCoord.x * uSize.x;\n
+        if( pixelPos < uSpineShadowParameter.x )\n
         {\n
           float x = pixelPos - uSpineShadowParameter.x;\n
           float y = sqrt( uSpineShadowParameter.x*uSpineShadowParameter.x - x*x );\n
           vec2 spineNormal = normalize(vec2(uSpineShadowParameter.y*x/uSpineShadowParameter.x, y));\n
           gl_FragColor.rgb *= spineNormal.y; \n
-        }
+        }\n
       } );
 
-  const Vector2 DEFAULT_SPINE_SHADOW_PARAMETER(50.0f, 20.0f);
-
-  ShaderEffect shaderEffect = ShaderEffect::New( "", fragmentSource );
+  Property::Map map;
 
-  shaderEffect.SetUniform( "uIsBackImageVisible", -1.f );
-  shaderEffect.SetUniform( "uSpineShadowParameter", DEFAULT_SPINE_SHADOW_PARAMETER );
+  Property::Map customShader;
 
-  float defaultPageWidth = Dali::Stage::GetCurrent().GetSize().x;
-  shaderEffect.SetUniform( "uPageWidth", defaultPageWidth );
+  customShader[ "vertexShader" ] = vertexSource;
+  customShader[ "fragmentShader" ] = fragmentSource;
 
-  return shaderEffect;
+  map[ "shader" ] = customShader;
+  return map;
 }
 
 } //namespace Internal
index f4ada4f..f4d1126 100644 (file)
  *
  */
 
+//EXTERNAL INCLUDES
+#include <string.h>
+#include <dali/public-api/animation/constraint.h>
+#include <dali/public-api/actors/actor.h>
+#include <dali/public-api/object/property-map.h>
+
+//INTERNAL INCLUDES
 #include <dali-toolkit/internal/controls/page-turn-view/page-turn-effect.h>
-#include <dali/public-api/math/matrix.h>
 
 using namespace Dali;
 using namespace Dali::Toolkit;
 
-void CommonParametersConstraint( Dali::Matrix& current, const PropertyInputContainer& inputs )
+namespace
 {
-  const Vector2& originalCenter = inputs[0]->GetVector2();
-  Vector2 currentCenter = inputs[1]->GetVector2();
-  const Vector2& pageSize = inputs[2]->GetVector2();
+#define DALI_COMPOSE_SHADER(STR) #STR
+const char * const PROPERTY_COMMON_PARAMETERS( "uCommonParameters" );
+const char * const PROPERTY_ORIGINAL_CENTER( "originalCenter" );
+const char * const PROPERTY_CURRENT_CENTER( "currentCenter" );
+}
 
-  // calculate the curve direction and the vanishing point
-  // here, the vanishing point is the intersection of spine with the line passing through original center and vertical to curve direction
-  Vector2 curveDirection( currentCenter - originalCenter );
-  curveDirection.Normalize();
-  if( fabs(curveDirection.y) < 0.01f) // eliminate the possibility of division by zero in the next step
-  {
-    curveDirection.y = 0.01f;
-  }
-  float vanishingPointY = originalCenter.y + curveDirection.x * originalCenter.x / curveDirection.y;
+/**
+ * This constraint updates the common parameter values used by every vertex.
+ * By using constraint, they are calculate once in CPU then pass into the vertex shader as uniforms
+ */
+struct CommonParametersConstraint
+{
+  CommonParametersConstraint( float pageHeight )
+  : mPageHeight( pageHeight )
+  {}
 
-  float curveEndY, cosTheta ,sinTheta ,translateX, translateY;
-  // when the vanishing point is very far away, make it infinitely, in this case, the page bent horizontally
-  const float THRESHOLD(20.0);
-  if( fabs(vanishingPointY-pageSize.y*0.5f) >= pageSize.y*THRESHOLD )
+  void operator()( Dali::Matrix& current, const PropertyInputContainer& inputs )
   {
-    curveDirection = Vector2(-1.f,0.f);
-    currentCenter.y = originalCenter.y;
+    const Vector2& originalCenter = inputs[0]->GetVector2();
+    Vector2 currentCenter = inputs[1]->GetVector2();
 
-    curveEndY = originalCenter.y;
-    cosTheta = 1.f;
-    sinTheta = 0.f;
-    translateX = currentCenter.x - originalCenter.x;
-    translateY = vanishingPointY;
-  }
-  else
-  {
-    curveEndY = currentCenter.y - curveDirection.y * (currentCenter.x/curveDirection.x) ;
-    Vector2 v1( currentCenter.x, currentCenter.y - vanishingPointY );
-    v1.Normalize();
-    Vector2 v2( originalCenter.x, originalCenter.y - vanishingPointY );
-    v2.Normalize();
-    cosTheta = v1.x*v2.x + v1.y*v2.y;
-    sinTheta = ( vanishingPointY > pageSize.y*0.5f ) ? sqrt(1.0-cosTheta*cosTheta) : -sqrt(1.0-cosTheta*cosTheta);
-    translateX = currentCenter.x - cosTheta*originalCenter.x - sinTheta*( originalCenter.y-vanishingPointY );
-    translateY = currentCenter.y + sinTheta*originalCenter.x - cosTheta*( originalCenter.y-vanishingPointY );
-  }
+    // calculate the curve direction and the vanishing point
+    // here, the vanishing point is the intersection of spine with the line passing through original center and vertical to curve direction
+    Vector2 curveDirection( currentCenter - originalCenter );
+    curveDirection.Normalize();
+    if( fabs(curveDirection.y) < 0.01f) // eliminate the possibility of division by zero in the next step
+    {
+      curveDirection.y = 0.01f;
+    }
+    float vanishingPointY = originalCenter.y + curveDirection.x * originalCenter.x / curveDirection.y;
 
-  float originalLength = fabs(originalCenter.x/curveDirection.x);
-  float currentLength = fabs(currentCenter.x/curveDirection.x);
-  float curveHeight = 0.45f*sqrt(originalLength*originalLength - currentLength*currentLength);
+    float curveEndY, cosTheta ,sinTheta ,translateX, translateY;
+    // when the vanishing point is very far away, make it infinitely, in this case, the page bent horizontally
+    const float THRESHOLD(20.0);
+    if( fabs(vanishingPointY-mPageHeight*0.5f) >= mPageHeight*THRESHOLD )
+    {
+      curveDirection = Vector2(-1.f,0.f);
+      currentCenter.y = originalCenter.y;
 
-  float* parameterArray = current.AsFloat();
-  parameterArray[0] = cosTheta;
-  parameterArray[1] = -sinTheta;
-  parameterArray[2] = originalCenter.x;
-  parameterArray[3] = originalCenter.y;
-  parameterArray[4] = sinTheta;
-  parameterArray[5] = cosTheta;
-  parameterArray[6] = currentCenter.x;
-  parameterArray[7] = currentCenter.y;
-  parameterArray[8] = translateX;
-  parameterArray[9] = translateY;
-  parameterArray[10] = vanishingPointY;
-  parameterArray[11] = curveEndY;
-  parameterArray[12] = curveDirection.x;
-  parameterArray[13] = curveDirection.y;
-  parameterArray[14] = curveHeight;
-  parameterArray[15] = currentLength;
-}
+      curveEndY = originalCenter.y;
+      cosTheta = 1.f;
+      sinTheta = 0.f;
+      translateX = currentCenter.x - originalCenter.x;
+      translateY = vanishingPointY;
+    }
+    else
+    {
+      curveEndY = currentCenter.y - curveDirection.y * (currentCenter.x/curveDirection.x) ;
+      Vector2 v1( currentCenter.x, currentCenter.y - vanishingPointY );
+      v1.Normalize();
+      Vector2 v2( originalCenter.x, originalCenter.y - vanishingPointY );
+      v2.Normalize();
+      cosTheta = v1.x*v2.x + v1.y*v2.y;
+      sinTheta = ( vanishingPointY > mPageHeight*0.5f ) ? sqrt(1.0-cosTheta*cosTheta) : -sqrt(1.0-cosTheta*cosTheta);
+      translateX = currentCenter.x - cosTheta*originalCenter.x - sinTheta*( originalCenter.y-vanishingPointY );
+      translateY = currentCenter.y + sinTheta*originalCenter.x - cosTheta*( originalCenter.y-vanishingPointY );
+    }
+
+    float originalLength = fabs(originalCenter.x/curveDirection.x);
+    float currentLength = fabs(currentCenter.x/curveDirection.x);
+    float curveHeight = 0.45f*sqrt(originalLength*originalLength - currentLength*currentLength);
+
+    float* parameterArray = current.AsFloat();
+    parameterArray[0] = cosTheta;
+    parameterArray[1] = -sinTheta;
+    parameterArray[2] = originalCenter.x;
+    parameterArray[3] = originalCenter.y;
+    parameterArray[4] = sinTheta;
+    parameterArray[5] = cosTheta;
+    parameterArray[6] = currentCenter.x;
+    parameterArray[7] = currentCenter.y;
+    parameterArray[8] = translateX;
+    parameterArray[9] = translateY;
+    parameterArray[10] = vanishingPointY;
+    parameterArray[11] = curveEndY;
+    parameterArray[12] = curveDirection.x;
+    parameterArray[13] = curveDirection.y;
+    parameterArray[14] = curveHeight;
+    parameterArray[15] = currentLength;
+  }
+
+  float mPageHeight;
+};
 
-void Dali::Toolkit::Internal::PageTurnApplyInternalConstraint( ShaderEffect& shaderEffect)
+void Dali::Toolkit::Internal::PageTurnApplyInternalConstraint( Actor& actor, float pageHeight )
 {
-  Constraint constraint = Constraint::New<Dali::Matrix>( shaderEffect, shaderEffect.GetPropertyIndex( "uCommonParameters" ), CommonParametersConstraint );
-  constraint.AddSource( LocalSource( shaderEffect.GetPropertyIndex( "uOriginalCenter" ) ) );
-  constraint.AddSource( LocalSource( shaderEffect.GetPropertyIndex( "uCurrentCenter" ) ) );
-  constraint.AddSource( LocalSource( shaderEffect.GetPropertyIndex( "uPageSize" ) ) );
+  Constraint constraint = Constraint::New<Dali::Matrix>( actor, actor.GetPropertyIndex( PROPERTY_COMMON_PARAMETERS ) , CommonParametersConstraint( pageHeight ) );
+  constraint.AddSource( LocalSource( actor.GetPropertyIndex( PROPERTY_ORIGINAL_CENTER ) ) );
+  constraint.AddSource( LocalSource( actor.GetPropertyIndex( PROPERTY_CURRENT_CENTER ) ) );
   constraint.Apply();
 }
 
-ShaderEffect Dali::Toolkit::Internal::CreatePageTurnEffect()
+Property::Map Dali::Toolkit::Internal::CreatePageTurnEffect()
 {
-  std::string vertexShader = DALI_COMPOSE_SHADER(
+  const char* vertexShader = DALI_COMPOSE_SHADER(
       /*
        * The common parameters for all the vertices, calculate in CPU then pass into the shader as uniforms
        *
@@ -117,17 +142,25 @@ ShaderEffect Dali::Toolkit::Internal::CreatePageTurnEffect()
        * ([3][3]) float currentLength: The length from the current center to the curveEnd.
        */
       precision mediump float;\n
+      \n
+      attribute mediump vec2 aPosition;\n
+      \n
+      uniform mediump mat4 uMvpMatrix;\n
+      uniform mediump mat3 uNormalMatrix;\n
+      uniform mediump mat4 uModelView;\n
+      \n
       uniform mat4 uCommonParameters;\n
       \n
-      uniform vec2 uPageSize;\n
+      uniform vec3 uSize;\n
       uniform float uIsTurningBack;\n
+      uniform float uTextureWidth;\n
       varying vec3 vNormal;\n
       varying vec4 vPosition;\n
-      varying float vEdgeShadow;\n
+      varying mediump vec2 vTexCoord;\n
       \n
       void main()\n
       {\n
-        vec4 position = vec4( aPosition, 1.0);\n
+        vec4 position = vec4( aPosition*uSize.xy, 0.0, 1.0);\n
         vec2 currentCenter = vec2( uCommonParameters[1][2], uCommonParameters[1][3]);\n
         vec2 originalCenter = vec2( uCommonParameters[0][2], uCommonParameters[0][3]);\n
         vec3 normal = vec3(0.0,0.0,1.0);\n
@@ -135,7 +168,7 @@ ShaderEffect Dali::Toolkit::Internal::CreatePageTurnEffect()
         if(currentCenter.x < originalCenter.x)\n
         {\n
           // change the coordinate origin from the center of the page to its top-left
-          position.xy += uPageSize * 0.5;\n
+          position.xy += uSize.xy * 0.5;\n
           vec2 curveDirection = vec2( uCommonParameters[3]);\n
           vec3 vanishingPoint = vec3(0.0, uCommonParameters[2][2], 0.0);\n
           // first part of the page, (outside the the line passing through original center and vertical to curve direction)
@@ -164,7 +197,7 @@ ShaderEffect Dali::Toolkit::Internal::CreatePageTurnEffect()
             }\n
             \n
             // define the control points of hermite curve, composed with two segments
-            // calulation is carried out on the 2D plane which is passing through both current and original center and vertical to the image plane
+            // calculation is carried out on the 2D plane which is passing through both current and original center and vertical to the image plane
             float currentLength = uCommonParameters[3][3];\n
             float originalLength =  abs(originalCenter.x/curveDirection.x);\n
             float height = uCommonParameters[3][2];\n
@@ -178,7 +211,7 @@ ShaderEffect Dali::Toolkit::Internal::CreatePageTurnEffect()
             vec2 SegmentTwoTangentVector0 = SegmentOneTangentVector1;\n
             vec2 SegmentTwoTangentVector1 = SegmentOneTangentVector1;\n
             \n
-            // calulate the corresponding curve point position and its tangent vector
+            // calculate the corresponding curve point position and its tangent vector
             // it is a linear mapping onto nonlinear curves, might cause some unwanted deformation
             // but as there are no analytical method to calculate the curve length on arbitrary segment
             // no efficient way to solve this nonlinear mapping, Numerical approximation would cost too much computation in shader
@@ -207,7 +240,7 @@ ShaderEffect Dali::Toolkit::Internal::CreatePageTurnEffect()
               // a trick to eliminate some optical illusion caused by the gradient matter of normal in per-fragment shading
               // which is caused by linear interpolation of normal vs. nonlinear lighting
               // will notice some artifact in the areas with dramatically normal changes, so compress the normal differences here
-              tangent.y *=  min(1.0, length(position.xyz - vanishingPoint) / uPageSize.y ); \n
+              tangent.y *=  min(1.0, length(position.xyz - vanishingPoint) / uSize.y ); \n
             }\n
             vec3 curvePoint = vec3(curveEnd - curvePoint2D.x*curveDirection,max(0.0,curvePoint2D.y));\n
             vec3 tangentVector = vec3(-tangent.x*curveDirection,tangent.y);\n
@@ -244,69 +277,67 @@ ShaderEffect Dali::Toolkit::Internal::CreatePageTurnEffect()
             normal.xy *= -uIsTurningBack;\n
           }\n
           // change the coordinate origin from the top-left of the page to its center
-          position.xy -= uPageSize * 0.5; \n
+          position.xy -= uSize.xy * 0.5; \n
         }\n
-        gl_Position = uMvpMatrix * position;\n
+        vNormal =  uNormalMatrix * normal;\n
+        gl_Position = uMvpMatrix * position;
         // varying parameters for fragment shader
-        vTexCoord = mix( sTextureRect.xy, sTextureRect.zw, aTexCoord );\n;
-        vNormal = uNormalMatrix*normal;\n
+        vTexCoord = aPosition + vec2(0.5);\n
+        vTexCoord.x /= uTextureWidth;
         vPosition = uModelView * position;\n
       }\n
   );
 
-  std::string fragmentShader = DALI_COMPOSE_SHADER(
+  const char* fragmentShader = DALI_COMPOSE_SHADER(
       precision mediump float;\n
-      uniform vec2 uPageSize;\n
+      \n
+      varying mediump vec2 vTexCoord;\n
+      \n
+      uniform sampler2D sTexture;\n
+      uniform lowp vec4 uColor;\n
+      uniform vec3 uSize;\n
       uniform vec2 uSpineShadowParameter;\n
       varying vec3 vNormal;\n
       varying vec4 vPosition;\n
-      varying float vEdgeShadow;\n
       \n
       void main()\n
       {\n
         // need to re-normalize the interpolated normal
-        vec3 normal = normalize(vNormal);\n
-        vec4 texel;\n
-        float spineShadowCoef = 1.0; \n
+        vec3 normal = normalize( vNormal );\n
         // display page content
+        vec4 texel;
         // display back image of the page, flip the texture
-        if(  dot(vPosition.xyz, normal) > 0.0 ) texel = texture2D( sTexture, vec2( sTextureRect.p+sTextureRect.s-vTexCoord.x, vTexCoord.y ) );\n
+        if(  dot(vPosition.xyz, normal) > 0.0 ) texel = texture2D( sTexture, vec2( 1.0 - vTexCoord.x, vTexCoord.y ) );\n
         // display front image of the page
         else texel = texture2D( sTexture, vTexCoord );\n
+
         // display book spine, a stripe of shadowed texture
-        float pixelPos = (vTexCoord.x-sTextureRect.s)*uPageSize.x; \n
-        if(pixelPos < uSpineShadowParameter.x) \n
+        float pixelPos = vTexCoord.x * uSize.x; \n
+        float spineShadowCoef = 1.0; \n
+        if( pixelPos < uSpineShadowParameter.x ) \n
         {\n
           float x = pixelPos - uSpineShadowParameter.x;\n
-          float y = sqrt( uSpineShadowParameter.x*uSpineShadowParameter.x - x*x);\n
+          float y = sqrt( uSpineShadowParameter.x*uSpineShadowParameter.x - x*x );\n
           spineShadowCoef = normalize( vec2( uSpineShadowParameter.y*x/uSpineShadowParameter.x, y ) ).y;\n
         }\n
         // calculate the lighting
         // set the ambient color as vec3(0.4);
         float lightColor = abs( normal.z ) * 0.6 + 0.4;\n
-        gl_FragColor = vec4( ( spineShadowCoef* lightColor)* texel.rgb , texel.a ) * uColor;\n
+        gl_FragColor = vec4( ( spineShadowCoef * lightColor ) * texel.rgb , texel.a ) * uColor;\n
       }
   );
 
-  // Create the implementation, temporarily owned on stack,
-  Dali::ShaderEffect shaderEffectCustom = Dali::ShaderEffect::New( vertexShader, fragmentShader,ShaderEffect::HINT_GRID );
-
-  static const Vector2 DEFAULT_SPINE_SHADOW_PARAMETER(50.0f, 20.0f);
-
-  Vector2 defaultPageSize = Dali::Stage::GetCurrent().GetSize();
-  Dali::Matrix zeroMatrix(true);
-  shaderEffectCustom.SetUniform( "uCommonParameters", zeroMatrix );
-  shaderEffectCustom.SetUniform( "uPageSize", defaultPageSize );
-  shaderEffectCustom.SetUniform( "uSpineShadowParameter", DEFAULT_SPINE_SHADOW_PARAMETER );
+  Property::Map map;
 
-  shaderEffectCustom.RegisterProperty( "uOriginalCenter", Vector2( defaultPageSize[0], defaultPageSize[1]*0.5f ) );
-  shaderEffectCustom.RegisterProperty( "uCurrentCenter", Vector2( defaultPageSize[0], defaultPageSize[1]*0.5f ) );
+  Property::Map customShader;
 
-  PageTurnApplyInternalConstraint(shaderEffectCustom);
+  customShader[ "vertexShader" ] = vertexShader;
+  customShader[ "fragmentShader" ] = fragmentShader;
+  customShader[ "subdivideGridX" ] = 20;
+  customShader[ "subdivideGridY" ] = 20;
 
-  // setting isTurningBack to -1.0f here means turning page forward
-  shaderEffectCustom.SetUniform( "uIsTurningBack", -1.0f );
+  map[ "shader" ] = customShader;
+  return map;
 
-  return shaderEffectCustom;
 }
 
index 59a4603..1025d2d 100644 (file)
  */
 
 // EXTERNAL INCLUDES
-#include <dali/public-api/animation/constraint.h>
-#include <dali/public-api/common/stage.h>
-#include <dali/public-api/object/property-input.h>
-#include <dali/public-api/shader-effects/shader-effect.h>
-#include <sstream>
 
 namespace Dali
 {
@@ -37,15 +32,16 @@ namespace Internal
 
 /**
  * @brief Re-applies PageTurnEffect internal constraints
- * The internal constraint uses the OriginalCenter property and the CurrentCenter Property
+ * The internal constraint uses the OriginalCenter property and the CURRENT_CENTER Property
  * to update the variety of common parameters which are with the same value for all the vertices.
  * Note: For each actor, the constraints are applied in the same order as the calls to Actor::ApplyConstraint().
- * So if there are other contraints applied to the OriginalCenter or CurrentCenter while when using this effect,
+ * So if there are other contraints applied to the ORIGINAL_CENTER or CURRENT_CENTER while when using this effect,
  * call this method to get the internal constraints and re-apply it afterwards.
  *
- * @param[in] shaderEffect The page turn effect to which internal constraints should be re-applied
+ * @param[in] actor The page turn actor to which internal constraints should be re-applied
+ * @param[in] pageHeight The page height.
  */
-void PageTurnApplyInternalConstraint( ShaderEffect& shaderEffect);
+void PageTurnApplyInternalConstraint( Actor& actor, float pageHeight );
 
 /**
  * @brief Create a new PageTurnEffect
@@ -54,33 +50,33 @@ void PageTurnApplyInternalConstraint( ShaderEffect& shaderEffect);
  * Usage example:-
  *
  * // create shader used for doing page-turn effect\n
- * ShaderEffect pageTurnEffect = CreatePageTurnEffect();
+ * Property::Map pageTurnEffect = CreatePageTurnEffect();
  *
- * // set image actor shader to the page-turn one\n
+ * // set image view custom shader to the page-turn one\n
  * // for portrait view, one image actor for each page\n
  * // for landscape view, the page turned over is still visible, so back image is needed \n
  * //     in this case, create another image Actor using the back image and added to the page actor \n
- * ImageActor pageActor = ImageActor::New(....); \n
- * ImageActor backImageActor = ImageActor::New(....); \n
- * pageActor.Add(backPageActor);\n
- * pageActor.SetShaderEffect ( pageTurnEffect ); \n
+ * ImageView page = ImageView::New(....); \n
+ * page.SetProperty ( ImageView::Property::IMAGE, pageTurnEffect ); \n
  *
  * //set initial values
- * pageTurnEffect.SetUniform("uPageSize", Vector2);\n
- * pageTurnEffect.SetUniform("uOriginalCenter", Vector2);\n
- * pageTurnEffect.SetUniform("uIsTurningBack", bool);\n
- * pageTurnEffect.SetUniform("uCurrentCenter",Vector2);\n
+ * page.SetProperty( page.GetPropertyIndex("uIsTurningBack",) bool );\n
+ * page.SetProperty( page.GetPropertyIndex("uSpineShadowParameter",) Vector2 );\n
+ * page.SetProperty( page.GetPropertyIndex("ORIGINAL_CENTER"), Vector2 );\n
+ * page.SetProperty( page.GetPropertyIndex("CURRENT_CENTER"), Vector2 );\n
+ * page.SetProperty( page.GetPropertyIndex("uCommonParameters"), Matrix );\n
+ * page.SetProperty( page.GetPropertyIndex("uTextureWidth"), float ); // Set to 1.0 for single-sided or 2.0 for double-sided \n
+ * PageTurnApplyInternalConstraint( page );\n
  *
  * //Animate it with the current center property\n
- * Animation animation[mAnimationIndex] = Animation::New( ... );\n
- * animation.AnimateTo(Property( pageTurnEffect, "uCurrentCenter" ),
- *                            currentCenter,
- *                            AlphaFunction::...);\n
- * animation[mAnimationIndex].Play(); \n
+ * Animation animation = Animation::New( ... );\n
+ * animation.AnimateTo(Property( page, "CURRENT_CENTER" ),
+ *                               currentCenter,
+ *                               AlphaFunction::...);\n
+ * animation.Play(); \n
  *
- * Animatable/Constrainable uniforms:
  */
-ShaderEffect CreatePageTurnEffect();
+Property::Map CreatePageTurnEffect();
 
 } // namespace Internal
 
index df0db93..593eac5 100644 (file)
@@ -21,7 +21,6 @@
 // EXTERNAL INCLUDES
 #include <dali/public-api/object/type-registry.h>
 #include <dali/devel-api/object/type-registry-helper.h>
-#include <dali/devel-api/rendering/cull-face.h>
 
 namespace Dali
 {
@@ -34,7 +33,6 @@ namespace Internal
 
 namespace
 {
-using namespace Dali;
 
 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::PageTurnLandscapeView, Toolkit::PageTurnView, NULL )
 DALI_TYPE_REGISTRATION_END()
@@ -66,33 +64,22 @@ Toolkit::PageTurnLandscapeView PageTurnLandscapeView::New( PageFactory& pageFact
 
 void PageTurnLandscapeView::OnPageTurnViewInitialize()
 {
+  mTurnEffectShader.RegisterProperty(PROPERTY_TEXTURE_WIDTH, 2.f );
+  mSpineEffectShader.RegisterProperty(PROPERTY_TEXTURE_WIDTH, 2.f );
+
   mControlSize = Vector2( mPageSize.width * 2.f,  mPageSize.height  );
   Self().SetSize( mControlSize );
   mTurningPageLayer.SetParentOrigin( ParentOrigin::CENTER );
 }
 
-void PageTurnLandscapeView::OnAddPage( ImageActor newPage, bool isLeftSide )
+void PageTurnLandscapeView::OnAddPage( Actor newPage, bool isLeftSide )
 {
   newPage.SetParentOrigin( ParentOrigin::CENTER );
-  SetCullFace( newPage, CullBack );
-
-  if( 0 < newPage.GetChildCount() )
-  {
-     ImageActor backImage = ImageActor::DownCast( newPage.GetChildAt( 0 ) );
-     backImage.SetParentOrigin( ParentOrigin::CENTER );
-     backImage.SetSize( mPageSize );
-     SetCullFace( backImage, CullFront );
-     backImage.SetZ( 0.25f * STATIC_PAGE_INTERVAL_DISTANCE );
-  }
-  if( isLeftSide )
-  {
-    SetShaderEffect( newPage, mSpineEffectBack );
-  }
 }
 
 Vector2 PageTurnLandscapeView::SetPanPosition( const Vector2& gesturePosition )
 {
-  if( mIsTurnBack[mPanActor] )
+  if( mPages[mIndex].isTurnBack )
   {
     return Vector2( mPageSize.width - gesturePosition.x, gesturePosition.y );
   }
@@ -104,31 +91,17 @@ Vector2 PageTurnLandscapeView::SetPanPosition( const Vector2& gesturePosition )
 
 void PageTurnLandscapeView::SetPanActor( const Vector2& panPosition )
 {
-  if( panPosition.x > mPageSize.width  && mCurrentPageIndex < mTotalPageCount-1 )
+  if( panPosition.x > mPageSize.width  && mCurrentPageIndex < mTotalPageCount )
   {
-    mPanActor = mPageActors[mCurrentPageIndex%NUMBER_OF_CACHED_PAGES]; // right side page
     mTurningPageIndex = mCurrentPageIndex;
   }
   else if( panPosition.x <= mPageSize.width && mCurrentPageIndex > 0 )
   {
-    mPanActor = mPageActors[ (mCurrentPageIndex-1)%NUMBER_OF_CACHED_PAGES ]; // left side page
     mTurningPageIndex = mCurrentPageIndex - 1;
   }
   else
   {
-    mPanActor.Reset();
-  }
-}
-
-void PageTurnLandscapeView::SetSpineEffect(ImageActor actor, bool isLeftSide)
-{
-  if(isLeftSide)
-  {
-    SetShaderEffect( actor, mSpineEffectBack );
-  }
-  else
-  {
-    SetShaderEffect( actor, mSpineEffectFront );
+    mTurningPageIndex = -1;
   }
 }
 
index 2033649..6f29d67 100644 (file)
@@ -36,15 +36,16 @@ class PageTurnLandscapeView : public PageTurnView
 public:
 
   /**
-   * Create a new PageTurnLandscapeView
-   * @return A handle to the newly allocated PageTurnLandscapeView
+   * @copydoc Toolkit::PageTurnLandscapeView::New( PageFactory&, const Vector2& )
    */
   static Toolkit::PageTurnLandscapeView New( PageFactory& pageFactory, const Vector2& pageSize );
 
 protected:
   /**
    * Constructor.
-   * It initializes the PageTurnLandscapeView members
+   * It initializes the PageTurnPortraitView members
+   * @param[in] pageFactory The factory which provides image actors to PageTurnView as the page content.
+   * @param[in] pageSize The size of the page
    */
   PageTurnLandscapeView( PageFactory& pageFactory, const Vector2& pageSize );
 
@@ -63,7 +64,7 @@ protected: // From PageTurnView
   /**
    * @copydoc PageTurnView::OnAddPage
    */
-  virtual void OnAddPage( ImageActor newPage, bool isLeftSide );
+  virtual void OnAddPage( Actor newPage, bool isLeftSide );
 
   /**
    * @copydoc PageTurnView::SetPanPosition
@@ -75,11 +76,6 @@ protected: // From PageTurnView
    */
   virtual void SetPanActor( const Vector2& panPosition );
 
-  /**
-   * @copydoc PageTurnView::SetSpineEffect
-   */
-  virtual void SetSpineEffect(ImageActor actor, bool isLeftSide);
-
 private:
 
   //Undefined
index 9fe3a00..84e9854 100644 (file)
@@ -22,7 +22,6 @@
 #include <dali/public-api/animation/animation.h>
 #include <dali/public-api/object/type-registry.h>
 #include <dali/devel-api/object/type-registry-helper.h>
-#include <dali/devel-api/rendering/cull-face.h>
 
 //INTERNAL INCLUDES
 #include <dali-toolkit/internal/controls/page-turn-view/page-turn-effect.h>
@@ -38,8 +37,6 @@ namespace Internal
 
 namespace
 {
-using namespace Dali;
-
 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::PageTurnPortraitView, Toolkit::PageTurnView, NULL )
 DALI_TYPE_REGISTRATION_END()
 
@@ -54,7 +51,6 @@ const float PAGE_TURN_OVER_ANIMATION_DURATION(0.5f);
 PageTurnPortraitView::PageTurnPortraitView( PageFactory& pageFactory, const Vector2& pageSize )
 : PageTurnView( pageFactory, pageSize )
 {
-
 }
 
 PageTurnPortraitView::~PageTurnPortraitView()
@@ -78,6 +74,9 @@ Toolkit::PageTurnPortraitView PageTurnPortraitView::New( PageFactory& pageFactor
 
 void PageTurnPortraitView::OnPageTurnViewInitialize()
 {
+  mTurnEffectShader.RegisterProperty(PROPERTY_TEXTURE_WIDTH, 1.f );
+  mSpineEffectShader.RegisterProperty(PROPERTY_TEXTURE_WIDTH, 1.f );
+
   mControlSize = mPageSize;
   Self().SetSize( mPageSize );
   mTurningPageLayer.SetParentOrigin( ParentOrigin::CENTER_LEFT );
@@ -92,24 +91,11 @@ void PageTurnPortraitView::SetPanActor( const Vector2& panPosition )
 {
   if( mCurrentPageIndex < mTotalPageCount )
   {
-    mPanActor = mPageActors[mCurrentPageIndex%NUMBER_OF_CACHED_PAGES];
     mTurningPageIndex = mCurrentPageIndex;
   }
   else
   {
-    mPanActor.Reset();
-  }
-}
-
-void PageTurnPortraitView::SetSpineEffect(ImageActor actor, bool isLeftSide)
-{
-  if(isLeftSide)
-  {
-    actor.RemoveShaderEffect();
-  }
-  else
-  {
-    actor.SetShaderEffect( mSpineEffectFront );
+    mTurningPageIndex = -1;
   }
 }
 
@@ -119,7 +105,8 @@ void PageTurnPortraitView::OnPossibleOutwardsFlick( const Vector2& panPosition,
   // There is previous page and an outwards flick is detected
   if( mCurrentPageIndex > 0 && gestureSpeed > GESTURE_SPEED_THRESHOLD && offset.x > fabs( offset.y ))
   {
-    ImageActor actor = mPageActors[ (mCurrentPageIndex-1) % NUMBER_OF_CACHED_PAGES ];
+    int actorIndex = (mCurrentPageIndex-1) % NUMBER_OF_CACHED_PAGES;
+    Actor actor = mPages[ actorIndex ].actor;
     if(actor.GetParent() != Self())
     {
       return;
@@ -136,40 +123,34 @@ void PageTurnPortraitView::OnPossibleOutwardsFlick( const Vector2& panPosition,
     RemovePage( mCurrentPageIndex+NUMBER_OF_CACHED_PAGES_EACH_SIDE );
     AddPage( mCurrentPageIndex-NUMBER_OF_CACHED_PAGES_EACH_SIDE );
     OrganizePageDepth();
+    mPageUpdated = true;
 
-    mPageActors[mTurningPageIndex%NUMBER_OF_CACHED_PAGES].SetVisible(true);
+    actor.SetVisible(true);
 
     // Add the page to tuning page layer and set up PageTurnEffect
     mShadowView.Add( actor );
-    actor.SetShaderEffect( mTurnEffect[mIndex] );
-    PageTurnApplyInternalConstraint(mTurnEffect[mIndex]);
-    mIsAnimating[mIndex] = true;
-    mTurnEffect[mIndex].SetUniform("uIsTurningBack", 1.f );
+    mPages[actorIndex].UseEffect( mTurnEffectShader );
+    mAnimatingCount++;
     Vector2 originalCenter( mPageSize.width*1.5f, 0.5f*mPageSize.height );
-    mTurnEffect[mIndex].SetUniform("uOriginalCenter", originalCenter );
-    mTurnEffect[mIndex].SetUniform("uCurrentCenter", Vector2( mPageSize.width*0.5f, mPageSize.height*0.5f ) );
+    mPages[actorIndex].SetOriginalCenter( originalCenter );
+    mPages[actorIndex].SetCurrentCenter( Vector2( mPageSize.width*0.5f, mPageSize.height*0.5f ) );
+    PageTurnApplyInternalConstraint(actor, mPageSize.height);
 
     // Start an animation to turn the previous page back
     Animation animation = Animation::New( PAGE_TURN_OVER_ANIMATION_DURATION );
     mAnimationPageIdPair[animation] = mCurrentPageIndex;
-    mAnimationIndexPair[animation] = mIndex;
 
-    animation.AnimateTo( Property( mTurnEffect[mIndex], "uCurrentCenter" ),
+    animation.AnimateTo( Property( actor, mPages[actorIndex].propertyCurrentCenter ),
                          originalCenter,
                          AlphaFunction::EASE_OUT, TimePeriod(PAGE_TURN_OVER_ANIMATION_DURATION*0.75f) );
     animation.AnimateBy( Property( actor, Actor::Property::ORIENTATION ), AngleAxis( Degree( 180.0f ), Vector3::YAXIS ) ,AlphaFunction::EASE_OUT );
     animation.Play();
 
-    ImageActor imageActor = ImageActor::DownCast(actor);
-    if( imageActor )
-    {
-      SetCullFace( imageActor, CullBack );
-    }
     animation.FinishedSignal().Connect( this, &PageTurnPortraitView::TurnedOverBackwards );
   }
 }
 
-void PageTurnPortraitView::OnTurnedOver( ImageActor actor, bool isLeftSide )
+void PageTurnPortraitView::OnTurnedOver( Actor actor, bool isLeftSide )
 {
   if( isLeftSide )
   {
@@ -179,11 +160,6 @@ void PageTurnPortraitView::OnTurnedOver( ImageActor actor, bool isLeftSide )
 
 void PageTurnPortraitView::TurnedOverBackwards( Animation& animation )
 {
-  ImageActor imageActor =  mPageActors[mAnimationPageIdPair[animation] % NUMBER_OF_CACHED_PAGES];
-  if( imageActor )
-  {
-    SetCullFace( imageActor, CullNone );
-  }
   TurnedOver( animation );
 }
 
index 0adb4e5..6fb4c62 100644 (file)
@@ -39,8 +39,7 @@ class PageTurnPortraitView : public PageTurnView
 public:
 
   /**
-   * Create a new PageTurnPortraitView
-   * @return A handle to the newly allocated PageTurnPortraitView
+   * @copydoc Toolkit::PageTurnPortraitView::New( PageFactory&, const Vector2& )
    */
   static Toolkit::PageTurnPortraitView New( PageFactory& pageFactory, const Vector2& pageSize );
 
@@ -49,6 +48,8 @@ protected:
   /**
    * Constructor.
    * It initializes the PageTurnPortraitView members
+   * @param[in] pageFactory The factory which provides image actors to PageTurnView as the page content.
+   * @param[in] pageSize The size of the page
    */
   PageTurnPortraitView( PageFactory& pageFactory, const Vector2& pageSize );
 
@@ -75,16 +76,14 @@ protected: // From PageTurnView
   virtual void SetPanActor( const Vector2& panPosition );
 
   /**
-   * @copydoc PageTurnView::SetSpineEffect
-   */
-  virtual void SetSpineEffect(ImageActor actor, bool isLeftSide);
-
-  /**
    * @copydoc PageTurnView::OnPossibleOutwardsFlick
    */
   virtual void OnPossibleOutwardsFlick( const Vector2& panPosition, float gestureSpeed );
 
-  virtual void OnTurnedOver( ImageActor actor, bool isLeftSide );
+  /**
+   * @copydoc PageTurnView::OnTurnedOver
+   */
+  virtual void OnTurnedOver( Actor actor, bool isLeftSide );
 
 private:
 
index 6db3956..19e8421 100644 (file)
 #include <cstring> // for strcmp
 #include <dali/public-api/animation/animation.h>
 #include <dali/public-api/animation/constraint.h>
-#include <dali/devel-api/events/hit-test-algorithm.h>
+#include <dali/public-api/images/resource-image.h>
 #include <dali/public-api/object/type-registry.h>
 #include <dali/devel-api/object/type-registry-helper.h>
-#include <dali/public-api/render-tasks/render-task-list.h>
-#include <dali/devel-api/rendering/cull-face.h>
+#include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/controls/page-turn-view/page-turn-effect.h>
 #include <dali-toolkit/internal/controls/page-turn-view/page-turn-book-spine-effect.h>
+#include <dali-toolkit/internal/controls/renderers/renderer-factory-cache.h>
+
+// headers needed for backward compatibility of PageFactory::NewPage(pageId) API
+#include <dali/public-api/actors/image-actor.h>
 
 using namespace Dali;
 
 namespace //Unnamed namespace
 {
-// default grid density for page turn effect, 10 pixels by 10 pixels
-const float DEFAULT_GRID_DENSITY(10.0f);
+// broken image is loaded if there is no valid image provided for the page
+const char * const BROKEN_IMAGE_URL( DALI_IMAGE_DIR "broken.png");
+
+// names of shader property map
+const char * const CUSTOM_SHADER( "shader" );
+const char * const CUSTOM_VERTEX_SHADER( "vertexShader" );
+const char * const CUSTOM_FRAGMENT_SHADER( "fragmentShader" );
+
+// name of the texture in material
+const char * const TEXTURE_NAME( "sTexture" );
+
+// properties set on shader, these properties have the constant value in regardless of the page status
+const char * const PROPERTY_SPINE_SHADOW ( "uSpineShadowParameter" ); // uniform for both spine and turn effect
+
+// properties set on actor, the value of these properties varies depending on the page status
+//    properties used in turn effect
+const char * const PROPERTY_TURN_DIRECTION( "uIsTurningBack" ); // uniform
+const char * const PROPERTY_COMMON_PARAMETERS( "uCommonParameters" ); //uniform
+
+const char * const PROPERTY_PAN_DISPLACEMENT( "panDisplacement" );// property used to constrain the uniforms
+const char * const PROPERTY_PAN_CENTER( "panCenter" );// property used to constrain the uniforms
+
+// default grid density for page turn effect, 20 pixels by 20 pixels
+const float DEFAULT_GRID_DENSITY(20.0f);
 
 // to bent the page, the minimal horizontal pan start position is pageSize.x * MINIMUM_START_POSITION_RATIO
 const float MINIMUM_START_POSITION_RATIO(0.6f);
@@ -163,7 +188,7 @@ struct CurrentCenterConstraint
       const Vector2& centerOrigin = inputs[1]->GetVector2();
       Vector2 direction = centerOrigin - Vector2(mThres, centerPosition.y);
       float coef = 1.f+(centerPosition.x*2.f / mPageWidth);
-      // Todo: when coef <= 0, the page is flat, slow down the last moment of the page stretch by 10 times to avoid a small bounce
+      // when coef <= 0, the page is flat, slow down the last moment of the page stretch by 10 times to avoid a small bounce
       if(coef < 0.025f)
       {
         coef = (coef+0.225f)/10.0f;
@@ -239,38 +264,115 @@ DALI_TYPE_REGISTRATION_END()
 }
 
 // these several constants are also used in the derived classes
+const char * const PageTurnView::PROPERTY_TEXTURE_WIDTH( "uTextureWidth" ); // uniform name
+const char * const PageTurnView::PROPERTY_ORIGINAL_CENTER( "originalCenter" ); // property used to constrain the uniform
+const char * const PageTurnView::PROPERTY_CURRENT_CENTER( "currentCenter" );// property used to constrain the uniform
 const int PageTurnView::MAXIMUM_TURNING_NUM = 4;
 const int PageTurnView::NUMBER_OF_CACHED_PAGES_EACH_SIDE = MAXIMUM_TURNING_NUM + 1;
 const int PageTurnView::NUMBER_OF_CACHED_PAGES = NUMBER_OF_CACHED_PAGES_EACH_SIDE*2;
 const float PageTurnView::STATIC_PAGE_INTERVAL_DISTANCE = 1.0f;
 
+PageTurnView::Page::Page()
+: isTurnBack( false )
+{
+  actor = Actor::New();
+  actor.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
+  actor.SetParentOrigin( ParentOrigin::CENTER_LEFT );
+  actor.SetVisible( false );
+
+  propertyPanDisplacement = actor.RegisterProperty( PROPERTY_PAN_DISPLACEMENT, 0.f );
+  propertyPanCenter = actor.RegisterProperty(PROPERTY_PAN_CENTER, Vector2::ZERO);
+
+  propertyOriginalCenter = actor.RegisterProperty(PROPERTY_ORIGINAL_CENTER, Vector2::ZERO);
+  propertyCurrentCenter = actor.RegisterProperty(PROPERTY_CURRENT_CENTER, Vector2::ZERO);
+  Matrix zeroMatrix(true);
+  actor.RegisterProperty(PROPERTY_COMMON_PARAMETERS, zeroMatrix);
+  propertyTurnDirection = actor.RegisterProperty(PROPERTY_TURN_DIRECTION, -1.f);
+}
+
+void PageTurnView::Page::SetImage( Image image  )
+{
+  if( material.GetNumberOfTextures() > 0  )
+  {
+    material.SetTextureImage( 0u, image );
+  }
+  else
+  {
+    material.AddTexture(image, TEXTURE_NAME);
+  }
+}
+
+void PageTurnView::Page::UseEffect(Shader shader)
+{
+  if( material )
+  {
+    material.SetShader( shader );
+  }
+  else
+  {
+    material = Material::New( shader );
+  }
+}
+
+void PageTurnView::Page::UseEffect(Shader shader, Geometry geometry)
+{
+  UseEffect( shader );
+
+  if( !renderer )
+  {
+    renderer = Renderer::New( geometry, material );
+    actor.AddRenderer( renderer );
+  }
+}
+
+void PageTurnView::Page::ChangeTurnDirection()
+{
+  isTurnBack = !isTurnBack;
+  actor.SetProperty( propertyTurnDirection, isTurnBack ? 1.f : -1.f );
+}
+
+void PageTurnView::Page::SetPanDisplacement(float value)
+{
+ actor.SetProperty( propertyPanDisplacement, value );
+}
+
+void PageTurnView::Page::SetPanCenter( const Vector2& value )
+{
+  actor.SetProperty( propertyPanCenter, value );
+}
+
+void PageTurnView::Page::SetOriginalCenter( const Vector2& value )
+{
+  actor.SetProperty( propertyOriginalCenter, value );
+}
+
+void PageTurnView::Page::SetCurrentCenter( const Vector2& value )
+{
+  actor.SetProperty( propertyCurrentCenter, value );
+}
+
 PageTurnView::PageTurnView( PageFactory& pageFactory, const Vector2& pageSize )
 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
-  mPageFactory( pageFactory ),
+  mPageFactory( &pageFactory ),
   mPageSize( pageSize ),
-  mTotalPageCount( 0 ),
-  mPanning( false ),
   mSpineShadowParameter( DEFAULT_SPINE_SHADOW_PARAMETER ),
+  mDistanceUpCorner( 0.f ),
+  mDistanceBottomCorner( 0.f ),
+  mPanDisplacement( 0.f ),
+  mTotalPageCount( 0 ),
   mCurrentPageIndex( 0 ),
   mTurningPageIndex( 0 ),
   mIndex( 0 ),
+  mSlidingCount( 0 ),
+  mAnimatingCount( 0 ),
+  mConstraints( false ),
   mPress( false ),
   mPageUpdated( true ),
-  mDistanceUpCorner( 0.f ),
-  mDistanceBottomCorner( 0.f ),
-  mPanDisplacement( 0.f ),
-  mConstraints( false ),
   mPageTurnStartedSignal(),
   mPageTurnFinishedSignal(),
   mPagePanStartedSignal(),
   mPagePanFinishedSignal()
 {
-  mPageActors.resize( NUMBER_OF_CACHED_PAGES );
-  mIsAnimating.resize( MAXIMUM_TURNING_NUM );
-  mIsSliding.resize( MAXIMUM_TURNING_NUM );
-  mTurnEffect.resize( MAXIMUM_TURNING_NUM );
-  mPropertyPanDisplacement.resize( MAXIMUM_TURNING_NUM );
-  mPropertyCurrentCenter.resize( MAXIMUM_TURNING_NUM );
 }
 
 PageTurnView::~PageTurnView()
@@ -279,58 +381,82 @@ PageTurnView::~PageTurnView()
 
 void PageTurnView::OnInitialize()
 {
-   // create the two book spine effect for static images, left and right side pages respectively
-  mSpineEffectFront = CreatePageTurnBookSpineEffect();
-  mSpineEffectFront.SetUniform("uIsBackImageVisible", -1.f );
-  mSpineEffectFront.SetUniform("uPageWidth", mPageSize.width );
-  mSpineEffectFront.SetUniform("uShadowWidth", 0.f );
-  mSpineEffectFront.SetUniform("uSpineShadowParameter", mSpineShadowParameter );
-
-  mSpineEffectBack = CreatePageTurnBookSpineEffect();
-  mSpineEffectBack.SetUniform("uIsBackImageVisible", 1.f );
-  mSpineEffectBack.SetUniform("uPageWidth", mPageSize.width );
-  mSpineEffectBack.SetUniform("uShadowWidth", 0.f );
-  mSpineEffectBack.SetUniform("uSpineShadowParameter", mSpineShadowParameter );
-
-  // create the page turn effect objects
-  for( int i = 0; i < MAXIMUM_TURNING_NUM; i++ )
+   // create the book spine effect for static pages
+  Property::Map spineEffectMap = CreatePageTurnBookSpineEffect();
+  mSpineEffectShader = CreateShader( spineEffectMap );
+  mSpineEffectShader.RegisterProperty(PROPERTY_SPINE_SHADOW, mSpineShadowParameter );
+  // create the turn effect for turning pages
+  Property::Map turnEffectMap = CreatePageTurnEffect();
+  mTurnEffectShader = CreateShader( turnEffectMap );
+  mTurnEffectShader.RegisterProperty(PROPERTY_SPINE_SHADOW, mSpineShadowParameter );
+
+  // create the grid geometry for pages
+  uint16_t width = static_cast<uint16_t>(mPageSize.width / DEFAULT_GRID_DENSITY + 0.5f);
+  uint16_t height = static_cast<uint16_t>(mPageSize.height / DEFAULT_GRID_DENSITY + 0.5f);
+  mGeometry = RendererFactoryCache::CreateGridGeometry( Uint16Pair( width, height ) );
+  mGeometry.SetRequiresDepthTesting( true );
+
+  mPages.reserve( NUMBER_OF_CACHED_PAGES );
+  for( int i = 0; i < NUMBER_OF_CACHED_PAGES; i++ )
   {
-    mTurnEffect[i] = CreatePageTurnEffect();
-    mTurnEffect[i].SetProperty( ShaderEffect::Property::GRID_DENSITY, Property::Value( DEFAULT_GRID_DENSITY ) );
-    mTurnEffect[i].SetUniform( "uPageSize", mPageSize );
-    mTurnEffect[i].SetUniform( "uShadowWidth", 0.f);
-    mTurnEffect[i].SetUniform( "uSpineShadowParameter", mSpineShadowParameter );
-    mIsAnimating[i] = false;
-    mIsSliding[i] = false;
-    mPropertyPanDisplacement[i] = Self().RegisterProperty("PAN_DISPLACEMENT_PROPERTY_"+i, 0.0f);
-    mPropertyCurrentCenter[i] = Self().RegisterProperty("CURRENT_CENTER_PROPERTY_"+i, Vector2(0.0f,0.0f));
+    mPages.push_back( Page() );
+    mPages[i].actor.SetSize( mPageSize );
+    Self().Add( mPages[i].actor );
   }
 
+  // create the layer for turning images
   mTurningPageLayer = Layer::New();
   mTurningPageLayer.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
   mTurningPageLayer.SetBehavior(Layer::LAYER_3D);
+  mTurningPageLayer.Raise();
 
   // Set control size and the parent origin of page layers
   OnPageTurnViewInitialize();
 
   Self().Add(mTurningPageLayer);
 
-  mTotalPageCount = static_cast<int>( mPageFactory.GetNumberOfPages() );
+  mTotalPageCount = static_cast<int>( mPageFactory->GetNumberOfPages() );
   // add pages to the scene, and set depth for the stacked pages
   for( int i = 0; i < NUMBER_OF_CACHED_PAGES_EACH_SIDE; i++ )
   {
     AddPage( i );
-    if(mPageActors[i])
-    {
-      mPageActors[i].SetZ( -static_cast<float>( i )*STATIC_PAGE_INTERVAL_DISTANCE );
-    }
+    mPages[i].actor.SetZ( -static_cast<float>( i )*STATIC_PAGE_INTERVAL_DISTANCE );
   }
-  mPageActors[0].SetVisible(true);
+  mPages[0].actor.SetVisible(true);
 
   // enable the pan gesture which is attached to the control
   EnableGestureDetection(Gesture::Type(Gesture::Pan));
 }
 
+Shader PageTurnView::CreateShader( const Property::Map& shaderMap )
+{
+  Shader shader;
+  Property::Value* shaderValue = shaderMap.Find( CUSTOM_SHADER );
+  Property::Map shaderSource;
+  if( shaderValue && shaderValue->Get( shaderSource ) )
+  {
+    std::string vertexShader;
+    Property::Value* vertexShaderValue = shaderSource.Find( CUSTOM_VERTEX_SHADER );
+    if( !vertexShaderValue || !vertexShaderValue->Get( vertexShader ) )
+    {
+      DALI_LOG_ERROR("PageTurnView::CreateShader failed: vertex shader source is not available.\n");
+    }
+    std::string fragmentShader;
+    Property::Value* fragmentShaderValue = shaderSource.Find( CUSTOM_FRAGMENT_SHADER );
+    if( !fragmentShaderValue || !fragmentShaderValue->Get( fragmentShader ) )
+    {
+      DALI_LOG_ERROR("PageTurnView::CreateShader failed: fragment shader source is not available.\n");
+    }
+    shader = Shader::New( vertexShader, fragmentShader );
+  }
+  else
+  {
+    DALI_LOG_ERROR("PageTurnView::CreateShader failed: shader source is not available.\n");
+  }
+
+  return shader;
+}
+
 void PageTurnView::SetupShadowView()
 {
   mShadowView = Toolkit::ShadowView::New( 0.25f, 0.25f );
@@ -362,31 +488,20 @@ void PageTurnView::OnStageConnection( int depth )
   Control::OnStageConnection( depth );
 
   SetupShadowView();
-  mTurningPageLayer.Raise();
 }
 
 void PageTurnView::OnStageDisconnection()
 {
   if(mShadowView)
   {
+    mShadowView.RemoveConstraints();
     mPointLight.Unparent();
     mShadowPlaneBackground.Unparent();
     mShadowView.Unparent();
   }
 
   // make sure the status of the control is updated correctly when the pan gesture is interrupted
-  if(mPanning)
-  {
-    mPanning = false;
-
-    Self().Add(mPanActor);
-    mIsAnimating[mIndex] = false;
-    mPanActor.RemoveConstraints();
-    mTurnEffect[mIndex].RemoveConstraints();
-    mPageUpdated = true;
-
-    SetSpineEffect( mPanActor, mIsTurnBack[mPanActor] );
-  }
+  StopTurning();
 
   Control::OnStageDisconnection();
 }
@@ -394,28 +509,15 @@ void PageTurnView::OnStageDisconnection()
 void PageTurnView::SetPageSize( const Vector2& pageSize )
 {
   mPageSize = pageSize;
-  mSpineEffectFront.SetUniform("uPageWidth", mPageSize.width );
-  mSpineEffectBack.SetUniform("uPageWidth", mPageSize.width );
-  for( int i = 0; i < MAXIMUM_TURNING_NUM; i++ )
-  {
-    mTurnEffect[i].SetUniform( "uPageSize", mPageSize );
-  }
 
   if( mPointLight )
   {
     mPointLight.SetPosition( 0.f, 0.f, mPageSize.width*POINT_LIGHT_HEIGHT_RATIO );
   }
 
-  for( size_t i=0; i<mPageActors.size(); i++ )
+  for( size_t i=0; i<mPages.size(); i++ )
   {
-    if( mPageActors[i] )
-    {
-      mPageActors[i].SetSize( mPageSize );
-      if( mPageActors[i].GetChildCount()>0 )
-      {
-        mPageActors[i].GetChildAt(0).SetSize( mPageSize );
-      }
-    }
+    mPages[i].actor.SetSize( mPageSize );
   }
 
   OnPageTurnViewInitialize();
@@ -436,12 +538,8 @@ void PageTurnView::SetSpineShadowParameter( const Vector2& spineShadowParameter
   mSpineShadowParameter = spineShadowParameter;
 
   // set spine shadow parameter to all the shader effects
-  mSpineEffectFront.SetUniform("uSpineShadowParameter", mSpineShadowParameter );
-  mSpineEffectBack.SetUniform("uSpineShadowParameter", mSpineShadowParameter );
-  for( int i = 0; i < MAXIMUM_TURNING_NUM; i++ )
-  {
-    mTurnEffect[i].SetUniform("uSpineShadowParameter", mSpineShadowParameter );
-  }
+  mSpineEffectShader.RegisterProperty(PROPERTY_SPINE_SHADOW, mSpineShadowParameter );
+  mTurnEffectShader.RegisterProperty(PROPERTY_SPINE_SHADOW, mSpineShadowParameter );
 }
 
 Vector2 PageTurnView::GetSpineShadowParameter()
@@ -458,18 +556,12 @@ void PageTurnView::GoToPage( unsigned int pageId )
     return;
   }
 
+  // if any animation ongoing, stop it.
+  StopTurning();
+
   // record the new current page index
   mCurrentPageIndex = pageIdx;
 
-  // clear the old pages
-  for(int i = 0; i < NUMBER_OF_CACHED_PAGES; i++ )
-  {
-    if( mPageActors[i] )
-    {
-      mPageActors[i].Unparent();
-      mPageActors[i].Reset();
-    }
-  }
 
   // add the current page and the pages right before and after it
   for( int i = pageIdx - NUMBER_OF_CACHED_PAGES_EACH_SIDE; i < pageIdx + NUMBER_OF_CACHED_PAGES_EACH_SIDE; i++ )
@@ -477,10 +569,10 @@ void PageTurnView::GoToPage( unsigned int pageId )
     AddPage( i );
   }
 
-  mPageActors[pageId%NUMBER_OF_CACHED_PAGES].SetVisible(true);
+  mPages[pageId%NUMBER_OF_CACHED_PAGES].actor.SetVisible(true);
   if( pageId > 0 )
   {
-    mPageActors[(pageId-1)%NUMBER_OF_CACHED_PAGES].SetVisible(true);
+    mPages[(pageId-1)%NUMBER_OF_CACHED_PAGES].actor.SetVisible(true);
   }
   // set ordered depth to the stacked pages
   OrganizePageDepth();
@@ -497,32 +589,30 @@ void PageTurnView::AddPage( int pageIndex )
   if(pageIndex > -1  && pageIndex < mTotalPageCount) // whether the page is available from the page factory
   {
     int index = pageIndex % NUMBER_OF_CACHED_PAGES;
-    ImageActor newPage= ImageActor::DownCast( mPageFactory.NewPage( pageIndex ) );
-     DALI_ASSERT_ALWAYS( newPage );
 
-    newPage.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
-    newPage.SetParentOrigin( ParentOrigin::CENTER_LEFT );
-    newPage.SetSize( mPageSize );
-    Self().Add( newPage );
-    mPageActors[index] = newPage;
+    Image newPageImage;
+    newPageImage = mPageFactory->NewPage( pageIndex );
 
-    bool isLeftSide = ( pageIndex < mCurrentPageIndex );
-    mIsTurnBack[ newPage ] = isLeftSide;
-    if( isLeftSide )
+    if( !newPageImage ) // load the broken image
     {
-      // new page is added to the left side, so need to rotate it 180 degrees
-      newPage.RotateBy( Degree(-180.0f ), Vector3::YAXIS );
+      newPageImage = ResourceImage::New( BROKEN_IMAGE_URL );
     }
-    else
+
+    bool isLeftSide = ( pageIndex < mCurrentPageIndex );
+    if( mPages[index].isTurnBack != isLeftSide )
     {
-      newPage.SetShaderEffect(mSpineEffectFront);
+      mPages[index].ChangeTurnDirection();
     }
 
-    newPage.SetVisible( false );
+    float degree = isLeftSide ? 180.f :0.f;
+    mPages[index].actor.SetOrientation( Degree( degree ), Vector3::YAXIS );
+    mPages[index].actor.SetVisible( false );
+    mPages[index].UseEffect( mSpineEffectShader, mGeometry );
+    mPages[index].SetImage( newPageImage );
 
     // For Portrait, nothing to do
-    // For Landscape, set spineEffectBack to the new effect if it is in the left side, and set properties to the back image actor if it exists
-    OnAddPage( newPage, isLeftSide );
+    // For Landscape, set the parent origin to CENTER
+     OnAddPage( mPages[index].actor, isLeftSide );
   }
 }
 
@@ -531,9 +621,7 @@ void PageTurnView::RemovePage( int pageIndex )
   if( pageIndex > -1 && pageIndex < mTotalPageCount)
   {
     int index = pageIndex % NUMBER_OF_CACHED_PAGES;
-    mPageActors[index].Unparent();
-    mIsTurnBack.erase( mPageActors[index] );
-    mPageActors[index].Reset();
+    mPages[index].actor.SetVisible(false);
   }
 }
 
@@ -544,38 +632,19 @@ void PageTurnView::OnPan( const PanGesture& gesture )
   {
     case Gesture::Started:
     {
-      mPanning = true;
-      // to find out whether the undergoing turning page number already reaches the maximum allowed
-      // and get one idle index when it is animatable
-      bool animatable = false;
-      for( int i = 0; i < MAXIMUM_TURNING_NUM; i++ )
-      {
-        if( !mIsAnimating[mIndex] )
-        {
-          animatable = true;
-          break;
-        }
-        if( mIsSliding[mIndex] )
-        {
-          animatable = false;
-          break;
-        }
-        mIndex++;
-        mIndex = mIndex % MAXIMUM_TURNING_NUM;
-      }
-
-      if( mPageUpdated && animatable )
+      // check whether the undergoing turning page number already reaches the maximum allowed
+      if( mPageUpdated && mAnimatingCount< MAXIMUM_TURNING_NUM && mSlidingCount < 1 )
       {
         SetPanActor( gesture.position ); // determine which page actor is panned
-        if(mPanActor && mPanActor.GetParent() != Self()) // if the page is added to turning layer,it is undergoing an animation currently
+        if( mTurningPageIndex != -1 && mPages[mTurningPageIndex % NUMBER_OF_CACHED_PAGES].actor.GetParent() != Self()) // if the page is added to turning layer,it is undergoing an animation currently
         {
-          mPanActor.Reset();
+          mTurningPageIndex = -1;
         }
         PanStarted( SetPanPosition( gesture.position ) );  // pass in the pan position in the local page coordinate
       }
       else
       {
-        mPanActor.Reset();
+        mTurningPageIndex = -1;
       }
       break;
     }
@@ -587,7 +656,6 @@ void PageTurnView::OnPan( const PanGesture& gesture )
     case Gesture::Finished:
     case Gesture::Cancelled:
     {
-      mPanning = false;
       PanFinished( SetPanPosition( gesture.position ), gesture.GetSpeed() );
       break;
     }
@@ -604,13 +672,14 @@ void PageTurnView::PanStarted( const Vector2& gesturePosition )
 {
   mPressDownPosition = gesturePosition;
 
-  if( !mPanActor )
+  if( mTurningPageIndex == -1 )
   {
     return;
   }
 
+  mIndex = mTurningPageIndex % NUMBER_OF_CACHED_PAGES;
+
   mOriginalCenter = gesturePosition;
-  mTurnEffect[mIndex].SetUniform("uIsTurningBack", mIsTurnBack[ mPanActor] ? 1.f : -1.f);
   mPress = false;
   mPageUpdated = false;
 
@@ -621,7 +690,7 @@ void PageTurnView::PanStarted( const Vector2& gesturePosition )
 
 void PageTurnView::PanContinuing( const Vector2& gesturePosition )
 {
-  if( !mPanActor )
+  if( mTurningPageIndex == -1  )
   {
     return;
   }
@@ -645,31 +714,31 @@ void PageTurnView::PanContinuing( const Vector2& gesturePosition )
     {
       mDistanceUpCorner = mOriginalCenter.Length();
       mDistanceBottomCorner = ( mOriginalCenter - Vector2( 0.0f, mPageSize.height ) ).Length();
-      mShadowView.Add( mPanActor );
-      SetShaderEffect( mPanActor, mTurnEffect[mIndex] );
-      mTurnEffect[mIndex].SetUniform("uOriginalCenter", mOriginalCenter );
+      mShadowView.Add( mPages[mIndex].actor );
+      mPages[mIndex].UseEffect( mTurnEffectShader );
+      mPages[mIndex].SetOriginalCenter( mOriginalCenter );
       mCurrentCenter = mOriginalCenter;
-      mTurnEffect[mIndex].SetUniform("uCurrentCenter", mCurrentCenter );
+      mPages[mIndex].SetCurrentCenter( mCurrentCenter );
       mPanDisplacement = 0.f;
-      mConstraints = true;
+      mConstraints = false;
       mPress = true;
-      mIsAnimating[mIndex] = true;
+      mAnimatingCount++;
 
-      mPageTurnStartedSignal.Emit( handle, static_cast<unsigned int>(mTurningPageIndex), !mIsTurnBack[mPanActor] );
-      int id = mTurningPageIndex + (mIsTurnBack[mPanActor]? -1 : 1);
+      mPageTurnStartedSignal.Emit( handle, static_cast<unsigned int>(mTurningPageIndex), !mPages[mIndex].isTurnBack );
+      int id = mTurningPageIndex + (mPages[mIndex].isTurnBack ? -1 : 1);
       if( id >=0 && id < mTotalPageCount )
       {
-        mPageActors[id%NUMBER_OF_CACHED_PAGES].SetVisible(true);
+        mPages[id%NUMBER_OF_CACHED_PAGES].actor.SetVisible(true);
       }
 
       mShadowView.RemoveConstraints();
       Actor self = Self();
-      self.SetProperty( mPropertyPanDisplacement[mIndex], 0.f );
+      mPages[mIndex].SetPanDisplacement( 0.f );
 
       Constraint shadowBlurStrengthConstraint = Constraint::New<float>( mShadowView, mShadowView.GetBlurStrengthPropertyIndex(), ShadowBlurStrengthConstraint( mPageSize.width*PAGE_TURN_OVER_THRESHOLD_RATIO ) );
-      shadowBlurStrengthConstraint.AddSource( Source(mTurnEffect[mIndex],  mTurnEffect[mIndex].GetPropertyIndex("uCurrentCenter")) );
-      shadowBlurStrengthConstraint.AddSource( Source(mTurnEffect[mIndex],  mTurnEffect[mIndex].GetPropertyIndex("uOriginalCenter")) );
-      shadowBlurStrengthConstraint.AddSource( Source( self, mPropertyPanDisplacement[mIndex] ) );
+      shadowBlurStrengthConstraint.AddSource( Source(mPages[mIndex].actor,  mPages[mIndex].propertyCurrentCenter) );
+      shadowBlurStrengthConstraint.AddSource( Source(mPages[mIndex].actor,  mPages[mIndex].propertyOriginalCenter) );
+      shadowBlurStrengthConstraint.AddSource( Source(mPages[mIndex].actor,  mPages[mIndex].propertyPanDisplacement) );
       shadowBlurStrengthConstraint.Apply();
     }
   }
@@ -709,12 +778,12 @@ void PageTurnView::PanContinuing( const Vector2& gesturePosition )
     {
       // set the property values used by the constraints
       mPanDisplacement = mPageSize.width*PAGE_TURN_OVER_THRESHOLD_RATIO - currentCenter.x;
-      Self().SetProperty( mPropertyPanDisplacement[mIndex], mPanDisplacement );
-      Self().SetProperty( mPropertyCurrentCenter[mIndex], currentCenter );
+      mPages[mIndex].SetPanDisplacement( mPanDisplacement );
+      mPages[mIndex].SetPanCenter( currentCenter );
 
       // set up the OriginalCenterConstraint and CurrentCebterConstraint to the PageTurnEdffect
       // also set up the RotationConstraint to the page actor
-      if( mConstraints )
+      if( !mConstraints )
       {
         Vector2 corner;
         // the corner position need to be a little far away from the page edge to ensure the whole page is lift up
@@ -733,41 +802,38 @@ void PageTurnView::PanContinuing( const Vector2& gesturePosition )
         offset *= k;
         Actor self = Self();
 
-        Property::Index shaderOriginalCenterPropertyIndex = mTurnEffect[mIndex].GetPropertyIndex("uOriginalCenter");
-        Constraint originalCenterConstraint = Constraint::New<Vector2>( mTurnEffect[mIndex], shaderOriginalCenterPropertyIndex, OriginalCenterConstraint( mOriginalCenter, offset ));
-        originalCenterConstraint.AddSource( Source( self, mPropertyPanDisplacement[mIndex] ) );
+        Constraint originalCenterConstraint = Constraint::New<Vector2>( mPages[mIndex].actor, mPages[mIndex].propertyOriginalCenter, OriginalCenterConstraint( mOriginalCenter, offset ));
+        originalCenterConstraint.AddSource( Source( mPages[mIndex].actor, mPages[mIndex].propertyPanDisplacement ) );
         originalCenterConstraint.Apply();
 
-        Property::Index shaderCurrentCenterPropertyIndex = mTurnEffect[mIndex].GetPropertyIndex("uCurrentCenter");
-        Constraint currentCenterConstraint = Constraint::New<Vector2>( mTurnEffect[mIndex], shaderCurrentCenterPropertyIndex, CurrentCenterConstraint(mPageSize.width));
-        currentCenterConstraint.AddSource( Source(self, mPropertyCurrentCenter[mIndex]) );
-        currentCenterConstraint.AddSource( Source(mTurnEffect[mIndex], shaderOriginalCenterPropertyIndex) );
+        Constraint currentCenterConstraint = Constraint::New<Vector2>( mPages[mIndex].actor, mPages[mIndex].propertyCurrentCenter, CurrentCenterConstraint(mPageSize.width));
+        currentCenterConstraint.AddSource( Source( mPages[mIndex].actor, mPages[mIndex].propertyPanCenter ) );
+        currentCenterConstraint.AddSource( Source( mPages[mIndex].actor, mPages[mIndex].propertyOriginalCenter ) );
         currentCenterConstraint.Apply();
 
-        PageTurnApplyInternalConstraint(mTurnEffect[mIndex]);
+        PageTurnApplyInternalConstraint( mPages[mIndex].actor, mPageSize.height );
 
         float distance = offset.Length();
-        Constraint rotationConstraint = Constraint::New<Quaternion>( mPanActor, Actor::Property::ORIENTATION, RotationConstraint(distance, mPageSize.width, mIsTurnBack[mPanActor]));
-        rotationConstraint.AddSource( Source( self, mPropertyPanDisplacement[mIndex] ) );
+        Constraint rotationConstraint = Constraint::New<Quaternion>( mPages[mIndex].actor, Actor::Property::ORIENTATION, RotationConstraint(distance, mPageSize.width, mPages[mIndex].isTurnBack));
+        rotationConstraint.AddSource( Source( mPages[mIndex].actor, mPages[mIndex].propertyPanDisplacement ) );
         rotationConstraint.Apply();
 
-        mConstraints = false;
+        mConstraints = true;
       }
     }
     else
     {
-      if(!mConstraints) // remove the constraint is the pan position move back to far away from the spine
+      if(mConstraints) // remove the constraint is the pan position move back to far away from the spine
       {
-        mPanActor.RemoveConstraints();
-        mTurnEffect[mIndex].RemoveConstraints();
-        mTurnEffect[mIndex].SetUniform("uOriginalCenter",mOriginalCenter );
-        mConstraints = true;
+        mPages[mIndex].actor.RemoveConstraints();
+        mPages[mIndex].SetOriginalCenter(mOriginalCenter );
+        mConstraints = false;
         mPanDisplacement = 0.f;
       }
 
-      mTurnEffect[mIndex].SetUniform("uCurrentCenter", currentCenter );
+      mPages[mIndex].SetCurrentCenter( currentCenter );
       mCurrentCenter = currentCenter;
-      PageTurnApplyInternalConstraint(mTurnEffect[mIndex]);
+      PageTurnApplyInternalConstraint(mPages[mIndex].actor, mPageSize.height );
     }
   }
 }
@@ -777,25 +843,25 @@ void PageTurnView::PanFinished( const Vector2& gesturePosition, float gestureSpe
   // Guard against destruction during signal emission
   Toolkit::PageTurnView handle( GetOwner() );
 
-  if( !mPanActor )
+  if( mTurningPageIndex == -1  )
   {
-    if(!mIsAnimating[mIndex])
+    if( mAnimatingCount< MAXIMUM_TURNING_NUM && mSlidingCount < 1)
     {
       OnPossibleOutwardsFlick( gesturePosition, gestureSpeed );
     }
+
     return;
   }
 
   mPagePanFinishedSignal.Emit( handle );
 
-  ImageActor actor = mPanActor;
   if(mPress)
   {
-    if(!mConstraints) // if with constraints, the pan finished position is near spine, set up an animation to turn the page over
+    if(mConstraints) // if with constraints, the pan finished position is near spine, set up an animation to turn the page over
     {
       // update the pages here instead of in the TurnedOver callback function
       // as new page is allowed to respond to the pan gesture before other pages finishing animation
-      if(mIsTurnBack[actor])
+      if(mPages[mIndex].isTurnBack)
       {
         mCurrentPageIndex--;
         RemovePage( mCurrentPageIndex+NUMBER_OF_CACHED_PAGES_EACH_SIDE );
@@ -810,30 +876,27 @@ void PageTurnView::PanFinished( const Vector2& gesturePosition, float gestureSpe
       OrganizePageDepth();
 
       // set up an animation to turn the page over
-      Actor self = Self();
       float width = mPageSize.width*(1.f+PAGE_TURN_OVER_THRESHOLD_RATIO);
       Animation animation = Animation::New( std::max(0.1f,PAGE_TURN_OVER_ANIMATION_DURATION * (1.0f - mPanDisplacement / width)) );
-      animation.AnimateTo( Property(self, mPropertyPanDisplacement[mIndex]),
+      animation.AnimateTo( Property(mPages[mIndex].actor, mPages[mIndex].propertyPanDisplacement),
                            width,AlphaFunction::EASE_OUT_SINE);
-      animation.AnimateTo( Property(self, mPropertyCurrentCenter[mIndex]),
+      animation.AnimateTo( Property(mPages[mIndex].actor, mPages[mIndex].propertyPanCenter),
                            Vector2(-mPageSize.width*1.1f, 0.5f*mPageSize.height), AlphaFunction::EASE_OUT_SINE);
       mAnimationPageIdPair[animation] = mTurningPageIndex;
-      mAnimationIndexPair[animation] = mIndex;
       animation.Play();
       animation.FinishedSignal().Connect( this, &PageTurnView::TurnedOver );
     }
     else // the pan finished position is far away from the spine, set up an animation to slide the page back instead of turning over
     {
       Animation animation= Animation::New( PAGE_SLIDE_BACK_ANIMATION_DURATION * (mOriginalCenter.x - mCurrentCenter.x) / mPageSize.width / PAGE_TURN_OVER_THRESHOLD_RATIO );
-      animation.AnimateTo( Property( mTurnEffect[mIndex], "uCurrentCenter" ),
+      animation.AnimateTo( Property( mPages[mIndex].actor, mPages[mIndex].propertyCurrentCenter ),
                            mOriginalCenter, AlphaFunction::LINEAR );
       mAnimationPageIdPair[animation] = mTurningPageIndex;
-      mAnimationIndexPair[animation] = mIndex;
       animation.Play();
-      mIsSliding[mIndex] = true;
+      mSlidingCount++;
       animation.FinishedSignal().Connect( this, &PageTurnView::SliddenBack );
 
-      mPageTurnStartedSignal.Emit( handle, static_cast<unsigned int>(mTurningPageIndex), mIsTurnBack[actor] );
+      mPageTurnStartedSignal.Emit( handle, static_cast<unsigned int>(mTurningPageIndex), mPages[mIndex].isTurnBack );
     }
   }
   else
@@ -842,60 +905,57 @@ void PageTurnView::PanFinished( const Vector2& gesturePosition, float gestureSpe
     // In landscape view, nothing to do
     OnPossibleOutwardsFlick( gesturePosition, gestureSpeed );
   }
-
   mPageUpdated = true;
 }
 
 void PageTurnView::TurnedOver( Animation& animation )
 {
   int pageId = mAnimationPageIdPair[animation];
-  ImageActor actor = mPageActors[pageId % NUMBER_OF_CACHED_PAGES];
-  mIsTurnBack[actor] = !mIsTurnBack[actor];
-  actor.RemoveConstraints();
-  Self().Add(actor);
-  int index = mAnimationIndexPair[animation];
-  mIsAnimating[index] = false;
-  mTurnEffect[index].RemoveConstraints();
-  mAnimationIndexPair.erase( animation );
+  int index = pageId%NUMBER_OF_CACHED_PAGES;
+
+  mPages[index].ChangeTurnDirection();
+  mPages[index].actor.RemoveConstraints();
+  Self().Add(mPages[index].actor);
+  mAnimatingCount--;
   mAnimationPageIdPair.erase( animation );
 
-  SetSpineEffect( actor, mIsTurnBack[actor] );
+  float degree = mPages[index].isTurnBack ? 180.f : 0.f;
+  mPages[index].actor.SetOrientation( Degree(degree), Vector3::YAXIS );
+  mPages[index].UseEffect( mSpineEffectShader );
 
-  int id = pageId + (mIsTurnBack[actor]? -1 : 1);
+  int id = pageId + (mPages[index].isTurnBack ? -1 : 1);
   if( id >=0 && id < mTotalPageCount )
   {
-    mPageActors[id%NUMBER_OF_CACHED_PAGES].SetVisible(false);
+    mPages[id%NUMBER_OF_CACHED_PAGES].actor.SetVisible(false);
   }
 
-  OnTurnedOver( actor, mIsTurnBack[actor] );
+  OnTurnedOver( mPages[index].actor, mPages[index].isTurnBack );
 
   // Guard against destruction during signal emission
   Toolkit::PageTurnView handle( GetOwner() );
-  mPageTurnFinishedSignal.Emit( handle, static_cast<unsigned int>(pageId), mIsTurnBack[actor] );
+  mPageTurnFinishedSignal.Emit( handle, static_cast<unsigned int>(pageId), mPages[index].isTurnBack );
 }
 
 void PageTurnView::SliddenBack( Animation& animation )
 {
   int pageId = mAnimationPageIdPair[animation];
-  ImageActor actor = mPageActors[pageId % NUMBER_OF_CACHED_PAGES];
-  Self().Add(actor);
-  int index = mAnimationIndexPair[animation];
-  mIsSliding[index] = false;
-  mIsAnimating[index] = false;
-  mAnimationIndexPair.erase( animation );
+  int index = pageId%NUMBER_OF_CACHED_PAGES;
+  Self().Add(mPages[index].actor);
+  mSlidingCount--;
+  mAnimatingCount--;
   mAnimationPageIdPair.erase( animation );
 
-  SetSpineEffect( actor, mIsTurnBack[actor] );
+  mPages[index].UseEffect( mSpineEffectShader );
 
-  int id = pageId + (mIsTurnBack[actor]? -1 : 1);
+  int id = pageId + (mPages[index].isTurnBack ? -1 : 1);
   if( id >=0 && id < mTotalPageCount )
   {
-    mPageActors[id%NUMBER_OF_CACHED_PAGES].SetVisible(false);
+    mPages[id%NUMBER_OF_CACHED_PAGES].actor.SetVisible(false);
   }
 
   // Guard against destruction during signal emission
   Toolkit::PageTurnView handle( GetOwner() );
-  mPageTurnFinishedSignal.Emit( handle, static_cast<unsigned int>(pageId), mIsTurnBack[actor] );
+  mPageTurnFinishedSignal.Emit( handle, static_cast<unsigned int>(pageId), mPages[index].isTurnBack );
 }
 
 void PageTurnView::OrganizePageDepth()
@@ -904,18 +964,38 @@ void PageTurnView::OrganizePageDepth()
   {
     if(mCurrentPageIndex+i < mTotalPageCount)
     {
-      mPageActors[( mCurrentPageIndex+i )%NUMBER_OF_CACHED_PAGES].SetZ( -static_cast<float>( i )*STATIC_PAGE_INTERVAL_DISTANCE );
+      mPages[( mCurrentPageIndex+i )%NUMBER_OF_CACHED_PAGES].actor.SetZ( -static_cast<float>( i )*STATIC_PAGE_INTERVAL_DISTANCE );
     }
     if( mCurrentPageIndex >= i + 1 )
     {
-      mPageActors[( mCurrentPageIndex-i-1 )%NUMBER_OF_CACHED_PAGES].SetZ( -static_cast<float>( i )*STATIC_PAGE_INTERVAL_DISTANCE );
+      mPages[( mCurrentPageIndex-i-1 )%NUMBER_OF_CACHED_PAGES].actor.SetZ( -static_cast<float>( i )*STATIC_PAGE_INTERVAL_DISTANCE );
     }
   }
 }
 
-void PageTurnView::SetShaderEffect( ImageActor actor, ShaderEffect shaderEffect )
+void PageTurnView::StopTurning()
 {
-  SetShaderEffectRecursively( actor, shaderEffect );
+  mAnimatingCount = 0;
+  mSlidingCount = 0;
+
+  if( !mPageUpdated )
+  {
+    int index = mTurningPageIndex % NUMBER_OF_CACHED_PAGES;
+    Self().Add( mPages[ index ].actor );
+    mPages[ index ].actor.RemoveConstraints();
+    mPages[ index ].UseEffect( mSpineEffectShader );
+    float degree = mTurningPageIndex==mCurrentPageIndex ? 0.f :180.f;
+    mPages[index].actor.SetOrientation( Degree(degree), Vector3::YAXIS );
+    mPageUpdated = true;
+  }
+
+  if( !mAnimationPageIdPair.empty() )
+  {
+    for (std::map<Animation,int>::iterator it=mAnimationPageIdPair.begin(); it!=mAnimationPageIdPair.end(); ++it)
+    {
+      static_cast<Animation>(it->first).SetCurrentProgress( 1.f );
+    }
+  }
 }
 
 Toolkit::PageTurnView::PageTurnSignal& PageTurnView::PageTurnStartedSignal()
index 91a714f..e17f2a0 100644 (file)
 // EXTERNAL INCLUDES
 #include <dali/devel-api/common/map-wrapper.h>
 #include <dali/public-api/actors/layer.h>
-#include <dali/public-api/actors/camera-actor.h>
-#include <dali/public-api/actors/image-actor.h>
-#include <dali/public-api/images/frame-buffer-image.h>
-#include <dali/public-api/render-tasks/render-task.h>
+#include <dali/devel-api/rendering/renderer.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-impl.h>
@@ -46,6 +43,82 @@ class PageTurnView : public Control
 protected:
 
   /**
+   * The book page class
+   */
+  struct Page
+  {
+    /**
+     * Constructor
+     */
+    Page();
+    /**
+     * Destructor
+     */
+    ~Page(){};
+
+    /**
+     * Set the page image content
+     * @param[in] image The content of the page.
+     */
+    void SetImage( Image image );
+
+    /**
+     * Apply an effect onto the page actor.
+     * @param[in] shader The shader for rendering effect.
+     */
+    void UseEffect(Shader shader);
+
+    /**
+     * Apply an effect onto the page actor.
+     * @param[in] shader The shader for rendering effect.
+     * @param[in] geometry The geometry for rendering effect.
+     */
+    void UseEffect(Shader shader, Geometry geometry);
+
+    /**
+     * Change the page turning direction.
+     */
+    void ChangeTurnDirection();
+
+    /**
+     * Set the pan displacement property
+     * @param[in] value The property value
+     */
+    void SetPanDisplacement(float value);
+
+    /**
+     * Set the pan center property
+     * @param[in] value The property value
+     */
+    void SetPanCenter( const Vector2& value );
+
+    /**
+     * Set the original center property to be used by shader
+     * @param[in] value The property value
+     */
+    void SetOriginalCenter( const Vector2& value );
+
+    /**
+     * Set the current center property to be used by shader
+     * @param[in] value The property value
+     */
+    void SetCurrentCenter( const Vector2& value );
+
+    Actor actor;                              ///< The page actor
+    Material material;                        ///< The material of the actor
+    Renderer renderer;                        ///< The renderer of the actor
+    bool isTurnBack;                          ///< The turning direction
+    Property::Index propertyPanDisplacement;  ///< The horizontal displacement of the pan
+    Property::Index propertyPanCenter;        ///< The current pan position
+    Property::Index propertyOriginalCenter;   ///< The original center to be used by the shader
+    Property::Index propertyCurrentCenter;    ///< The current center to be used by the shader
+    Property::Index propertyTurnDirection;    ///< The turning direction property
+  };
+
+
+protected:
+
+  /**
    * Constructor.
    * It initializes the PageTurnView members
    */
@@ -125,15 +198,14 @@ protected:
    */
   void OrganizePageDepth();
 
+private:
+
   /**
-   * Set shader Effect to the actor.
-   * If the actor has children, the shader effect is also applied to its first child
-   * @param[in] actor The actor which the shader effect would be applied onto
-   * @param[in] shaderEffect The shader effect to be set to the actor
+   * Create shader from a property map.
+   * @param[in] shaderMap The shader property map;
+   * @return The created shader.
    */
-  void SetShaderEffect( ImageActor actor, ShaderEffect shaderEffect );
-
-private:
+  Shader CreateShader( const Property::Map& shaderMap );
 
  /**
   * Set up the shadow view control to cast shadow
@@ -166,6 +238,11 @@ private:
    */
   void SliddenBack( Animation& animation );
 
+  /**
+   * Stop the page turning animation and contraint.
+   * This method should be called when taking off stage or jump to a specified page.
+   */
+  void StopTurning();
 
 private: // from Control
 
@@ -204,7 +281,7 @@ private: // implemented differently by PageTurnLandscapeView and PageTurnPortrai
    * @param[in] newPage The added page actor
    * @param[in] isLeftSide Which side the new page is added to
    */
-  virtual void OnAddPage( ImageActor newPage, bool isLeftSide ) { }
+  virtual void OnAddPage( Actor newPage, bool isLeftSide ) { }
 
   /**
    * This method is called when pan started or continuing
@@ -223,15 +300,6 @@ private: // implemented differently by PageTurnLandscapeView and PageTurnPortrai
   virtual void SetPanActor( const Vector2& panPosition ) = 0;
 
   /**
-   * This method is called when a page is turned over or slidden back
-   * Remove PageTurnEffect and use a proper PageTurnBookSpineEffect
-   * Implemented in subclasses to provide specific behaviour.
-   * @param[in] actor The current page actor
-   * @param[in] isLeftSide Which side the current page is located
-   */
-  virtual void SetSpineEffect(ImageActor actor, bool isLeftSide) = 0;
-
-  /**
    * This method is called when pan finished to detect outwards flick
    * In portrait view, start an animation of turning previous page back when outwards flick is detected
    * In landscape view, nothing to do
@@ -246,7 +314,7 @@ private: // implemented differently by PageTurnLandscapeView and PageTurnPortrai
    * @param[in] actor The page actor
    * @param[in] isLeftSide Which side the page is turned to
    */
-  virtual void OnTurnedOver( ImageActor actor, bool isLeftSide ) { }
+  virtual void OnTurnedOver( Actor actor, bool isLeftSide ) { }
 
 public: //signal and property
 
@@ -309,53 +377,50 @@ private:
 
 protected:
 
-  Vector2                        mControlSize;             ///< The size of the control, it is decided by the page size, the SetSize from application can not change it
   Layer                          mTurningPageLayer;        ///< The layer for the turning page, to avoid possible depth conflict
   Toolkit::ShadowView            mShadowView;              ///< The shadow view control for shadow casting
   Actor                          mShadowPlaneBackground;   ///< The plane for the shadow to cast on
   Actor                          mPointLight;              ///< The point light used for shadow casting
 
-  PageFactory&                   mPageFactory;             ///< The page factory which provides the page actors
-  Vector2                        mPageSize;                ///< The page size
-  int                            mTotalPageCount;          ///< The total number of pages provided by the page factory
+  PageFactory* const             mPageFactory;             ///< The factory which provides the page actors
+  Shader                         mTurnEffectShader;        ///< The group of PageTurnEffects
+  Shader                         mSpineEffectShader;       ///< The book spine shader effect
+  Geometry                       mGeometry;                ///< The grid geometry for pages
 
-  bool                           mPanning;                 ///< The boolean to indicate whether the pan gesture is continuing
+  std::vector<Page>              mPages;                   ///< The vector of pages on stage
+  std::map<Animation,int>        mAnimationPageIdPair;     ///< The map to keep track which page actor is the animation act on
 
-  std::vector<ShaderEffect>      mTurnEffect;              ///< The group of PageTurnEffects
-  ShaderEffect                   mSpineEffectFront;        ///< The book spine shader effect without flipping image content
-  ShaderEffect                   mSpineEffectBack;         ///< The book spine shader effect with image content flipped
+  Vector2                        mPageSize;                ///< The page size
+  Vector2                        mControlSize;             ///< The size of the control, it is decided by the page size, the SetSize from application can not change it
   Vector2                        mSpineShadowParameter;    ///< The spine shadow parameter for all the above shader effects
   Vector2                        mOriginalCenter;          ///< The original center set to the PageTurnEffect
   Vector2                        mCurrentCenter;           ///< The current center set to the PageTurnEffect
-
-  std::vector<ImageActor>        mPageActors;              ///< The vector of pages on stage
-  int                            mCurrentPageIndex;        ///< The index of the current page, between 0 ~ mTotalPageCount-1
-  int                            mTurningPageIndex;        ///< The index of the turning page
-  std::map<ImageActor,bool>      mIsTurnBack;              ///< The map to keep track the page actor's turning direction
-  std::map<Animation,int>        mAnimationPageIdPair;     ///< The map to keep track which page actor is the animation act on
-  std::map<Animation, int>       mAnimationIndexPair;      ///< The map to keep track which PageTurnEffect, PanDisplacementProperty, CurrentCenterProperty is used for the animation
-  int                            mIndex;                   ///< The index to keep track which PageTurnEffect, PanDisplacementProperty, CurrentCenterProperty is used for the current panning page
-  std::vector<bool>              mIsAnimating;             ///< The boolean vector to keep track which PageTurnEffect, PanDisplacementProperty, CurrentCenterProperty is available for using
-  std::vector<bool>              mIsSliding;               ///< The boolean vector to keep track whether there are animating pages sliding back
-
-  ImageActor                     mPanActor;                ///< The page being panned by the pan gesture
   Vector2                        mPressDownPosition;       ///< The first press down position of the pan gesture
-  bool                           mPress;                   ///< The boolean to keep track the state of the pageTurnEffect is activated or not
-  bool                           mPageUpdated;             ///< The boolean to keep track whether is page is updated after any turning activity
 
   float                          mDistanceUpCorner;        ///< The distance between the original center of PageTurnEffect and the top-left corner of the page
   float                          mDistanceBottomCorner;    ///< The distance between the original center of PageTurnEffect and the bottom-left corner of the page
-
-  std::vector<Property::Index>   mPropertyPanDisplacement; ///< The pan displacement property group
-  std::vector<Property::Index>   mPropertyCurrentCenter;   ///< The current center property group
   float                          mPanDisplacement;         ///< The displacement of the pan after the constrains are applied
+
+  int                            mTotalPageCount;          ///< The total number of pages provided by the page factory
+  int                            mCurrentPageIndex;        ///< The index of the current page, between 0 ~ mTotalPageCount-1
+  int                            mTurningPageIndex;        ///< The index of the turning page
+  int                            mIndex;                   ///< The index to keep track which PanDisplacementProperty, CurrentCenterProperty is used for the current panning page
+  int                            mSlidingCount;            ///< The boolean vector to keep track whether there are animating pages sliding back
+  int                            mAnimatingCount;          ///< The boolean vector to keep track which PageTurnEffect, PanDisplacementProperty, CurrentCenterProperty is available for using
+
   bool                           mConstraints;             ///< The boolean to keep track the constrains are applied or not
+  bool                           mPress;                   ///< The boolean to keep track the state of the pageTurnEffect is activated or not
+  bool                           mPageUpdated;             ///< The boolean to keep track whether is page is updated after any turning activity
 
   Toolkit::PageTurnView::PageTurnSignal   mPageTurnStartedSignal;   ///< The signal to notify that a page has started turning
   Toolkit::PageTurnView::PageTurnSignal   mPageTurnFinishedSignal;  ///< The signal to notify that a page has finished turning
   Toolkit::PageTurnView::PagePanSignal    mPagePanStartedSignal;    ///< The signal to notify that a page has started panning
   Toolkit::PageTurnView::PagePanSignal    mPagePanFinishedSignal;   ///< The signal to notify that a page has finished panning
 
+  static const char * const PROPERTY_TEXTURE_WIDTH;     ///< The uniform name of texture width
+  static const char * const PROPERTY_ORIGINAL_CENTER;   ///< The property name of original center, which is used to constrain the uniforms
+  static const char * const PROPERTY_CURRENT_CENTER;    ///< The property name of current center, which is used to constrain the uniforms
+
   static const int               MAXIMUM_TURNING_NUM;                  ///< How many pages are allowed to animating in the same time
   static const int               NUMBER_OF_CACHED_PAGES_EACH_SIDE;     ///< The maximum number of pages kept, (MAXIMUM_ANIMATION_NUM+1) pages for each side
   static const int               NUMBER_OF_CACHED_PAGES;               ///< The maximum number of pages kept, (MAXIMUM_ANIMATION_NUM+1)*2 pages in total
index 4a260c5..de35289 100755 (executable)
@@ -1506,14 +1506,18 @@ bool Popup::OnDialogTouched(Actor actor, const TouchEvent& event)
   return true;
 }
 
-void Popup::OnControlStageConnection()
+void Popup::OnStageConnection( int depth )
 {
+  Control::OnStageConnection( depth );
+
   mLayoutDirty = true;
   RelayoutRequest();
 }
 
-void Popup::OnControlChildAdd( Actor& child )
+void Popup::OnChildAdd( Actor& child )
 {
+  Control::OnChildAdd( child );
+
   // Re-parent any children added by user to the body layer.
   if( mAlterAddedChild )
   {
index 6893716..91d68b7 100755 (executable)
@@ -432,13 +432,13 @@ private:
   /**
    * Called when the popup is directly or indirectly parented to the stage.
    */
-  virtual void OnControlStageConnection();
+  virtual void OnStageConnection( int depth );
 
   /**
    * From Control; called after a child has been added to the owning actor.
    * @param[in] child The child which has been added.
    */
-  virtual void OnControlChildAdd( Actor& child );
+  virtual void OnChildAdd( Actor& child );
 
   /**
    * @copydoc Control::OnRelayOut()
index b8c6343..17eae58 100644 (file)
@@ -109,34 +109,6 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
   }\n
 );
 
-
-Geometry GenerateGeometry( const Vector< Vector2 >& vertices, const Vector< unsigned int >& indices )
-{
-  Property::Map vertexFormat;
-  vertexFormat[ "aPosition" ] = Property::VECTOR2;
-  PropertyBuffer vertexPropertyBuffer = PropertyBuffer::New( vertexFormat );
-  if( vertices.Size() > 0 )
-  {
-    vertexPropertyBuffer.SetData( &vertices[ 0 ], vertices.Size() );
-  }
-
-  Property::Map indexFormat;
-  indexFormat[ "indices" ] = Property::INTEGER;
-  PropertyBuffer indexPropertyBuffer = PropertyBuffer::New( indexFormat );
-  if( indices.Size() > 0 )
-  {
-    indexPropertyBuffer.SetData( &indices[ 0 ], indices.Size() );
-  }
-
-  // Create the geometry object
-  Geometry geometry = Geometry::New();
-  geometry.AddVertexBuffer( vertexPropertyBuffer );
-  geometry.SetIndexBuffer( indexPropertyBuffer );
-  geometry.SetGeometryType( Geometry::TRIANGLE_STRIP );
-
-  return geometry;
-}
-
 Geometry CreateGeometry( RendererFactoryCache& factoryCache, ImageDimensions gridSize )
 {
   Geometry geometry;
@@ -146,54 +118,13 @@ Geometry CreateGeometry( RendererFactoryCache& factoryCache, ImageDimensions gri
     geometry = factoryCache.GetGeometry( RendererFactoryCache::QUAD_GEOMETRY );
     if( !geometry )
     {
-      geometry =  factoryCache.CreateQuadGeometry();
+      geometry =  RendererFactoryCache::CreateQuadGeometry();
       factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, geometry );
     }
   }
   else
   {
-    uint16_t gridWidth = gridSize.GetWidth();
-    uint16_t gridHeight = gridSize.GetHeight();
-
-    // Create vertices
-    Vector< Vector2 > vertices;
-    vertices.Reserve( ( gridWidth + 1 ) * ( gridHeight + 1 ) );
-
-    for( int y = 0; y < gridHeight + 1; ++y )
-    {
-      for( int x = 0; x < gridWidth + 1; ++x )
-      {
-        vertices.PushBack( Vector2( (float)x/gridWidth - 0.5f, (float)y/gridHeight  - 0.5f) );
-      }
-    }
-
-    // Create indices
-    Vector< unsigned int > indices;
-    indices.Reserve( (gridWidth+2)*gridHeight*2 - 2);
-
-    for( unsigned int row = 0u; row < gridHeight; ++row )
-    {
-      unsigned int rowStartIndex = row*(gridWidth+1u);
-      unsigned int nextRowStartIndex = rowStartIndex + gridWidth +1u;
-
-      if( row != 0u ) // degenerate index on non-first row
-      {
-        indices.PushBack( rowStartIndex );
-      }
-
-      for( unsigned int column = 0u; column < gridWidth+1u; column++) // main strip
-      {
-        indices.PushBack( rowStartIndex + column);
-        indices.PushBack( nextRowStartIndex + column);
-      }
-
-      if( row != gridHeight-1u ) // degenerate index on non-last row
-      {
-        indices.PushBack( nextRowStartIndex + gridWidth );
-      }
-    }
-
-    return GenerateGeometry( vertices, indices );
+    geometry = RendererFactoryCache::CreateGridGeometry( gridSize );
   }
 
   return geometry;
index ecfc6b5..3a6b79f 100644 (file)
@@ -161,8 +161,8 @@ Geometry RendererFactoryCache::CreateQuadGeometry()
   QuadVertex quadVertexData[4] =
   {
       { Vector2(-halfWidth, -halfHeight) },
-      { Vector2( halfWidth, -halfHeight) },
       { Vector2(-halfWidth, halfHeight)  },
+      { Vector2( halfWidth, -halfHeight) },
       { Vector2( halfWidth, halfHeight)  }
   };
 
@@ -197,6 +197,74 @@ void RendererFactoryCache::ApplyRasterizedSVGToSampler()
   }
 }
 
+Geometry RendererFactoryCache::CreateGridGeometry( Uint16Pair gridSize )
+{
+  uint16_t gridWidth = gridSize.GetWidth();
+  uint16_t gridHeight = gridSize.GetHeight();
+
+  // Create vertices
+  Vector< Vector2 > vertices;
+  vertices.Reserve( ( gridWidth + 1 ) * ( gridHeight + 1 ) );
+
+  for( int y = 0; y < gridHeight + 1; ++y )
+  {
+    for( int x = 0; x < gridWidth + 1; ++x )
+    {
+      vertices.PushBack( Vector2( (float)x/gridWidth - 0.5f, (float)y/gridHeight  - 0.5f) );
+    }
+  }
+
+  // Create indices
+  Vector< unsigned int > indices;
+  indices.Reserve( (gridWidth+2)*gridHeight*2 - 2);
+
+  for( unsigned int row = 0u; row < gridHeight; ++row )
+  {
+    unsigned int rowStartIndex = row*(gridWidth+1u);
+    unsigned int nextRowStartIndex = rowStartIndex + gridWidth +1u;
+
+    if( row != 0u ) // degenerate index on non-first row
+    {
+      indices.PushBack( rowStartIndex );
+    }
+
+    for( unsigned int column = 0u; column < gridWidth+1u; column++) // main strip
+    {
+      indices.PushBack( rowStartIndex + column);
+      indices.PushBack( nextRowStartIndex + column);
+    }
+
+    if( row != gridHeight-1u ) // degenerate index on non-last row
+    {
+      indices.PushBack( nextRowStartIndex + gridWidth );
+    }
+  }
+
+  Property::Map vertexFormat;
+  vertexFormat[ "aPosition" ] = Property::VECTOR2;
+  PropertyBuffer vertexPropertyBuffer = PropertyBuffer::New( vertexFormat );
+  if( vertices.Size() > 0 )
+  {
+    vertexPropertyBuffer.SetData( &vertices[ 0 ], vertices.Size() );
+  }
+
+  Property::Map indexFormat;
+  indexFormat[ "indices" ] = Property::INTEGER;
+  PropertyBuffer indexPropertyBuffer = PropertyBuffer::New( indexFormat );
+  if( indices.Size() > 0 )
+  {
+    indexPropertyBuffer.SetData( &indices[ 0 ], indices.Size() );
+  }
+
+  // Create the geometry object
+  Geometry geometry = Geometry::New();
+  geometry.AddVertexBuffer( vertexPropertyBuffer );
+  geometry.SetIndexBuffer( indexPropertyBuffer );
+  geometry.SetGeometryType( Geometry::TRIANGLE_STRIP );
+
+  return geometry;
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index 89334c5..f6fd573 100644 (file)
@@ -21,6 +21,7 @@
 #include "svg/svg-rasterize-thread.h"
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/math/uint-16-pair.h>
 #include <dali/public-api/object/ref-object.h>
 #include <dali/devel-api/rendering/geometry.h>
 #include <dali/devel-api/rendering/shader.h>
@@ -114,6 +115,13 @@ public:
    */
   static Geometry CreateQuadGeometry();
 
+  /**
+   * Create the grid geometry.
+   * @param[in] gridSize The size of the grid.
+   * @return The created grid geometry.
+   */
+  static Geometry CreateGridGeometry( Uint16Pair gridSize );
+
 public:
 
   /**
index 82df8cc..33dbe22 100644 (file)
@@ -1956,6 +1956,8 @@ void ScrollView::OnSizeSet( const Vector3& size )
 
 void ScrollView::OnChildAdd(Actor& child)
 {
+  ScrollBase::OnChildAdd( child );
+
   Dali::Toolkit::ScrollBar scrollBar = Dali::Toolkit::ScrollBar::DownCast(child);
   if(scrollBar)
   {
@@ -1987,6 +1989,8 @@ void ScrollView::OnChildRemove(Actor& child)
 {
   // TODO: Actor needs a RemoveConstraint method to take out an individual constraint.
   UnbindActor(child);
+
+  ScrollBase::OnChildRemove( child );
 }
 
 void ScrollView::StartTouchDownTimer()
index d3f3f87..7ae8fa4 100644 (file)
@@ -293,17 +293,21 @@ void ShadowView::OnInitialize()
   blurStrengthConstraint.Apply();
 }
 
-void ShadowView::OnControlChildAdd( Actor& child )
+void ShadowView::OnChildAdd( Actor& child )
 {
+  Control::OnChildAdd( child );
+
   if( child != mChildrenRoot && child != mBlurRootActor)
   {
     mChildrenRoot.Add( child );
   }
 }
 
-void ShadowView::OnControlChildRemove( Actor& child )
+void ShadowView::OnChildRemove( Actor& child )
 {
   mChildrenRoot.Remove( child );
+
+  Control::OnChildRemove( child );
 }
 
 void ShadowView::ConstrainCamera()
index 9f7d9d6..10c0887 100644 (file)
@@ -118,14 +118,14 @@ private:
   virtual void OnInitialize();
 
   /**
-   * @copydoc Control::OnControlChildAdd()
+   * @copydoc Control::OnChildAdd()
    */
-  virtual void OnControlChildAdd( Actor& child );
+  virtual void OnChildAdd( Actor& child );
 
   /**
-   * @copydoc Control::OnControlChildRemove()
+   * @copydoc Control::OnChildRemove()
    */
-  virtual void OnControlChildRemove( Actor& child );
+  virtual void OnChildRemove( Actor& child );
 
   /**
    * Constrain the camera actor to the position of the point light, pointing
index a730e40..bac0402 100644 (file)
@@ -287,7 +287,7 @@ Actor TableView::RemoveChildAt( const Toolkit::TableView::CellPosition& position
   if( child )
   {
     RelayoutingLock lock( *this );
-    // Remove the child, this will trigger a call to OnControlChildRemove
+    // Remove the child, this will trigger a call to OnChildRemove
     Self().Remove( child );
 
     // relayout the table only if instances were found
@@ -968,8 +968,10 @@ Property::Value TableView::GetProperty( BaseObject* object, Property::Index inde
   return value;
 }
 
-void TableView::OnControlChildAdd( Actor& child )
+void TableView::OnChildAdd( Actor& child )
 {
+  Control::OnChildAdd( child );
+
   if( mLayoutingChild )
   {
     // we're in the middle of laying out children so no point doing anything here
@@ -1061,7 +1063,7 @@ void TableView::OnControlChildAdd( Actor& child )
   RelayoutRequest();
 }
 
-void TableView::OnControlChildRemove( Actor& child )
+void TableView::OnChildRemove( Actor& child )
 {
   // dont process if we're in the middle of bigger operation like delete row, column or resize
   if( !mLayoutingChild )
@@ -1072,6 +1074,8 @@ void TableView::OnControlChildRemove( Actor& child )
       RelayoutRequest();
     }
   }
+
+  Control::OnChildRemove( child );
 }
 
 TableView::TableView( unsigned int initialRows, unsigned int initialColumns )
index d6ccf4b..d6e62b6 100644 (file)
@@ -212,14 +212,14 @@ public:
 private: // From Control
 
   /**
-   * @copydoc Control::OnControlChildAdd(Actor& child)
+   * @copydoc Control::OnChildAdd(Actor& child)
    */
-  virtual void OnControlChildAdd( Actor& child );
+  virtual void OnChildAdd( Actor& child );
 
   /**
-   * @copydoc Control::OnControlChildRemove(Actor& child)
+   * @copydoc Control::OnChildRemove(Actor& child)
    */
-  virtual void OnControlChildRemove( Actor& child );
+  virtual void OnChildRemove( Actor& child );
 
   /**
    * @copydoc Control::OnRelayout
index a3e4d00..4cb2ec6 100644 (file)
@@ -315,8 +315,10 @@ void ToolBar::OnInitialize()
   mLayout.SetRelativeWidth( 1, mRightRelativeSpace );
 }
 
-void ToolBar::OnControlChildAdd(Actor& child)
+void ToolBar::OnChildAdd(Actor& child)
 {
+  Control::OnChildAdd( child );
+
   if( !mInitializing )
   {
     // An actor is being added through the Actor's API.
@@ -330,7 +332,7 @@ void ToolBar::OnControlChildAdd(Actor& child)
     AddControl( child, DEFAULT_RELATIVE_SIZE, DEFAULT_ALIGNMENT, Toolkit::ToolBar::DEFAULT_PADDING );
   }
 
-  // No OnControlChildRemove method required because Actors are added to the mLayout table view, so if an
+  // No OnChildRemove method required because Actors are added to the mLayout table view, so if an
   // actor is removed using the Actor::RemoveChild method it will not remove anything because the
   // actor is in mLayout not in Self().
 }
index 7caaed5..f64d9e8 100644 (file)
@@ -72,9 +72,9 @@ private: // From Control
    * Adds a control using some default values (the control uses 10% of the tool bar space and is placed on the left group).
    * @param child The control to be added.
    *
-   * @see Control::OnControlChildAdd()
+   * @see Control::OnChildAdd()
    */
-  virtual void OnControlChildAdd(Actor& child);
+  virtual void OnChildAdd(Actor& child);
 
 private:
   /**
index af62fb3..1b3a5f1 100644 (file)
@@ -22,7 +22,9 @@
 #include <sstream>
 #include <dali/public-api/animation/constraints.h>
 #include <dali/public-api/common/stage.h>
+#include <dali/public-api/object/property-map.h>
 #include <dali/public-api/render-tasks/render-task-list.h>
+#include <dali/devel-api/rendering/renderer.h>
 
 // INTERNAL INCLUDES
 
@@ -55,36 +57,20 @@ const float DEFAULT_KERNEL4[] = { 2.0f/16.0f, 1.5f/16.0f, 1.5f/16.0f, 1.5f/16.0f
                                   1.0f/16.0f, 1.0f/16.0f, 1.0f/16.0f, 0.5f/16.0f,
                                   0.5f/16.0f, 0.5f/16.0f, 0.5f/16.0f };
 
-
-const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f;
-
 const char* BLUR_TWO_PASS_FRAGMENT_SOURCE =
 {
  "precision highp float;\n"
+ "varying mediump vec2 vTexCoord;\n"
+ "uniform sampler2D sTexture;\n"
  "uniform vec2 uSampleOffsets[NUM_SAMPLES];\n"
  "uniform float uSampleWeights[NUM_SAMPLES];\n"
  "void main()\n"
  "{\n"
  "  vec4 color = vec4(0.0);\n"
- "# ifdef DEBUG_RENDER\n"
- "  if( vTexCoord.s < 0.495 )\n"
- "  {\n"
- "# endif //def DEBUG_RENDER\n"
- "    for( int i = 0; i < NUM_SAMPLES; ++i )\n"
- "    {\n"
- "      color += texture2D( sTexture, vTexCoord + uSampleOffsets[i] ) * uSampleWeights[i];\n"
- "    }\n"
- "# ifdef DEBUG_RENDER\n"
- "  }\n"
- "  else if( vTexCoord.s > 0.505 )\n"
- "  {\n"
- "    color = texture2D( sTexture, vTexCoord );\n"
- "  }\n"
- "  else\n"
+ "  for( int i = 0; i < NUM_SAMPLES; ++i )\n"
  "  {\n"
- "    color = vec4( 1.0, 0.0, 0.0, 1.0 );\n"
+ "    color += texture2D( sTexture, vTexCoord + uSampleOffsets[i] ) * uSampleWeights[i];\n"
  "  }\n"
- "# endif //def DEBUG_RENDER\n"
  "  gl_FragColor = color;\n"
  "}\n"
 };
@@ -106,7 +92,10 @@ std::string GetWeightUniformName( int index )
 const char* BLEND_TWO_IMAGES_FRAGMENT_SOURCE =
 {
  "precision highp float;\n"
- "uniform float uBlurStrength; \n "
+ "uniform float uBlurStrength;\n "
+ "uniform sampler2D sTexture;\n"
+ "uniform sampler2D sEffect;\n"
+ "varying mediump vec2 vTexCoord;\n"
  "void main()\n"
  "{\n"
  "  gl_FragColor = texture2D( sTexture, vTexCoord ) * uBlurStrength"
@@ -114,10 +103,8 @@ const char* BLEND_TWO_IMAGES_FRAGMENT_SOURCE =
  "}\n"
 };
 
-std::string GetBlurStrengthUniformName()
-{
-  return "uBlurStrength";
-}
+const char* const BLUR_STRENGTH_UNIFORM_NAME( "uBlurStrength"  );
+const char* const EFFECT_IMAGE_NAME( "sEffect" );
 
 } // namespace
 
@@ -125,9 +112,10 @@ std::string GetBlurStrengthUniformName()
 BlurTwoPassFilter::BlurTwoPassFilter()
 : ImageFilter()
 {
-  mShaderForBlending = ShaderEffect::New( "", BLEND_TWO_IMAGES_FRAGMENT_SOURCE );
-  mShaderForBlending.SetUniform( GetBlurStrengthUniformName(), 1.f );
-  mBlurStrengthPropertyIndex = mShaderForBlending.GetPropertyIndex( GetBlurStrengthUniformName() );
+  // create blending actor and register the property in constructor
+  // to make sure that GetBlurStrengthPropertyIndex() always returns a valid index
+  mActorForBlending = Toolkit::ImageView::New();
+  mBlurStrengthPropertyIndex = mActorForBlending.RegisterProperty( BLUR_STRENGTH_UNIFORM_NAME, 1.f );
 }
 
 BlurTwoPassFilter::~BlurTwoPassFilter()
@@ -136,37 +124,24 @@ BlurTwoPassFilter::~BlurTwoPassFilter()
 
 void BlurTwoPassFilter::Enable()
 {
-  mCameraForBlur = CameraActor::New();
-  mCameraForBlur.SetParentOrigin(ParentOrigin::CENTER);
-
   // create actor to render input with applied emboss effect
-  mActorForInput = ImageActor::New( mInputImage );
+  mActorForInput = Toolkit::ImageView::New( mInputImage );
   mActorForInput.SetParentOrigin( ParentOrigin::CENTER );
   mActorForInput.SetSize( mTargetSize );
-  mActorForInput.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
 
   // create internal offscreen for result of horizontal pass
   mImageForHorz = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::UNUSED );
-
   // create an actor to render mImageForHorz for vertical blur pass
-  mActorForHorz = ImageActor::New( mImageForHorz );
+  mActorForHorz = Toolkit::ImageView::New( mImageForHorz );
   mActorForHorz.SetParentOrigin( ParentOrigin::CENTER );
   mActorForHorz.SetSize( mTargetSize );
-  mActorForHorz.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
 
   // create internal offscreen for result of the two pass blurred image
   mBlurredImage = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::UNUSED);
-
   // create an actor to blend the blurred image and the input image with the given blur strength
-  mActorForBlending = ImageActor::New( mBlurredImage );
+  mActorForBlending.SetImage( mBlurredImage );
   mActorForBlending.SetParentOrigin( ParentOrigin::CENTER );
   mActorForBlending.SetSize( mTargetSize );
-  mActorForBlending.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
-
-  mRootActor.Add( mActorForInput );
-  mRootActor.Add( mActorForHorz );
-  mRootActor.Add( mActorForBlending );
-  mRootActor.Add( mCameraForBlur );
 
   // create custom shader effect
   if( !GetKernelSize() )
@@ -175,32 +150,50 @@ void BlurTwoPassFilter::Enable()
   }
   int kernelSize( static_cast< int >(GetKernelSize()) );
 
-  std::ostringstream fragmentSource;
-  if( mDebugRender )
-  {
-    fragmentSource << "#define DEBUG_RENDER\n";
-  }
-  fragmentSource << "#define NUM_SAMPLES " << kernelSize << "\n";
-  fragmentSource << BLUR_TWO_PASS_FRAGMENT_SOURCE;
-  mShaderForHorz = ShaderEffect::New( "", fragmentSource.str() );
-  mActorForInput.SetShaderEffect( mShaderForHorz );
-  mShaderForVert = ShaderEffect::New( "", fragmentSource.str() );
-  mActorForHorz.SetShaderEffect( mShaderForVert );
-
   for( int i = 0; i < kernelSize; ++i )
   {
     const std::string offsetUniform( GetOffsetUniformName( i ) );
     const std::string weightUniform( GetWeightUniformName( i ) );
 
-    mShaderForHorz.SetUniform( offsetUniform, Vector2(mKernel[i]) * Vector2::XAXIS );
-    mShaderForHorz.SetUniform( weightUniform, mKernel[i].z );
+    mActorForInput.RegisterProperty( offsetUniform, Vector2(mKernel[i]) * Vector2::XAXIS );
+    mActorForInput.RegisterProperty( weightUniform, mKernel[i].z );
 
-    mShaderForVert.SetUniform( offsetUniform, Vector2(mKernel[i]) * Vector2::YAXIS );
-    mShaderForVert.SetUniform( weightUniform, mKernel[i].z );
+    mActorForHorz.RegisterProperty( offsetUniform, Vector2(mKernel[i]) * Vector2::YAXIS );
+    mActorForHorz.RegisterProperty( weightUniform, mKernel[i].z );
   }
 
-  mActorForBlending.SetShaderEffect( mShaderForBlending );
-  mShaderForBlending.SetEffectImage( mInputImage );
+  // Set up blur-two-pass custom shader
+  std::ostringstream fragmentSource;
+  fragmentSource << "#define NUM_SAMPLES " << kernelSize << "\n";
+  fragmentSource << BLUR_TWO_PASS_FRAGMENT_SOURCE;
+
+  Property::Map customShader;
+  customShader[ "fragmentShader" ] = fragmentSource.str();
+  Property::Map rendererMap;
+  rendererMap.Insert( "shader", customShader );
+  mActorForInput.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap );
+  mActorForHorz.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap );
+
+  // Set up blend-two-image custom shader
+  customShader[ "fragmentShader" ] = BLEND_TWO_IMAGES_FRAGMENT_SOURCE;
+  rendererMap[ "shader"] = customShader;
+  mActorForBlending.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap );
+
+  mRootActor.Add( mActorForInput );
+  mRootActor.Add( mActorForHorz );
+  mRootActor.Add( mActorForBlending );
+
+  // Add effect texture to blend-two-image custom shader
+  Material material = mActorForBlending.GetRendererAt(0).GetMaterial();
+  int textureIndex = material.GetTextureIndex( EFFECT_IMAGE_NAME );
+  if( textureIndex == -1 )
+  {
+    material.AddTexture( mInputImage, EFFECT_IMAGE_NAME );
+  }
+  else
+  {
+    material.SetTextureImage( textureIndex, mInputImage );
+  }
 
   SetupCamera();
   CreateRenderTasks();
@@ -210,10 +203,10 @@ void BlurTwoPassFilter::Disable()
 {
   if( mRootActor )
   {
-    if( mCameraForBlur )
+    if( mCameraActor )
     {
-      mRootActor.Remove( mCameraForBlur );
-      mCameraForBlur.Reset();
+      mRootActor.Remove( mCameraActor );
+      mCameraActor.Reset();
     }
 
     if( mActorForInput )
@@ -228,12 +221,6 @@ void BlurTwoPassFilter::Disable()
       mActorForHorz.Reset();
     }
 
-    if( mActorForBlending )
-    {
-      mRootActor.Remove( mActorForBlending );
-      mActorForBlending.Reset();
-    }
-
     RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
 
     if( mRenderTaskForHorz )
@@ -290,17 +277,7 @@ void BlurTwoPassFilter::SetSize( const Vector2& size )
 
 Handle BlurTwoPassFilter::GetHandleForAnimateBlurStrength()
 {
-  return mShaderForBlending;
-}
-
-void BlurTwoPassFilter::SetupCamera()
-{
-  // Create and place a camera for the embossing render, corresponding to its render target size
-  mCameraForBlur.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
-  mCameraForBlur.SetNearClippingPlane(1.0f);
-  mCameraForBlur.SetAspectRatio(mTargetSize.width / mTargetSize.height);
-  mCameraForBlur.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
-  mCameraForBlur.SetPosition(0.0f, 0.0f, ((mTargetSize.height * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f)));
+  return mActorForBlending;
 }
 
 void BlurTwoPassFilter::CreateRenderTasks()
@@ -316,7 +293,7 @@ void BlurTwoPassFilter::CreateRenderTasks()
   mRenderTaskForHorz.SetClearEnabled( true );
   mRenderTaskForHorz.SetClearColor( mBackgroundColor );
   mRenderTaskForHorz.SetTargetFrameBuffer( mImageForHorz );
-  mRenderTaskForHorz.SetCameraActor( mCameraForBlur );
+  mRenderTaskForHorz.SetCameraActor( mCameraActor );
 
   // use the internal buffer and perform a horizontal blur targeting the output buffer
   mRenderTaskForVert = taskList.CreateTask();
@@ -327,7 +304,7 @@ void BlurTwoPassFilter::CreateRenderTasks()
   mRenderTaskForVert.SetClearEnabled( true );
   mRenderTaskForVert.SetClearColor( mBackgroundColor );
   mRenderTaskForVert.SetTargetFrameBuffer( mBlurredImage );
-  mRenderTaskForVert.SetCameraActor( mCameraForBlur );
+  mRenderTaskForVert.SetCameraActor( mCameraActor );
 
   //Perform a blending between the blurred image and the input image
   mRenderTaskForBlending = taskList.CreateTask();
@@ -338,7 +315,7 @@ void BlurTwoPassFilter::CreateRenderTasks()
   mRenderTaskForBlending.SetClearEnabled( true );
   mRenderTaskForBlending.SetClearColor( mBackgroundColor );
   mRenderTaskForBlending.SetTargetFrameBuffer( mOutputImage );
-  mRenderTaskForBlending.SetCameraActor( mCameraForBlur );
+  mRenderTaskForBlending.SetCameraActor( mCameraActor );
 }
 
 } // namespace Internal
index 1e723b9..e130897 100644 (file)
  */
 
 // EXTERNAL INCLUDES
-#include <dali/public-api/actors/camera-actor.h>
-#include <dali/public-api/actors/image-actor.h>
 #include <dali/public-api/render-tasks/render-task.h>
-#include <dali/public-api/shader-effects/shader-effect.h>
+#include <dali-toolkit/public-api/controls/image-view/image-view.h>
+#include <dali/public-api/actors/image-actor.h>
 
 // INTERNAL INCLUDES
 #include "image-filter.h"
@@ -79,10 +78,6 @@ public: // From ImageFilter
   Handle GetHandleForAnimateBlurStrength();
 
 private:
-  /**
-   * Setup position and parameters for camera
-   */
-  void SetupCamera();
 
   /**
    * Setup render tasks for blur
@@ -95,26 +90,21 @@ private:
 
 private: // Attributes
 
-  CameraActor      mCameraForBlur;
-
   // To perform horizontal blur from mInputImage to mImageForHorz
-  RenderTask       mRenderTaskForHorz;
-  ImageActor       mActorForInput;
-  FrameBufferImage mImageForHorz;
-  ShaderEffect     mShaderForHorz;
+  RenderTask         mRenderTaskForHorz;
+  Toolkit::ImageView mActorForInput;
+  FrameBufferImage   mImageForHorz;
 
   // To perform vertical blur from mImageForHorz to mOutputImage
-  RenderTask       mRenderTaskForVert;
-  ImageActor       mActorForHorz;
-  ShaderEffect     mShaderForVert;
-  FrameBufferImage mBlurredImage;
+  RenderTask         mRenderTaskForVert;
+  Toolkit::ImageView mActorForHorz;
+  FrameBufferImage   mBlurredImage;
 
   // To blend the blurred image and input image according to the blur strength
-  RenderTask       mRenderTaskForBlending;
-  ImageActor       mActorForBlending;
-  Actor            mRootActorForBlending;
-  ShaderEffect     mShaderForBlending;
-  Property::Index  mBlurStrengthPropertyIndex;
+  RenderTask         mRenderTaskForBlending;
+  Toolkit::ImageView mActorForBlending;
+  Actor              mRootActorForBlending;
+  Property::Index    mBlurStrengthPropertyIndex;
 
 }; // class BlurTwoPassFilter
 
index f437c73..e44877e 100644 (file)
 #include <sstream>
 #include <dali/public-api/animation/constraints.h>
 #include <dali/public-api/common/stage.h>
+#include <dali/public-api/object/property-map.h>
 #include <dali/public-api/render-tasks/render-task-list.h>
-#include <dali/public-api/shader-effects/shader-effect.h>
+#include <dali/devel-api/rendering/renderer.h>
+#include <dali-toolkit/devel-api/controls/renderer-factory/renderer-factory.h>
 
 // INTERNAL INCLUDES
 
@@ -39,74 +41,38 @@ namespace Internal
 namespace
 {
 
-const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f;
-
-const char* EMBOSS_FRAGMENT_SOURCE1 =
+const char* EMBOSS_FRAGMENT_SOURCE =
 {
  "precision highp float;\n"
+ "varying mediump vec2 vTexCoord;\n"
+ "uniform sampler2D sTexture;\n"
  "uniform vec2 uTexScale;\n"
+ "uniform vec3 uCoefficient;\n"
  "\n"
  "void main()\n"
  "{\n"
- "  vec4 color;\n"
- "# ifdef DEBUG_RENDER\n"
- "  if( vTexCoord.s < 0.495 )\n"
- "  {\n"
- "# endif //def DEBUG_RENDER\n"
- "    color  =  2.0 * texture2D( sTexture, vTexCoord + vec2(0.0, -uTexScale.y) );\n"
- "    color += -1.0 * texture2D( sTexture, vTexCoord );\n"
- "    color += -1.0 * texture2D( sTexture, vTexCoord + vec2(0.0, uTexScale.y) );\n"
- "# ifdef DEBUG_RENDER\n"
- "  }\n"
- "  else if( vTexCoord.s > 0.505 )\n"
- "  {\n"
- "    color = texture2D( sTexture, vTexCoord );\n"
- "  }\n"
- "  else\n"
- "  {\n"
- "    color = vec4( 1.0, 0.0, 0.0, 1.0 );\n"
- "  }\n"
- "# endif //def DEBUG_RENDER\n"
- "  gl_FragColor = uColor * color;\n"
+ "  vec4 color  = uCoefficient.x * texture2D( sTexture, vTexCoord + vec2(0.0, -uTexScale.y) );\n"
+ "  color += uCoefficient.y * texture2D( sTexture, vTexCoord );\n"
+ "  color += uCoefficient.z * texture2D( sTexture, vTexCoord + vec2(0.0, uTexScale.y) );\n"
+ "  gl_FragColor = color;\n"
  "}\n"
 };
 
-const char* EMBOSS_FRAGMENT_SOURCE2 =
+const char* const COMPOSITE_FRAGMENT_SOURCE =
 {
- "precision highp float;\n"
- "uniform vec2 uTexScale;\n"
- "\n"
- "void main()\n"
- "{\n"
- "  vec4 color;\n"
- "# ifdef DEBUG_RENDER\n"
- "  if( vTexCoord.s < 0.495 )\n"
- "  {\n"
- "# endif //def DEBUG_RENDER\n"
- "    color  = -1.0 * texture2D( sTexture, vTexCoord + vec2(0.0, -uTexScale.y) );\n"
- "    color += -1.0 * texture2D( sTexture, vTexCoord );\n"
- "    color +=  2.0 * texture2D( sTexture, vTexCoord + vec2(0.0, uTexScale.y) );\n"
- "# ifdef DEBUG_RENDER\n"
- "  }\n"
- "  else if( vTexCoord.s > 0.505 )\n"
- "  {\n"
- "    color = texture2D( sTexture, vTexCoord );\n"
- "  }\n"
- "  else\n"
- "  {\n"
- "    color = vec4( 1.0, 0.0, 0.0, 1.0 );\n"
- "  }\n"
- "# endif //def DEBUG_RENDER\n"
- "  gl_FragColor = uColor * color;\n"
- "}\n"
+  "varying mediump vec2 vTexCoord;\n"
+  "uniform sampler2D sTexture;\n"
+  "uniform lowp vec4 uEffectColor;\n"
+  "void main()\n"
+  "{\n"
+  "  gl_FragColor = uEffectColor;\n"
+  "  gl_FragColor.a *= texture2D( sTexture, vTexCoord).a;\n"
+  "}\n"
 };
 
-const char* const COMPOSITE_FRAGMENT_SOURCE =
-    "void main()\n"
-    "{\n"
-    "  gl_FragColor = uColor;\n"
-    "  gl_FragColor.a *= texture2D( sTexture, vTexCoord).a;\n"
-    "}\n";
+const char* const TEX_SCALE_UNIFORM_NAME( "uTexScale" );
+const char* const COEFFICIENT_UNIFORM_NAME( "uCoefficient" );
+const char* const COLOR_UNIFORM_NAME( "uEffectColor" );
 
 } // namespace
 
@@ -121,73 +87,56 @@ EmbossFilter::~EmbossFilter()
 
 void EmbossFilter::Enable()
 {
-  // Create camera
-  mCameraActor = CameraActor::New();
-  mCameraActor.SetParentOrigin(ParentOrigin::CENTER);
-
   mImageForEmboss1 = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::UNUSED );
   mImageForEmboss2 = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::UNUSED );
 
+  Property::Map customShader;
+  customShader[ "fragmentShader" ] = EMBOSS_FRAGMENT_SOURCE;
+  Property::Map rendererMap;
+  rendererMap.Insert( "shader", customShader );
+
   // create actor to render input with applied emboss effect
-  mActorForInput1 = ImageActor::New( mInputImage );
+  mActorForInput1 = Toolkit::ImageView::New( mInputImage );
   mActorForInput1.SetParentOrigin( ParentOrigin::CENTER );
   mActorForInput1.SetSize(mTargetSize);
-  mActorForInput1.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
-  mActorForInput1.SetColor( Color::WHITE );
+  Vector2 textureScale( 1.5f/mTargetSize.width, 1.5f/mTargetSize.height);
+  mActorForInput1.RegisterProperty( TEX_SCALE_UNIFORM_NAME, textureScale );
+  mActorForInput1.RegisterProperty( COEFFICIENT_UNIFORM_NAME, Vector3( 2.f, -1.f, -1.f ) );
+  // set EMBOSS custom shader
+  mActorForInput1.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap );
+  mRootActor.Add( mActorForInput1 );
 
-  mActorForInput2 = ImageActor::New( mInputImage );
+  mActorForInput2 = Toolkit::ImageView::New( mInputImage );
   mActorForInput2.SetParentOrigin( ParentOrigin::CENTER );
   mActorForInput2.SetSize(mTargetSize);
-  mActorForInput2.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
-  mActorForInput2.SetColor( Color::WHITE );
-
-  mActorForEmboss1 = ImageActor::New( mImageForEmboss1 );
-  mActorForEmboss1.SetParentOrigin( ParentOrigin::CENTER );
-  mActorForEmboss1.SetSize(mTargetSize);
-  mActorForEmboss1.SetColor( Color::BLACK );
-  mActorForEmboss1.SetShaderEffect( ShaderEffect::New( "", COMPOSITE_FRAGMENT_SOURCE ) );
-
-  mActorForEmboss2 = ImageActor::New( mImageForEmboss2 );
-  mActorForEmboss2.SetParentOrigin( ParentOrigin::CENTER );
-  mActorForEmboss2.SetSize(mTargetSize);
-  mActorForEmboss2.SetColor( Color::WHITE );
-  mActorForEmboss2.SetShaderEffect( ShaderEffect::New( "", COMPOSITE_FRAGMENT_SOURCE ) );
+  mActorForInput2.RegisterProperty( TEX_SCALE_UNIFORM_NAME, textureScale );
+  mActorForInput2.RegisterProperty( COEFFICIENT_UNIFORM_NAME, Vector3( -1.f, -1.f, 2.f ) );
+  // set EMBOSS custom shader
+  mActorForInput2.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap );
+  mRootActor.Add( mActorForInput2 );
 
   mActorForComposite = Actor::New();
   mActorForComposite.SetParentOrigin( ParentOrigin::CENTER );
   mActorForComposite.SetSize(mTargetSize);
-  mActorForComposite.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
-
-  // create custom shader effect
-  std::ostringstream embossFragmentSource1;
-  if( mDebugRender )
-  {
-    embossFragmentSource1 << "#define DEBUG_RENDER\n";
-  }
-  embossFragmentSource1 << EMBOSS_FRAGMENT_SOURCE1;
-  ShaderEffect effect1 = ShaderEffect::New( "", embossFragmentSource1.str() );
-  mActorForInput1.SetShaderEffect( effect1 );
-  effect1.SetUniform( "uTexScale", Vector2( 1.0f/mTargetSize.width, 1.0f/mTargetSize.height) * 1.5f );
-
-  std::ostringstream embossFragmentSource2;
-  if( mDebugRender )
-  {
-    embossFragmentSource2 << "#define DEBUG_RENDER\n";
-  }
-  embossFragmentSource2 << EMBOSS_FRAGMENT_SOURCE2;
-  ShaderEffect effect2 = ShaderEffect::New( "", embossFragmentSource2.str() );
-  mActorForInput2.SetShaderEffect( effect2 );
-  effect2.SetUniform( "uTexScale", Vector2( 1.0f/mTargetSize.width, 1.0f/mTargetSize.height) * 1.5f );
+  mActorForComposite.SetColor( Color::BLACK );
+
+  customShader[ "fragmentShader" ] = COMPOSITE_FRAGMENT_SOURCE;
+  rendererMap[ "shader"] = customShader;
+  Toolkit::RendererFactory rendererFactory = Toolkit::RendererFactory::Get();
+  mRendererForEmboss1 = rendererFactory.GetControlRenderer( mImageForEmboss1 );
+  mRendererForEmboss2 = rendererFactory.GetControlRenderer( mImageForEmboss2 );
+  // set COMPOSITE custom shader to both renderers
+  rendererFactory.ResetRenderer( mRendererForEmboss1, mActorForComposite, rendererMap);
+  rendererFactory.ResetRenderer( mRendererForEmboss2, mActorForComposite, rendererMap);
+  // apply renderers to the actor
+  mRendererForEmboss1.SetOnStage( mActorForComposite );
+  mRendererForEmboss2.SetOnStage( mActorForComposite );
+  mActorForComposite.GetRendererAt(0).RegisterProperty( COLOR_UNIFORM_NAME, Color::BLACK );
+  mActorForComposite.GetRendererAt(1).RegisterProperty( COLOR_UNIFORM_NAME, Color::WHITE );
+  mRootActor.Add( mActorForComposite );
 
   SetupCamera();
   CreateRenderTasks();
-
-  mRootActor.Add( mActorForInput1 );
-  mRootActor.Add( mActorForInput2 );
-  mRootActor.Add( mActorForComposite );
-  mActorForComposite.Add( mActorForEmboss1 );
-  mActorForComposite.Add( mActorForEmboss2 );
-  mRootActor.Add( mCameraActor );
 }
 
 void EmbossFilter::Disable()
@@ -214,10 +163,12 @@ void EmbossFilter::Disable()
 
     if( mActorForComposite )
     {
+      mRendererForEmboss1.SetOffStage( mActorForComposite );
+      mRendererForEmboss2.SetOffStage( mActorForComposite );
+      mRendererForEmboss1.Reset();
+      mRendererForEmboss2.Reset();
       mRootActor.Remove( mActorForComposite );
       mActorForComposite.Reset();
-      mActorForEmboss1.Reset();
-      mActorForEmboss2.Reset();
     }
 
     RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
@@ -258,30 +209,12 @@ void EmbossFilter::SetSize( const Vector2& size )
   {
     mActorForInput2.SetSize(mTargetSize);
   }
-  if( mActorForEmboss1 )
-  {
-    mActorForEmboss1.SetSize(mTargetSize);
-  }
-  if( mActorForEmboss2 )
-  {
-    mActorForEmboss2.SetSize(mTargetSize);
-  }
   if( mActorForComposite )
   {
     mActorForComposite.SetSize(mTargetSize);
   }
 }
 
-void EmbossFilter::SetupCamera()
-{
-  // Create and place a camera for the embossing render, corresponding to its render target size
-  mCameraActor.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
-  mCameraActor.SetNearClippingPlane(1.0f);
-  mCameraActor.SetAspectRatio(mTargetSize.width / mTargetSize.height);
-  mCameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
-  mCameraActor.SetPosition(0.0f, 0.0f, ((mTargetSize.height * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f)));
-}
-
 void EmbossFilter::CreateRenderTasks()
 {
   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
index c912428..2c811f1 100644 (file)
@@ -19,9 +19,9 @@
  */
 
 // EXTERNAL INCLUDES
-#include <dali/public-api/actors/camera-actor.h>
-#include <dali/public-api/actors/image-actor.h>
 #include <dali/public-api/render-tasks/render-task.h>
+#include <dali-toolkit/public-api/controls/image-view/image-view.h>
+#include <dali-toolkit/devel-api/controls/renderer-factory/control-renderer.h>
 
 // INTERNAL INCLUDES
 #include "image-filter.h"
@@ -66,11 +66,6 @@ public: // From ImageFilter
 
 private:
   /**
-   * Setup position and parameters for camera
-   */
-  void SetupCamera();
-
-  /**
    * Setup render tasks for blur
    */
   void CreateRenderTasks();
@@ -81,17 +76,16 @@ private:
 
 private: // Attributes
 
-  RenderTask       mRenderTaskForEmboss1;
-  RenderTask       mRenderTaskForEmboss2;
-  RenderTask       mRenderTaskForOutput;
-  FrameBufferImage mImageForEmboss1;
-  FrameBufferImage mImageForEmboss2;
-  CameraActor      mCameraActor;
-  ImageActor       mActorForInput1;
-  ImageActor       mActorForInput2;
-  ImageActor       mActorForEmboss1;
-  ImageActor       mActorForEmboss2;
-  Actor            mActorForComposite;
+  RenderTask         mRenderTaskForEmboss1;
+  RenderTask         mRenderTaskForEmboss2;
+  RenderTask         mRenderTaskForOutput;
+  FrameBufferImage   mImageForEmboss1;
+  FrameBufferImage   mImageForEmboss2;
+  Toolkit::ImageView mActorForInput1;
+  Toolkit::ImageView mActorForInput2;
+  Toolkit::ControlRenderer mRendererForEmboss1;
+  Toolkit::ControlRenderer mRendererForEmboss2;
+  Actor              mActorForComposite;
 }; // class EmbossFilter
 
 } // namespace Internal
index 80e69c2..f564c96 100644 (file)
@@ -31,15 +31,14 @@ namespace Internal
 
 namespace
 {
-
+const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f;
 } // namespace
 
 ImageFilter::ImageFilter()
 : mBackgroundColor( Vector4( 1.0f, 1.0f, 1.0f, 0.0f ) ),
   mTargetSize( Vector2::ZERO ),
   mPixelFormat( Pixel::RGBA8888 ),
-  mRefreshOnDemand( false ),
-  mDebugRender( false )
+  mRefreshOnDemand( false )
 {
 }
 
@@ -116,11 +115,28 @@ void ImageFilter::SetBackgroundColor( const Vector4& color )
   mBackgroundColor = color;
 }
 
-void ImageFilter::RenderDebug( bool flag )
+void ImageFilter::SetupCamera()
 {
-  mDebugRender = flag;
+  if( !mCameraActor )
+  {
+    // create a camera for the render task, corresponding to its render target size
+    mCameraActor = CameraActor::New(mTargetSize);
+    mCameraActor.SetParentOrigin(ParentOrigin::CENTER);
+    mCameraActor.SetInvertYAxis( true );
+    mRootActor.Add( mCameraActor );
+  }
+  else
+  {
+    // place the camera for the render task, corresponding to its render target size
+    mCameraActor.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
+    mCameraActor.SetNearClippingPlane(1.0f);
+    mCameraActor.SetAspectRatio(mTargetSize.width / mTargetSize.height);
+    mCameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
+    mCameraActor.SetPosition(0.0f, 0.0f, ((mTargetSize.height * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f)));
+  }
 }
 
+
 } // namespace Internal
 
 } // namespace Toolkit
index bc4b164..3a4fac9 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/actors/camera-actor.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-impl.h>
@@ -136,22 +137,24 @@ public:
    */
   void SetBackgroundColor( const Vector4& color );
 
+protected:
+
   /**
-   * Enable optional debug output in the shader
-   * @param[in] flag Set true to enable, dalse to disable.
+   * Setup position and parameters for camera
    */
-  void RenderDebug( bool flag );
+  void SetupCamera();
 
 protected:
   Image            mInputImage;
   FrameBufferImage mOutputImage;
   FilterKernel     mKernel;
   Actor            mRootActor;
+  CameraActor      mCameraActor;
   Vector4          mBackgroundColor;
   Vector2          mTargetSize;
   Pixel::Format    mPixelFormat;
   bool             mRefreshOnDemand;
-  bool             mDebugRender;
+
 }; // class Imagefilter
 
 } // namespace Internal
index d0b54f9..de205b6 100644 (file)
@@ -19,9 +19,9 @@
 #include "spread-filter.h"
 
 // EXTERNAL INCLUDES
-#include <sstream>
 #include <dali/public-api/animation/constraints.h>
 #include <dali/public-api/common/stage.h>
+#include <dali/public-api/object/property-map.h>
 #include <dali/public-api/render-tasks/render-task-list.h>
 
 // INTERNAL INCLUDES
@@ -38,38 +38,29 @@ namespace Internal
 namespace
 {
 
-const float ARBITRARY_FIELD_OF_VIEW = Math::PI / 4.0f;
-
 const char* const SPREAD_FRAGMENT_SOURCE =
 {
  "precision highp float;\n"
- "uniform float uSpread;\n"
+ "varying mediump vec2 vTexCoord;\n"
+ "uniform sampler2D sTexture;\n"
+ "uniform int uSpread;\n"
  "uniform vec2 uTexScale;\n"
  "void main()\n"
  "{\n"
  "  vec4 color = texture2D( sTexture, vTexCoord);\n"
- "# ifdef DEBUG_RENDER\n"
- "  if( vTexCoord.s < 0.495 )\n"
- "  {\n"
- "# endif //def DEBUG_RENDER\n"
- "    int spread = int(uSpread);\n"
- "    for( int i = 1; i <= spread; ++i )\n"
- "    {\n"
- "      vec2 offset = uTexScale * float(i);\n"
- "      color = max( texture2D( sTexture, vTexCoord + offset), color );\n"
- "      color = max( texture2D( sTexture, vTexCoord - offset), color );\n"
- "    }\n"
- "# ifdef DEBUG_RENDER\n"
- "  }\n"
- "  else if( vTexCoord.s <= 0.505 )\n"
+ "  for( int i = 1; i <= uSpread; ++i )\n"
  "  {\n"
- "    color = vec4( 1.0, 0.0, 0.0, 1.0 );\n"
+ "    vec2 offset = uTexScale * float(i);\n"
+ "    color = max( texture2D( sTexture, vTexCoord + offset), color );\n"
+ "    color = max( texture2D( sTexture, vTexCoord - offset), color );\n"
  "  }\n"
- "# endif //def DEBUG_RENDER\n"
  "  gl_FragColor = color;\n"
  "}\n"
 };
 
+const char* const SPREAD_UNIFORM_NAME( "uSpread" );
+const char* const TEX_SCALE_UNIFORM_NAME( "uTexScale" );
+
 } // namespace
 
 
@@ -90,44 +81,35 @@ void SpreadFilter::SetSpread( float spread )
 
 void SpreadFilter::Enable()
 {
-  mCameraActor = CameraActor::New();
-  mCameraActor.SetParentOrigin(ParentOrigin::CENTER);
-
   // create actor to render input with applied emboss effect
-  mActorForInput = ImageActor::New( mInputImage );
+  mActorForInput = Toolkit::ImageView::New( mInputImage );
   mActorForInput.SetParentOrigin( ParentOrigin::CENTER );
   mActorForInput.SetSize(mTargetSize);
-  mActorForInput.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
+  // register properties as shader uniforms
+  mActorForInput.RegisterProperty( SPREAD_UNIFORM_NAME, mSpread );
+  mActorForInput.RegisterProperty( TEX_SCALE_UNIFORM_NAME, Vector2( 1.0f / mTargetSize.width, 0.0f ) );
 
   // create internal offscreen for result of horizontal pass
   mImageForHorz = FrameBufferImage::New( mTargetSize.width, mTargetSize.height, mPixelFormat, Image::UNUSED );
-
   // create an actor to render mImageForHorz for vertical blur pass
-  mActorForHorz = ImageActor::New( mImageForHorz );
+  mActorForHorz = Toolkit::ImageView::New( mImageForHorz );
   mActorForHorz.SetParentOrigin( ParentOrigin::CENTER );
   mActorForHorz.SetSize(mTargetSize);
-  mActorForHorz.ScaleBy( Vector3(1.0f, -1.0f, 1.0f) );
-
-  mRootActor.Add( mActorForInput );
-  mRootActor.Add( mActorForHorz );
-  mRootActor.Add( mCameraActor );
+  // register properties as shader uniforms
+  mActorForHorz.RegisterProperty( SPREAD_UNIFORM_NAME, mSpread );
+  mActorForHorz.RegisterProperty( TEX_SCALE_UNIFORM_NAME, Vector2( 0.0f, 1.0f / mTargetSize.height ) );
 
-  std::ostringstream fragmentSource;
-  if( mDebugRender )
-  {
-    fragmentSource << "#define DEBUG_RENDER\n";
-  }
-  fragmentSource << SPREAD_FRAGMENT_SOURCE;
+  Property::Map customShader;
+  customShader[ "fragmentShader" ] = SPREAD_FRAGMENT_SOURCE;
+  Property::Map rendererMap;
+  rendererMap.Insert( "shader", customShader );
 
-  mShaderForHorz = ShaderEffect::New( "", fragmentSource.str() );
-  mActorForInput.SetShaderEffect( mShaderForHorz );
-  mShaderForHorz.SetUniform( "uSpread", mSpread );
-  mShaderForHorz.SetUniform( "uTexScale", Vector2( 1.0f / mTargetSize.width, 0.0f ) );
+  // set SPREAD custom shader
+  mActorForInput.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap );
+  mActorForHorz.SetProperty( Toolkit::ImageView::Property::IMAGE, rendererMap );
 
-  mShaderForVert = ShaderEffect::New( "", fragmentSource.str() );
-  mActorForHorz.SetShaderEffect( mShaderForVert );
-  mShaderForVert.SetUniform( "uSpread", mSpread );
-  mShaderForVert.SetUniform( "uTexScale", Vector2( 0.0f, 1.0f / mTargetSize.height ) );
+  mRootActor.Add( mActorForInput );
+  mRootActor.Add( mActorForHorz );
 
   SetupCamera();
   CreateRenderTasks();
@@ -196,16 +178,6 @@ void SpreadFilter::SetSize( const Vector2& size )
   }
 }
 
-void SpreadFilter::SetupCamera()
-{
-  // Create and place a camera for the embossing render, corresponding to its render target size
-  mCameraActor.SetFieldOfView(ARBITRARY_FIELD_OF_VIEW);
-  mCameraActor.SetNearClippingPlane(1.0f);
-  mCameraActor.SetAspectRatio(mTargetSize.width / mTargetSize.height);
-  mCameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
-  mCameraActor.SetPosition(0.0f, 0.0f, ((mTargetSize.height * 0.5f) / tanf(ARBITRARY_FIELD_OF_VIEW * 0.5f)));
-}
-
 void SpreadFilter::CreateRenderTasks()
 {
   RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList();
index 5f5d857..3ef2155 100644 (file)
  */
 
 // EXTERNAL INCLUDES
-#include <dali/public-api/actors/camera-actor.h>
-#include <dali/public-api/actors/image-actor.h>
 #include <dali/public-api/render-tasks/render-task.h>
-#include <dali/public-api/shader-effects/shader-effect.h>
+#include <dali-toolkit/public-api/controls/image-view/image-view.h>
 
 // INTERNAL INCLUDES
 #include "image-filter.h"
@@ -72,10 +70,6 @@ public: // From ImageFilter
   virtual void SetSize( const Vector2& size );
 
 private:
-  /**
-   * Setup position and parameters for camera
-   */
-  void SetupCamera();
 
   /**
    * Setup render tasks for blur
@@ -87,19 +81,17 @@ private:
   SpreadFilter& operator=( const SpreadFilter& );
 
 private: // Attributes
-  int              mSpread;
-  CameraActor      mCameraActor;
 
   // To perform horizontal spread from mInputImage to mImageForHorz
-  RenderTask       mRenderTaskForHorz;
-  ImageActor       mActorForInput;
-  FrameBufferImage mImageForHorz;
-  ShaderEffect     mShaderForHorz;
+  RenderTask         mRenderTaskForHorz;
+  Toolkit::ImageView mActorForInput;
+  FrameBufferImage   mImageForHorz;
 
   // To perform vertical spread from mImageForHorz to mOutputImage
-  RenderTask       mRenderTaskForVert;
-  ImageActor       mActorForHorz;
-  ShaderEffect     mShaderForVert;
+  RenderTask         mRenderTaskForVert;
+  Toolkit::ImageView mActorForHorz;
+
+  int                mSpread;
 }; // class SpreadFilter
 
 } // namespace Internal
index 8af3e91..239a2f8 100644 (file)
@@ -420,6 +420,131 @@ void LogicalModel::ClearFontDescriptionRuns()
   FreeFontFamilyNames( mFontDescriptionRuns );
 }
 
+void LogicalModel::CreateParagraphInfo( CharacterIndex startIndex,
+                                        Length numberOfCharacters )
+{
+  const Length totalNumberOfCharacters = mLineBreakInfo.Count();
+
+  // Count the number of LINE_MUST_BREAK to reserve some space for the vector of paragraph's info.
+  Vector<CharacterIndex> paragraphs;
+  paragraphs.Reserve( numberOfCharacters );
+  const TextAbstraction::LineBreakInfo* lineBreakInfoBuffer = mLineBreakInfo.Begin();
+  const CharacterIndex lastCharacterIndexPlusOne = startIndex + numberOfCharacters;
+  for( Length index = startIndex; index < lastCharacterIndexPlusOne; ++index )
+  {
+    if( TextAbstraction::LINE_MUST_BREAK == *( lineBreakInfoBuffer + index ) )
+    {
+      paragraphs.PushBack( index );
+    }
+  }
+
+  // Whether the current paragraphs are updated or set from scratch.
+  const bool updateCurrentParagraphs = numberOfCharacters < totalNumberOfCharacters;
+
+  // Reserve space for current paragraphs plus new ones.
+  const Length numberOfNewParagraphs = paragraphs.Count();
+  const Length totalNumberOfParagraphs = mParagraphInfo.Count() + numberOfNewParagraphs;
+  mParagraphInfo.Resize( totalNumberOfParagraphs );
+
+  ParagraphRun* paragraphInfoBuffer = NULL;
+  Vector<ParagraphRun> newParagraphs;
+
+  if( updateCurrentParagraphs )
+  {
+    newParagraphs.Resize( numberOfNewParagraphs );
+    paragraphInfoBuffer = newParagraphs.Begin();
+  }
+  else
+  {
+    paragraphInfoBuffer = mParagraphInfo.Begin();
+  }
+
+  // Find where to insert the new paragraphs.
+  ParagraphRunIndex paragraphIndex = 0u;
+  CharacterIndex firstIndex = startIndex;
+
+  if( updateCurrentParagraphs )
+  {
+    for( Vector<ParagraphRun>::ConstIterator it = mParagraphInfo.Begin(),
+           endIt = mParagraphInfo.Begin() + totalNumberOfParagraphs - numberOfNewParagraphs;
+         it != endIt;
+         ++it )
+    {
+      const ParagraphRun& paragraph( *it );
+
+      if( startIndex < paragraph.characterRun.characterIndex + paragraph.characterRun.numberOfCharacters )
+      {
+        firstIndex = paragraph.characterRun.characterIndex;
+        break;
+      }
+
+      ++paragraphIndex;
+    }
+  }
+
+  // Create the paragraph info.
+  ParagraphRunIndex newParagraphIndex = 0u;
+  for( Vector<CharacterIndex>::ConstIterator it = paragraphs.Begin(),
+         endIt = paragraphs.End();
+       it != endIt;
+       ++it, ++newParagraphIndex )
+  {
+    const CharacterIndex index = *it;
+
+    ParagraphRun& paragraph = *( paragraphInfoBuffer + newParagraphIndex );
+    paragraph.characterRun.characterIndex = firstIndex;
+    paragraph.characterRun.numberOfCharacters = 1u + index - firstIndex;
+
+    firstIndex += paragraph.characterRun.numberOfCharacters;
+  }
+
+
+  // Insert the new paragraphs.
+  if( updateCurrentParagraphs )
+  {
+    mParagraphInfo.Insert( mParagraphInfo.Begin() + paragraphIndex,
+                           newParagraphs.Begin(),
+                           newParagraphs.End() );
+
+    mParagraphInfo.Resize( totalNumberOfParagraphs );
+
+    // Update the next paragraph indices.
+    for( Vector<ParagraphRun>::Iterator it = mParagraphInfo.Begin() + paragraphIndex + newParagraphs.Count(),
+           endIt = mParagraphInfo.End();
+         it != endIt;
+         ++it )
+    {
+      ParagraphRun& paragraph( *it );
+
+      paragraph.characterRun.characterIndex += numberOfCharacters;
+    }
+  }
+}
+
+void LogicalModel::FindParagraphs( CharacterIndex index,
+                                   Length numberOfCharacters,
+                                   Vector<ParagraphRunIndex>& paragraphs )
+{
+  // Reserve som space for the paragraph indices.
+  paragraphs.Reserve( mParagraphInfo.Count() );
+
+  // Traverse the paragraphs to find which ones contain the given characters.
+  ParagraphRunIndex paragraphIndex = 0u;
+  for( Vector<ParagraphRun>::ConstIterator it = mParagraphInfo.Begin(),
+         endIt = mParagraphInfo.End();
+       it != endIt;
+       ++it, ++paragraphIndex )
+  {
+    const ParagraphRun& paragraph( *it );
+
+    if( ( paragraph.characterRun.characterIndex + paragraph.characterRun.numberOfCharacters > index ) &&
+        ( paragraph.characterRun.characterIndex < index + numberOfCharacters ) )
+    {
+      paragraphs.PushBack( paragraphIndex );
+    }
+  }
+}
+
 LogicalModel::~LogicalModel()
 {
   ClearFontDescriptionRuns();
index 7085d79..e41f0fa 100644 (file)
@@ -29,6 +29,7 @@
 #include <dali-toolkit/internal/text/color-run.h>
 #include <dali-toolkit/internal/text/font-run.h>
 #include <dali-toolkit/internal/text/font-description-run.h>
+#include <dali-toolkit/internal/text/paragraph-run.h>
 #include <dali-toolkit/internal/text/script-run.h>
 
 namespace Dali
@@ -136,6 +137,30 @@ public:
    */
   void ClearFontDescriptionRuns();
 
+  // Paragraphs
+
+  /**
+   * @brief Creates the paragraph info.
+   *
+   * @pre The line break info must be set.
+   *
+   * @param[in] startIndex The character from where the paragraph info is set.
+   * @param[in] numberOfCharacters The number of characters.
+   */
+  void CreateParagraphInfo( CharacterIndex startIndex,
+                            Length numberOfCharacters );
+
+  /**
+   * @brief Find the paragraphs which contains the given characters.
+   *
+   * @param[in] index The first character's index of the run.
+   * @param[in] numberOfCharacters The number of characters of the run.
+   * @param[out] paragraphs Indices to the paragraphs which contain the characters.
+   */
+  void FindParagraphs( CharacterIndex index,
+                       Length numberOfCharacters,
+                       Vector<ParagraphRunIndex>& paragraphs );
+
 protected:
 
   /**
@@ -165,6 +190,7 @@ public:
   Vector<FontDescriptionRun>            mFontDescriptionRuns;
   Vector<LineBreakInfo>                 mLineBreakInfo;
   Vector<WordBreakInfo>                 mWordBreakInfo;
+  Vector<ParagraphRun>                  mParagraphInfo;
   Vector<BidirectionalParagraphInfoRun> mBidirectionalParagraphInfo;
   Vector<CharacterDirection>            mCharacterDirections;        ///< For each character, whether is right to left. ( @e flase is left to right, @e true right to left ).
   Vector<BidirectionalLineInfoRun>      mBidirectionalLineInfo;
diff --git a/dali-toolkit/internal/text/paragraph-run.h b/dali-toolkit/internal/text/paragraph-run.h
new file mode 100644 (file)
index 0000000..7a90363
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef __DALI_TOOLKIT_TEXT_PARAGRAPH_RUN_H__
+#define __DALI_TOOLKIT_TEXT_PARAGRAPH_RUN_H__
+
+/*
+ * Copyright (c) 2016 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/math/vector2.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/character-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief ParagraphRun
+ *
+ * In terms of the bidirectional algorithm, a 'paragraph' is understood as a run of characters between Paragraph Separators or appropriate Newline Functions.
+ * A 'paragraph' may also be determined by higher-level protocols like a mark-up tag.
+ */
+struct ParagraphRun
+{
+  CharacterRun  characterRun; ///< The initial character index within the whole text and the number of characters of the run.
+  Size          layoutSize;   ///< The size of the paragraph when is laid-out.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_PARAGRAPH_RUN_H__
index 5e590b5..61afef1 100644 (file)
@@ -50,21 +50,51 @@ namespace Text
 {
 
 void SetLineBreakInfo( const Vector<Character>& text,
+                       CharacterIndex startIndex,
+                       Length numberOfCharacters,
                        Vector<LineBreakInfo>& lineBreakInfo )
 {
-  const Length numberOfCharacters = text.Count();
+  const Length totalNumberOfCharacters = text.Count();
 
-  if( 0u == numberOfCharacters )
+  if( 0u == totalNumberOfCharacters )
   {
     // Nothing to do if there are no characters.
     return;
   }
 
   // Retrieve the line break info.
-  lineBreakInfo.Resize( numberOfCharacters );
-  TextAbstraction::Segmentation::Get().GetLineBreakPositions( text.Begin(),
+  lineBreakInfo.Resize( totalNumberOfCharacters );
+
+  // Whether the current buffer is being updated or is set from scratch.
+  const bool updateCurrentBuffer = numberOfCharacters < totalNumberOfCharacters;
+
+  LineBreakInfo* lineBreakInfoBuffer = NULL;
+  Vector<LineBreakInfo> newLineBreakInfo;
+
+  if( updateCurrentBuffer )
+  {
+    newLineBreakInfo.Resize( numberOfCharacters );
+    lineBreakInfoBuffer = newLineBreakInfo.Begin();
+  }
+  else
+  {
+    lineBreakInfoBuffer = lineBreakInfo.Begin();
+  }
+
+  // Retrieve the line break info.
+  TextAbstraction::Segmentation::Get().GetLineBreakPositions( text.Begin() + startIndex,
                                                               numberOfCharacters,
-                                                              lineBreakInfo.Begin() );
+                                                              lineBreakInfoBuffer );
+
+  // If the line break info is updated, it needs to be inserted in the model.
+  if( updateCurrentBuffer )
+  {
+    lineBreakInfo.Insert( lineBreakInfo.Begin() + startIndex,
+                          newLineBreakInfo.Begin(),
+                          newLineBreakInfo.End() );
+    lineBreakInfo.Resize( totalNumberOfCharacters );
+  }
+
 #ifdef DEBUG_ENABLED
   if( gLogFilter->IsEnabledFor(Debug::Verbose) )
   {
index 61ddcc7..e23065a 100644 (file)
@@ -45,9 +45,13 @@ class LogicalModel;
  *  - 2 is a LINE_NO_BREAK.    Text can't be broken into a new line.
  *
  * @param[in] text Vector of UTF-32 characters.
+ * @param[in] startIndex The character from where the break info is set.
+ * @param[in] numberOfCharacters The number of characters.
  * @param[out] lineBreakInfo The line break info
  */
 void SetLineBreakInfo( const Vector<Character>& text,
+                       CharacterIndex startIndex,
+                       Length numberOfCharacters,
                        Vector<LineBreakInfo>& lineBreakInfo );
 
 /**
index 5313d0c..cd0b1d7 100644 (file)
@@ -175,7 +175,7 @@ void ShapeText( const Vector<Character>& text,
     shaping.GetGlyphs( tmpGlyphs.Begin(),
                        tmpGlyphToCharacterMap.Begin() );
 
-    // Update the indices.
+    // Update the new indices of the glyph to character map.
     if( 0u != totalNumberOfGlyphs )
     {
       for( Vector<CharacterIndex>::Iterator it = tmpGlyphToCharacterMap.Begin(),
index d681730..5571f94 100644 (file)
@@ -336,7 +336,13 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired )
     lineBreakInfo.Resize( numberOfCharacters, TextAbstraction::LINE_NO_BREAK );
 
     SetLineBreakInfo( utf32Characters,
+                      startIndex,
+                      requestedNumberOfCharacters,
                       lineBreakInfo );
+
+    // Create the paragraph info.
+    mLogicalModel->CreateParagraphInfo( startIndex,
+                                        requestedNumberOfCharacters );
   }
 
   Vector<WordBreakInfo>& wordBreakInfo = mLogicalModel->mWordBreakInfo;
@@ -471,8 +477,8 @@ void Controller::Impl::UpdateModel( OperationsMask operationsRequired )
                newParagraphGlyphs );
 
     // Create the 'number of glyphs' per character and the glyph to character conversion tables.
-    mVisualModel->CreateGlyphsPerCharacterTable( startIndex, numberOfCharacters );
-    mVisualModel->CreateCharacterToGlyphTable( startIndex, numberOfCharacters );
+    mVisualModel->CreateGlyphsPerCharacterTable( startIndex, startGlyphIndex, numberOfCharacters );
+    mVisualModel->CreateCharacterToGlyphTable( startIndex, startGlyphIndex, numberOfCharacters );
   }
 
   const Length numberOfGlyphs = glyphs.Count();
index 153a36c..ab41790 100644 (file)
@@ -466,7 +466,7 @@ float Controller::GetDefaultPointSize() const
   return 0.0f;
 }
 
-void Controller::UpdateAfterFontChange( std::string& newDefaultFont )
+void Controller::UpdateAfterFontChange( const std::string& newDefaultFont )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::UpdateAfterFontChange");
 
@@ -499,7 +499,7 @@ const Vector4& Controller::GetTextColor() const
   return mImpl->mTextColor;
 }
 
-bool Controller::RemoveText( int cursorOffset, int numberOfChars )
+bool Controller::RemoveText( int cursorOffset, int numberOfCharacters )
 {
   bool removed = false;
 
@@ -508,8 +508,8 @@ bool Controller::RemoveText( int cursorOffset, int numberOfChars )
     return removed;
   }
 
-  DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::RemoveText %p mText.Count() %d cursor %d cursorOffset %d numberOfChars %d\n",
-                 this, mImpl->mLogicalModel->mText.Count(), mImpl->mEventData->mPrimaryCursorPosition, cursorOffset, numberOfChars );
+  DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::RemoveText %p mText.Count() %d cursor %d cursorOffset %d numberOfCharacters %d\n",
+                 this, mImpl->mLogicalModel->mText.Count(), mImpl->mEventData->mPrimaryCursorPosition, cursorOffset, numberOfCharacters );
 
   if( !mImpl->IsShowingPlaceholderText() )
   {
@@ -525,12 +525,12 @@ bool Controller::RemoveText( int cursorOffset, int numberOfChars )
       cursorIndex = oldCursorIndex + cursorOffset;
     }
 
-    if( ( cursorIndex + numberOfChars ) > currentText.Count() )
+    if( ( cursorIndex + numberOfCharacters ) > currentText.Count() )
     {
-      numberOfChars = currentText.Count() - cursorIndex;
+      numberOfCharacters = currentText.Count() - cursorIndex;
     }
 
-    if( ( cursorIndex + numberOfChars ) <= currentText.Count() )
+    if( ( cursorIndex + numberOfCharacters ) <= currentText.Count() )
     {
       // Update the input style and remove the text's style before removing the text.
 
@@ -541,18 +541,18 @@ bool Controller::RemoveText( int cursorOffset, int numberOfChars )
       mImpl->mLogicalModel->RetrieveStyle( cursorIndex, mImpl->mEventData->mInputStyle );
 
       // Remove the text's style before removing the text.
-      mImpl->mLogicalModel->UpdateTextStyleRuns( cursorIndex, -numberOfChars );
+      mImpl->mLogicalModel->UpdateTextStyleRuns( cursorIndex, -numberOfCharacters );
 
       // Remove the characters.
       Vector<Character>::Iterator first = currentText.Begin() + cursorIndex;
-      Vector<Character>::Iterator last  = first + numberOfChars;
+      Vector<Character>::Iterator last  = first + numberOfCharacters;
 
       currentText.Erase( first, last );
 
       // Cursor position retreat
       oldCursorIndex = cursorIndex;
 
-      DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::RemoveText %p removed %d\n", this, numberOfChars );
+      DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::RemoveText %p removed %d\n", this, numberOfCharacters );
       removed = true;
     }
   }
@@ -1776,14 +1776,14 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
 
   // Remove the previous IMF pre-edit (predicitive text)
   if( mImpl->mEventData->mPreEditFlag &&
-      ( 0 != mImpl->mEventData->mPreEditLength ) )
+      ( 0u != mImpl->mEventData->mPreEditLength ) )
   {
-    CharacterIndex offset = mImpl->mEventData->mPrimaryCursorPosition - mImpl->mEventData->mPreEditStartPosition;
+    const CharacterIndex offset = mImpl->mEventData->mPrimaryCursorPosition - mImpl->mEventData->mPreEditStartPosition;
 
-    removedPrevious = RemoveText( -static_cast<int>(offset), mImpl->mEventData->mPreEditLength );
+    removedPrevious = RemoveText( -static_cast<int>( offset ), mImpl->mEventData->mPreEditLength );
 
     mImpl->mEventData->mPrimaryCursorPosition = mImpl->mEventData->mPreEditStartPosition;
-    mImpl->mEventData->mPreEditLength = 0;
+    mImpl->mEventData->mPreEditLength = 0u;
   }
   else
   {
@@ -1842,7 +1842,7 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
 
     const Length numberOfCharactersInModel = mImpl->mLogicalModel->mText.Count();
 
-    // Restrict new text to fit within Maximum characters setting
+    // Restrict new text to fit within Maximum characters setting.
     Length maxSizeOfNewText = std::min( ( mImpl->mMaximumNumberOfCharacters - numberOfCharactersInModel ), characterCount );
     maxLengthReached = ( characterCount > maxSizeOfNewText );
 
@@ -2514,7 +2514,7 @@ void Controller::ShowPlaceholderText()
 
     // Transform a text array encoded in utf8 into an array encoded in utf32.
     // It returns the actual number of characters.
-    Length characterCount = Utf8ToUtf32( utf8, size, utf32Characters.Begin() );
+    const Length characterCount = Utf8ToUtf32( utf8, size, utf32Characters.Begin() );
     utf32Characters.Resize( characterCount );
 
     // Reset the cursor position
index d239d13..7e22134 100644 (file)
@@ -151,10 +151,10 @@ public:
    * @brief Remove a given number of characters
    *
    * @param[in] cursorOffset Start position from the current cursor position to start deleting characters.
-   * @param[in] numberOfChars The number of characters to delete from the cursorOffset.
+   * @param[in] numberOfCharacters The number of characters to delete from the cursorOffset.
    * @return True if the remove was successful.
    */
-  bool RemoveText( int cursorOffset, int numberOfChars );
+  bool RemoveText( int cursorOffset, int numberOfCharacters );
 
   /**
    * @brief Retrieve the current cursor position.
@@ -283,7 +283,7 @@ public:
    * @ brief Update the text after a font change
    * @param[in] newDefaultFont The new font to change to
    */
-  void UpdateAfterFontChange( std::string& newDefaultFont );
+  void UpdateAfterFontChange( const std::string& newDefaultFont );
 
   /**
    * @brief Set the text color
index 4879090..0e9fb3f 100644 (file)
@@ -59,6 +59,7 @@ typedef uint32_t                         UnderlineRunIndex;         ///< An inde
 typedef uint32_t                         BidirectionalRunIndex;     ///< An index into an array of bidirectional info.
 typedef uint32_t                         BidirectionalLineRunIndex; ///< An index into an array of bidirectional line info.
 typedef uint32_t                         LineIndex;                 ///< An index into an array of lines.
+typedef uint32_t                         ParagraphRunIndex;         ///< An index into an array of paragraphs.
 
 } // namespace Text
 
index 37d7b00..ecac39d 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_TOOLKIT_TEXT_STYLE_RUN_CONTAINER_H__
-#define __DALI_TOOLKIT_TEXT_STYLE_RUN_CONTAINER_H__
+#ifndef __DALI_TOOLKIT_TEXT_RUN_CONTAINER_H__
+#define __DALI_TOOLKIT_TEXT_RUN_CONTAINER_H__
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
@@ -300,6 +300,7 @@ void ClearGlyphRuns( GlyphIndex startIndex,
         ( startIndex >= run->glyphRun.glyphIndex + run->glyphRun.numberOfGlyphs ) )
     {
       // Run found. Nothing else to do.
+      break;
     }
 
     ++run;
@@ -352,4 +353,4 @@ void ClearGlyphRuns( GlyphIndex startIndex,
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_STYLE_RUN_CONTAINER_H__
+#endif // __DALI_TOOLKIT_TEXT_RUN_CONTAINER_H__
index 138ce54..c1faee7 100644 (file)
@@ -36,6 +36,7 @@ VisualModelPtr VisualModel::New()
 }
 
 void VisualModel::CreateCharacterToGlyphTable( CharacterIndex startIndex,
+                                               GlyphIndex startGlyphIndex,
                                                Length numberOfCharacters )
 {
   if( 0u == numberOfCharacters )
@@ -72,7 +73,6 @@ void VisualModel::CreateCharacterToGlyphTable( CharacterIndex startIndex,
   // 2) Traverse the glyphs and set the glyph indices per character.
 
   // Index to the glyph.
-  const GlyphIndex startGlyphIndex = updateCurrentBuffer ? *( mCharactersToGlyph.Begin() + startIndex ) : 0u;
   GlyphIndex glyphIndex = startGlyphIndex;
   CharacterIndex characterIndex = startIndex;
   const CharacterIndex lastCharacterIndexPlusOne = startIndex + numberOfCharacters;
@@ -115,6 +115,7 @@ void VisualModel::CreateCharacterToGlyphTable( CharacterIndex startIndex,
 }
 
 void VisualModel::CreateGlyphsPerCharacterTable( CharacterIndex startIndex,
+                                                 GlyphIndex startGlyphIndex,
                                                  Length numberOfCharacters )
 {
   if( 0u == numberOfCharacters )
@@ -146,14 +147,12 @@ void VisualModel::CreateGlyphsPerCharacterTable( CharacterIndex startIndex,
 
   // 2) Traverse the glyphs and set the number of glyphs per character.
 
-  // The glyph index.
-  const GlyphIndex glyphIndex = updateCurrentBuffer  ? *( mCharactersToGlyph.Begin() + startIndex ) : 0u;
   Length traversedCharacters = 0;
 
   // The number of 'characters per glyph' equal to zero.
   Length zeroCharactersPerGlyph = 0u;
 
-  for( Vector<Length>::ConstIterator it = mCharactersPerGlyph.Begin() + glyphIndex,
+  for( Vector<Length>::ConstIterator it = mCharactersPerGlyph.Begin() + startGlyphIndex,
          endIt = mCharactersPerGlyph.End();
        ( it != endIt ) && ( traversedCharacters < numberOfCharacters );
        ++it )
index a0339a4..5aa90af 100644 (file)
@@ -67,18 +67,22 @@ public:
    * @pre The glyphs per character table needs to be created first.
    *
    * @param[in] startIndex The character from where the conversion table is created.
+   * @param[in] startGlyphIndex The glyph from where the conversion table is created.
    * @param[in] numberOfCharacters The number of characters.
    */
   void CreateCharacterToGlyphTable( CharacterIndex startIndex,
+                                    GlyphIndex startGlyphIndex,
                                     Length numberOfCharacters );
 
   /**
    * @brief Creates an array containing the number of glyphs per character.
    *
    * @param[in] startIndex The character from where the table is created.
+   * @param[in] startGlyphIndex The glyph from where the conversion table is created.
    * @param[in] numberOfCharacters The number of characters.
    */
   void CreateGlyphsPerCharacterTable( CharacterIndex startIndex,
+                                      GlyphIndex startGlyphIndex,
                                       Length numberOfCharacters );
 
   /**
index b8ecd96..5a76197 100644 (file)
@@ -270,6 +270,8 @@ void CubeTransitionEffect::Initialize()
 
 void CubeTransitionEffect::OnStageConnection( int depth )
 {
+  Control::OnStageConnection( depth );
+
   Geometry geometry = CreateQuadGeometry();
   Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
 
@@ -306,6 +308,8 @@ void CubeTransitionEffect::OnStageDisconnection()
     }
     mTargetRenderer.Reset();
   }
+
+  Control::OnStageDisconnection();
 }
 
 void CubeTransitionEffect::SetTransitionDuration( float duration )
index 7cc7571..841e3d3 100644 (file)
@@ -187,8 +187,7 @@ public:
   mLongPressGestureDetector(),
   mFlags( Control::ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ),
   mIsKeyboardNavigationSupported( false ),
-  mIsKeyboardFocusGroup( false ),
-  mAddRemoveBackgroundChild( false )
+  mIsKeyboardFocusGroup( false )
 {
 }
 
@@ -384,7 +383,6 @@ public:
   ControlBehaviour mFlags :CONTROL_BEHAVIOUR_FLAG_COUNT;    ///< Flags passed in from constructor.
   bool mIsKeyboardNavigationSupported :1;  ///< Stores whether keyboard navigation is supported by the control.
   bool mIsKeyboardFocusGroup :1;           ///< Stores whether the control is a focus group.
-  bool mAddRemoveBackgroundChild:1;        ///< Flag to know when we are adding or removing our own actor to avoid call to OnControlChildAdd
 
   // Properties - these need to be members of Internal::Control::Impl as they need to function within this class.
   static const PropertyRegistration PROPERTY_1;
@@ -841,31 +839,23 @@ void Control::OnKeyInputFocusLost()
 
 void Control::OnChildAdd(Actor& child)
 {
-  // If this is the background actor, then we do not want to inform deriving classes
-  if ( mImpl->mAddRemoveBackgroundChild )
-  {
-    return;
-  }
-
   // Notify derived classes.
   OnControlChildAdd( child );
 }
 
 void Control::OnChildRemove(Actor& child)
 {
-  // If this is the background actor, then we do not want to inform deriving classes
-  if ( mImpl->mAddRemoveBackgroundChild )
-  {
-    return;
-  }
-
   // Notify derived classes.
   OnControlChildRemove( child );
 }
 
 void Control::OnSizeSet(const Vector3& targetSize)
 {
-  // Background is resized through size negotiation
+  if( mImpl->mBackgroundRenderer )
+  {
+    Vector2 size( targetSize );
+    mImpl->mBackgroundRenderer.SetSize( size );
+  }
 }
 
 void Control::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
index b3d0c1e..4779d58 100644 (file)
@@ -301,31 +301,37 @@ protected: // From CustomActorImpl, not to be used by application developers
 
   /**
    * @copydoc CustomActorImpl::OnStageConnection()
+   * @note If overridden, then an up-call to Control::OnStageConnection MUST be made at the start.
    */
   virtual void OnStageConnection( int depth );
 
   /**
    * @copydoc CustomActorImpl::OnStageDisconnection()
+   * @note If overridden, then an up-call to Control::OnStageDisconnection MUST be made at the end.
    */
   virtual void OnStageDisconnection();
 
   /**
    * @copydoc CustomActorImpl::OnChildAdd()
+   * @note If overridden, then an up-call to Control::OnChildAdd MUST be made at the start.
    */
   virtual void OnChildAdd( Actor& child );
 
   /**
    * @copydoc CustomActorImpl::OnChildRemove()
+   * @note If overridden, then an up-call to Control::OnChildRemove MUST be made at the end.
    */
   virtual void OnChildRemove( Actor& child );
 
   /**
    * @copydoc CustomActorImpl::OnSizeSet()
+   * @note If overridden, then an up-call to Control::OnSizeSet MUST be made at the start.
    */
   virtual void OnSizeSet( const Vector3& targetSize );
 
   /**
    * @copydoc CustomActorImpl::OnSizeAnimation()
+   * @note If overridden, then an up-call to Control::OnSizeAnimation MUST be made at the start.
    */
   virtual void OnSizeAnimation( Animation& animation, const Vector3& targetSize );
 
@@ -436,6 +442,8 @@ public: // API for derived classes to override
   virtual void OnInitialize();
 
   /**
+   * @DEPRECATED_1_1.30. Override OnChildAdd instead.
+   *
    * @brief Called whenever an Actor is added to the control.
    *
    * Could be overridden by derived classes.
@@ -446,6 +454,8 @@ public: // API for derived classes to override
   virtual void OnControlChildAdd( Actor& child );
 
   /**
+   * @DEPRECATED_1_1.30. Override OnChildRemove instead.
+   *
    * @brief Called whenever an Actor is removed from the control.
    *
    * Could be overridden by derived classes.
index 99d036a..16bfdca 100644 (file)
@@ -29,7 +29,7 @@ namespace Toolkit
 
 /**
  * @brief PageFactory is an abstract interface for providing image actors to PageTurnView
- * Each image actor is identified by a unique ID, and has a linear order from 0 to GetNumberOfPages()-1
+ * Each page is identified by a unique ID, and has a linear order from 0 to GetNumberOfPages()-1
  *
  * @SINCE_1_1.4
  */
@@ -37,6 +37,8 @@ class DALI_IMPORT_API PageFactory
 {
 public:
 
+  class Extension; ///< Forward declare future extension interface
+
   /**
    * @brief Virtual destructor
    * @SINCE_1_1.4
@@ -45,18 +47,35 @@ public:
 
   /**
    * @brief Query the number of pages available from the factory.
+   *
    * The maximum available page has an ID of GetNumberOfPages()-1.
    * @SINCE_1_1.4
+   * @return The page count.
    */
   virtual unsigned int GetNumberOfPages() = 0;
 
   /**
    * @brief Create an actor to represent the page content.
-   * @SINCE_1_1.4
+   * @SINCE_1_1.30
+   *
+   * If no valid image provided, a broken image is displayed.
+   * For double-sided page( PageTurnLandscapeView ), the left half of image is used as page front side, and the right half as page back side.
+   *
    * @param[in] pageId The ID of the page to create.
    * @return An actor, or an uninitialized pointer if the ID is out of range.
    */
-  virtual Actor NewPage( unsigned int pageId ) = 0;
+  virtual Image NewPage( unsigned int pageId ) = 0;
+
+  /**
+   * @brief Retrieve the extension for this factory
+   * @SINCE_1_1.30
+   *
+   * @return The extension if available, NULL otherwise.
+   */
+  virtual Extension* GetExtension()
+  {
+    return NULL;
+  }
 };
 
 } // namespace Toolkit
index 62ea7a1..ea5036c 100644 (file)
@@ -31,7 +31,7 @@ namespace Toolkit
 
 const unsigned int TOOLKIT_MAJOR_VERSION = 1;
 const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 29;
+const unsigned int TOOLKIT_MICRO_VERSION = 30;
 const char * const TOOLKIT_BUILD_DATE    = __DATE__ " " __TIME__;
 
 #ifdef DEBUG_ENABLED
index b40262b..7410978 100644 (file)
@@ -327,6 +327,93 @@ void AppFunction()
 
 customControl.MyCustomSignal.Connect( this, &AppFunction );
 ~~~
+___________________________________________________________________________________________________
+
+### Children Added/Removed {#creating-controls-children}
+
+Methods are provided that can be overridden if notification is required when a child is added or removed from our control.
+An up call to the Control class is necessary if these methods are overridden.
+~~~{.cpp}
+// C++
+void MyUIControlImpl::OnChildAdd( Actor& child );
+{
+  // Up call to Control first
+  Control::OnChildAdd( child );
+
+  // Do any other operations required upon child addition
+}
+~~~
+~~~{.cpp}
+// C++
+void MyUIControlImpl::OnChildRemove( Actor& child );
+{
+  // Do any other operations required upon child removal
+
+  // Up call to Control at the end
+  Control::OnChildRemove( child );
+}
+~~~
+Avoid adding or removing the child again within these methods.
+___________________________________________________________________________________________________
+
+### Stage Connection {#creating-controls-stage}
+
+Methods are provided that can be overridden if notification is required when our control is connected to or disconnected from the stage.
+An up call to the Control class is necessary if these methods are overridden.
+~~~{.cpp}
+// C++
+void MyUIControlImpl::OnStageConnection( int depth )
+{
+  // Up call to Control first
+  Control::OnStageConnection( depth );
+
+  // Do any other operations required upon stage connection
+}
+~~~
+~~~{.cpp}
+// C++
+void MyUIControlImpl::OnStageDisconnection()
+{
+  // Do any other operations required upon stage disconnection
+
+  // Up call to Control at the end
+  Control::OnStageDisconnection();
+}
+~~~
+___________________________________________________________________________________________________
+
+### Size {#creating-controls-size}
+
+Methods are provided that can be overridden if notification is required when our control's size is manipulated.
+An up call to the Control class is necessary if these methods are overridden.
+~~~{.cpp}
+// C++
+void MyUIControlImpl::OnSizeSet( const Vector3& targetSize )
+{
+  // Up call to Control
+  Control::OnSizeSet( targetSize );
+
+  // Do any other operations required upon size set
+}
+~~~
+~~~{.cpp}
+// C++
+void MyUIControlImpl::OnSizeAnimation( Animation& animation, const Vector3& targetSize )
+{
+  // Up call to Control
+  Control::OnSizeAnimation( animation, targetSize );
+
+  // Do any other operations required upon size animation
+}
+~~~
 ___________________________________________________________________________________________________
 
 ### Other Features {#creating-controls-other}
index 9cc1a48..c00ee57 100644 (file)
@@ -1,6 +1,6 @@
 Name:       dali-toolkit
 Summary:    The OpenGLES Canvas Core Library Toolkit
-Version:    1.1.29
+Version:    1.1.30
 Release:    1
 Group:      System/Libraries
 License:    Apache-2.0 and BSD-2-Clause and MIT