--- /dev/null
+/*
+ * 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.
+ *
+ */
+
+#include <iostream>
+#include <stdlib.h>
+
+// Need to override adaptor classes for toolkit test harness, so include
+// test harness headers before dali headers.
+#include <dali-toolkit-test-suite-utils.h>
+#include <toolkit-timer.h>
+
+#include <dali.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/controls/popup/popup.h>
+#include <dali-toolkit/devel-api/controls/tooltip/tooltip-properties.h>
+#include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
+#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
+#include <dali/integration-api/events/hover-event-integ.h>
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+void utc_dali_toolkit_tooltip_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void utc_dali_toolkit_tooltip_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace
+{
+
+Integration::HoverEvent GenerateSingleHover( TouchPoint::State state, const Vector2& screenPosition )
+{
+ Integration::HoverEvent hoverEvent;
+ Integration::Point point;
+ point.SetState( static_cast< PointState::Type >( state ) );
+ point.SetScreenPosition( screenPosition );
+ hoverEvent.points.push_back( point );
+ return hoverEvent;
+}
+
+} // unnamed namespace
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+int UtcDaliTooltipGetWithoutSetting(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ tet_infoline( "Check if Property::MAP is returned" );
+ Property::Value value = control.GetProperty( DevelControl::Property::TOOLTIP );
+ DALI_TEST_EQUALS( value.GetType(), Property::MAP, TEST_LOCATION );
+
+ tet_infoline( "Ensure map is valid" );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+
+ tet_infoline( "Ensure map is empty" );
+ DALI_TEST_EQUALS( true, map->Empty(), TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipCreateWithString(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetProperty( DevelControl::Property::TOOLTIP, "Hello Test" );
+
+ tet_infoline( "Check if Property::MAP is returned" );
+ Property::Value value = control.GetProperty( DevelControl::Property::TOOLTIP );
+ DALI_TEST_EQUALS( value.GetType(), Property::MAP, TEST_LOCATION );
+
+ tet_infoline( "Ensure map is valid" );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+
+ tet_infoline( "Ensure map contains the content" );
+ Property::Value* contentValue = map->Find( Tooltip::Property::CONTENT );
+ DALI_TEST_CHECK( contentValue );
+
+ tet_infoline( "Check content is a property map" );
+ Property::Map* contentMap = contentValue->GetMap();
+ DALI_TEST_CHECK( contentMap );
+
+ tet_infoline( "Check that the map contains the text item" );
+ Property::Value* textStringValue = contentMap->Find( TextVisual::Property::TEXT );
+ DALI_TEST_CHECK( textStringValue );
+
+ tet_infoline( "Ensure it matches what we set" );
+ DALI_TEST_EQUALS( "Hello Test", textStringValue->Get< std::string >(), TEST_LOCATION );
+
+ tet_infoline( "We sent valid text, so ensure the hover signal has been connected to" );
+ DALI_TEST_EQUALS( control.HoveredSignal().GetConnectionCount(), 1u, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipCreateWithTextVisualMap(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT,
+ Property::Map().Add( Visual::Property::TYPE, DevelVisual::TEXT )
+ .Add( TextVisual::Property::TEXT, "Hello TextVisual Test" ) )
+ );
+
+ tet_infoline( "Check if Property::MAP is returned" );
+ Property::Value value = control.GetProperty( DevelControl::Property::TOOLTIP );
+ DALI_TEST_EQUALS( value.GetType(), Property::MAP, TEST_LOCATION );
+
+ tet_infoline( "Ensure map is valid" );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+
+ tet_infoline( "Ensure map contains the content" );
+ Property::Value* contentValue = map->Find( Tooltip::Property::CONTENT );
+ DALI_TEST_CHECK( contentValue );
+
+ tet_infoline( "Check content is a property map" );
+ Property::Map* contentMap = contentValue->GetMap();
+ DALI_TEST_CHECK( contentMap );
+
+ tet_infoline( "Check that the map contains the text item" );
+ Property::Value* textStringValue = contentMap->Find( TextVisual::Property::TEXT );
+ DALI_TEST_CHECK( textStringValue );
+
+ tet_infoline( "Ensure it matches what we set" );
+ DALI_TEST_EQUALS( "Hello TextVisual Test", textStringValue->Get< std::string >(), TEST_LOCATION );
+
+ tet_infoline( "We sent a text visual with TEXT property set, so ensure the hover signal has been connected to" );
+ DALI_TEST_EQUALS( control.HoveredSignal().GetConnectionCount(), 1u, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipCreateWithTextVisualMapWithoutString(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT,
+ Property::Map().Add( Visual::Property::TYPE, DevelVisual::TEXT )
+ .Add( TextVisual::Property::POINT_SIZE, 20 ) )
+ );
+
+ tet_infoline( "Check if Property::MAP is returned" );
+ Property::Value value = control.GetProperty( DevelControl::Property::TOOLTIP );
+ DALI_TEST_EQUALS( value.GetType(), Property::MAP, TEST_LOCATION );
+
+ tet_infoline( "Ensure map is valid" );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+
+ tet_infoline( "Ensure map contains the content" );
+ Property::Value* contentValue = map->Find( Tooltip::Property::CONTENT );
+ DALI_TEST_CHECK( contentValue );
+
+ tet_infoline( "Check content is a property map" );
+ Property::Map* contentMap = contentValue->GetMap();
+ DALI_TEST_CHECK( contentMap );
+
+ tet_infoline( "Check that the map contains the point-size item" );
+ Property::Value* pointSizeValue = contentMap->Find( TextVisual::Property::POINT_SIZE );
+ DALI_TEST_CHECK( pointSizeValue );
+
+ tet_infoline( "Ensure it matches what we set" );
+ DALI_TEST_EQUALS( 20, pointSizeValue->Get< int >(), TEST_LOCATION );
+
+ tet_infoline( "We sent a text visual without a TEXT property set, so ensure the hover signal has NOT been connected to" );
+ DALI_TEST_EQUALS( control.HoveredSignal().GetConnectionCount(), 0u, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipCreateWithImageVisualMap(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT,
+ Property::Map().Add( Visual::Property::TYPE, Visual::IMAGE )
+ .Add( ImageVisual::Property::URL, "dummy-url.png" ) )
+ );
+
+ tet_infoline( "Check if Property::MAP is returned" );
+ Property::Value value = control.GetProperty( DevelControl::Property::TOOLTIP );
+ DALI_TEST_EQUALS( value.GetType(), Property::MAP, TEST_LOCATION );
+
+ tet_infoline( "Ensure map is valid" );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+
+ tet_infoline( "Ensure map contains the content" );
+ Property::Value* contentValue = map->Find( Tooltip::Property::CONTENT );
+ DALI_TEST_CHECK( contentValue );
+
+ tet_infoline( "Check content is a property map" );
+ Property::Map* contentMap = contentValue->GetMap();
+ DALI_TEST_CHECK( contentMap );
+
+ tet_infoline( "Check that the map contains the url item" );
+ Property::Value* urlValue = contentMap->Find( ImageVisual::Property::URL );
+ DALI_TEST_CHECK( urlValue );
+
+ tet_infoline( "Ensure it matches what we set" );
+ DALI_TEST_EQUALS( "dummy-url.png", urlValue->Get< std::string >(), TEST_LOCATION );
+
+ tet_infoline( "We sent an ImageVisual, so ensure the hover signal has been connected to" );
+ DALI_TEST_EQUALS( control.HoveredSignal().GetConnectionCount(), 1u, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipCreateWithArray(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Array().Add( Property::Map().Add( Visual::Property::TYPE, Visual::IMAGE )
+ .Add( ImageVisual::Property::URL, "dummy-url.png" ) )
+ .Add( Property::Map().Add( Visual::Property::TYPE, DevelVisual::TEXT )
+ .Add( TextVisual::Property::TEXT, "Hello Array Test" ) )
+ );
+
+ tet_infoline( "Check if Property::MAP is returned" );
+ Property::Value value = control.GetProperty( DevelControl::Property::TOOLTIP );
+ DALI_TEST_EQUALS( value.GetType(), Property::MAP, TEST_LOCATION );
+
+ tet_infoline( "Ensure map is valid" );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+
+ tet_infoline( "Ensure map contains the content" );
+ Property::Value* contentValue = map->Find( Tooltip::Property::CONTENT );
+ DALI_TEST_CHECK( contentValue );
+
+ tet_infoline( "Check content is a property array" );
+ Property::Array* contentArray = contentValue->GetArray();
+ DALI_TEST_CHECK( contentArray );
+
+ tet_infoline( "Ensure the array contains two items" );
+ DALI_TEST_EQUALS( 2u, contentArray->Count(), TEST_LOCATION );
+
+ tet_infoline( "Ensure first value is a map and contains the right item" );
+ const Property::Value mapValue1 = contentArray->GetElementAt( 0 );
+ Property::Map* map1 = mapValue1.GetMap();
+ DALI_TEST_CHECK( map1 );
+ Property::Value* urlValue = map1->Find( ImageVisual::Property::URL );
+ DALI_TEST_CHECK( urlValue );
+ DALI_TEST_EQUALS( "dummy-url.png", urlValue->Get< std::string >(), TEST_LOCATION );
+
+ tet_infoline( "Ensure second value is a map and contains the right item" );
+ const Property::Value mapValue2 = contentArray->GetElementAt( 1 );
+ Property::Map* map2 = mapValue2.GetMap();
+ DALI_TEST_CHECK( map2 );
+ Property::Value* textValue = map2->Find( TextVisual::Property::TEXT );
+ DALI_TEST_CHECK( textValue );
+ DALI_TEST_EQUALS( "Hello Array Test", textValue->Get< std::string >(), TEST_LOCATION );
+
+ tet_infoline( "We sent an array, so ensure the hover signal has been connected to" );
+ DALI_TEST_EQUALS( control.HoveredSignal().GetConnectionCount(), 1u, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipCreateWithFullMap(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT,
+ Property::Map().Add( Visual::Property::TYPE, DevelVisual::TEXT )
+ .Add( TextVisual::Property::TEXT, "Hello TextVisual Test" ) )
+ .Add( Tooltip::Property::LAYOUT, Vector2( 1.0f, 2.0f ) )
+ .Add( Tooltip::Property::WAIT_TIME, 2.5f )
+ .Add( Tooltip::Property::BACKGROUND, "tooltip-background.png" )
+ .Add( Tooltip::Property::TAIL, true )
+ .Add( Tooltip::Property::POSITION, Tooltip::Position::HOVER_POINT )
+ .Add( Tooltip::Property::HOVER_POINT_OFFSET, Vector2( 100.0f, 50.f ) )
+ .Add( Tooltip::Property::MOVEMENT_THRESHOLD, 50 )
+ .Add( Tooltip::Property::DISAPPEAR_ON_MOVEMENT, true )
+ );
+
+ tet_infoline( "Check if Property::MAP is returned" );
+ Property::Value value = control.GetProperty( DevelControl::Property::TOOLTIP );
+ DALI_TEST_EQUALS( value.GetType(), Property::MAP, TEST_LOCATION );
+
+ tet_infoline( "Ensure map is valid" );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+
+ tet_infoline( "Check content" );
+ Property::Value* contentValue = map->Find( Tooltip::Property::CONTENT );
+ DALI_TEST_CHECK( contentValue );
+ Property::Map* contentMap = contentValue->GetMap();
+ DALI_TEST_CHECK( contentMap );
+
+ tet_infoline( "Check layout" );
+ Property::Value* layoutValue = map->Find( Tooltip::Property::LAYOUT );
+ DALI_TEST_CHECK( layoutValue );
+ DALI_TEST_EQUALS( layoutValue->Get< Vector2 >(), Vector2( 1.0f, 2.0f ), TEST_LOCATION );
+
+ tet_infoline( "Check wait time" );
+ Property::Value* waitTimeValue = map->Find( Tooltip::Property::WAIT_TIME );
+ DALI_TEST_CHECK( waitTimeValue );
+ DALI_TEST_EQUALS( waitTimeValue->Get< float >(), 2.5f, TEST_LOCATION );
+
+ tet_infoline( "Check background" );
+ Property::Value* backgroundMapValue = map->Find( Tooltip::Property::BACKGROUND );
+ DALI_TEST_CHECK( backgroundMapValue );
+ Property::Map* backgroundMap = backgroundMapValue->GetMap();
+ DALI_TEST_CHECK( backgroundMap );
+ Property::Value* backgroundStringValue = backgroundMap->Find( Tooltip::Background::Property::VISUAL );
+ DALI_TEST_CHECK( backgroundStringValue );
+ DALI_TEST_EQUALS( backgroundStringValue->Get< std::string >(), "tooltip-background.png", TEST_LOCATION );
+
+ tet_infoline( "Check Tail" );
+ Property::Value* tailMapValue = map->Find( Tooltip::Property::TAIL );
+ DALI_TEST_CHECK( tailMapValue );
+ Property::Map* tailMap = tailMapValue->GetMap();
+ DALI_TEST_CHECK( tailMap );
+ Property::Value* tailVisibilityValue = tailMap->Find( Tooltip::Tail::Property::VISIBILITY );
+ DALI_TEST_CHECK( tailVisibilityValue );
+ DALI_TEST_EQUALS( tailVisibilityValue->Get< bool >(), true, TEST_LOCATION );
+
+ tet_infoline( "Check position" );
+ Property::Value* positionValue = map->Find( Tooltip::Property::POSITION );
+ DALI_TEST_CHECK( positionValue );
+ DALI_TEST_EQUALS( positionValue->Get< int >(), static_cast< int >( Tooltip::Position::HOVER_POINT ), TEST_LOCATION );
+
+ tet_infoline( "Check hover point offset" );
+ Property::Value* hoverPointOffsetValue = map->Find( Tooltip::Property::HOVER_POINT_OFFSET );
+ DALI_TEST_CHECK( hoverPointOffsetValue );
+ DALI_TEST_EQUALS( hoverPointOffsetValue->Get< Vector2 >(), Vector2( 100.0f, 50.f ), TEST_LOCATION );
+
+ tet_infoline( "Check movement threshold" );
+ Property::Value* movementThresholdValue = map->Find( Tooltip::Property::MOVEMENT_THRESHOLD );
+ DALI_TEST_CHECK( movementThresholdValue );
+ DALI_TEST_EQUALS( movementThresholdValue->Get< int >(), 50, TEST_LOCATION );
+
+ tet_infoline( "Check disappear on movement" );
+ Property::Value* disappearOnMovementValue = map->Find( Tooltip::Property::DISAPPEAR_ON_MOVEMENT );
+ DALI_TEST_CHECK( disappearOnMovementValue );
+ DALI_TEST_EQUALS( disappearOnMovementValue->Get< bool >(), true, TEST_LOCATION );
+
+ tet_infoline( "We sent a text visual with TEXT property set, so ensure the hover signal has been connected to" );
+ DALI_TEST_EQUALS( control.HoveredSignal().GetConnectionCount(), 1u, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipCreateWithBackgroundMap(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT, "Hello TextVisual Test" )
+ .Add( Tooltip::Property::BACKGROUND,
+ Property::Map().Add( Tooltip::Background::Property::VISUAL, "tooltip-background.png" )
+ .Add( Tooltip::Background::Property::BORDER, Rect< int >( 10, 20, 30, 40 ) ) )
+ );
+
+ tet_infoline( "Check if Property::MAP is returned" );
+ Property::Value value = control.GetProperty( DevelControl::Property::TOOLTIP );
+ DALI_TEST_EQUALS( value.GetType(), Property::MAP, TEST_LOCATION );
+
+ tet_infoline( "Ensure map is valid" );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+
+ tet_infoline( "Check background map" );
+ Property::Value* backgroundMapValue = map->Find( Tooltip::Property::BACKGROUND );
+ DALI_TEST_CHECK( backgroundMapValue );
+ Property::Map* backgroundMap = backgroundMapValue->GetMap();
+ DALI_TEST_CHECK( backgroundMap );
+
+ tet_infoline( "Check visual" );
+ Property::Value* backgroundStringValue = backgroundMap->Find( Tooltip::Background::Property::VISUAL );
+ DALI_TEST_CHECK( backgroundStringValue );
+ DALI_TEST_EQUALS( backgroundStringValue->Get< std::string >(), "tooltip-background.png", TEST_LOCATION );
+
+ tet_infoline( "Check border" );
+ Property::Value* borderValue = backgroundMap->Find( Tooltip::Background::Property::BORDER );
+ DALI_TEST_CHECK( borderValue );
+ DALI_TEST_EQUALS( borderValue->Get< Rect< int > >(), Rect< int >( 10, 20, 30, 40 ), TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipCreateWithBackgroundMapVector4(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT, "Hello TextVisual Test" )
+ .Add( Tooltip::Property::BACKGROUND,
+ Property::Map().Add( Tooltip::Background::Property::VISUAL, "tooltip-background.png" )
+ .Add( Tooltip::Background::Property::BORDER, Vector4( 40.0f, 30.0f, 20.0f, 10.0f ) ) )
+ );
+
+ tet_infoline( "Check if Property::MAP is returned" );
+ Property::Value value = control.GetProperty( DevelControl::Property::TOOLTIP );
+ DALI_TEST_EQUALS( value.GetType(), Property::MAP, TEST_LOCATION );
+
+ tet_infoline( "Ensure map is valid" );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+
+ tet_infoline( "Check background map" );
+ Property::Value* backgroundMapValue = map->Find( Tooltip::Property::BACKGROUND );
+ DALI_TEST_CHECK( backgroundMapValue );
+ Property::Map* backgroundMap = backgroundMapValue->GetMap();
+ DALI_TEST_CHECK( backgroundMap );
+
+ tet_infoline( "Check visual" );
+ Property::Value* backgroundStringValue = backgroundMap->Find( Tooltip::Background::Property::VISUAL );
+ DALI_TEST_CHECK( backgroundStringValue );
+ DALI_TEST_EQUALS( backgroundStringValue->Get< std::string >(), "tooltip-background.png", TEST_LOCATION );
+
+ tet_infoline( "Check border" );
+ Property::Value* borderValue = backgroundMap->Find( Tooltip::Background::Property::BORDER );
+ DALI_TEST_CHECK( borderValue );
+ DALI_TEST_EQUALS( borderValue->Get< Rect< int > >(), Rect< int >( 40, 30, 20, 10 ), TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipCreateWithTailMap(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT, "Hello TextVisual Test" )
+ .Add( Tooltip::Property::TAIL,
+ Property::Map().Add( Tooltip::Tail::Property::VISIBILITY, true )
+ .Add( Tooltip::Tail::Property::ABOVE_VISUAL, "above-visual.png" )
+ .Add( Tooltip::Tail::Property::BELOW_VISUAL, "below-visual.png" ))
+ );
+
+ tet_infoline( "Check if Property::MAP is returned" );
+ Property::Value value = control.GetProperty( DevelControl::Property::TOOLTIP );
+ DALI_TEST_EQUALS( value.GetType(), Property::MAP, TEST_LOCATION );
+
+ tet_infoline( "Ensure map is valid" );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+
+ tet_infoline( "Check Tail" );
+ Property::Value* tailMapValue = map->Find( Tooltip::Property::TAIL );
+ DALI_TEST_CHECK( tailMapValue );
+ Property::Map* tailMap = tailMapValue->GetMap();
+ DALI_TEST_CHECK( tailMap );
+
+ tet_infoline( "Check visibility" );
+ Property::Value* tailVisibilityValue = tailMap->Find( Tooltip::Tail::Property::VISIBILITY );
+ DALI_TEST_CHECK( tailVisibilityValue );
+ DALI_TEST_EQUALS( tailVisibilityValue->Get< bool >(), true, TEST_LOCATION );
+
+ tet_infoline( "Check above visual" );
+ Property::Value* aboveVisualValue = tailMap->Find( Tooltip::Tail::Property::ABOVE_VISUAL );
+ DALI_TEST_CHECK( aboveVisualValue );
+ DALI_TEST_EQUALS( aboveVisualValue->Get< std::string >(), "above-visual.png", TEST_LOCATION );
+
+ tet_infoline( "Check below visual" );
+ Property::Value* belowVisualValue = tailMap->Find( Tooltip::Tail::Property::BELOW_VISUAL );
+ DALI_TEST_CHECK( belowVisualValue );
+ DALI_TEST_EQUALS( belowVisualValue->Get< std::string >(), "below-visual.png", TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipDisplay(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetProperty( DevelControl::Property::TOOLTIP, "Test" );
+ control.SetAnchorPoint( AnchorPoint::CENTER );
+ control.SetParentOrigin( ParentOrigin::CENTER );
+ control.SetSize( 100.0f, 100.0f );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ int rootChildCount = rootActor.GetChildCount();
+
+ Vector2 centerPoint = Stage::GetCurrent().GetSize() * 0.5f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, centerPoint ) );
+
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Get number of actors on the Stage, they should have incremented by one" );
+ ++rootChildCount;
+ DALI_TEST_EQUALS( rootActor.GetChildCount(), rootChildCount, TEST_LOCATION );
+
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Stationary, centerPoint ) ); // Emit for code coverage, will have no effect
+
+ END_TEST;
+}
+
+int UtcDaliTooltipDisplayWithTail(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetAnchorPoint( AnchorPoint::CENTER );
+ control.SetParentOrigin( ParentOrigin::CENTER );
+ control.SetSize( 100.0f, 100.0f );
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT, "Test" )
+ .Add( Tooltip::Property::TAIL,
+ Property::Map().Add( Tooltip::Tail::Property::VISIBILITY, true )
+ .Add( Tooltip::Tail::Property::ABOVE_VISUAL, "above-visual.png" )
+ .Add( Tooltip::Tail::Property::BELOW_VISUAL, "below-visual.png" ))
+ );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ int rootChildCount = rootActor.GetChildCount();
+
+ Vector2 centerPoint = Stage::GetCurrent().GetSize() * 0.5f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, centerPoint ) );
+
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Get number of actors on the Stage, they should have incremented by one" );
+ ++rootChildCount;
+ DALI_TEST_EQUALS( rootActor.GetChildCount(), rootChildCount, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipDisplayWithContentArray(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetAnchorPoint( AnchorPoint::CENTER );
+ control.SetParentOrigin( ParentOrigin::CENTER );
+ control.SetSize( 100.0f, 100.0f );
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT,
+ Property::Array().Add( Property::Map().Add( Visual::Property::TYPE, Visual::IMAGE )
+ .Add( ImageVisual::Property::URL, "dummy-url.png" ) )
+ .Add( Property::Map().Add( Visual::Property::TYPE, DevelVisual::TEXT )
+ .Add( TextVisual::Property::TEXT, "Hello Array Test" ) ))
+ .Add( Tooltip::Property::TAIL,
+ Property::Map().Add( Tooltip::Tail::Property::VISIBILITY, true )
+ .Add( Tooltip::Tail::Property::ABOVE_VISUAL, "above-visual.png" )
+ .Add( Tooltip::Tail::Property::BELOW_VISUAL, "below-visual.png" ))
+ );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ int rootChildCount = rootActor.GetChildCount();
+
+ Vector2 centerPoint = Stage::GetCurrent().GetSize() * 0.5f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, centerPoint ) );
+
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Get number of actors on the Stage, they should have incremented by one" );
+ ++rootChildCount;
+ DALI_TEST_EQUALS( rootActor.GetChildCount(), rootChildCount, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipDisplayBelow(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetAnchorPoint( AnchorPoint::CENTER );
+ control.SetParentOrigin( ParentOrigin::CENTER );
+ control.SetSize( 100.0f, 100.0f );
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT, "Test" )
+ .Add( Tooltip::Property::POSITION, Tooltip::Position::BELOW )
+ );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector2 centerPoint = Stage::GetCurrent().GetSize() * 0.5f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, centerPoint ) );
+
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ Actor tooltip = rootActor.GetChildAt( rootActor.GetChildCount() - 1 ); // Last actor added will be our tooltip
+
+ tet_infoline( "Ensure tooltip is below control" );
+ DALI_TEST_CHECK( ( control.GetCurrentWorldPosition().y + 50.0f /* Half Size */) < tooltip.GetCurrentWorldPosition().y );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipDisplayAbove(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetAnchorPoint( AnchorPoint::CENTER );
+ control.SetParentOrigin( ParentOrigin::CENTER );
+ control.SetSize( 100.0f, 100.0f );
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT, "Test" )
+ .Add( Tooltip::Property::POSITION, Tooltip::Position::ABOVE )
+ );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector2 centerPoint = Stage::GetCurrent().GetSize() * 0.5f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, centerPoint ) );
+
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ Actor tooltip = rootActor.GetChildAt( rootActor.GetChildCount() - 1 ); // Last actor added will be our tooltip
+
+ tet_infoline( "Ensure tooltip is above control" );
+ DALI_TEST_CHECK( ( control.GetCurrentWorldPosition().y - 50.0f /* Half Size */) >= ( tooltip.GetCurrentWorldPosition().y + 0.5f * tooltip.GetCurrentSize().height ) );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipDisplayAtHoverPoint(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetAnchorPoint( AnchorPoint::CENTER );
+ control.SetParentOrigin( ParentOrigin::CENTER );
+ control.SetSize( 100.0f, 100.0f );
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT, "Test" )
+ .Add( Tooltip::Property::POSITION, Tooltip::Position::HOVER_POINT )
+ );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ const Vector2 stageSize = Stage::GetCurrent().GetSize();
+ Vector2 hoverPoint = stageSize * 0.5f;
+ hoverPoint.x -= 10.0f;
+ hoverPoint.y -= 10.0f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, hoverPoint ) );
+
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ Actor tooltip = rootActor.GetChildAt( rootActor.GetChildCount() - 1 ); // Last actor added will be our tooltip
+
+ tet_infoline( "Ensure tooltip is below and to the right of control" );
+ DALI_TEST_CHECK( ( hoverPoint.y - stageSize.height * 0.5f ) < tooltip.GetCurrentWorldPosition().y );
+ DALI_TEST_CHECK( ( hoverPoint.x - stageSize.width * 0.5f ) < tooltip.GetCurrentWorldPosition().x );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipExceedThreshold(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetAnchorPoint( AnchorPoint::CENTER );
+ control.SetParentOrigin( ParentOrigin::CENTER );
+ control.SetSize( 100.0f, 100.0f );
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT, "Test" )
+ .Add( Tooltip::Property::MOVEMENT_THRESHOLD, 5 )
+ );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ int rootChildCount = rootActor.GetChildCount();
+
+ tet_infoline( "Start hover" );
+ Vector2 hoverPoint = Stage::GetCurrent().GetSize() * 0.5f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, hoverPoint ) );
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Emit a value which exceeds threshold, timer should start again" );
+ hoverPoint.x += 10.0f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Motion, hoverPoint ) );
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Emit Timer signal - timeout at new point which is still within bounds" );
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Get number of actors on the Stage, they should have incremented by one" );
+ ++rootChildCount;
+ DALI_TEST_EQUALS( rootActor.GetChildCount(), rootChildCount, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipGoOutOfBounds(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetAnchorPoint( AnchorPoint::CENTER );
+ control.SetParentOrigin( ParentOrigin::CENTER );
+ control.SetSize( 100.0f, 100.0f );
+ control.SetProperty( DevelControl::Property::TOOLTIP, "Test" );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ int rootChildCount = rootActor.GetChildCount();
+
+ tet_infoline( "Start hover" );
+ Vector2 hoverPoint = Stage::GetCurrent().GetSize() * 0.5f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, hoverPoint ) );
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Emit a value which goes out of bounds" );
+ hoverPoint.x += 100.0f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Motion, hoverPoint ) );
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Emit Timer signal - nothing should happen" );
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Get number of actors on the Stage, they should be the same as before" );
+ DALI_TEST_EQUALS( rootActor.GetChildCount(), rootChildCount, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipHideTooltipWhenOutOfBounds(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetProperty( DevelControl::Property::TOOLTIP, "Test" );
+ control.SetAnchorPoint( AnchorPoint::CENTER );
+ control.SetParentOrigin( ParentOrigin::CENTER );
+ control.SetSize( 100.0f, 100.0f );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ int rootChildCount = rootActor.GetChildCount();
+
+ Vector2 hoverPoint = Stage::GetCurrent().GetSize() * 0.5f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, hoverPoint ) );
+
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Get number of actors on the Stage, they should have incremented by one" );
+ ++rootChildCount;
+ DALI_TEST_EQUALS( rootActor.GetChildCount(), rootChildCount, TEST_LOCATION );
+
+ hoverPoint.x += 100.0f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Motion, hoverPoint ) );
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Get number of actors on the Stage, they should be back to what was there before the tooltip was shown" );
+ --rootChildCount;
+ DALI_TEST_EQUALS( rootActor.GetChildCount(), rootChildCount, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipHideTooltipWhenSetToDisapperOnMovement(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetAnchorPoint( AnchorPoint::CENTER );
+ control.SetParentOrigin( ParentOrigin::CENTER );
+ control.SetSize( 100.0f, 100.0f );
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT, "Test" )
+ .Add( Tooltip::Property::DISAPPEAR_ON_MOVEMENT, true )
+ .Add( Tooltip::Property::MOVEMENT_THRESHOLD, 5 )
+ );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ int rootChildCount = rootActor.GetChildCount();
+
+ Vector2 hoverPoint = Stage::GetCurrent().GetSize() * 0.5f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, hoverPoint ) );
+
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Get number of actors on the Stage, they should have incremented by one" );
+ ++rootChildCount;
+ DALI_TEST_EQUALS( rootActor.GetChildCount(), rootChildCount, TEST_LOCATION );
+
+ hoverPoint.x += 10.0f; // Stay within bounds but exceed threshold
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Motion, hoverPoint ) );
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Get number of actors on the Stage, they should be back to what was there before the tooltip was shown" );
+ --rootChildCount;
+ DALI_TEST_EQUALS( rootActor.GetChildCount(), rootChildCount, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipChangeContent(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Control control = Control::New();
+ control.SetProperty( DevelControl::Property::TOOLTIP, "Test" );
+ control.SetAnchorPoint( AnchorPoint::CENTER );
+ control.SetParentOrigin( ParentOrigin::CENTER );
+ control.SetSize( 100.0f, 100.0f );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ int rootChildCount = rootActor.GetChildCount();
+
+ Vector2 centerPoint = Stage::GetCurrent().GetSize() * 0.5f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, centerPoint ) );
+
+ tet_infoline( "Change content while timer is running and ensure it matches the new value" );
+ control.SetProperty( DevelControl::Property::TOOLTIP, "Second Value" );
+
+ Property::Value value = control.GetProperty( DevelControl::Property::TOOLTIP );
+ DALI_TEST_EQUALS( value.GetType(), Property::MAP, TEST_LOCATION );
+ Property::Map* map = value.GetMap();
+ DALI_TEST_CHECK( map );
+ Property::Value* contentValue = map->Find( Tooltip::Property::CONTENT );
+ DALI_TEST_CHECK( contentValue );
+ Property::Map* contentMap = contentValue->GetMap();
+ DALI_TEST_CHECK( contentMap );
+ Property::Value* textStringValue = contentMap->Find( TextVisual::Property::TEXT );
+ DALI_TEST_CHECK( textStringValue );
+ DALI_TEST_EQUALS( "Second Value", textStringValue->Get< std::string >(), TEST_LOCATION );
+
+ tet_infoline( "Emit signal, nothing should happen as everything has been reset" );
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Get number of actors on the Stage, there should NOT be any new actors" );
+ DALI_TEST_EQUALS( rootActor.GetChildCount(), rootChildCount, TEST_LOCATION );
+
+ tet_infoline( "More movement at same point, and emit signal, we should get the tooltip" );
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Motion, centerPoint ) );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Get number of actors on the Stage, they should have incremented by one" );
+ ++rootChildCount;
+ DALI_TEST_EQUALS( rootActor.GetChildCount(), rootChildCount, TEST_LOCATION );
+
+ tet_infoline( "Change content while tooltip is showing, current one should be removed from the stage and ensure it matches new value" );
+ control.SetProperty( DevelControl::Property::TOOLTIP, "Third Value" );
+
+ value = control.GetProperty( DevelControl::Property::TOOLTIP );
+ DALI_TEST_EQUALS( value.GetType(), Property::MAP, TEST_LOCATION );
+ map = value.GetMap();
+ DALI_TEST_CHECK( map );
+ contentValue = map->Find( Tooltip::Property::CONTENT );
+ DALI_TEST_CHECK( contentValue );
+ contentMap = contentValue->GetMap();
+ DALI_TEST_CHECK( contentMap );
+ textStringValue = contentMap->Find( TextVisual::Property::TEXT );
+ DALI_TEST_CHECK( textStringValue );
+ DALI_TEST_EQUALS( "Third Value", textStringValue->Get< std::string >(), TEST_LOCATION );
+
+ tet_infoline( "Emit signal, nothing should happen as everything has been reset" );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Get number of actors on the Stage, there should be one less actor on the stage" );
+ --rootChildCount;
+ DALI_TEST_EQUALS( rootActor.GetChildCount(), rootChildCount, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipEnsureRemainsOnStage1(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Vector2 stageSize = Stage::GetCurrent().GetSize();
+
+ tet_infoline( "Create a control and place it at the bottom of the screen, setting the tooltip to appear below" );
+ Control control = Control::New();
+ control.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
+ control.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
+ control.SetSize( stageSize );
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT, "Test" )
+ .Add( Tooltip::Property::TAIL,
+ Property::Map().Add( Tooltip::Tail::Property::VISIBILITY, true )
+ .Add( Tooltip::Tail::Property::ABOVE_VISUAL, "above-visual.png" )
+ .Add( Tooltip::Tail::Property::BELOW_VISUAL, "below-visual.png" ) )
+ .Add( Tooltip::Property::POSITION, Tooltip::Position::BELOW )
+ );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector2 centerPoint = stageSize * 0.5f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, centerPoint ) );
+
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Ensure tooltip is still on the screen" );
+ Actor tooltip = rootActor.GetChildAt( rootActor.GetChildCount() - 1 ); // Last actor added will be our tooltip
+ DALI_TEST_CHECK( ( tooltip.GetCurrentWorldPosition().y + tooltip.GetCurrentSize().height * 0.5f ) <= centerPoint.height );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipEnsureRemainsOnStage2(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Vector2 stageSize = Stage::GetCurrent().GetSize();
+
+ tet_infoline( "Create a control and place it at the top of the screen, setting the tooltip to appear above" );
+ Control control = Control::New();
+ control.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ control.SetParentOrigin( ParentOrigin::TOP_CENTER );
+ control.SetSize( stageSize );
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT, "Test" )
+ .Add( Tooltip::Property::TAIL,
+ Property::Map().Add( Tooltip::Tail::Property::VISIBILITY, true )
+ .Add( Tooltip::Tail::Property::ABOVE_VISUAL, "above-visual.png" )
+ .Add( Tooltip::Tail::Property::BELOW_VISUAL, "below-visual.png" ) )
+ .Add( Tooltip::Property::POSITION, Tooltip::Position::ABOVE )
+ );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector2 centerPoint = stageSize * 0.5f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, centerPoint ) );
+
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Ensure tooltip is still on the screen" );
+ Actor tooltip = rootActor.GetChildAt( rootActor.GetChildCount() - 1 ); // Last actor added will be our tooltip
+ DALI_TEST_CHECK( ( tooltip.GetCurrentWorldPosition().y - tooltip.GetCurrentSize().height * 0.5f ) >= -centerPoint.height );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipEnsureRemainsOnStage3(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Vector2 stageSize = Stage::GetCurrent().GetSize();
+ Vector2 centerPoint = stageSize * 0.5f;
+
+ tet_infoline( "Create a control and adjust it's position so that the tooltip will attempt to appear to the left of the screen" );
+ Control control = Control::New();
+ control.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
+ control.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
+ control.SetSize( stageSize );
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT, "Test" )
+ .Add( Tooltip::Property::TAIL,
+ Property::Map().Add( Tooltip::Tail::Property::VISIBILITY, true )
+ .Add( Tooltip::Tail::Property::ABOVE_VISUAL, "above-visual.png" )
+ .Add( Tooltip::Tail::Property::BELOW_VISUAL, "below-visual.png" ) )
+ .Add( Tooltip::Property::POSITION, Tooltip::Position::BELOW )
+ );
+ control.SetX( -centerPoint.x );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector2 hoverPoint( centerPoint );
+ hoverPoint.x = 1.0f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, centerPoint ) );
+
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Ensure tooltip is still on the screen" );
+ Actor tooltip = rootActor.GetChildAt( rootActor.GetChildCount() - 1 ); // Last actor added will be our tooltip
+ DALI_TEST_CHECK( ( tooltip.GetCurrentWorldPosition().x - tooltip.GetCurrentSize().width * 0.5f ) >= -centerPoint.width );
+
+ END_TEST;
+}
+
+int UtcDaliTooltipEnsureRemainsOnStage4(void)
+{
+ ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
+
+ Vector2 stageSize = Stage::GetCurrent().GetSize();
+ Vector2 centerPoint = stageSize * 0.5f;
+
+ tet_infoline( "Create a control and adjust it's position so that the tooltip will attempt to appear to the right of the screen" );
+ Control control = Control::New();
+ control.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
+ control.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
+ control.SetSize( stageSize );
+ control.SetProperty( DevelControl::Property::TOOLTIP,
+ Property::Map().Add( Tooltip::Property::CONTENT, "Test" )
+ .Add( Tooltip::Property::TAIL,
+ Property::Map().Add( Tooltip::Tail::Property::VISIBILITY, true )
+ .Add( Tooltip::Tail::Property::ABOVE_VISUAL, "above-visual.png" )
+ .Add( Tooltip::Tail::Property::BELOW_VISUAL, "below-visual.png" ) )
+ .Add( Tooltip::Property::POSITION, Tooltip::Position::BELOW )
+ );
+ control.SetX( centerPoint.x );
+
+ Actor rootActor = Stage::GetCurrent().GetRootLayer();
+ rootActor.Add( control );
+
+ application.SendNotification();
+ application.Render();
+
+ Vector2 hoverPoint( centerPoint );
+ hoverPoint.x = 1.0f;
+ application.ProcessEvent( GenerateSingleHover( TouchPoint::Started, centerPoint ) );
+
+ Dali::Timer timer = Timer::New( 1u );
+ timer.MockEmitSignal();
+
+ application.SendNotification();
+ application.Render();
+
+ tet_infoline( "Ensure tooltip is still on the screen" );
+ Actor tooltip = rootActor.GetChildAt( rootActor.GetChildCount() - 1 ); // Last actor added will be our tooltip
+ DALI_TEST_CHECK( ( tooltip.GetCurrentWorldPosition().x + tooltip.GetCurrentSize().width * 0.5f ) <= centerPoint.width );
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * 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.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/controls/tooltip/tooltip.h>
+
+// EXTERNAL INCLUDES
+#include <cmath>
+
+#include <dali/public-api/events/hover-event.h>
+#include <dali/public-api/adaptor-framework/timer.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/devel-api/scripting/enum-helper.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/table-view/table-view.h>
+#include <dali-toolkit/public-api/controls/text-controls/text-label.h>
+#include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali-toolkit/devel-api/controls/tooltip/tooltip-properties.h>
+#include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
+#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
+#include <dali-toolkit/internal/controls/popup/popup-impl.h>
+#include <dali-toolkit/internal/visuals/visual-string-constants.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+DALI_ENUM_TO_STRING_TABLE_BEGIN( TOOLTIP_POSITION )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Tooltip::Position, ABOVE )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Tooltip::Position, BELOW )
+DALI_ENUM_TO_STRING_WITH_SCOPE( Toolkit::Tooltip::Position, HOVER_POINT )
+DALI_ENUM_TO_STRING_TABLE_END( TOOLTIP_POSITION )
+
+const float MILLISECONDS_PER_SECOND = 1000.0f;
+
+const char * const PROPERTY_CONTENT_NAME = "content";
+const char * const PROPERTY_LAYOUT_NAME = "layout";
+const char * const PROPERTY_WAIT_TIME_NAME = "waitTime";
+const char * const PROPERTY_BACKGROUND_NAME = "background";
+const char * const PROPERTY_TAIL_NAME = "tail";
+const char * const PROPERTY_POSITION_NAME = "position";
+const char * const PROPERTY_HOVER_POINT_OFFSET_NAME = "hoverPointOffset";
+const char * const PROPERTY_MOVEMENT_THRESHOLD = "movementThreshold";
+const char * const PROPERTY_DISAPPEAR_ON_MOVEMENT = "disappearOnMovement";
+
+const char * const PROPERTY_BACKGROUND_VISUAL = "visual";
+const char * const PROPERTY_BACKGROUND_BORDER = "border";
+
+const char * const PROPERTY_TAIL_VISIBILITY = "visibility";
+const char * const PROPERTY_TAIL_ABOVE_VISUAL = "aboveVisual";
+const char * const PROPERTY_TAIL_BELOW_VISUAL = "belowVisual";
+
+} // unnamed namespace
+
+TooltipPtr Tooltip::New( Toolkit::Control control )
+{
+ return new Tooltip( control );
+}
+
+void Tooltip::SetProperties( const Property::Value& value )
+{
+ Toolkit::Control control = mControl.GetHandle();
+ if( control )
+ {
+ Property::Map* properties = value.GetMap();
+ if( properties )
+ {
+ const Property::Map::SizeType count = properties->Count();
+ for( Property::Map::SizeType position = 0; position < count; ++position )
+ {
+ KeyValuePair keyValue = properties->GetKeyValue( position );
+ Property::Key& key = keyValue.first;
+ Property::Value& value = keyValue.second;
+
+ if( key == Toolkit::Tooltip::Property::CONTENT || key == PROPERTY_CONTENT_NAME )
+ {
+ SetContent( control, value );
+ }
+ else if( key == Toolkit::Tooltip::Property::LAYOUT || key == PROPERTY_LAYOUT_NAME )
+ {
+ value.Get( mLayout );
+ }
+ else if( key == Toolkit::Tooltip::Property::WAIT_TIME || key == PROPERTY_WAIT_TIME_NAME )
+ {
+ float waitTime = 0.0f;
+ if( value.Get( waitTime ) )
+ {
+ mWaitTime = waitTime * MILLISECONDS_PER_SECOND;
+ }
+ }
+ else if( key == Toolkit::Tooltip::Property::BACKGROUND || key == PROPERTY_BACKGROUND_NAME )
+ {
+ SetBackground( value );
+ }
+ else if( key == Toolkit::Tooltip::Property::TAIL || key == PROPERTY_TAIL_NAME )
+ {
+ SetTail( value );
+ }
+ else if( key == Toolkit::Tooltip::Property::POSITION || key == PROPERTY_POSITION_NAME )
+ {
+ Scripting::GetEnumerationProperty< Toolkit::Tooltip::Position::Type >( value, TOOLTIP_POSITION_TABLE, TOOLTIP_POSITION_TABLE_COUNT, mPositionType );
+ }
+ else if( key == Toolkit::Tooltip::Property::HOVER_POINT_OFFSET || key == PROPERTY_HOVER_POINT_OFFSET_NAME )
+ {
+ value.Get( mHoverPointOffset );
+ }
+ else if( key == Toolkit::Tooltip::Property::MOVEMENT_THRESHOLD || key == PROPERTY_MOVEMENT_THRESHOLD )
+ {
+ value.Get( mMovementThreshold );
+ }
+ else if( key == Toolkit::Tooltip::Property::DISAPPEAR_ON_MOVEMENT || key == PROPERTY_DISAPPEAR_ON_MOVEMENT )
+ {
+ value.Get( mDisappearOnMovement );
+ }
+ }
+ }
+ else
+ {
+ Property::Type type = value.GetType();
+ if( ( value.GetType() == Property::STRING ) || ( type == Property::ARRAY ) )
+ {
+ SetContent( control, value );
+ }
+ }
+ }
+}
+
+void Tooltip::CreatePropertyMap( Property::Map& map ) const
+{
+ if( ! mContentTextVisual.Empty() )
+ {
+ Property::Map content = mContentTextVisual; // Need this copy as there's no Value constructor which takes in a 'const Property::Map&'.
+ map.Insert( Toolkit::Tooltip::Property::CONTENT, content );
+ }
+ else if( ! mContentArray.Empty() )
+ {
+ Property::Array content = mContentArray; // Need this copy as there's no Value constructor which takes in a 'const Property::Array&'.
+ map.Insert( Toolkit::Tooltip::Property::CONTENT, content );
+ }
+
+ map.Insert( Toolkit::Tooltip::Property::LAYOUT, mLayout );
+ map.Insert( Toolkit::Tooltip::Property::WAIT_TIME, static_cast<float>( mWaitTime ) / MILLISECONDS_PER_SECOND );
+ map.Insert( Toolkit::Tooltip::Property::BACKGROUND,
+ Property::Map().Add( Toolkit::Tooltip::Background::Property::VISUAL, mBackgroundImage )
+ .Add( Toolkit::Tooltip::Background::Property::BORDER, mBackgroundBorder ) );
+ map.Insert( Toolkit::Tooltip::Property::TAIL,
+ Property::Map().Add( Toolkit::Tooltip::Tail::Property::VISIBILITY, mTailVisibility )
+ .Add( Toolkit::Tooltip::Tail::Property::ABOVE_VISUAL, mTailImages[ Toolkit::Tooltip::Tail::Property::ABOVE_VISUAL ])
+ .Add( Toolkit::Tooltip::Tail::Property::BELOW_VISUAL, mTailImages[ Toolkit::Tooltip::Tail::Property::BELOW_VISUAL ]) );
+ map.Insert( Toolkit::Tooltip::Property::POSITION, mPositionType );
+ map.Insert( Toolkit::Tooltip::Property::HOVER_POINT_OFFSET, mHoverPointOffset );
+ map.Insert( Toolkit::Tooltip::Property::MOVEMENT_THRESHOLD, mMovementThreshold );
+ map.Insert( Toolkit::Tooltip::Property::DISAPPEAR_ON_MOVEMENT, mDisappearOnMovement );
+}
+
+Tooltip::Tooltip( Toolkit::Control control )
+: mPopup(),
+ mTooltipTimer(),
+ mControl( control ),
+ mContentTextVisual(),
+ mTailImages(),
+ mContentArray(),
+ mBackgroundBorder( 0, 0, 0, 0 ),
+ mLayout( 1, 1 ),
+ mHoverPoint(),
+ mHoverPointOffset( 10.0f, 10.0f ),
+ mBackgroundImage(),
+ mMovementThreshold( 5.0f ),
+ mWaitTime( 500 ),
+ mPositionType( Toolkit::Tooltip::Position::ABOVE ),
+ mTailVisibility( false ),
+ mDisappearOnMovement( false ),
+ mSignalsConnected( false )
+{
+ mTailImages[ Toolkit::Tooltip::Tail::Property::ABOVE_VISUAL ] = "";
+ mTailImages[ Toolkit::Tooltip::Tail::Property::BELOW_VISUAL ] = "";
+}
+
+Tooltip::~Tooltip()
+{
+ if( mPopup )
+ {
+ mPopup.Unparent();
+ mPopup.Reset();
+ }
+}
+
+void Tooltip::SetContent( Toolkit::Control& control, const Property::Value& value )
+{
+ // Delete popup & timer
+
+ if( mTooltipTimer )
+ {
+ mTooltipTimer.Stop();
+ mTooltipTimer.Reset();
+ }
+
+ if( mPopup )
+ {
+ mPopup.Unparent();
+ mPopup.Reset();
+ }
+
+ bool connectSignals = false;
+
+ Property::Type type = value.GetType();
+ if( type == Property::MAP )
+ {
+ Property::Map* map = value.GetMap();
+ if( map )
+ {
+ mContentTextVisual.Merge( *map );
+
+ Property::Value* typeValue = map->Find( Toolkit::Visual::Property::TYPE, VISUAL_TYPE );
+ if( typeValue )
+ {
+ // Set to an invalid value so it definitely changes if set in Scripting::GetEnumerationProperty
+ Toolkit::DevelVisual::Type visualType = static_cast< Toolkit::DevelVisual::Type >( -1 );
+
+ if( Scripting::GetEnumerationProperty( *typeValue, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT, visualType ) )
+ {
+ if( visualType == Toolkit::DevelVisual::TEXT )
+ {
+ // Visual Type is text, ensure we have a the TEXT property set before we connect to the signals.
+
+ if( map->Find( Toolkit::TextVisual::Property::TEXT, TEXT_PROPERTY ) )
+ {
+ mContentArray.Clear();
+ connectSignals = true;
+ }
+ }
+ else
+ {
+ // Visual Type is not text, so connect to the signals as we're displaying a non text visual.
+
+ mContentArray.Clear();
+ connectSignals = true;
+ }
+ }
+ }
+ }
+ }
+ else if( type == Property::ARRAY )
+ {
+ if( value.Get( mContentArray ) )
+ {
+ mContentTextVisual.Clear();
+ connectSignals = true;
+ }
+ }
+ else if( type == Property::STRING )
+ {
+ std::string text;
+ if( value.Get( text ) )
+ {
+ mContentTextVisual[ Toolkit::TextVisual::Property::TEXT ] = text;
+ mContentTextVisual[ Toolkit::Visual::Property::TYPE ] = DevelVisual::TEXT;
+ mContentArray.Clear();
+ connectSignals = true;
+ }
+ }
+
+ if( connectSignals && ! mSignalsConnected )
+ {
+ control.HoveredSignal().Connect( this, &Tooltip::OnHovered );
+ control.SetLeaveRequired( true );
+ mSignalsConnected = true;
+ }
+}
+
+void Tooltip::SetBackground( const Property::Value& value )
+{
+ Property::Type type = value.GetType();
+
+ if( type == Property::STRING )
+ {
+ value.Get( mBackgroundImage );
+ mBackgroundBorder.Set( 0, 0, 0, 0 );
+ }
+ else if( type == Property::MAP )
+ {
+ Property::Map* map = value.GetMap();
+ if( map )
+ {
+ const Property::Map::SizeType count = map->Count();
+ for( Property::Map::SizeType position = 0; position < count; ++position )
+ {
+ KeyValuePair keyValue = map->GetKeyValue( position );
+ Property::Key& key = keyValue.first;
+ Property::Value& value = keyValue.second;
+
+ if( key == Toolkit::Tooltip::Background::Property::VISUAL || key == PROPERTY_BACKGROUND_VISUAL )
+ {
+ value.Get( mBackgroundImage );
+ }
+ else if( key == Toolkit::Tooltip::Background::Property::BORDER || key == PROPERTY_BACKGROUND_BORDER )
+ {
+ if( ! value.Get( mBackgroundBorder ) )
+ {
+ // If not a Property::RECTANGLE, then check if it's a Vector4 and set it accordingly
+ Vector4 valueVector4;
+ if( value.Get( valueVector4 ) )
+ {
+ mBackgroundBorder.left = valueVector4.x;
+ mBackgroundBorder.right = valueVector4.y;
+ mBackgroundBorder.bottom = valueVector4.z;
+ mBackgroundBorder.top = valueVector4.w;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void Tooltip::SetTail( const Property::Value& value )
+{
+ Property::Type type = value.GetType();
+
+ if( type == Property::BOOLEAN )
+ {
+ value.Get( mTailVisibility );
+ }
+ else if( type == Property::MAP )
+ {
+ Property::Map map;
+ if( value.Get( map ) )
+ {
+ const Property::Map::SizeType count = map.Count();
+ for( Property::Map::SizeType position = 0; position < count; ++position )
+ {
+ KeyValuePair keyValue = map.GetKeyValue( position );
+ Property::Key& key = keyValue.first;
+ Property::Value& value = keyValue.second;
+
+ // Set the values manually rather than merging so that we only have to deal with Property indices when creating the actual tooltip.
+
+ if( key == Toolkit::Tooltip::Tail::Property::VISIBILITY || key == PROPERTY_TAIL_VISIBILITY )
+ {
+ value.Get( mTailVisibility );
+ }
+ else if( key == Toolkit::Tooltip::Tail::Property::ABOVE_VISUAL || key == PROPERTY_TAIL_ABOVE_VISUAL )
+ {
+ std::string path;
+ if( value.Get( path ) )
+ {
+ mTailImages[ Toolkit::Tooltip::Tail::Property::ABOVE_VISUAL ] = path;
+ }
+ }
+ else if( key == Toolkit::Tooltip::Tail::Property::BELOW_VISUAL || key == PROPERTY_TAIL_BELOW_VISUAL )
+ {
+ std::string path;
+ if( value.Get( path ) )
+ {
+ mTailImages[ Toolkit::Tooltip::Tail::Property::BELOW_VISUAL ] = path;
+ }
+ }
+ }
+ }
+ }
+}
+
+bool Tooltip::OnHovered( Actor /* actor */, const HoverEvent& hover )
+{
+ const TouchPoint::State state = hover.points[0].state;
+ switch( state )
+ {
+ case TouchPoint::Started:
+ case TouchPoint::Motion:
+ {
+ if( ! mPopup )
+ {
+ if( ! mTooltipTimer )
+ {
+ mHoverPoint = hover.points[ 0 ].screen;
+ mTooltipTimer = Timer::New( mWaitTime );
+ mTooltipTimer.TickSignal().Connect( this, &Tooltip::OnTimeout );
+ mTooltipTimer.Start();
+ }
+ else
+ {
+ Vector2 movement = mHoverPoint - hover.points[ 0 ].screen;
+ if( std::abs( movement.Length() ) > mMovementThreshold )
+ {
+ mTooltipTimer.Stop();
+ mTooltipTimer.Reset();
+
+ mHoverPoint = hover.points[ 0 ].screen;
+ mTooltipTimer = Timer::New( mWaitTime );
+ mTooltipTimer.TickSignal().Connect( this, &Tooltip::OnTimeout );
+ mTooltipTimer.Start();
+ }
+ }
+ }
+ else if( mDisappearOnMovement )
+ {
+ // Popup is showing, and we're set to disappear on excessive movement so make sure we're still within the threshold.
+
+ Vector2 movement = mHoverPoint - hover.points[ 0 ].screen;
+ if( std::abs( movement.Length() ) > mMovementThreshold )
+ {
+ // Exceeding the threshold, hide the popup.
+
+ if( mTooltipTimer )
+ {
+ mTooltipTimer.Stop();
+ mTooltipTimer.Reset();
+ }
+ if( mPopup )
+ {
+ mPopup.Unparent();
+ mPopup.Reset();
+ }
+ }
+ }
+ break;
+ }
+ case TouchPoint::Finished:
+ case TouchPoint::Leave:
+ case TouchPoint::Interrupted:
+ {
+ if( mTooltipTimer )
+ {
+ mTooltipTimer.Stop();
+ mTooltipTimer.Reset();
+ }
+ if( mPopup )
+ {
+ mPopup.Unparent();
+ mPopup.Reset();
+ }
+ break;
+ }
+
+ case TouchPoint::Stationary:
+ case TouchPoint::Last:
+ {
+ break;
+ }
+ }
+
+ return true;
+}
+
+bool Tooltip::OnTimeout()
+{
+ Toolkit::Control control = mControl.GetHandle();
+ if( ! mPopup && control )
+ {
+ mPopup = Toolkit::Popup::New();
+
+ // General set up of popup
+ mPopup.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
+ mPopup.SetProperty( Toolkit::Popup::Property::CONTEXTUAL_MODE, "NON_CONTEXTUAL" );
+ mPopup.SetProperty( Toolkit::Popup::Property::ANIMATION_MODE, "NONE" );
+ mPopup.SetProperty( Toolkit::Popup::Property::BACKING_ENABLED, false ); // Disable the dimmed backing.
+ mPopup.SetProperty( Toolkit::Popup::Property::TOUCH_TRANSPARENT, true ); // Let events pass through the popup
+ mPopup.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ mPopup.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+ // Background
+ mPopup.SetProperty( Toolkit::Popup::Property::POPUP_BACKGROUND_IMAGE, mBackgroundImage );
+ mPopup.SetProperty( Toolkit::Popup::Property::POPUP_BACKGROUND_BORDER, mBackgroundBorder );
+
+ // Tail
+ mPopup.SetProperty( Toolkit::Popup::Property::TAIL_VISIBILITY, mTailVisibility );
+ mPopup.SetProperty( Toolkit::Popup::Property::TAIL_UP_IMAGE, mTailImages[ Toolkit::Tooltip::Tail::Property::ABOVE_VISUAL ] );
+ mPopup.SetProperty( Toolkit::Popup::Property::TAIL_DOWN_IMAGE, mTailImages[ Toolkit::Tooltip::Tail::Property::BELOW_VISUAL ] );
+
+ Vector3 tailPosition;
+ switch( mPositionType )
+ {
+ case Toolkit::Tooltip::Position::HOVER_POINT:
+ case Toolkit::Tooltip::Position::BELOW:
+ {
+ tailPosition = Vector3( 0.5f, 0.0f, 0.0 );
+ break;
+ }
+
+ case Toolkit::Tooltip::Position::ABOVE:
+ {
+ tailPosition = Vector3( 0.5f, 1.0f, 0.0 );
+ break;
+ }
+ }
+ mPopup.SetProperty( Toolkit::Popup::Property::TAIL_POSITION, tailPosition );
+
+ // Content
+ Actor content;
+ if( ! mContentTextVisual.Empty() )
+ {
+ content = Toolkit::Control::New();
+ content.SetProperty( Toolkit::Control::Property::BACKGROUND, mContentTextVisual );
+ }
+ else if( ! mContentArray.Empty() )
+ {
+ const unsigned int visuals = mContentArray.Size();
+ unsigned int rows = mLayout.x;
+ unsigned int columns = mLayout.y;
+ if( Equals( mLayout.x, 1.0f, Math::MACHINE_EPSILON_1 ) &&
+ Equals( mLayout.y, 1.0f, Math::MACHINE_EPSILON_1 ) &&
+ visuals > 1 )
+ {
+ rows = mLayout.x;
+ columns = visuals;
+ }
+
+ Toolkit::TableView tableView = Toolkit::TableView::New( rows, columns );
+ tableView.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
+
+ for( unsigned int currentContent = 0, currentRow = 0; currentRow < rows && currentContent < visuals; ++currentRow )
+ {
+ tableView.SetFitHeight( currentRow );
+ for( unsigned int currentColumn = 0; currentColumn < columns && currentContent < visuals; ++currentColumn )
+ {
+ Actor child = Toolkit::Control::New();
+ child.SetProperty( Toolkit::Control::Property::BACKGROUND, mContentArray[ currentContent ] );
+
+ Toolkit::TableView::CellPosition cellPosition( currentRow, currentColumn );
+ tableView.AddChild( child, cellPosition );
+ tableView.SetCellAlignment( cellPosition, HorizontalAlignment::CENTER, VerticalAlignment::CENTER );
+ tableView.SetFitWidth( currentColumn );
+
+ ++currentContent;
+ }
+ }
+ content = tableView;
+ }
+ mPopup.SetContent( content );
+
+ // Connect to the relayout signal of the background of the popup as at that point we have the full size
+ Actor popupBackground = GetImpl( mPopup ).GetPopupBackgroundImage();
+ if( popupBackground )
+ {
+ popupBackground.OnRelayoutSignal().Connect( this, &Tooltip::OnRelayout );
+ }
+
+ mPopup.SetDisplayState( Toolkit::Popup::SHOWN );
+
+ Stage::GetCurrent().Add( mPopup );
+ }
+
+ return false;
+}
+
+void Tooltip::OnRelayout( Actor actor )
+{
+ if( mPopup && actor )
+ {
+ float popupWidth = actor.GetRelayoutSize( Dimension::WIDTH );
+ float popupHeight = actor.GetRelayoutSize( Dimension::HEIGHT );
+ float tailHeight = 0.0f;
+ Actor tail;
+
+ if( mTailVisibility )
+ {
+ // Popup's background has the tail, we want to know the tail size as well.
+ if( actor.GetChildCount() )
+ {
+ tail = actor.GetChildAt( 0 );
+ if( tail )
+ {
+ tailHeight = tail.GetRelayoutSize( Dimension::HEIGHT );
+ }
+ }
+ }
+
+ Vector2 stageSize = Stage::GetCurrent().GetSize();
+ Vector3 position;
+
+ switch( mPositionType )
+ {
+ case Toolkit::Tooltip::Position::HOVER_POINT:
+ {
+ position = mHoverPoint + mHoverPointOffset;
+ position.y += tailHeight;
+ break;
+ }
+
+ case Toolkit::Tooltip::Position::ABOVE:
+ {
+ Toolkit::Control control = mControl.GetHandle();
+ if( control )
+ {
+ Vector3 worldPos = control.GetCurrentWorldPosition();
+ float height = control.GetRelayoutSize( Dimension::HEIGHT );
+
+ position.x = stageSize.width * 0.5f + worldPos.x - popupWidth * 0.5f;
+ position.y = stageSize.height * 0.5f + worldPos.y - height * 0.5f - popupHeight * 1.0f - tailHeight;
+ }
+ break;
+ }
+
+ case Toolkit::Tooltip::Position::BELOW:
+ {
+ Toolkit::Control control = mControl.GetHandle();
+ if( control )
+ {
+ Vector3 worldPos = control.GetCurrentWorldPosition();
+ float height = control.GetRelayoutSize( Dimension::HEIGHT );
+
+ position.x = stageSize.width * 0.5f + worldPos.x - popupWidth * 0.5f;
+ position.y = stageSize.height * 0.5f + worldPos.y + height * 0.5f + tailHeight;
+ }
+ break;
+ }
+ }
+
+ // Ensure the Popup is still on the screen
+
+ if( position.x < 0.0f )
+ {
+ position.x = 0.0f;
+ }
+ else if( ( position.x + popupWidth ) > stageSize.width )
+ {
+ position.x -= position.x + popupWidth - stageSize.width;
+ }
+
+ bool yPosChanged = false;
+ if( position.y < 0.0f )
+ {
+ yPosChanged = true;
+ position.y = 0.0f;
+ }
+ else if( ( position.y + popupHeight ) > stageSize.height )
+ {
+ yPosChanged = true;
+ position.y -= position.y + popupHeight - stageSize.height;
+ }
+
+ if( yPosChanged && tail )
+ {
+ // If we change the y position, then the tail may be shown pointing to the wrong control so just hide it.
+ tail.SetVisible( false );
+ }
+
+ mPopup.SetPosition( position );
+ }
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali