PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
dali-core
- dali
+ dali-adaptor
dali-toolkit
)
utc-Dali-ShadowView.cpp
utc-Dali-Slider.cpp
utc-Dali-TableView.cpp
+ utc-Dali-TextEditor.cpp
utc-Dali-TextField.cpp
utc-Dali-TextLabel.cpp
utc-Dali-TextSelectionPopup.cpp
PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
dali-core
- dali
+ dali-adaptor
dali-toolkit
)
#include <dali-toolkit/dali-toolkit.h>
#include <dali/devel-api/scripting/scripting.h>
+#include <dali/devel-api/rendering/material.h>
+#include <dali/devel-api/rendering/renderer.h>
using namespace Dali;
using namespace Toolkit;
END_TEST;
}
+int UtcDaliImageViewSetGetProperty02(void)
+{
+ ToolkitTestApplication application;
+
+ Image image = CreateBufferImage( 10, 10, Color::WHITE );
+ ImageView imageView = ImageView::New(image);
+ Vector4 fullImageRect( 0.f, 0.f, 1.f, 1.f );
+
+ Stage::GetCurrent().Add( imageView );
+
+ application.SendNotification();
+ application.Render();
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+
+ Vector4 pixelAreaUniform;
+ DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "pixelArea", pixelAreaUniform ) );
+ DALI_TEST_EQUALS( pixelAreaUniform, fullImageRect, TEST_LOCATION );
+
+ Property::Value value = imageView.GetProperty( ImageView::Property::PIXEL_AREA );
+ Vector4 pixelAreaValue;
+ DALI_TEST_CHECK( value.Get(pixelAreaValue) );
+ DALI_TEST_EQUALS( pixelAreaValue, fullImageRect, TEST_LOCATION );
+
+ Vector4 pixelAreaSet( 0.2f, 0.2f, 0.3f, 0.3f );
+ imageView.SetProperty( ImageView::Property::PIXEL_AREA, pixelAreaSet);
+
+ application.SendNotification();
+ application.Render();
+
+ value = imageView.GetProperty( ImageView::Property::PIXEL_AREA );
+ value.Get(pixelAreaValue);
+ DALI_TEST_EQUALS( pixelAreaValue, pixelAreaSet, TEST_LOCATION );
+
+ DALI_TEST_CHECK( gl.GetUniformValue<Vector4>( "pixelArea", pixelAreaUniform ) );
+ DALI_TEST_EQUALS( pixelAreaUniform, pixelAreaSet, TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliImageViewSetGetProperty03(void)
+{
+ ToolkitTestApplication application;
+
+ Image image = CreateBufferImage( 10, 10, Color::WHITE );
+ ImageView imageView = ImageView::New(image);
+ Stage::GetCurrent().Add( imageView );
+ application.SendNotification();
+ application.Render();
+
+ // conventional alpha blending
+ Material material = imageView.GetRendererAt( 0 ).GetMaterial();
+ BlendingFactor::Type srcFactorRgb;
+ BlendingFactor::Type destFactorRgb;
+ BlendingFactor::Type srcFactorAlpha;
+ BlendingFactor::Type destFactorAlpha;
+ material.GetBlendFunc(srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha);
+ DALI_TEST_CHECK( srcFactorRgb == BlendingFactor::SRC_ALPHA );
+ DALI_TEST_CHECK( destFactorRgb == BlendingFactor::ONE_MINUS_SRC_ALPHA );
+ DALI_TEST_CHECK( srcFactorAlpha == BlendingFactor::ONE );
+ DALI_TEST_CHECK( destFactorAlpha == BlendingFactor::ONE_MINUS_SRC_ALPHA );
+
+ TestGlAbstraction& gl = application.GetGlAbstraction();
+
+ float alphaBlendingUniform;
+ DALI_TEST_CHECK( gl.GetUniformValue<float>( "uAlphaBlending", alphaBlendingUniform ) );
+ DALI_TEST_EQUALS( alphaBlendingUniform, 1.f, TEST_LOCATION );
+
+ // pre-multiplied alpha blending
+ imageView.SetProperty( Toolkit::ImageView::Property::PRE_MULTIPLIED_ALPHA, true );
+ application.SendNotification();
+ application.Render();
+
+ material.GetBlendFunc(srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha);
+ DALI_TEST_CHECK( srcFactorRgb == BlendingFactor::ONE );
+ DALI_TEST_CHECK( destFactorRgb == BlendingFactor::ONE_MINUS_SRC_ALPHA );
+ DALI_TEST_CHECK( srcFactorAlpha == BlendingFactor::ONE );
+ DALI_TEST_CHECK( destFactorAlpha == BlendingFactor::ONE );
+
+ DALI_TEST_CHECK( gl.GetUniformValue<float>( "uAlphaBlending", alphaBlendingUniform ) );
+ DALI_TEST_EQUALS( alphaBlendingUniform, 0.f, TEST_LOCATION );
+
+ END_TEST;
+}
+
int UtcDaliImageViewSizeWithBackground(void)
{
ToolkitTestApplication application;
END_TEST;
}
+
+int UtcDaliItemViewSetGetProperty(void)
+{
+ ToolkitTestApplication application;
+
+ // Create the ItemView actor
+ TestItemFactory factory;
+ ItemView view = ItemView::New(factory);
+ DALI_TEST_CHECK(view);
+
+ // Event side properties
+
+ // Test "minimumSwipeSpeed" property
+ DALI_TEST_CHECK( view.GetPropertyIndex("minimumSwipeSpeed") == ItemView::Property::MINIMUM_SWIPE_SPEED );
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::MINIMUM_SWIPE_SPEED).Get<float>(), view.GetMinimumSwipeSpeed(), TEST_LOCATION );
+ view.SetProperty( ItemView::Property::MINIMUM_SWIPE_SPEED, 2.5f );
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::MINIMUM_SWIPE_SPEED).Get<float>(), 2.5f, TEST_LOCATION );
+
+ // Test "minimumSwipeDistance" property
+ DALI_TEST_CHECK( view.GetPropertyIndex("minimumSwipeDistance") == ItemView::Property::MINIMUM_SWIPE_DISTANCE );
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::MINIMUM_SWIPE_DISTANCE).Get<float>(), view.GetMinimumSwipeDistance(), TEST_LOCATION );
+ view.SetProperty( ItemView::Property::MINIMUM_SWIPE_DISTANCE, 8.725f );
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::MINIMUM_SWIPE_DISTANCE).Get<float>(), 8.725f, TEST_LOCATION );
+
+ // Test "wheelScrollDistanceStep" property
+ DALI_TEST_CHECK( view.GetPropertyIndex("wheelScrollDistanceStep") == ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP );
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP).Get<float>(), view.GetWheelScrollDistanceStep(), TEST_LOCATION );
+ view.SetProperty( ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP, 5.0f );
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP).Get<float>(), 5.0f, TEST_LOCATION );
+
+ // Test "snapToItemEnabled" property
+ DALI_TEST_CHECK( view.GetPropertyIndex("snapToItemEnabled") == ItemView::Property::SNAP_TO_ITEM_ENABLED );
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::SNAP_TO_ITEM_ENABLED).Get<bool>(), view.GetAnchoring(), TEST_LOCATION );
+ view.SetProperty( ItemView::Property::SNAP_TO_ITEM_ENABLED, true );
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::SNAP_TO_ITEM_ENABLED).Get<bool>(), true, TEST_LOCATION );
+
+ // Test "refreshInterval" property
+ DALI_TEST_CHECK( view.GetPropertyIndex("refreshInterval") == ItemView::Property::REFRESH_INTERVAL );
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::REFRESH_INTERVAL).Get<float>(), view.GetRefreshInterval(), TEST_LOCATION );
+ view.SetProperty( ItemView::Property::REFRESH_INTERVAL, 11.0f );
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::REFRESH_INTERVAL).Get<float>(), 11.0f, TEST_LOCATION );
+
+ // Test "overshootEnabled" property
+ DALI_TEST_CHECK( view.GetPropertyIndex("overshootEnabled") == Scrollable::Property::OVERSHOOT_ENABLED );
+ DALI_TEST_EQUALS( view.GetProperty(Scrollable::Property::OVERSHOOT_ENABLED).Get<bool>(), view.IsOvershootEnabled(), TEST_LOCATION );
+ view.SetProperty( Scrollable::Property::OVERSHOOT_ENABLED, false );
+ DALI_TEST_EQUALS( view.GetProperty(Scrollable::Property::OVERSHOOT_ENABLED).Get<bool>(), false, TEST_LOCATION );
+
+ // Animatable properties
+
+ // Test "layoutPosition" property
+ DALI_TEST_CHECK( view.GetPropertyIndex("layoutPosition") == ItemView::Property::LAYOUT_POSITION );
+ view.SetProperty( ItemView::Property::LAYOUT_POSITION, 20.5f );
+ Wait(application);
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::LAYOUT_POSITION).Get<float>(), 20.5f, TEST_LOCATION );
+
+ // Test "scrollSpeed" property
+ DALI_TEST_CHECK( view.GetPropertyIndex("scrollSpeed") == ItemView::Property::SCROLL_SPEED );
+ view.SetProperty( ItemView::Property::SCROLL_SPEED, 3.35f );
+ Wait(application);
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::SCROLL_SPEED).Get<float>(), 3.35f, TEST_LOCATION );
+
+ // Test "overshoot" property
+ DALI_TEST_CHECK( view.GetPropertyIndex("overshoot") == ItemView::Property::OVERSHOOT );
+ view.SetProperty( ItemView::Property::OVERSHOOT, 0.15f );
+ Wait(application);
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::OVERSHOOT).Get<float>(), 0.15f, TEST_LOCATION );
+
+ // Test "scrollDirection" property
+ DALI_TEST_CHECK( view.GetPropertyIndex("scrollDirection") == ItemView::Property::SCROLL_DIRECTION );
+ view.SetProperty( ItemView::Property::SCROLL_DIRECTION, Vector2(0.85f, 0.5f) );
+ Wait(application);
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::SCROLL_DIRECTION).Get<Vector2>(), Vector2(0.85f, 0.5f), TEST_LOCATION );
+
+ // Test "layoutOrientation" property
+ DALI_TEST_CHECK( view.GetPropertyIndex("layoutOrientation") == ItemView::Property::LAYOUT_ORIENTATION );
+ view.SetProperty( ItemView::Property::LAYOUT_ORIENTATION, 2 );
+ Wait(application);
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::LAYOUT_ORIENTATION).Get<int>(), 2, TEST_LOCATION );
+
+ // Test "scrollContentSize" property
+ DALI_TEST_CHECK( view.GetPropertyIndex("scrollContentSize") == ItemView::Property::SCROLL_CONTENT_SIZE );
+ view.SetProperty( ItemView::Property::SCROLL_CONTENT_SIZE, 250.0f );
+ Wait(application);
+ DALI_TEST_EQUALS( view.GetProperty(ItemView::Property::SCROLL_CONTENT_SIZE).Get<float>(), 250.0f, TEST_LOCATION );
+
+ END_TEST;
+}
+
tet_result(TET_PASS);
END_TEST;
}
+
+
+int UtcDaliJsonParserMerge1(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline("JSON tree merge");
+
+ std::string s1( ReplaceQuotes(" \
+{ \
+ 'styles': \
+ { \
+ 'button': \
+ { \
+ 'backgroundColor':[0.8, 0.0, 1.0, 1.0], \
+ 'foregroundColor':[1, 1, 1, 1] \
+ } \
+ } \
+} \
+"));
+
+ JsonParser parser = JsonParser::New();
+ JsonParser testParser = JsonParser::New();
+
+ testParser.Parse( s1 );
+
+ parser.Parse( s1 );
+ parser.Parse( s1 ); // Merge the tree into itself. The value array should not grow.
+
+ DALI_TEST_CHECK(parser.GetRoot());
+
+ CompareTrees( *parser.GetRoot(), *testParser.GetRoot() );
+
+ END_TEST;
+}
END_TEST;
}
+
+int UtcDaliScrollViewSetGetProperty(void)
+{
+ ToolkitTestApplication application;
+
+ // Create the ScrollView actor
+ ScrollView scrollView = ScrollView::New();
+ DALI_TEST_CHECK(scrollView);
+
+ // Event side properties
+
+ // Test "wrapEnabled" property
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("wrapEnabled") == ScrollView::Property::WRAP_ENABLED );
+ scrollView.SetProperty( ScrollView::Property::WRAP_ENABLED, true );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::WRAP_ENABLED).Get<bool>(), true, TEST_LOCATION );
+
+ // Test "panningEnabled" property
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("panningEnabled") == ScrollView::Property::PANNING_ENABLED );
+ scrollView.SetProperty( ScrollView::Property::PANNING_ENABLED, false );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::PANNING_ENABLED).Get<bool>(), false, TEST_LOCATION );
+
+ // Test "axisAutoLockEnabled" property
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("axisAutoLockEnabled") == ScrollView::Property::AXIS_AUTO_LOCK_ENABLED );
+ scrollView.SetProperty( ScrollView::Property::AXIS_AUTO_LOCK_ENABLED, false );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::AXIS_AUTO_LOCK_ENABLED).Get<bool>(), false, TEST_LOCATION );
+
+ // Test "wheelScrollDistanceStep" property
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("wheelScrollDistanceStep") == ScrollView::Property::WHEEL_SCROLL_DISTANCE_STEP );
+ scrollView.SetProperty( ScrollView::Property::WHEEL_SCROLL_DISTANCE_STEP, Vector2(100.0f, 50.0f) );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::WHEEL_SCROLL_DISTANCE_STEP).Get<Vector2>(), Vector2(100.0f, 50.0f), TEST_LOCATION );
+
+ // Test "overshootEnabled" property
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("overshootEnabled") == Scrollable::Property::OVERSHOOT_ENABLED );
+ DALI_TEST_EQUALS( scrollView.GetProperty(Scrollable::Property::OVERSHOOT_ENABLED).Get<bool>(), scrollView.IsOvershootEnabled(), TEST_LOCATION );
+ scrollView.SetProperty( Scrollable::Property::OVERSHOOT_ENABLED, false );
+ DALI_TEST_EQUALS( scrollView.GetProperty(Scrollable::Property::OVERSHOOT_ENABLED).Get<bool>(), false, TEST_LOCATION );
+
+ // Animatable properties
+
+ // Test "scrollPosition" property
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPosition") == ScrollView::Property::SCROLL_POSITION );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_POSITION, Vector2(320.0f, 550.0f) );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_POSITION).Get<Vector2>(), Vector2(320.0f, 550.0f), TEST_LOCATION );
+
+ // Test "scrollPrePosition", "scrollPrePositionX" and "scrollPrePositionY" properties
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPrePosition") == ScrollView::Property::SCROLL_PRE_POSITION );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_PRE_POSITION, Vector2(300.0f, 500.0f) );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION).Get<Vector2>(), Vector2(300.0f, 500.0f), TEST_LOCATION );
+
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPrePositionX") == ScrollView::Property::SCROLL_PRE_POSITION_X );
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPrePositionY") == ScrollView::Property::SCROLL_PRE_POSITION_Y );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_X).Get<float>(), 300.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_Y).Get<float>(), 500.0f, TEST_LOCATION );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_PRE_POSITION_X, 400.0f );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_PRE_POSITION_Y, 600.0f );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_X).Get<float>(), 400.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_Y).Get<float>(), 600.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION).Get<Vector2>(), Vector2(400.0f, 600.0f), TEST_LOCATION );
+
+ // Test "scrollPrePositionMax", "scrollPrePositionMaxX" and "scrollPrePositionMaxY" properties
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPrePositionMax") == ScrollView::Property::SCROLL_PRE_POSITION_MAX );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_PRE_POSITION_MAX, Vector2(100.0f, 200.0f) );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_MAX).Get<Vector2>(), Vector2(100.0f, 200.0f), TEST_LOCATION );
+
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPrePositionMaxX") == ScrollView::Property::SCROLL_PRE_POSITION_MAX_X );
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPrePositionMaxY") == ScrollView::Property::SCROLL_PRE_POSITION_MAX_Y );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_MAX_X).Get<float>(), 100.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_MAX_Y).Get<float>(), 200.0f, TEST_LOCATION );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_PRE_POSITION_MAX_X, 300.0f );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_PRE_POSITION_MAX_Y, 400.0f );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_MAX_X).Get<float>(), 300.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_MAX_Y).Get<float>(), 400.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_PRE_POSITION_MAX).Get<Vector2>(), Vector2(300.0f, 400.0f), TEST_LOCATION );
+
+ // Test "overshootX" property
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("overshootX") == ScrollView::Property::OVERSHOOT_X );
+ scrollView.SetProperty( ScrollView::Property::OVERSHOOT_X, 0.8f );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::OVERSHOOT_X).Get<float>(), 0.8f, TEST_LOCATION );
+
+ // Test "overshootY" property
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("overshootY") == ScrollView::Property::OVERSHOOT_Y );
+ scrollView.SetProperty( ScrollView::Property::OVERSHOOT_Y, 0.8f );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::OVERSHOOT_Y).Get<float>(), 0.8f, TEST_LOCATION );
+
+ // Test "scrollFinal", "scrollFinalX" and "scrollFinalY" properties
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollFinal") == ScrollView::Property::SCROLL_FINAL );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_FINAL, Vector2(200.0f, 300.0f) );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_FINAL).Get<Vector2>(), Vector2(200.0f, 300.0f), TEST_LOCATION );
+
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollFinalX") == ScrollView::Property::SCROLL_FINAL_X );
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollFinalY") == ScrollView::Property::SCROLL_FINAL_Y );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_FINAL_X).Get<float>(), 200.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_FINAL_Y).Get<float>(), 300.0f, TEST_LOCATION );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_FINAL_X, 500.0f );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_FINAL_Y, 600.0f );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_FINAL_X).Get<float>(), 500.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_FINAL_Y).Get<float>(), 600.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_FINAL).Get<Vector2>(), Vector2(500.0f, 600.0f), TEST_LOCATION );
+
+ // Test "wrap" property
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("wrap") == ScrollView::Property::WRAP );
+ scrollView.SetProperty( ScrollView::Property::WRAP, false );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::WRAP).Get<bool>(), false, TEST_LOCATION );
+
+ // Test "panning" property
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("panning") == ScrollView::Property::PANNING );
+ scrollView.SetProperty( ScrollView::Property::PANNING, true );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::PANNING).Get<bool>(), true, TEST_LOCATION );
+
+ // Test "scrolling" property
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrolling") == ScrollView::Property::SCROLLING );
+ scrollView.SetProperty( ScrollView::Property::SCROLLING, false );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLLING).Get<bool>(), false, TEST_LOCATION );
+
+ // Test "scrollDomainSize", "scrollDomainSizeX" and "scrollDomainSizeY" properties
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollDomainSize") == ScrollView::Property::SCROLL_DOMAIN_SIZE );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_DOMAIN_SIZE, Vector2(1200.0f, 1300.0f) );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_DOMAIN_SIZE).Get<Vector2>(), Vector2(1200.0f, 1300.0f), TEST_LOCATION );
+
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollDomainSizeX") == ScrollView::Property::SCROLL_DOMAIN_SIZE_X );
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollDomainSizeY") == ScrollView::Property::SCROLL_DOMAIN_SIZE_Y );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_DOMAIN_SIZE_X).Get<float>(), 1200.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_DOMAIN_SIZE_Y).Get<float>(), 1300.0f, TEST_LOCATION );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_DOMAIN_SIZE_X, 1500.0f );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_DOMAIN_SIZE_Y, 1600.0f );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_DOMAIN_SIZE_X).Get<float>(), 1500.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_DOMAIN_SIZE_Y).Get<float>(), 1600.0f, TEST_LOCATION );
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_DOMAIN_SIZE).Get<Vector2>(), Vector2(1500.0f, 1600.0f), TEST_LOCATION );
+
+ // Test "scrollDomainOffset" property
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollDomainOffset") == ScrollView::Property::SCROLL_DOMAIN_OFFSET );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_DOMAIN_OFFSET, Vector2(500.0f, 200.0f) );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_DOMAIN_OFFSET).Get<Vector2>(), Vector2(500.0f, 200.0f), TEST_LOCATION );
+
+ // Test "scrollPositionDelta" property
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("scrollPositionDelta") == ScrollView::Property::SCROLL_POSITION_DELTA );
+ scrollView.SetProperty( ScrollView::Property::SCROLL_POSITION_DELTA, Vector2(10.0f, 30.0f) );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::SCROLL_POSITION_DELTA).Get<Vector2>(), Vector2(10.0f, 30.0f), TEST_LOCATION );
+
+ // Test "startPagePosition" property
+ DALI_TEST_CHECK( scrollView.GetPropertyIndex("startPagePosition") == ScrollView::Property::START_PAGE_POSITION );
+ scrollView.SetProperty( ScrollView::Property::START_PAGE_POSITION, Vector3(50.0f, 100.0f, 20.0f) );
+ Wait(application);
+ DALI_TEST_EQUALS( scrollView.GetProperty(ScrollView::Property::START_PAGE_POSITION).Get<Vector3>(), Vector3(50.0f, 100.0f, 20.0f), TEST_LOCATION );
+
+ 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.
+ *
+ */
+
+#include <iostream>
+#include <stdlib.h>
+#include <dali/devel-api/rendering/renderer.h>
+#include <dali/integration-api/events/key-event-integ.h>
+#include <dali/integration-api/events/tap-gesture-event.h>
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <dali-toolkit/devel-api/controls/text-controls/text-editor.h> ///< @todo to be removed when text-editor is added to the dali-toolkit.h
+#include <dali-toolkit/devel-api/styling/style-manager.h>
+
+using namespace Dali;
+using namespace Toolkit;
+
+void dali_texteditor_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void dali_texteditor_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+namespace
+{
+
+const char* const PROPERTY_NAME_RENDERING_BACKEND = "renderingBackend";
+const char* const PROPERTY_NAME_TEXT = "text";
+const char* const PROPERTY_NAME_TEXT_COLOR = "textColor";
+const char* const PROPERTY_NAME_FONT_FAMILY = "fontFamily";
+const char* const PROPERTY_NAME_FONT_STYLE = "fontStyle";
+const char* const PROPERTY_NAME_POINT_SIZE = "pointSize";
+const char* const PROPERTY_NAME_HORIZONTAL_ALIGNMENT = "horizontalAlignment";
+const char* const PROPERTY_NAME_SCROLL_THRESHOLD = "scrollThreshold";
+const char* const PROPERTY_NAME_SCROLL_SPEED = "scrollSpeed";
+const char* const PROPERTY_NAME_PRIMARY_CURSOR_COLOR = "primaryCursorColor";
+const char* const PROPERTY_NAME_SECONDARY_CURSOR_COLOR = "secondaryCursorColor";
+const char* const PROPERTY_NAME_ENABLE_CURSOR_BLINK = "enableCursorBlink";
+const char* const PROPERTY_NAME_CURSOR_BLINK_INTERVAL = "cursorBlinkInterval";
+const char* const PROPERTY_NAME_CURSOR_BLINK_DURATION = "cursorBlinkDuration";
+const char* const PROPERTY_NAME_CURSOR_WIDTH = "cursorWidth";
+const char* const PROPERTY_NAME_GRAB_HANDLE_IMAGE = "grabHandleImage";
+const char* const PROPERTY_NAME_GRAB_HANDLE_PRESSED_IMAGE = "grabHandlePressedImage";
+const char* const PROPERTY_NAME_SELECTION_HANDLE_IMAGE_LEFT = "selectionHandleImageLeft";
+const char* const PROPERTY_NAME_SELECTION_HANDLE_IMAGE_RIGHT = "selectionHandleImageRight";
+const char* const PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_LEFT = "selectionHandlePressedImageLeft";
+const char* const PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_RIGHT = "selectionHandlePressedImageRight";
+const char* const PROPERTY_NAME_SELECTION_HANDLE_MARKER_IMAGE_LEFT = "selectionHandleMarkerImageLeft";
+const char* const PROPERTY_NAME_SELECTION_HANDLE_MARKER_IMAGE_RIGHT = "selectionHandleMarkerImageRight";
+const char* const PROPERTY_NAME_SELECTION_HIGHLIGHT_COLOR = "selectionHighlightColor";
+const char* const PROPERTY_NAME_DECORATION_BOUNDING_BOX = "decorationBoundingBox";
+const char* const PROPERTY_NAME_ENABLE_MARKUP = "enableMarkup";
+const char* const PROPERTY_NAME_INPUT_COLOR = "inputColor";
+const char* const PROPERTY_NAME_INPUT_FONT_FAMILY = "inputFontFamily";
+const char* const PROPERTY_NAME_INPUT_FONT_STYLE = "inputFontStyle";
+const char* const PROPERTY_NAME_INPUT_POINT_SIZE = "inputPointSize";
+
+const int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
+
+const Dali::Vector4 LIGHT_BLUE( 0.75f, 0.96f, 1.f, 1.f ); // The text highlight color.
+
+const unsigned int CURSOR_BLINK_INTERVAL = 500u; // Cursor blink interval
+const float TO_MILLISECONDS = 1000.f;
+const float TO_SECONDS = 1.f / TO_MILLISECONDS;
+
+const float SCROLL_THRESHOLD = 10.f;
+const float SCROLL_SPEED = 300.f;
+
+static bool gTextChangedCallBackCalled;
+
+static void TestTextChangedCallback( TextEditor control )
+{
+ tet_infoline(" TestTextChangedCallback");
+
+ gTextChangedCallBackCalled = true;
+}
+
+// Generate a TapGestureEvent to send to Core.
+Integration::TapGestureEvent GenerateTap(
+ Gesture::State state,
+ unsigned int numberOfTaps,
+ unsigned int numberOfTouches,
+ Vector2 point)
+{
+ Integration::TapGestureEvent tap( state );
+
+ tap.numberOfTaps = numberOfTaps;
+ tap.numberOfTouches = numberOfTouches;
+ tap.point = point;
+
+ return tap;
+}
+
+// Generate a KeyEvent to send to Core.
+Integration::KeyEvent GenerateKey( const std::string& keyName,
+ const std::string& keyString,
+ int keyCode,
+ int keyModifier,
+ unsigned long timeStamp,
+ const Integration::KeyEvent::State& keyState )
+{
+ return Integration::KeyEvent( keyName,
+ keyString,
+ keyCode,
+ keyModifier,
+ timeStamp,
+ keyState );
+}
+
+} // namespace
+
+int UtcDaliToolkitTextEditorConstructorP(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextEditorConstructorP");
+ TextEditor textEditor;
+ DALI_TEST_CHECK( !textEditor );
+ END_TEST;
+}
+
+int UtcDaliToolkitTextEditorNewP(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextEditorNewP");
+ TextEditor textEditor = TextEditor::New();
+ DALI_TEST_CHECK( textEditor );
+ END_TEST;
+}
+
+int UtcDaliToolkitTextEditorDownCastP(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextEditorDownCastP");
+ TextEditor textEditor1 = TextEditor::New();
+ BaseHandle object( textEditor1 );
+
+ TextEditor textEditor2 = TextEditor::DownCast( object );
+ DALI_TEST_CHECK( textEditor2 );
+
+ TextEditor textEditor3 = DownCast< TextEditor >( object );
+ DALI_TEST_CHECK( textEditor3 );
+ END_TEST;
+}
+
+int UtcDaliToolkitTextEditorDownCastN(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextEditorDownCastN");
+ BaseHandle uninitializedObject;
+ TextEditor textEditor1 = TextEditor::DownCast( uninitializedObject );
+ DALI_TEST_CHECK( !textEditor1 );
+
+ TextEditor textEditor2 = DownCast< TextEditor >( uninitializedObject );
+ DALI_TEST_CHECK( !textEditor2 );
+ END_TEST;
+}
+
+int UtcDaliToolkitTextEditorCopyConstructorP(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextEditorCopyConstructorP");
+ TextEditor textEditor = TextEditor::New();
+ textEditor.SetProperty( TextEditor::Property::TEXT, "Test" );
+
+ TextEditor copy( textEditor );
+ DALI_TEST_CHECK( copy );
+ DALI_TEST_CHECK( copy.GetProperty<std::string>( TextLabel::Property::TEXT ) == textEditor.GetProperty<std::string>( TextLabel::Property::TEXT ) );
+ END_TEST;
+}
+
+int UtcDaliToolkitTextEditorAssignmentOperatorP(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextEditorAssignmentOperatorP");
+ TextEditor textEditor = TextEditor::New();
+ textEditor.SetProperty( TextEditor::Property::TEXT, "Test" );
+
+ TextEditor copy = textEditor;
+ DALI_TEST_CHECK( copy );
+ DALI_TEST_CHECK( copy.GetProperty<std::string>( TextEditor::Property::TEXT ) == textEditor.GetProperty<std::string>( TextEditor::Property::TEXT ) );
+ END_TEST;
+}
+
+int UtcDaliTextEditorNewP(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextEditorNewP");
+ TextEditor textEditor = TextEditor::New();
+ DALI_TEST_CHECK( textEditor );
+ END_TEST;
+}
+
+// Positive test case for a method
+int UtcDaliTextEditorGetPropertyP(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextEditorGetPropertyP");
+ TextEditor editor = TextEditor::New();
+ DALI_TEST_CHECK( editor );
+
+ // Check Property Indices are correct
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_RENDERING_BACKEND ) == TextEditor::Property::RENDERING_BACKEND );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_TEXT ) == TextEditor::Property::TEXT );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_TEXT_COLOR ) == TextEditor::Property::TEXT_COLOR );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_FONT_FAMILY ) == TextEditor::Property::FONT_FAMILY );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_FONT_STYLE ) == TextEditor::Property::FONT_STYLE );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_POINT_SIZE ) == TextEditor::Property::POINT_SIZE );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_HORIZONTAL_ALIGNMENT ) == TextEditor::Property::HORIZONTAL_ALIGNMENT );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SCROLL_THRESHOLD ) == TextEditor::Property::SCROLL_THRESHOLD );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SCROLL_SPEED ) == TextEditor::Property::SCROLL_SPEED );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_PRIMARY_CURSOR_COLOR ) == TextEditor::Property::PRIMARY_CURSOR_COLOR );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SECONDARY_CURSOR_COLOR ) == TextEditor::Property::SECONDARY_CURSOR_COLOR );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_ENABLE_CURSOR_BLINK ) == TextEditor::Property::ENABLE_CURSOR_BLINK );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_CURSOR_BLINK_INTERVAL ) == TextEditor::Property::CURSOR_BLINK_INTERVAL );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_CURSOR_BLINK_DURATION ) == TextEditor::Property::CURSOR_BLINK_DURATION );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_CURSOR_WIDTH ) == TextEditor::Property::CURSOR_WIDTH );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_GRAB_HANDLE_IMAGE ) == TextEditor::Property::GRAB_HANDLE_IMAGE );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_GRAB_HANDLE_PRESSED_IMAGE ) == TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_IMAGE_LEFT ) == TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_IMAGE_RIGHT ) == TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_LEFT ) == TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_PRESSED_IMAGE_RIGHT ) == TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_MARKER_IMAGE_LEFT ) == TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SELECTION_HANDLE_MARKER_IMAGE_RIGHT ) == TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_SELECTION_HIGHLIGHT_COLOR ) == TextEditor::Property::SELECTION_HIGHLIGHT_COLOR );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_DECORATION_BOUNDING_BOX ) == TextEditor::Property::DECORATION_BOUNDING_BOX );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_ENABLE_MARKUP ) == TextEditor::Property::ENABLE_MARKUP );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_COLOR ) == TextEditor::Property::INPUT_COLOR );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_FONT_FAMILY ) == TextEditor::Property::INPUT_FONT_FAMILY );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_FONT_STYLE ) == TextEditor::Property::INPUT_FONT_STYLE );
+ DALI_TEST_CHECK( editor.GetPropertyIndex( PROPERTY_NAME_INPUT_POINT_SIZE ) == TextEditor::Property::INPUT_POINT_SIZE );
+ END_TEST;
+}
+
+bool SetPropertyMapRetrieved( TextEditor& editor, const Property::Index property, const std::string mapKey, const std::string mapValue )
+{
+ bool result = false;
+ Property::Map imageMap;
+ imageMap[mapKey] =mapValue;
+
+ editor.SetProperty( property , imageMap );
+ Property::Value propValue = editor.GetProperty( property );
+ Property::Map* resultMap = propValue.GetMap();
+
+ if ( resultMap->Find( mapKey )->Get< std::string>() == mapValue )
+ {
+ result = true;
+ }
+
+ return result;
+}
+
+// Positive test case for a method
+int UtcDaliTextEditorSetPropertyP(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextEditorSetPropertyP");
+ TextEditor editor = TextEditor::New();
+ DALI_TEST_CHECK( editor );
+ Stage::GetCurrent().Add( editor );
+
+ // Note - we can't check the defaults since the stylesheets are platform-specific
+
+ // Check the render backend property.
+ editor.SetProperty( TextEditor::Property::RENDERING_BACKEND, Text::RENDERING_SHARED_ATLAS );
+ DALI_TEST_EQUALS( (Text::RenderingType)editor.GetProperty<int>( TextEditor::Property::RENDERING_BACKEND ), Text::RENDERING_SHARED_ATLAS, TEST_LOCATION );
+
+ // Check text property.
+ editor.SetProperty( TextEditor::Property::TEXT, "Setting Text" );
+ DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::TEXT ), std::string("Setting Text"), TEST_LOCATION );
+
+ // Check text's color property
+ editor.SetProperty( TextEditor::Property::TEXT_COLOR, Color::WHITE );
+ DALI_TEST_EQUALS( editor.GetProperty<Vector4>( TextEditor::Property::TEXT_COLOR ), Color::WHITE, TEST_LOCATION );
+
+ // Check font properties.
+ editor.SetProperty( TextEditor::Property::FONT_FAMILY, "Setting font family" );
+ DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::FONT_FAMILY ), std::string("Setting font family"), TEST_LOCATION );
+ editor.SetProperty( TextEditor::Property::FONT_STYLE, "Setting font style" );
+ DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::FONT_STYLE ), std::string("Setting font style"), TEST_LOCATION );
+ editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f );
+ DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::POINT_SIZE ), 10.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+ // Check that the Alignment properties can be correctly set
+ editor.SetProperty( TextEditor::Property::HORIZONTAL_ALIGNMENT, "END" );
+ DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::HORIZONTAL_ALIGNMENT ), "END", TEST_LOCATION );
+
+ // Check scroll properties.
+ editor.SetProperty( TextEditor::Property::SCROLL_THRESHOLD, 1.f );
+ DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::SCROLL_THRESHOLD ), 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+ editor.SetProperty( TextEditor::Property::SCROLL_SPEED, 100.f );
+ DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::SCROLL_SPEED ), 100.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+ // Check cursor properties
+ editor.SetProperty( TextEditor::Property::PRIMARY_CURSOR_COLOR, Color::RED );
+ DALI_TEST_EQUALS( editor.GetProperty<Vector4>( TextEditor::Property::PRIMARY_CURSOR_COLOR ), Color::RED, TEST_LOCATION );
+ editor.SetProperty( TextEditor::Property::SECONDARY_CURSOR_COLOR, Color::BLUE );
+ DALI_TEST_EQUALS( editor.GetProperty<Vector4>( TextEditor::Property::SECONDARY_CURSOR_COLOR ), Color::BLUE, TEST_LOCATION );
+
+ editor.SetProperty( TextEditor::Property::ENABLE_CURSOR_BLINK, false );
+ DALI_TEST_EQUALS( editor.GetProperty<bool>( TextEditor::Property::ENABLE_CURSOR_BLINK ), false, TEST_LOCATION );
+ editor.SetProperty( TextEditor::Property::CURSOR_BLINK_INTERVAL, 1.f );
+ DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::CURSOR_BLINK_INTERVAL ), 1.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+ editor.SetProperty( TextEditor::Property::CURSOR_BLINK_DURATION, 10.f );
+ DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::CURSOR_BLINK_DURATION ), 10.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+ editor.SetProperty( TextEditor::Property::CURSOR_WIDTH, 1 );
+ DALI_TEST_EQUALS( editor.GetProperty<int>( TextEditor::Property::CURSOR_WIDTH ), 1, TEST_LOCATION );
+
+ // Check handle images
+ editor.SetProperty( TextEditor::Property::GRAB_HANDLE_IMAGE, "image1" );
+ DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::GRAB_HANDLE_IMAGE ), "image1", TEST_LOCATION );
+ editor.SetProperty( TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE, "image2" );
+ DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE ), "image2", TEST_LOCATION );
+ editor.SetProperty( TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT, "image3" );
+
+ // Check handle images
+ DALI_TEST_CHECK( SetPropertyMapRetrieved( editor, TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT, "filename", "leftHandleImage" ) );
+ DALI_TEST_CHECK( SetPropertyMapRetrieved( editor, TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT, "filename", "rightHandleImage" ) );
+ DALI_TEST_CHECK( SetPropertyMapRetrieved( editor, TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT, "filename", "leftHandleImagePressed" ) );
+ DALI_TEST_CHECK( SetPropertyMapRetrieved( editor, TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT, "filename", "rightHandleImagePressed" ) );
+ DALI_TEST_CHECK( SetPropertyMapRetrieved( editor, TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT, "filename", "leftHandleMarkerImage" ) );
+ DALI_TEST_CHECK( SetPropertyMapRetrieved( editor, TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT, "filename", "rightHandleMarkerImage" ) );
+
+ // Check the highlight color
+ editor.SetProperty( TextEditor::Property::SELECTION_HIGHLIGHT_COLOR, Color::GREEN );
+ DALI_TEST_EQUALS( editor.GetProperty<Vector4>( TextEditor::Property::SELECTION_HIGHLIGHT_COLOR ), Color::GREEN, TEST_LOCATION );
+
+ // Decoration bounding box
+ editor.SetProperty( TextEditor::Property::DECORATION_BOUNDING_BOX, Rect<int>( 0, 0, 1, 1 ) );
+ DALI_TEST_EQUALS( editor.GetProperty<Rect <int > >( TextEditor::Property::DECORATION_BOUNDING_BOX ), Rect<int>( 0, 0, 1, 1 ), TEST_LOCATION );
+
+ // Check the enable markup property.
+ DALI_TEST_CHECK( !editor.GetProperty<bool>( TextEditor::Property::ENABLE_MARKUP ) );
+ editor.SetProperty( TextEditor::Property::ENABLE_MARKUP, true );
+ DALI_TEST_CHECK( editor.GetProperty<bool>( TextEditor::Property::ENABLE_MARKUP ) );
+
+ // Check input color property.
+ editor.SetProperty( TextEditor::Property::INPUT_COLOR, Color::YELLOW );
+ DALI_TEST_EQUALS( editor.GetProperty<Vector4>( TextEditor::Property::INPUT_COLOR ), Color::YELLOW, TEST_LOCATION );
+
+ // Check input font properties.
+ editor.SetProperty( TextEditor::Property::INPUT_FONT_FAMILY, "Setting input font family" );
+ DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::INPUT_FONT_FAMILY ), "Setting input font family", TEST_LOCATION );
+ editor.SetProperty( TextEditor::Property::INPUT_FONT_STYLE, "Setting input font style" );
+ DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::INPUT_FONT_STYLE ), "Setting input font style", TEST_LOCATION );
+ editor.SetProperty( TextEditor::Property::INPUT_POINT_SIZE, 12.f );
+ DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::INPUT_POINT_SIZE ), 12.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+ END_TEST;
+}
+
+// Positive Atlas Text Renderer test
+int utcDaliTextEditorAtlasRenderP(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" UtcDaliToolkitTextEditorAtlasRenderP");
+ StyleManager styleManager = StyleManager::Get();
+ styleManager.RequestDefaultTheme();
+ TextEditor editor = TextEditor::New();
+ DALI_TEST_CHECK( editor );
+
+ editor.SetProperty( TextEditor::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
+
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+ Stage::GetCurrent().Add( editor );
+
+ try
+ {
+ // Render some text with the shared atlas backend
+ editor.SetProperty( TextEditor::Property::RENDERING_BACKEND, Text::RENDERING_SHARED_ATLAS );
+ application.SendNotification();
+ application.Render();
+ }
+ catch( ... )
+ {
+ tet_result(TET_FAIL);
+ }
+ END_TEST;
+}
+
+// Positive test for the textChanged signal.
+int utcDaliTextEditorTextChangedP(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextEditorTextChangedP");
+ TextEditor editor = TextEditor::New();
+ DALI_TEST_CHECK( editor );
+
+ Stage::GetCurrent().Add( editor );
+
+ editor.TextChangedSignal().Connect(&TestTextChangedCallback);
+
+ gTextChangedCallBackCalled = false;
+ editor.SetProperty( TextEditor::Property::TEXT, "ABC" );
+ DALI_TEST_CHECK( gTextChangedCallBackCalled );
+
+ application.SendNotification();
+
+ editor.SetKeyInputFocus();
+
+ gTextChangedCallBackCalled = false;
+ application.ProcessEvent( GenerateKey( "D", "D", 0, 0, 0, Integration::KeyEvent::Down ) );
+ DALI_TEST_CHECK( gTextChangedCallBackCalled );
+
+ END_TEST;
+}
+
+int utcDaliTextEditorEvent01(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextEditorEvent01");
+
+ // Creates a tap event. After creating a tap event the text editor should
+ // have the focus and add text with key events should be possible.
+
+ TextEditor editor = TextEditor::New();
+ DALI_TEST_CHECK( editor );
+
+ Stage::GetCurrent().Add( editor );
+
+ editor.SetSize( 300.f, 50.f );
+ editor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ editor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+ // Avoid a crash when core load gl resources.
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Add a key event but as the text editor has not the focus it should do nothing.
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::TEXT ), std::string(""), TEST_LOCATION );
+
+ // Create a tap event to touch the text editor.
+ application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+ application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Now the text editor has the focus, so it can handle the key events.
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::TEXT ), std::string("aa"), TEST_LOCATION );
+
+ // Create a second text editor and send key events to it.
+ TextEditor editor2 = TextEditor::New();
+
+ editor2.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ editor2.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+ editor2.SetSize( 100.f, 100.f );
+ editor2.SetPosition( 100.f, 100.f );
+
+ Stage::GetCurrent().Add( editor2 );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Create a tap event on the second text editor.
+ application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 125.0f ) ) );
+ application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 125.0f ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // The second text editor has the focus. It should handle the key events.
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Check the text has been added to the second text editor.
+ DALI_TEST_EQUALS( editor2.GetProperty<std::string>( TextEditor::Property::TEXT ), std::string("aa"), TEST_LOCATION );
+
+ END_TEST;
+}
+
+int utcDaliTextEditorEvent02(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextEditorEvent02");
+
+ // Checks if the right number of actors are created.
+
+ TextEditor editor = TextEditor::New();
+ editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f );
+ DALI_TEST_CHECK( editor );
+
+ Stage::GetCurrent().Add( editor );
+
+ editor.SetSize( 300.f, 50.f );
+ editor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ editor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+ // Avoid a crash when core load gl resources.
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Check there are the expected number of children ( active layer, offscreen root actor, and the offscreen image actor
+ DALI_TEST_EQUALS( editor.GetChildCount(), 3u, TEST_LOCATION );
+
+ Actor layer = editor.GetChildAt( 0u );
+ DALI_TEST_CHECK( layer.IsLayer() );
+
+ Actor offscreenRoot = editor.GetChildAt( 1u );
+ DALI_TEST_CHECK( offscreenRoot.IsLayer() );
+ DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor.
+
+ Actor offscreenImage = editor.GetChildAt( 2u );
+ ImageActor imageActor = ImageActor::DownCast( offscreenImage );
+ DALI_TEST_CHECK( imageActor );
+
+ // Create a tap event to touch the text editor.
+ application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+ application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 150.0f, 25.0f ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor.
+ DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor.
+
+ // Now the text editor has the focus, so it can handle the key events.
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+ application.ProcessEvent( GenerateKey( "a", "a", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Checks the cursor and the renderer have been created.
+ DALI_TEST_EQUALS( layer.GetChildCount(), 1u, TEST_LOCATION ); // The cursor.
+ DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 2u, TEST_LOCATION ); // The camera actor and the renderer
+
+ Control cursor = Control::DownCast( layer.GetChildAt( 0u ) );
+ DALI_TEST_CHECK( cursor );
+
+ CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) );
+ DALI_TEST_CHECK( camera );
+
+ Renderer renderer = offscreenRoot.GetChildAt( 1u ).GetRendererAt( 0u );
+ DALI_TEST_CHECK( renderer );
+
+ // Move the cursor and check the position changes.
+ Vector3 position1 = cursor.GetCurrentPosition();
+
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down ) );
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ Vector3 position2 = cursor.GetCurrentPosition();
+
+ DALI_TEST_CHECK( position2.x < position1.x );
+
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down ) );
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ Vector3 position3 = cursor.GetCurrentPosition();
+
+ DALI_TEST_EQUALS( position1, position3, TEST_LOCATION ); // Should be in the same position1.
+
+ // Send some taps and check the cursor positions.
+
+ // Try to tap at the beginning.
+ application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 1.f, 25.0f ) ) );
+ application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 1.f, 25.0f ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Cursor position should be the same than position1.
+ Vector3 position4 = cursor.GetCurrentPosition();
+
+ DALI_TEST_EQUALS( position2, position4, TEST_LOCATION ); // Should be in the same position2.
+
+ // Tap away from the start position.
+ application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 16.f, 25.0f ) ) );
+ application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 16.0f, 25.0f ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ Vector3 position5 = cursor.GetCurrentPosition();
+
+ DALI_TEST_CHECK( position5.x > position4.x );
+
+ // Remove all the text.
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down ) );
+ application.ProcessEvent( GenerateKey( "", "", DALI_KEY_BACKSPACE, 0, 0, Integration::KeyEvent::Down ) );
+ editor.SetProperty( TextEditor::Property::TEXT, "" );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Cursor position should be the same than position2.
+ Vector3 position6 = cursor.GetCurrentPosition();
+
+ DALI_TEST_EQUALS( position2, position6, TEST_LOCATION );// Should be in the same position2.
+
+ // Should not be a renderer.
+ DALI_TEST_EQUALS( offscreenRoot.GetChildCount(), 1u, TEST_LOCATION ); // The camera actor only.
+
+ END_TEST;
+}
+
+int utcDaliTextEditorEvent03(void)
+{
+ ToolkitTestApplication application;
+ tet_infoline(" utcDaliTextEditorEvent03");
+
+ // Checks if the highlight actor is created.
+
+ TextEditor editor = TextEditor::New();
+ DALI_TEST_CHECK( editor );
+
+ Stage::GetCurrent().Add( editor );
+
+ editor.SetProperty( TextEditor::Property::TEXT, "This is a long text for the size of the text-editor." );
+ editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f );
+ editor.SetSize( 30.f, 50.f );
+ editor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+ editor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+ // Avoid a crash when core load gl resources.
+ application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Tap first to get the focus.
+ application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 3.f, 25.0f ) ) );
+ application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 3.f, 25.0f ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // Double tap to select a word.
+ application.ProcessEvent( GenerateTap( Gesture::Possible, 2u, 1u, Vector2( 3.f, 25.0f ) ) );
+ application.ProcessEvent( GenerateTap( Gesture::Started, 2u, 1u, Vector2( 3.f, 25.0f ) ) );
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ // The offscreen root actor should have three actors: the camera, a renderer and the highlight actor.
+ Actor offscreenRoot = editor.GetChildAt( 1u );
+ DALI_TEST_CHECK( offscreenRoot.IsLayer() );
+
+ CameraActor camera = CameraActor::DownCast( offscreenRoot.GetChildAt( 0u ) );
+ DALI_TEST_CHECK( camera );
+
+ Renderer renderer = offscreenRoot.GetChildAt( 1u ).GetRendererAt( 0u );
+ DALI_TEST_CHECK( renderer );
+
+ Renderer highlight = offscreenRoot.GetChildAt( 2u ).GetRendererAt( 0u );
+ DALI_TEST_CHECK( highlight );
+
+ END_TEST;
+}
AC_SUBST(DALI_TOOLKIT_VERSION)
PKG_CHECK_MODULES(DALICORE, dali-core)
-PKG_CHECK_MODULES(DALI, dali)
DALI_TOOLKIT_CFLAGS=-DPLATFORM_TIZEN
-I../../../ \
$(DALI_TOOLKIT_CFLAGS) \
$(DALICORE_CFLAGS) \
- $(DALI_CFLAGS) \
$(DLOG_CFLAGS) \
$(FRIBIDI_CFLAGS) \
$(HTMLCXX_CFLAGS)
libdali_toolkit_la_LIBADD = \
$(DALICORE_LIBS) \
- $(DALI_LIBS) \
$(DLOG_LIBS) \
$(FRIBIDI_LIBS) \
$(HTMLCXX_LIBS)
--- /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/devel-api/controls/text-controls/text-editor.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/controls/text-controls/text-editor-impl.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+TextEditor TextEditor::New()
+{
+ return Internal::TextEditor::New();
+}
+
+TextEditor::TextEditor()
+{
+}
+
+TextEditor::TextEditor( const TextEditor& handle )
+: Control( handle )
+{
+}
+
+TextEditor& TextEditor::operator=( const TextEditor& handle )
+{
+ if( &handle != this )
+ {
+ Control::operator=( handle );
+ }
+ return *this;
+}
+
+TextEditor::~TextEditor()
+{
+}
+
+TextEditor TextEditor::DownCast( BaseHandle handle )
+{
+ return Control::DownCast<TextEditor, Internal::TextEditor>( handle );
+}
+
+TextEditor::TextChangedSignalType& TextEditor::TextChangedSignal()
+{
+ return Dali::Toolkit::GetImpl( *this ).TextChangedSignal();
+}
+
+TextEditor::TextEditor( Internal::TextEditor& implementation )
+: Control( implementation )
+{
+}
+
+TextEditor::TextEditor( Dali::Internal::CustomActor* internal )
+: Control( internal )
+{
+ VerifyCustomActorPointer<Internal::TextEditor>( internal );
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_TEXT_EDITOR_H__
+#define __DALI_TOOLKIT_TEXT_EDITOR_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal DALI_INTERNAL
+{
+class TextEditor;
+}
+/**
+ * @addtogroup dali_toolkit_controls_text_controls
+ * @{
+ */
+
+/**
+ * @brief A control which provides a multi-line editable text editor.
+ *
+ * * Signals
+ * | %Signal Name | Method |
+ * |----------------------|-----------------------------------------------------|
+ * | textChanged | @ref TextChangedSignal() |
+ *
+ */
+class DALI_IMPORT_API TextEditor : public Control
+{
+public:
+
+ /**
+ * @brief The start and end property ranges for this control.
+ */
+ enum PropertyRange
+ {
+ PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
+ PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000 ///< Reserve property indices
+ };
+
+ /**
+ * @brief An enumeration of properties belonging to the TextEditor class.
+ */
+ struct Property
+ {
+ enum
+ {
+ RENDERING_BACKEND = PROPERTY_START_INDEX, ///< name "renderingBackend", The type or rendering e.g. bitmap-based, type INT
+ TEXT, ///< name "text", The text to display in UTF-8 format, type STRING
+ TEXT_COLOR, ///< name "textColor", The text color, type VECTOR4
+ FONT_FAMILY, ///< name "fontFamily", The requested font family, type STRING
+ FONT_STYLE, ///< name "fontStyle", The requested font style, type STRING
+ POINT_SIZE, ///< name "pointSize", The size of font in points, type FLOAT
+ HORIZONTAL_ALIGNMENT, ///< name "horizontalAlignment", The text horizontal alignment, type STRING, values "BEGIN", "CENTER", "END"
+ SCROLL_THRESHOLD, ///< name "scrollThreshold" Vertical scrolling will occur if the cursor is this close to the control border, type FLOAT
+ SCROLL_SPEED, ///< name "scrollSpeed" The scroll speed in pixels per second, type FLOAT
+ PRIMARY_CURSOR_COLOR, ///< name "primaryCursorColor", The color to apply to the primary cursor, type VECTOR4
+ SECONDARY_CURSOR_COLOR, ///< name "secondaryCursorColor", The color to apply to the secondary cursor, type VECTOR4
+ ENABLE_CURSOR_BLINK, ///< name "enableCursorBlink", Whether the cursor should blink or not, type BOOLEAN
+ CURSOR_BLINK_INTERVAL, ///< name "cursorBlinkInterval", The time interval in seconds between cursor on/off states, type FLOAT
+ CURSOR_BLINK_DURATION, ///< name "cursorBlinkDuration", The cursor will stop blinking after this number of seconds (if non-zero), type FLOAT
+ CURSOR_WIDTH, ///< name "cursorWidth", The cursor width, type INTEGER
+ GRAB_HANDLE_IMAGE, ///< name "grabHandleImage", The image to display for the grab handle, type STRING
+ GRAB_HANDLE_PRESSED_IMAGE, ///< name "grabHandlePressedImage", The image to display when the grab handle is pressed, type STRING
+ SELECTION_HANDLE_IMAGE_LEFT, ///< name "selectionHandleImageLeft", The image to display for the left selection handle, type MAP
+ SELECTION_HANDLE_IMAGE_RIGHT, ///< name "selectionHandleImageRight", The image to display for the right selection handle, type MAP
+ SELECTION_HANDLE_PRESSED_IMAGE_LEFT, ///< name "selectionHandlePressedImageLeft", The image to display when the left selection handle is pressed, type MAP
+ SELECTION_HANDLE_PRESSED_IMAGE_RIGHT, ///< name "selectionHandlePressedImageRight", The image to display when the right selection handle is pressed, type MAP
+ SELECTION_HANDLE_MARKER_IMAGE_LEFT, ///< name "selectionHandleMarkerImageLeft", The image to display for the left selection handle marker, type MAP
+ SELECTION_HANDLE_MARKER_IMAGE_RIGHT, ///< name "selectionHandleMarkerImageRight", The image to display for the right selection handle marker, type MAP
+ SELECTION_HIGHLIGHT_COLOR, ///< name "selectionHighlightColor", The color of the selection highlight, type VECTOR4
+ DECORATION_BOUNDING_BOX, ///< name "decorationBoundingBox", The decorations (handles etc) will positioned within this area on-screen, type RECTANGLE
+ ENABLE_MARKUP, ///< name "enableMarkup", Whether the mark-up processing is enabled. type BOOLEAN
+ INPUT_COLOR, ///< name "inputColor", The color of the new input text, type VECTOR4
+ INPUT_FONT_FAMILY, ///< name "inputFontFamily", The font's family of the new input text, type STRING
+ INPUT_FONT_STYLE, ///< name "inputFontStyle", The font's style of the new input text, type STRING
+ INPUT_POINT_SIZE ///< name "inputPointSize", The font's size of the new input text in points, type FLOAT
+ };
+ };
+
+ // Type Defs
+
+ /// @brief Text changed signal type.
+ typedef Signal<void ( TextEditor ) > TextChangedSignalType;
+
+ /**
+ * @brief Create the TextEditor control.
+ * @return A handle to the TextEditor control.
+ */
+ static TextEditor New();
+
+ /**
+ * @brief Creates an empty handle.
+ */
+ TextEditor();
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param[in] handle The handle to copy from.
+ */
+ TextEditor( const TextEditor& handle );
+
+ /**
+ * @brief Assignment operator.
+ *
+ * @param[in] handle The handle to copy from.
+ * @return A reference to this.
+ */
+ TextEditor& operator=( const TextEditor& handle );
+
+ /**
+ * @brief Destructor.
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~TextEditor();
+
+ /**
+ * @brief Downcast a handle to TextEditor.
+ *
+ * If the BaseHandle points is a TextEditor the downcast returns a valid handle.
+ * If not the returned handle is left empty.
+ *
+ * @param[in] handle Handle to an object.
+ * @return handle to a TextEditor or an empty handle.
+ */
+ static TextEditor DownCast( BaseHandle handle );
+
+ // Signals
+
+ /**
+ * @brief This signal is emitted when the text changes.
+ *
+ * A callback of the following type may be connected:
+ * @code
+ * void YourCallbackName( TextEditor textEditor );
+ * @endcode
+ * @return The signal to connect to.
+ */
+ TextChangedSignalType& TextChangedSignal();
+
+public: // Not intended for application developers
+
+ /**
+ * @brief Creates a handle using the Toolkit::Internal implementation.
+ *
+ * @param[in] implementation The Control implementation.
+ */
+ DALI_INTERNAL TextEditor( Internal::TextEditor& implementation );
+
+ /**
+ * @brief Allows the creation of this Control from an Internal::CustomActor pointer.
+ *
+ * @param[in] internal A pointer to the internal CustomActor.
+ */
+ explicit DALI_INTERNAL TextEditor( Dali::Internal::CustomActor* internal );
+};
+
+/**
+ * @}
+ */
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_TEXT_EDITOR_H__
$(devel_api_src_dir)/controls/shadow-view/shadow-view.cpp \
$(devel_api_src_dir)/controls/slider/slider.cpp \
$(devel_api_src_dir)/controls/super-blur-view/super-blur-view.cpp \
+ $(devel_api_src_dir)/controls/text-controls/text-editor.cpp \
$(devel_api_src_dir)/controls/text-controls/text-selection-popup.cpp \
$(devel_api_src_dir)/controls/text-controls/text-selection-toolbar.cpp \
$(devel_api_src_dir)/controls/tool-bar/tool-bar.cpp \
$(devel_api_src_dir)/controls/super-blur-view/super-blur-view.h
devel_api_text_controls_header_files = \
+ $(devel_api_src_dir)/controls/text-controls/text-editor.h \
$(devel_api_src_dir)/controls/text-controls/text-selection-popup.h \
$(devel_api_src_dir)/controls/text-controls/text-selection-toolbar.h
parser.GetErrorDescription().c_str() );
DALI_ASSERT_ALWAYS(!"Cannot parse JSON");
-
}
else
{
}
DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Cannot parse JSON");
-
}
void Builder::AddConstants( const Property::Map& map )
mParser = Dali::Toolkit::JsonParser::New();
Property::Map defaultDirs;
- defaultDirs[ TOKEN_STRING(DALI_IMAGE_DIR) ] = DALI_IMAGE_DIR;
- defaultDirs[ TOKEN_STRING(DALI_SOUND_DIR) ] = DALI_SOUND_DIR;
- defaultDirs[ TOKEN_STRING(DALI_STYLE_DIR) ] = DALI_STYLE_DIR;
+ defaultDirs[ TOKEN_STRING(DALI_IMAGE_DIR) ] = DALI_IMAGE_DIR;
+ defaultDirs[ TOKEN_STRING(DALI_SOUND_DIR) ] = DALI_SOUND_DIR;
+ defaultDirs[ TOKEN_STRING(DALI_STYLE_DIR) ] = DALI_STYLE_DIR;
defaultDirs[ TOKEN_STRING(DALI_STYLE_IMAGE_DIR) ] = DALI_STYLE_IMAGE_DIR;
AddConstants( defaultDirs );
TreeNodeManipulator modify(node);
modify.SetName(name);
- // Set the type of the existing node, this may remove children where necessary
- // (changing from container type to value type)
+
+ // Set the type of the existing node.
+ // Where the new type is different, then any children of this node will
+ // be deleted.
+ // When the type is an array of numbers, then this will also remove any children
+ // When the type is an object or other array, then the children will not be removed,
+ // but will instead follow these replace rules.
modify.SetType(type);
mCurrent = modify;
namespace
{
-void Indent(std::ostream& o, int indent)
+void Indent(std::ostream& o, int level, int indentWidth)
{
- for (int i = 0; i < indent; ++i)
+ for (int i = 0; i < level*indentWidth; ++i)
{
o << " ";
}
}
+std::string EscapeQuotes( const char* aString)
+{
+ std::string escapedString;
+ int length = strlen(aString);
+ escapedString.reserve(length);
+
+ const char* end = aString+length;
+ for( const char* iter = aString; iter != end ; ++iter)
+ {
+ if(*iter != '\"')
+ {
+ escapedString.push_back(*iter);
+ }
+ else
+ {
+ escapedString.append("\\\"");
+ }
+ }
+ return escapedString;
}
+} // anonymous namespace
+
TreeNodeManipulator::TreeNodeManipulator(TreeNode* node)
: mNode(node)
{
}
}
}
+ else if( TreeNode::ARRAY == mNode->mType )
+ {
+ if( mNode->mFirstChild != NULL )
+ {
+ TreeNode::NodeType type = mNode->mFirstChild->GetType();
+
+ if( TreeNode::FLOAT == type || TreeNode::INTEGER == type )
+ {
+ // Arrays of numbers should be replaced, not appended to.
+ RemoveChildren();
+ }
+ }
+ }
}
void TreeNodeManipulator::SetName( const char* name )
void TreeNodeManipulator::Write(std::ostream& output, int indent) const
{
DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
- DoWrite(mNode, output, indent);
+ DoWrite(mNode, output, 0, indent, false);
}
-void TreeNodeManipulator::DoWrite(const TreeNode *value, std::ostream& output, int indent) const
+void TreeNodeManipulator::DoWrite(const TreeNode *value, std::ostream& output, int level, int indentWidth, bool groupChildren) const
{
DALI_ASSERT_DEBUG(value && "Operation on NULL JSON node");
- Indent(output, indent);
+ if(!groupChildren)
+ {
+ Indent(output, level, indentWidth);
+ }
if (value->GetName())
{
output << "null";
if(NULL != value->mNextSibling)
{
- output << ",";
+ output << ", ";
}
- if(indent)
+ if( !groupChildren )
{
output << std::endl;
}
case TreeNode::OBJECT:
case TreeNode::ARRAY:
{
+ bool groupMyChildren = false;
+
+ if( TreeNode::ARRAY == value->GetType() &&
+ ( TreeNode::INTEGER == value->mFirstChild->GetType() ||
+ TreeNode::FLOAT == value->mFirstChild->GetType() ) )
+ {
+ groupMyChildren = true;
+ }
+
if( value->GetType() == TreeNode::OBJECT)
{
+ output << std::endl;
+ Indent(output, level, indentWidth);
output << "{";
- if(indent)
- {
- output << std::endl;
- }
}
else
{
- output << "[";
- if(indent)
+ if( !groupMyChildren )
{
output << std::endl;
+ Indent(output, level, indentWidth);
}
+ output << "[";
+ }
+
+ if( groupMyChildren )
+ {
+ output << " ";
+ }
+ else
+ {
+ output << std::endl;
}
for (TreeNode::ConstIterator it = value->CBegin(); it != value->CEnd(); ++it)
{
- DoWrite( &((*it).second), output, indent + 1);
+ DoWrite( &((*it).second), output, level+1, indentWidth, groupMyChildren );
}
- Indent(output, indent);
+
+ if( !groupMyChildren )
+ {
+ Indent(output, level, indentWidth);
+ }
+
if( value->GetType() == TreeNode::OBJECT )
{
output << "}";
- if(indent)
- {
- output << std::endl;
- }
}
else
{
output << "]";
- if(indent)
- {
- output << std::endl;
- }
}
+
+ if( NULL != value->mNextSibling )
+ {
+ output << ",";
+ }
+
+ if( !groupChildren )
+ {
+ output << std::endl;
+ }
+
+ groupChildren = false;
break;
}
case TreeNode::STRING:
{
- output << "\"" << value->GetString() << "\"";
+ std::string escapedString = EscapeQuotes(value->GetString());
+ output << "\"" << escapedString << "\"";
if(NULL != value->mNextSibling)
{
output << ",";
}
- if(indent)
+
+ if( groupChildren )
+ {
+ output << " ";
+ }
+ else
{
output << std::endl;
}
-
break;
}
case TreeNode::INTEGER:
{
output << ",";
}
- if(indent)
+
+ if( groupChildren )
+ {
+ output << " ";
+ }
+ else
{
output << std::endl;
}
-
break;
}
case TreeNode::FLOAT:
{
output << ",";
}
- if(indent)
+
+ if( groupChildren )
+ {
+ output << " ";
+ }
+ else
{
output << std::endl;
}
{
output << "false";
}
+
if(NULL != value->mNextSibling)
{
output << ",";
}
- if(indent)
+
+ if( groupChildren )
+ {
+ output << " ";
+ }
+ else
{
output << std::endl;
}
} // namespace Toolkit
} // namespace Dali
-
/*
* Do write to string stream
*/
- void DoWrite(const TreeNode *value, std::ostream& output, int ident) const;
+ void DoWrite(const TreeNode *value, std::ostream& output, int level, int ident, bool groupChildren) const;
};
DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ImageView, Toolkit::Control, Create );
DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "resourceUrl", STRING, RESOURCE_URL )
DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "image", MAP, IMAGE )
+DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "preMultipliedAlpha", BOOLEAN, PRE_MULTIPLIED_ALPHA )
+
+DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, ImageView, "pixelArea", Vector4(0.f, 0.f, 1.f, 1.f), PIXEL_AREA )
DALI_TYPE_REGISTRATION_END()
} // anonymous namespace
using namespace Dali;
ImageView::ImageView()
-: Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) )
+: Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ),
+ mPremultipledAlphaEnabled( false )
{
}
}
}
+void ImageView::EnablePreMultipliedAlpha( bool preMultipled )
+{
+ mPremultipledAlphaEnabled = preMultipled;
+
+ if( mRenderer )
+ {
+ ControlRenderer& rendererImpl = GetImplementation( mRenderer );
+ if (&typeid( rendererImpl ) == &typeid(ImageRenderer) )
+ {
+ ImageRenderer* imageRenderer = static_cast<ImageRenderer*>( &rendererImpl );
+ imageRenderer->EnablePreMultipliedAlpha( preMultipled );
+ }
+ }
+}
+
+bool ImageView::IsPreMultipliedAlphaEnabled() const
+{
+ return mPremultipledAlphaEnabled;
+}
+
void ImageView::SetDepthIndex( int depthIndex )
{
- mRenderer.SetDepthIndex( depthIndex );
+ if( mRenderer )
+ {
+ mRenderer.SetDepthIndex( depthIndex );
+ }
}
Vector3 ImageView::GetNaturalSize()
size.x = mImageSize.GetWidth();
size.y = mImageSize.GetHeight();
- size.z = std::min(size.x, size.y);
if( size.x > 0 && size.y > 0 )
{
+ size.z = std::min(size.x, size.y);
return size;
}
else
}
}
+
///////////////////////////////////////////////////////////
//
// Private methods
Control::OnStageDisconnection();
}
-
///////////////////////////////////////////////////////////
//
// Properties
break;
}
+
+ case Toolkit::ImageView::Property::PRE_MULTIPLIED_ALPHA:
+ {
+ bool IsPre;
+ if( value.Get( IsPre ) )
+ {
+ GetImpl(imageView).EnablePreMultipliedAlpha( IsPre );
+ }
+ break;
+ }
}
}
}
if ( imageview )
{
+ ImageView& impl = GetImpl( imageview );
switch ( propertyIndex )
{
case Toolkit::ImageView::Property::RESOURCE_URL:
{
- ImageView& impl = GetImpl( imageview );
if ( !impl.mUrl.empty() )
{
value = impl.mUrl;
case Toolkit::ImageView::Property::IMAGE:
{
- ImageView& impl = GetImpl( imageview );
if ( !impl.mUrl.empty() )
{
value = impl.mUrl;
}
break;
}
+
+ case Toolkit::ImageView::Property::PRE_MULTIPLIED_ALPHA:
+ {
+ value = impl.IsPreMultipliedAlphaEnabled();
+ break;
+ }
}
}
{
class ImageView : public Control
{
- protected:
+protected:
/**
* Construct a new ImageView.
*/
virtual ~ImageView();
-
-
public:
/**
* Create a new ImageView.
*/
void SetImage( const std::string& imageUrl, ImageDimensions size );
+ /**
+ * @brief Set whether the Pre-multiplied Alpha Blending is required
+ *
+ * @param[in] preMultipled whether alpha is pre-multiplied.
+ */
+ void EnablePreMultipliedAlpha( bool preMultipled );
+
+ /**
+ * @brief Query whether alpha is pre-multiplied.
+ *
+ * @return True is alpha is pre-multiplied, false otherwise.
+ */
+ bool IsPreMultipliedAlphaEnabled() const;
+
// Properties
/**
* Called when a property of an object of this type is set.
virtual float GetWidthForHeight( float height );
private:
- /**
- * Attaches mImage member to the renderer, creating the renderers, samplers, meshes and materials if needed
- *
- * @pre mImage has been initialised
- */
- void AttachImage();
-
-private:
// Undefined
ImageView( const ImageView& );
ImageView& operator=( const ImageView& );
std::string mUrl; ///< the url for the image if the image came from a URL, empty otherwise
Image mImage; ///< the Image if the image came from a Image, null otherwise
Property::Map mPropertyMap; ///< the Property::Map if the image came from a Property::Map, empty otherwise
+
+ bool mPremultipledAlphaEnabled; ///< Flag indicating whether the Pre-multiplied Alpha Blending is required
};
} // namespace Internal
const char * const DONT_CARE("dontCare");
const std::string TEXTURE_UNIFORM_NAME = "sTexture";
-const std::string TEXTURE_RECT_UNIFORM_NAME = "uTextureRect";
+const std::string ATLAS_RECT_UNIFORM_NAME = "uAtlasRect";
+const std::string PIXEL_AREA_UNIFORM_NAME = "pixelArea";
+
+// Set this uniform to 1.0 for conventional alpha blending; if pre-multiplied alpha blending, set this uniform to 0.0
+const std::string ALPHA_BLENDING_UNIFORM_NAME = "uAlphaBlending";
+
const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
const char* VERTEX_SHADER = 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 vec4 uTextureRect;\n
+ uniform mediump vec4 uAtlasRect;\n
+ uniform mediump vec4 pixelArea;
+ varying mediump vec2 vTexCoord;\n
\n
void main()\n
{\n
vertexPosition.xyz *= uSize;\n
vertexPosition = uMvpMatrix * vertexPosition;\n
\n
- vTexCoord = mix( uTextureRect.xy, uTextureRect.zw, aPosition + vec2(0.5));\n
+ vTexCoord = mix( uAtlasRect.xy, uAtlasRect.zw, pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) ) );\n
gl_Position = vertexPosition;\n
}\n
);
varying mediump vec2 vTexCoord;\n
uniform sampler2D sTexture;\n
uniform lowp vec4 uColor;\n
+ uniform lowp float uAlphaBlending; // Set to 1.0 for conventional alpha blending; if pre-multiplied alpha blending, set to 0.0
\n
void main()\n
{\n
- gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
+ gl_FragColor = texture2D( sTexture, vTexCoord ) * vec4( uColor.rgb*max( uAlphaBlending, uColor.a ), uColor.a );\n
}\n
);
ImageRenderer::ImageRenderer( RendererFactoryCache& factoryCache, ImageAtlasManager& atlasManager )
: ControlRenderer( factoryCache ),
mAtlasManager( atlasManager ),
- mTextureRect( FULL_TEXTURE_RECT ),
mDesiredSize(),
mFittingMode( FittingMode::DEFAULT ),
- mSamplingMode( SamplingMode::DEFAULT )
+ mSamplingMode( SamplingMode::DEFAULT ),
+ mIsAlphaPreMultiplied( false )
{
}
shader = Shader::New( mImpl->mCustomShader->mVertexShader.empty() ? VERTEX_SHADER : mImpl->mCustomShader->mVertexShader,
mImpl->mCustomShader->mFragmentShader.empty() ? FRAGMENT_SHADER : mImpl->mCustomShader->mFragmentShader,
mImpl->mCustomShader->mHints );
+ if( mImpl->mCustomShader->mVertexShader.empty() )
+ {
+ shader.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT );
+ shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+ shader.RegisterProperty( ALPHA_BLENDING_UNIFORM_NAME, 1.f );
+ }
}
}
mImpl->mRenderer = mFactoryCache.GetRenderer( imageUrl );
if( !mImpl->mRenderer )
{
- Material material = mAtlasManager.Add(mTextureRect, imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
+ Vector4 atlasRect;
+ Material material = mAtlasManager.Add(atlasRect, imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
if( material )
{
Geometry geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
mImpl->mRenderer = Renderer::New( geometry, material );
- SetTextureRectUniform(mTextureRect);
+ mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, atlasRect );
}
else // big image, atlasing is not applied
{
mImpl->mRenderer = CreateRenderer();
- mTextureRect = FULL_TEXTURE_RECT;
- SetTextureRectUniform(mTextureRect);
- ResourceImage image = Dali::ResourceImage::New( imageUrl );
+ ResourceImage image = Dali::ResourceImage::New( imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
image.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
Material material = mImpl->mRenderer.GetMaterial();
material.AddTexture( image, TEXTURE_UNIFORM_NAME );
mFactoryCache.SaveRenderer( imageUrl, mImpl->mRenderer );
}
- else
- {
- Property::Value textureRect = mImpl->mRenderer.GetProperty( mImpl->mRenderer.GetPropertyIndex(TEXTURE_RECT_UNIFORM_NAME) );
- textureRect.Get( mTextureRect );
- }
+
mImpl->mFlags |= Impl::IS_FROM_CACHE;
}
else
ResourceImage resourceImage = Dali::ResourceImage::New( imageUrl, mDesiredSize, mFittingMode, mSamplingMode );
resourceImage.LoadingFinishedSignal().Connect( this, &ImageRenderer::OnImageLoaded );
ApplyImageToSampler( resourceImage );
-
- // custom vertex shader does not need texture rect uniform
- if( mImpl->mCustomShader && !mImpl->mCustomShader->mVertexShader.empty() )
- {
- return;
- }
-
- mTextureRect = FULL_TEXTURE_RECT;
- SetTextureRectUniform( mTextureRect );
}
}
{
ApplyImageToSampler( image );
}
-
- // default shader or custom shader with the default image vertex shader
- if( !mImpl->mCustomShader || mImpl->mCustomShader->mVertexShader.empty() )
- {
- mTextureRect = FULL_TEXTURE_RECT;
- SetTextureRectUniform( mTextureRect );
- }
}
{
InitializeRenderer( mImage );
}
+
+ EnablePreMultipliedAlpha( mIsAlphaPreMultiplied );
}
void ImageRenderer::DoSetOffStage( Actor& actor )
{
shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
factoryCache.SaveShader( RendererFactoryCache::IMAGE_SHADER, shader );
+ shader.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, FULL_TEXTURE_RECT );
+ shader.RegisterProperty( PIXEL_AREA_UNIFORM_NAME, FULL_TEXTURE_RECT );
+ shader.RegisterProperty( ALPHA_BLENDING_UNIFORM_NAME, 1.f );
}
return shader;
}
}
}
+void ImageRenderer::EnablePreMultipliedAlpha( bool preMultipled )
+{
+ mIsAlphaPreMultiplied = preMultipled;
+ if( mImpl->mRenderer )
+ {
+ Material material = mImpl->mRenderer.GetMaterial();
+
+ if( preMultipled )
+ {
+ material.SetBlendFunc( BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA,
+ BlendingFactor::ONE, BlendingFactor::ONE );
+ if( !mImpl->mCustomShader || mImpl->mCustomShader->mVertexShader.empty())
+ {
+ material.RegisterProperty( ALPHA_BLENDING_UNIFORM_NAME, 0.f );
+ }
+ }
+ else
+ {
+ // using default blend func
+ material.SetBlendFunc( BlendingFactor::SRC_ALPHA, BlendingFactor::ONE_MINUS_SRC_ALPHA,
+ BlendingFactor::ONE, BlendingFactor::ONE_MINUS_SRC_ALPHA );
+
+ Property::Index index = material.GetPropertyIndex( ALPHA_BLENDING_UNIFORM_NAME );
+ if( index != Property::INVALID_INDEX ) // only set value when the property already exist on the Material
+ {
+ material.SetProperty( index, 1.f );
+ }
+ }
+ }
+}
+
void ImageRenderer::ApplyImageToSampler( const Image& image )
{
if( image )
}
}
-void ImageRenderer::SetTextureRectUniform( const Vector4& textureRect )
+void ImageRenderer::CleanCache(const std::string& url)
{
- if( mImpl->mRenderer )
+ Material material = mImpl->mRenderer.GetMaterial();
+
+ Vector4 atlasRect( 0.f, 0.f, 1.f, 1.f );
+ Property::Index index = mImpl->mRenderer.GetPropertyIndex( ATLAS_RECT_UNIFORM_NAME );
+ if( index != Property::INVALID_INDEX )
{
- // Register/Set property.
- mImpl->mRenderer.RegisterProperty( TEXTURE_RECT_UNIFORM_NAME, textureRect );
+ Property::Value atlasRectValue = mImpl->mRenderer.GetProperty( index );
+ atlasRectValue.Get( atlasRect );
}
-}
-void ImageRenderer::CleanCache(const std::string& url)
-{
- Material material = mImpl->mRenderer.GetMaterial();
mImpl->mRenderer.Reset();
- if( mFactoryCache.CleanRendererCache( url ) )
+ if( mFactoryCache.CleanRendererCache( url ) && index != Property::INVALID_INDEX )
{
- mAtlasManager.Remove( material, mTextureRect );
+ mAtlasManager.Remove( material, atlasRect );
}
}
*/
void SetImage( Actor& actor, const Image& image );
+ /**
+ * @brief Set whether the Pre-multiplied Alpha Blending is required
+ *
+ * @param[in] preMultipled whether alpha is pre-multiplied.
+ */
+ void EnablePreMultipliedAlpha( bool preMultipled );
+
private:
/**
private:
Image mImage;
ImageAtlasManager& mAtlasManager;
- Vector4 mTextureRect;
std::string mImageUrl;
Dali::ImageDimensions mDesiredSize;
Dali::FittingMode::Type mFittingMode;
Dali::SamplingMode::Type mSamplingMode;
+ bool mIsAlphaPreMultiplied;
};
namespace // Unnamed namespace
{
-//Type registration
-
-DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ItemView, Toolkit::Scrollable, NULL)
-
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutPosition", FLOAT, LAYOUT_POSITION)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollSpeed", FLOAT, SCROLL_SPEED)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "overshoot", FLOAT, OVERSHOOT)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollDirection", VECTOR2, SCROLL_DIRECTION)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutOrientation", INTEGER, LAYOUT_ORIENTATION)
-DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollContentSize", FLOAT, SCROLL_CONTENT_SIZE)
-
-DALI_SIGNAL_REGISTRATION( Toolkit, ItemView, "layoutActivated", LAYOUT_ACTIVATED_SIGNAL )
-
-DALI_TYPE_REGISTRATION_END()
-
const float DEFAULT_MINIMUM_SWIPE_SPEED = 1.0f;
const float DEFAULT_MINIMUM_SWIPE_DISTANCE = 3.0f;
const float DEFAULT_WHEEL_SCROLL_DISTANCE_STEP_PROPORTION = 0.1f;
namespace // unnamed namespace
{
+//Type registration
+
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ItemView, Toolkit::Scrollable, NULL)
+
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "minimumSwipeSpeed", FLOAT, MINIMUM_SWIPE_SPEED )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "minimumSwipeDistance", FLOAT, MINIMUM_SWIPE_DISTANCE )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "wheelScrollDistanceStep", FLOAT, WHEEL_SCROLL_DISTANCE_STEP )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "snapToItemEnabled", BOOLEAN, SNAP_TO_ITEM_ENABLED )
+DALI_PROPERTY_REGISTRATION( Toolkit, ItemView, "refreshInterval", FLOAT, REFRESH_INTERVAL )
+
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutPosition", FLOAT, LAYOUT_POSITION)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollSpeed", FLOAT, SCROLL_SPEED)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "overshoot", FLOAT, OVERSHOOT)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollDirection", VECTOR2, SCROLL_DIRECTION)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "layoutOrientation", INTEGER, LAYOUT_ORIENTATION)
+DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ItemView, "scrollContentSize", FLOAT, SCROLL_CONTENT_SIZE)
+
+DALI_SIGNAL_REGISTRATION( Toolkit, ItemView, "layoutActivated", LAYOUT_ACTIVATED_SIGNAL )
+
+DALI_TYPE_REGISTRATION_END()
+
bool FindById( const ItemContainer& items, ItemId id )
{
for( ConstItemIter iter = items.begin(); items.end() != iter; ++iter )
return connected;
}
+void ItemView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+ Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( Dali::BaseHandle( object ) );
+
+ if( itemView )
+ {
+ ItemView& itemViewImpl( GetImpl( itemView ) );
+ switch( index )
+ {
+ case Toolkit::ItemView::Property::MINIMUM_SWIPE_SPEED:
+ {
+ itemViewImpl.SetMinimumSwipeSpeed( value.Get<float>() );
+ break;
+ }
+ case Toolkit::ItemView::Property::MINIMUM_SWIPE_DISTANCE:
+ {
+ itemViewImpl.SetMinimumSwipeDistance( value.Get<float>() );
+ break;
+ }
+ case Toolkit::ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP:
+ {
+ itemViewImpl.SetWheelScrollDistanceStep( value.Get<float>() );
+ break;
+ }
+ case Toolkit::ItemView::Property::SNAP_TO_ITEM_ENABLED:
+ {
+ itemViewImpl.SetAnchoring( value.Get<bool>() );
+ break;
+ }
+ case Toolkit::ItemView::Property::REFRESH_INTERVAL:
+ {
+ itemViewImpl.SetRefreshInterval( value.Get<float>() );
+ break;
+ }
+ }
+ }
+}
+
+Property::Value ItemView::GetProperty( BaseObject* object, Property::Index index )
+{
+ Property::Value value;
+
+ Toolkit::ItemView itemView = Toolkit::ItemView::DownCast( Dali::BaseHandle( object ) );
+
+ if( itemView )
+ {
+ ItemView& itemViewImpl( GetImpl( itemView ) );
+ switch( index )
+ {
+ case Toolkit::ItemView::Property::MINIMUM_SWIPE_SPEED:
+ {
+ value = itemViewImpl.GetMinimumSwipeSpeed();
+ break;
+ }
+ case Toolkit::ItemView::Property::MINIMUM_SWIPE_DISTANCE:
+ {
+ value = itemViewImpl.GetMinimumSwipeDistance();
+ break;
+ }
+ case Toolkit::ItemView::Property::WHEEL_SCROLL_DISTANCE_STEP:
+ {
+ value = itemViewImpl.GetWheelScrollDistanceStep();
+ break;
+ }
+ case Toolkit::ItemView::Property::SNAP_TO_ITEM_ENABLED:
+ {
+ value = itemViewImpl.GetAnchoring();
+ break;
+ }
+ case Toolkit::ItemView::Property::REFRESH_INTERVAL:
+ {
+ value = itemViewImpl.GetRefreshInterval();
+ break;
+ }
+ }
+ }
+
+ return value;
+}
+
} // namespace Internal
} // namespace Toolkit
*/
static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
+ //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.
+ */
+ static Property::Value GetProperty( BaseObject* object, Property::Index index );
+
private:
/**
// Setup properties, signals and actions using the type-registry.
DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ScrollView, Toolkit::Scrollable, Create )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "wrapEnabled", BOOLEAN, WRAP_ENABLED )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "panningEnabled", BOOLEAN, PANNING_ENABLED )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "axisAutoLockEnabled", BOOLEAN, AXIS_AUTO_LOCK_ENABLED )
+DALI_PROPERTY_REGISTRATION( Toolkit, ScrollView, "wheelScrollDistanceStep", VECTOR2, WHEEL_SCROLL_DISTANCE_STEP )
+
DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollPosition", VECTOR2, SCROLL_POSITION)
DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, ScrollView, "scrollPrePosition", VECTOR2, SCROLL_PRE_POSITION)
DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit, ScrollView, "scrollPrePositionX", SCROLL_PRE_POSITION_X, SCROLL_PRE_POSITION, 0)
}
}
+bool ScrollView::GetScrollSensitive()
+{
+ return mSensitive;
+}
+
void ScrollView::SetScrollSensitive(bool sensitive)
{
Actor self = Self();
mSnapOvershootAlphaFunction = alpha;
}
+float ScrollView::GetSnapOvershootDuration()
+{
+ return mSnapOvershootDuration;
+}
+
void ScrollView::SetSnapOvershootDuration(float duration)
{
mSnapOvershootDuration = duration;
}
+bool ScrollView::GetActorAutoSnap()
+{
+ return mActorAutoSnapEnabled;
+}
+
void ScrollView::SetActorAutoSnap(bool enable)
{
mActorAutoSnapEnabled = enable;
ApplyConstraintToBoundActors(constraint);
}
+void ScrollView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+ Toolkit::ScrollView scrollView = Toolkit::ScrollView::DownCast( Dali::BaseHandle( object ) );
+
+ if( scrollView )
+ {
+ ScrollView& scrollViewImpl( GetImpl( scrollView ) );
+ switch( index )
+ {
+ case Toolkit::ScrollView::Property::WRAP_ENABLED:
+ {
+ scrollViewImpl.SetWrapMode( value.Get<bool>() );
+ break;
+ }
+ case Toolkit::ScrollView::Property::PANNING_ENABLED:
+ {
+ scrollViewImpl.SetScrollSensitive( value.Get<bool>() );
+ break;
+ }
+ case Toolkit::ScrollView::Property::AXIS_AUTO_LOCK_ENABLED:
+ {
+ scrollViewImpl.SetAxisAutoLock( value.Get<bool>() );
+ break;
+ }
+ case Toolkit::ScrollView::Property::WHEEL_SCROLL_DISTANCE_STEP:
+ {
+ scrollViewImpl.SetWheelScrollDistanceStep( value.Get<Vector2>() );
+ break;
+ }
+ }
+ }
+}
+
+Property::Value ScrollView::GetProperty( BaseObject* object, Property::Index index )
+{
+ Property::Value value;
+
+ Toolkit::ScrollView scrollView = Toolkit::ScrollView::DownCast( Dali::BaseHandle( object ) );
+
+ if( scrollView )
+ {
+ ScrollView& scrollViewImpl( GetImpl( scrollView ) );
+ switch( index )
+ {
+ case Toolkit::ScrollView::Property::WRAP_ENABLED:
+ {
+ value = scrollViewImpl.GetWrapMode();
+ break;
+ }
+ case Toolkit::ScrollView::Property::PANNING_ENABLED:
+ {
+ value = scrollViewImpl.GetScrollSensitive();
+ break;
+ }
+ case Toolkit::ScrollView::Property::AXIS_AUTO_LOCK_ENABLED:
+ {
+ value = scrollViewImpl.GetAxisAutoLock();
+ break;
+ }
+ case Toolkit::ScrollView::Property::WHEEL_SCROLL_DISTANCE_STEP:
+ {
+ value = scrollViewImpl.GetWheelScrollDistanceStep();
+ break;
+ }
+ }
+ }
+
+ return value;
+}
+
} // namespace Internal
} // namespace Toolkit
void SetRulerY(RulerPtr ruler);
/**
+ * Retrieve the touch sensitivity.
+ *
+ * @return whether the touch sensitivity is true or false.
+ */
+ bool GetScrollSensitive();
+
+ /**
* @copydoc Toolkit::ScrollView::SetScrollSensitive
*/
void SetScrollSensitive(bool sensitive);
void SetSnapOvershootAlphaFunction(AlphaFunction alpha);
/**
+ * Retrieve the duartion of Snap Overshoot animation
+ *
+ * @return the duration.
+ */
+ float GetSnapOvershootDuration();
+
+ /**
* @copydoc Toolkit::ScrollView::SetSnapOvershootDuration
*/
void SetSnapOvershootDuration(float duration);
/**
+ * Retrieve whether Actor Auto-Snap mode is enabled or not.
+ *
+ * @return Actor Auto-Snap mode Enabled flag.
+ */
+ bool GetActorAutoSnap();
+
+ /**
* @copydoc Toolkit::ScrollView::SetActorAutoSnap
*/
void SetActorAutoSnap(bool enable);
*/
void SetOvershootEffectColor( const Vector4& color );
+ //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.
+ */
+ static Property::Value GetProperty( BaseObject* object, Property::Index index );
+
public: //Signals
/**
DALI_PROPERTY_REGISTRATION( Toolkit, Scrollable, "overshootEffectColor", VECTOR4, OVERSHOOT_EFFECT_COLOR )
DALI_PROPERTY_REGISTRATION( Toolkit, Scrollable, "overshootAnimationSpeed", FLOAT, OVERSHOOT_ANIMATION_SPEED )
-const int OVERSHOOT_SIZE = Dali::Toolkit::Scrollable::Property::OVERSHOOT_ANIMATION_SPEED + 1; // OVERSHOOT_SIZE is not public yet
+DALI_PROPERTY_REGISTRATION( Toolkit, Scrollable, "overshootEnabled", BOOLEAN, OVERSHOOT_ENABLED )
+const int OVERSHOOT_SIZE = Dali::Toolkit::Scrollable::Property::OVERSHOOT_ENABLED + 1; // OVERSHOOT_SIZE is not public yet
Dali::PropertyRegistration p1( typeRegistration, "overshootSize", OVERSHOOT_SIZE, Property::VECTOR2, Dali::Toolkit::Internal::Scrollable::SetProperty, Dali::Toolkit::Internal::Scrollable::GetProperty );
DALI_ANIMATABLE_PROPERTY_REGISTRATION( Toolkit, Scrollable, "scrollRelativePosition", VECTOR2, SCROLL_RELATIVE_POSITION)
scrollableImpl.SetOvershootAnimationSpeed( value.Get<float>() );
break;
}
+ case Toolkit::Scrollable::Property::OVERSHOOT_ENABLED:
+ {
+ scrollableImpl.SetOvershootEnabled( value.Get<bool>() );
+ break;
+ }
case OVERSHOOT_SIZE: // OVERSHOOT_SIZE is not public yet
{
Vector2 input;
value = scrollableImpl.GetOvershootAnimationSpeed();
break;
}
+ case Toolkit::Scrollable::Property::OVERSHOOT_ENABLED:
+ {
+ value = scrollableImpl.IsOvershootEnabled();
+ break;
+ }
case OVERSHOOT_SIZE: // OVERSHOOT_SIZE is not public yet
{
value = scrollableImpl.mOvershootSize;
--- /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/text-controls/text-editor-impl.h>
+
+// EXTERNAL INCLUDES
+#include <cstring>
+#include <limits>
+#include <dali/public-api/adaptor-framework/key.h>
+#include <dali/public-api/common/stage.h>
+#include <dali/public-api/images/resource-image.h>
+#include <dali/devel-api/adaptor-framework/virtual-keyboard.h>
+#include <dali/devel-api/object/type-registry-helper.h>
+#include <dali/integration-api/debug.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/text/rendering-backend.h>
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/internal/text/rendering/text-backend.h>
+#include <dali-toolkit/internal/text/text-font-style.h>
+#include <dali-toolkit/internal/text/text-view.h>
+#include <dali-toolkit/internal/styling/style-manager-impl.h>
+
+using namespace Dali::Toolkit::Text;
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace // unnamed namespace
+{
+
+#if defined(DEBUG_ENABLED)
+ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
+#endif
+
+ const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
+} // unnamed namespace
+
+namespace
+{
+
+const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
+{
+ { "BEGIN", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN },
+ { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
+ { "END", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END },
+};
+const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
+
+// Type registration
+BaseHandle Create()
+{
+ return Toolkit::TextEditor::New();
+}
+
+// Setup properties, signals and actions using the type-registry.
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextEditor, Toolkit::Control, Create );
+
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "renderingBackend", INTEGER, RENDERING_BACKEND )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "text", STRING, TEXT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "textColor", VECTOR4, TEXT_COLOR )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "fontFamily", STRING, FONT_FAMILY )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "fontStyle", STRING, FONT_STYLE )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "pointSize", FLOAT, POINT_SIZE )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "horizontalAlignment", STRING, HORIZONTAL_ALIGNMENT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "scrollThreshold", FLOAT, SCROLL_THRESHOLD )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "scrollSpeed", FLOAT, SCROLL_SPEED )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "primaryCursorColor", VECTOR4, PRIMARY_CURSOR_COLOR )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "secondaryCursorColor", VECTOR4, SECONDARY_CURSOR_COLOR )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableCursorBlink", BOOLEAN, ENABLE_CURSOR_BLINK )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "cursorBlinkInterval", FLOAT, CURSOR_BLINK_INTERVAL )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "cursorBlinkDuration", FLOAT, CURSOR_BLINK_DURATION )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "cursorWidth", INTEGER, CURSOR_WIDTH )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "grabHandleImage", STRING, GRAB_HANDLE_IMAGE )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "grabHandlePressedImage", STRING, GRAB_HANDLE_PRESSED_IMAGE )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandleImageLeft", MAP, SELECTION_HANDLE_IMAGE_LEFT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandleImageRight", MAP, SELECTION_HANDLE_IMAGE_RIGHT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandlePressedImageLeft", MAP, SELECTION_HANDLE_PRESSED_IMAGE_LEFT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandlePressedImageRight", MAP, SELECTION_HANDLE_PRESSED_IMAGE_RIGHT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandleMarkerImageLeft", MAP, SELECTION_HANDLE_MARKER_IMAGE_LEFT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHandleMarkerImageRight", MAP, SELECTION_HANDLE_MARKER_IMAGE_RIGHT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "selectionHighlightColor", VECTOR4, SELECTION_HIGHLIGHT_COLOR )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "decorationBoundingBox", RECTANGLE, DECORATION_BOUNDING_BOX )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "enableMarkup", BOOLEAN, ENABLE_MARKUP )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputColor", VECTOR4, INPUT_COLOR )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputFontFamily", STRING, INPUT_FONT_FAMILY )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputFontStyle", STRING, INPUT_FONT_STYLE )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextEditor, "inputPointSize", FLOAT, INPUT_POINT_SIZE )
+
+DALI_SIGNAL_REGISTRATION( Toolkit, TextEditor, "textChanged", SIGNAL_TEXT_CHANGED )
+
+DALI_TYPE_REGISTRATION_END()
+
+} // namespace
+
+Toolkit::TextEditor TextEditor::New()
+{
+ // Create the implementation, temporarily owned by this handle on stack
+ IntrusivePtr< TextEditor > impl = new TextEditor();
+
+ // Pass ownership to CustomActor handle
+ Toolkit::TextEditor handle( *impl );
+
+ // Second-phase init of the implementation
+ // This can only be done after the CustomActor connection has been made...
+ impl->Initialize();
+
+ return handle;
+}
+
+void TextEditor::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
+{
+ Toolkit::TextEditor textEditor = Toolkit::TextEditor::DownCast( Dali::BaseHandle( object ) );
+
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor SetProperty\n");
+
+
+ if( textEditor )
+ {
+ TextEditor& impl( GetImpl( textEditor ) );
+
+ switch( index )
+ {
+ case Toolkit::TextEditor::Property::RENDERING_BACKEND:
+ {
+ int backend = value.Get< int >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p RENDERING_BACKEND %d\n", impl.mController.Get(), backend );
+
+ if( impl.mRenderingBackend != backend )
+ {
+ impl.mRenderingBackend = backend;
+ impl.mRenderer.Reset();
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::TEXT:
+ {
+ if( impl.mController )
+ {
+ const std::string text = value.Get< std::string >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p TEXT %s\n", impl.mController.Get(), text.c_str() );
+
+ impl.mController->SetText( text );
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::TEXT_COLOR:
+ {
+ if( impl.mController )
+ {
+ const Vector4 textColor = value.Get< Vector4 >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
+
+ if( impl.mController->GetTextColor() != textColor )
+ {
+ impl.mController->SetTextColor( textColor );
+ impl.mController->SetInputColor( textColor );
+ impl.mRenderer.Reset();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::FONT_FAMILY:
+ {
+ if( impl.mController )
+ {
+ const std::string fontFamily = value.Get< std::string >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
+ impl.mController->SetDefaultFontFamily( fontFamily );
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::FONT_STYLE:
+ {
+ SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
+ break;
+ }
+ case Toolkit::TextEditor::Property::POINT_SIZE:
+ {
+ if( impl.mController )
+ {
+ const float pointSize = value.Get< float >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p POINT_SIZE %f\n", impl.mController.Get(), pointSize );
+
+ if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
+ {
+ impl.mController->SetDefaultPointSize( pointSize );
+ }
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
+ {
+ if( impl.mController )
+ {
+ const std::string alignStr = value.Get< std::string >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p HORIZONTAL_ALIGNMENT %s\n", impl.mController.Get(), alignStr.c_str() );
+
+ LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
+ if( Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
+ HORIZONTAL_ALIGNMENT_STRING_TABLE,
+ HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
+ alignment ) )
+ {
+ impl.mController->SetHorizontalAlignment( alignment );
+ }
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
+ {
+ const float threshold = value.Get< float >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold );
+
+ if( impl.mDecorator )
+ {
+ impl.mDecorator->SetScrollThreshold( threshold );
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SCROLL_SPEED:
+ {
+ const float speed = value.Get< float >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p SCROLL_SPEED %f\n", impl.mController.Get(), speed );
+
+ if( impl.mDecorator )
+ {
+ impl.mDecorator->SetScrollSpeed( speed );
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
+ {
+ if( impl.mDecorator )
+ {
+ const Vector4 color = value.Get< Vector4 >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+
+ impl.mDecorator->SetCursorColor( PRIMARY_CURSOR, color );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
+ {
+ if( impl.mDecorator )
+ {
+ const Vector4 color = value.Get< Vector4 >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+
+ impl.mDecorator->SetCursorColor( SECONDARY_CURSOR, color );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
+ {
+ if( impl.mController )
+ {
+ const bool enable = value.Get< bool >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable );
+
+ impl.mController->SetEnableCursorBlink( enable );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
+ {
+ if( impl.mDecorator )
+ {
+ const float interval = value.Get< float >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval );
+
+ impl.mDecorator->SetCursorBlinkInterval( interval );
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
+ {
+ if( impl.mDecorator )
+ {
+ const float duration = value.Get< float >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_BLINK_DURATION %f\n", impl.mController.Get(), duration );
+
+ impl.mDecorator->SetCursorBlinkDuration( duration );
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::CURSOR_WIDTH:
+ {
+ if( impl.mDecorator )
+ {
+ const int width = value.Get< int >();
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p CURSOR_WIDTH %d\n", impl.mController.Get(), width );
+
+ impl.mDecorator->SetCursorWidth( width );
+ impl.mController->GetLayoutEngine().SetCursorWidth( width );
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
+ {
+ const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), image.GetUrl().c_str() );
+
+ if( impl.mDecorator )
+ {
+ impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED, image );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE:
+ {
+ const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), image.GetUrl().c_str() );
+
+ if( impl.mDecorator )
+ {
+ impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED, image );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
+ {
+ const Image image = Scripting::NewImage( value );
+
+ if( impl.mDecorator && image )
+ {
+ impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT:
+ {
+ const Image image = Scripting::NewImage( value );
+
+ if( impl.mDecorator && image )
+ {
+ impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
+ {
+ const Image image = Scripting::NewImage( value );
+
+ if( impl.mDecorator && image )
+ {
+ impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, image );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
+ {
+ const Image image = Scripting::NewImage( value );
+
+ if( impl.mDecorator && image )
+ {
+ impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, image );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
+ {
+ const Image image = Scripting::NewImage( value );
+
+ if( impl.mDecorator && image )
+ {
+ impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, image );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
+ {
+ const Image image = Scripting::NewImage( value );
+
+ if( impl.mDecorator && image )
+ {
+ impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED, image );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR:
+ {
+ const Vector4 color = value.Get< Vector4 >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p SELECTION_HIGHLIGHT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
+
+ if( impl.mDecorator )
+ {
+ impl.mDecorator->SetHighlightColor( color );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
+ {
+ if( impl.mDecorator )
+ {
+ const Rect<int> box = value.Get< Rect<int> >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height );
+
+ impl.mDecorator->SetBoundingBox( box );
+ impl.RequestTextRelayout();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::ENABLE_MARKUP:
+ {
+ if( impl.mController )
+ {
+ const bool enableMarkup = value.Get<bool>();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p ENABLE_MARKUP %d\n", impl.mController.Get(), enableMarkup );
+
+ impl.mController->SetMarkupProcessorEnabled( enableMarkup );
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_COLOR:
+ {
+ if( impl.mController )
+ {
+ const Vector4 inputColor = value.Get< Vector4 >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), inputColor.r, inputColor.g, inputColor.b, inputColor.a );
+
+ impl.mController->SetInputColor( inputColor );
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
+ {
+ if( impl.mController )
+ {
+ const std::string fontFamily = value.Get< std::string >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
+ impl.mController->SetInputFontFamily( fontFamily );
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
+ {
+ SetFontStyleProperty( impl.mController, value, Text::FontStyle::INPUT );
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
+ {
+ if( impl.mController )
+ {
+ const float pointSize = value.Get< float >();
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_POINT_SIZE %f\n", impl.mController.Get(), pointSize );
+ impl.mController->SetInputFontPointSize( pointSize );
+ }
+ break;
+ }
+ } // switch
+ } // texteditor
+}
+
+Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index index )
+{
+ Property::Value value;
+
+ Toolkit::TextEditor textEditor = Toolkit::TextEditor::DownCast( Dali::BaseHandle( object ) );
+
+ if( textEditor )
+ {
+ TextEditor& impl( GetImpl( textEditor ) );
+
+ switch( index )
+ {
+ case Toolkit::TextEditor::Property::RENDERING_BACKEND:
+ {
+ value = impl.mRenderingBackend;
+ break;
+ }
+ case Toolkit::TextEditor::Property::TEXT:
+ {
+ if( impl.mController )
+ {
+ std::string text;
+ impl.mController->GetText( text );
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p returning text: %s\n", impl.mController.Get(), text.c_str() );
+ value = text;
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::TEXT_COLOR:
+ {
+ if ( impl.mController )
+ {
+ value = impl.mController->GetTextColor();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::FONT_FAMILY:
+ {
+ if( impl.mController )
+ {
+ value = impl.mController->GetDefaultFontFamily();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::FONT_STYLE:
+ {
+ GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
+ break;
+ }
+ case Toolkit::TextEditor::Property::POINT_SIZE:
+ {
+ if( impl.mController )
+ {
+ value = impl.mController->GetDefaultPointSize();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::HORIZONTAL_ALIGNMENT:
+ {
+ if( impl.mController )
+ {
+ const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
+ HORIZONTAL_ALIGNMENT_STRING_TABLE,
+ HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+ if( name )
+ {
+ value = std::string( name );
+ }
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SCROLL_THRESHOLD:
+ {
+ if( impl.mDecorator )
+ {
+ value = impl.mDecorator->GetScrollThreshold();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SCROLL_SPEED:
+ {
+ if( impl.mDecorator )
+ {
+ value = impl.mDecorator->GetScrollSpeed();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::PRIMARY_CURSOR_COLOR:
+ {
+ if( impl.mDecorator )
+ {
+ value = impl.mDecorator->GetColor( PRIMARY_CURSOR );
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SECONDARY_CURSOR_COLOR:
+ {
+ if( impl.mDecorator )
+ {
+ value = impl.mDecorator->GetColor( SECONDARY_CURSOR );
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::ENABLE_CURSOR_BLINK:
+ {
+ value = impl.mController->GetEnableCursorBlink();
+ break;
+ }
+ case Toolkit::TextEditor::Property::CURSOR_BLINK_INTERVAL:
+ {
+ if( impl.mDecorator )
+ {
+ value = impl.mDecorator->GetCursorBlinkInterval();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::CURSOR_BLINK_DURATION:
+ {
+ if( impl.mDecorator )
+ {
+ value = impl.mDecorator->GetCursorBlinkDuration();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::CURSOR_WIDTH:
+ {
+ if( impl.mDecorator )
+ {
+ value = impl.mDecorator->GetCursorWidth();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::GRAB_HANDLE_IMAGE:
+ {
+ if( impl.mDecorator )
+ {
+ ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED ) );
+ if( image )
+ {
+ value = image.GetUrl();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::GRAB_HANDLE_PRESSED_IMAGE:
+ {
+ if( impl.mDecorator )
+ {
+ ResourceImage image = ResourceImage::DownCast( impl.mDecorator->GetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED ) );
+ if( image )
+ {
+ value = image.GetUrl();
+ }
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_LEFT:
+ {
+ impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED );
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_IMAGE_RIGHT:
+ {
+ impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED ) ;
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
+ {
+ impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED );
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
+ {
+ impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED );
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_LEFT:
+ {
+ impl.GetHandleImagePropertyValue( value, LEFT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED );
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HANDLE_MARKER_IMAGE_RIGHT:
+ {
+ impl.GetHandleImagePropertyValue( value, RIGHT_SELECTION_HANDLE_MARKER, HANDLE_IMAGE_RELEASED );
+ break;
+ }
+ case Toolkit::TextEditor::Property::SELECTION_HIGHLIGHT_COLOR:
+ {
+ if( impl.mDecorator )
+ {
+ value = impl.mDecorator->GetHighlightColor();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::DECORATION_BOUNDING_BOX:
+ {
+ if( impl.mDecorator )
+ {
+ Rect<int> boundingBox;
+ impl.mDecorator->GetBoundingBox( boundingBox );
+ value = boundingBox;
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::ENABLE_MARKUP:
+ {
+ if( impl.mController )
+ {
+ value = impl.mController->IsMarkupProcessorEnabled();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_COLOR:
+ {
+ if( impl.mController )
+ {
+ value = impl.mController->GetInputColor();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_FONT_FAMILY:
+ {
+ if( impl.mController )
+ {
+ value = impl.mController->GetInputFontFamily();
+ }
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_FONT_STYLE:
+ {
+ GetFontStyleProperty( impl.mController, value, Text::FontStyle::INPUT );
+ break;
+ }
+ case Toolkit::TextEditor::Property::INPUT_POINT_SIZE:
+ {
+ if( impl.mController )
+ {
+ value = impl.mController->GetInputFontPointSize();
+ }
+ break;
+ }
+ } //switch
+ }
+
+ return value;
+}
+
+bool TextEditor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
+{
+ Dali::BaseHandle handle( object );
+
+ bool connected( true );
+ Toolkit::TextEditor editor = Toolkit::TextEditor::DownCast( handle );
+
+ if( 0 == strcmp( signalName.c_str(), SIGNAL_TEXT_CHANGED ) )
+ {
+ editor.TextChangedSignal().Connect( tracker, functor );
+ }
+ else
+ {
+ // signalName does not match any signal
+ connected = false;
+ }
+
+ return connected;
+}
+
+Toolkit::TextEditor::TextChangedSignalType& TextEditor::TextChangedSignal()
+{
+ return mTextChangedSignal;
+}
+
+void TextEditor::OnInitialize()
+{
+ Actor self = Self();
+
+ mController = Text::Controller::New( *this );
+
+ mDecorator = Text::Decorator::New( *mController,
+ *mController );
+
+ mController->GetLayoutEngine().SetLayout( LayoutEngine::MULTI_LINE_BOX );
+
+ mController->EnableTextInput( mDecorator );
+
+ mController->SetMaximumNumberOfCharacters( std::numeric_limits<Length>::max() );
+
+ // Forward input events to controller
+ EnableGestureDetection( static_cast<Gesture::Type>( Gesture::Tap | Gesture::Pan | Gesture::LongPress ) );
+ GetTapGestureDetector().SetMaximumTapsRequired( 2 );
+
+ self.TouchedSignal().Connect( this, &TextEditor::OnTouched );
+
+ // Set BoundingBox to stage size if not already set.
+ Rect<int> boundingBox;
+ mDecorator->GetBoundingBox( boundingBox );
+
+ if( boundingBox.IsEmpty() )
+ {
+ Vector2 stageSize = Dali::Stage::GetCurrent().GetSize();
+ mDecorator->SetBoundingBox( Rect<int>( 0.0f, 0.0f, stageSize.width, stageSize.height ) );
+ }
+
+ // Flip vertically the 'left' selection handle
+ mDecorator->FlipHandleVertically( LEFT_SELECTION_HANDLE, true );
+
+ // Fill-parent area by default
+ self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
+ self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
+ self.OnStageSignal().Connect( this, &TextEditor::OnStageConnect );
+}
+
+void TextEditor::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnStyleChange\n");
+
+ switch ( change )
+ {
+ case StyleChange::DEFAULT_FONT_CHANGE:
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnStyleChange DEFAULT_FONT_CHANGE\n");
+ std::string newFont = styleManager.GetDefaultFontFamily();
+ // Property system did not set the font so should update it.
+ mController->UpdateAfterFontChange( newFont );
+ break;
+ }
+
+ case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor::OnStyleChange StyleChange::DEFAULT_FONT_SIZE_CHANGE (%f)\n", mController->GetDefaultPointSize() );
+
+ if ( (mController->GetDefaultPointSize() <= 0.0f) ) // If DefaultPointSize not set by Property system it will be 0.0f
+ {
+ // Property system did not set the PointSize so should update it.
+ // todo instruct text-controller to update model
+ }
+ break;
+ }
+ case StyleChange::THEME_CHANGE:
+ {
+ GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
+ break;
+ }
+ }
+}
+
+Vector3 TextEditor::GetNaturalSize()
+{
+ return mController->GetNaturalSize();
+}
+
+float TextEditor::GetHeightForWidth( float width )
+{
+ return mController->GetHeightForWidth( width );
+}
+
+void TextEditor::OnRelayout( const Vector2& size, RelayoutContainer& container )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor OnRelayout\n");
+
+ if( mController->Relayout( size ) ||
+ !mRenderer )
+ {
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnRelayout %p Displaying new contents\n", mController.Get() );
+
+ if( mDecorator )
+ {
+ mDecorator->Relayout( size );
+ }
+
+ if( !mRenderer )
+ {
+ mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
+ }
+
+ EnableClipping( true, size );
+ RenderText();
+ }
+}
+
+void TextEditor::RenderText()
+{
+ Actor self = Self();
+ Actor renderableActor;
+ if( mRenderer )
+ {
+ renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT );
+ }
+
+ if( renderableActor != mRenderableActor )
+ {
+ UnparentAndReset( mRenderableActor );
+ mRenderableActor = renderableActor;
+ }
+
+ if( mRenderableActor )
+ {
+ const Vector2 offset = mController->GetScrollPosition() + mController->GetAlignmentOffset();
+
+ mRenderableActor.SetPosition( offset.x, offset.y );
+
+ Actor clipRootActor;
+ if( mClipper )
+ {
+ clipRootActor = mClipper->GetRootActor();
+ }
+
+ for( std::vector<Actor>::const_iterator it = mClippingDecorationActors.begin(),
+ endIt = mClippingDecorationActors.end();
+ it != endIt;
+ ++it )
+ {
+ Actor actor = *it;
+
+ if( clipRootActor )
+ {
+ clipRootActor.Add( actor );
+ }
+ else
+ {
+ self.Add( actor );
+ }
+ }
+ mClippingDecorationActors.clear();
+
+ // Make sure the actor is parented correctly with/without clipping
+ if( clipRootActor )
+ {
+ clipRootActor.Add( mRenderableActor );
+ }
+ else
+ {
+ self.Add( mRenderableActor );
+ }
+ }
+}
+
+void TextEditor::OnKeyInputFocusGained()
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnKeyInputFocusGained %p\n", mController.Get() );
+
+ VirtualKeyboard::StatusChangedSignal().Connect( this, &TextEditor::KeyboardStatusChanged );
+
+ ImfManager imfManager = ImfManager::Get();
+
+ if ( imfManager )
+ {
+ imfManager.EventReceivedSignal().Connect( this, &TextEditor::OnImfEvent );
+
+ // Notify that the text editing start.
+ imfManager.Activate();
+
+ // When window gain lost focus, the imf manager is deactivated. Thus when window gain focus again, the imf manager must be activated.
+ imfManager.SetRestoreAfterFocusLost( true );
+ }
+
+ ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
+
+ if ( notifier )
+ {
+ notifier.ContentSelectedSignal().Connect( this, &TextEditor::OnClipboardTextSelected );
+ }
+
+ mController->KeyboardFocusGainEvent(); // Called in the case of no virtual keyboard to trigger this event
+
+ EmitKeyInputFocusSignal( true ); // Calls back into the Control hence done last.
+}
+
+void TextEditor::OnKeyInputFocusLost()
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor:OnKeyInputFocusLost %p\n", mController.Get() );
+
+ VirtualKeyboard::StatusChangedSignal().Disconnect( this, &TextEditor::KeyboardStatusChanged );
+
+ ImfManager imfManager = ImfManager::Get();
+ if ( imfManager )
+ {
+ // The text editing is finished. Therefore the imf manager don't have restore activation.
+ imfManager.SetRestoreAfterFocusLost( false );
+
+ // Notify that the text editing finish.
+ imfManager.Deactivate();
+
+ imfManager.EventReceivedSignal().Disconnect( this, &TextEditor::OnImfEvent );
+ }
+
+ ClipboardEventNotifier notifier( ClipboardEventNotifier::Get() );
+
+ if ( notifier )
+ {
+ notifier.ContentSelectedSignal().Disconnect( this, &TextEditor::OnClipboardTextSelected );
+ }
+
+ mController->KeyboardFocusLostEvent();
+
+ EmitKeyInputFocusSignal( false ); // Calls back into the Control hence done last.
+}
+
+void TextEditor::OnTap( const TapGesture& gesture )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnTap %p\n", mController.Get() );
+
+ // Show the keyboard if it was hidden.
+ if (!VirtualKeyboard::IsVisible())
+ {
+ VirtualKeyboard::Show();
+ }
+
+ // Deliver the tap before the focus event to controller; this allows us to detect when focus is gained due to tap-gestures
+ mController->TapEvent( gesture.numberOfTaps, gesture.localPoint.x, gesture.localPoint.y );
+
+ SetKeyInputFocus();
+}
+
+void TextEditor::OnPan( const PanGesture& gesture )
+{
+ mController->PanEvent( gesture.state, gesture.displacement );
+}
+
+void TextEditor::OnLongPress( const LongPressGesture& gesture )
+{
+ // Show the keyboard if it was hidden.
+ if (!VirtualKeyboard::IsVisible())
+ {
+ VirtualKeyboard::Show();
+ }
+
+ mController->LongPressEvent( gesture.state, gesture.localPoint.x, gesture.localPoint.y );
+
+ SetKeyInputFocus();
+}
+
+bool TextEditor::OnKeyEvent( const KeyEvent& event )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnKeyEvent %p keyCode %d\n", mController.Get(), event.keyCode );
+
+ if( Dali::DALI_KEY_ESCAPE == event.keyCode ) // Make a Dali key code for this
+ {
+ ClearKeyInputFocus();
+ return true;
+ }
+
+ return mController->KeyEvent( event );
+}
+
+void TextEditor::AddDecoration( Actor& actor, bool needsClipping )
+{
+ if( actor )
+ {
+ if( needsClipping )
+ {
+ mClippingDecorationActors.push_back( actor );
+ }
+ else
+ {
+ Self().Add( actor );
+ }
+ }
+}
+
+void TextEditor::RequestTextRelayout()
+{
+ RelayoutRequest();
+}
+
+void TextEditor::TextChanged()
+{
+ Dali::Toolkit::TextEditor handle( GetOwner() );
+ mTextChangedSignal.Emit( handle );
+}
+
+void TextEditor::MaxLengthReached()
+{
+ // Nothing to do as TextEditor doesn't emit a max length reached signal.
+}
+
+void TextEditor::OnStageConnect( Dali::Actor actor )
+{
+ if ( mHasBeenStaged )
+ {
+ RenderText();
+ }
+ else
+ {
+ mHasBeenStaged = true;
+ }
+}
+
+ImfManager::ImfCallbackData TextEditor::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
+ return mController->OnImfEvent( imfManager, imfEvent );
+}
+
+void TextEditor::GetHandleImagePropertyValue( Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType )
+{
+ if( mDecorator )
+ {
+ ResourceImage image = ResourceImage::DownCast( mDecorator->GetHandleImage( handleType, handleImageType ) );
+
+ if ( image )
+ {
+ Property::Map map;
+ Scripting::CreatePropertyMap( image, map );
+ value = map;
+ }
+ }
+}
+
+void TextEditor::EnableClipping( bool clipping, const Vector2& size )
+{
+ if( clipping )
+ {
+ // Not worth to created clip actor if width or height is equal to zero.
+ if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
+ {
+ if( !mClipper )
+ {
+ Actor self = Self();
+
+ mClipper = Clipper::New( size );
+ self.Add( mClipper->GetRootActor() );
+ self.Add( mClipper->GetImageActor() );
+ }
+ else if ( mClipper )
+ {
+ mClipper->Refresh( size );
+ }
+ }
+ }
+ else
+ {
+ // Note - this will automatically remove the root & image actors
+ mClipper.Reset();
+ }
+}
+
+void TextEditor::OnClipboardTextSelected( ClipboardEventNotifier& clipboard )
+{
+ mController->PasteClipboardItemEvent();
+}
+
+void TextEditor::KeyboardStatusChanged(bool keyboardShown)
+{
+ DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextEditor::KeyboardStatusChanged %p keyboardShown %d\n", mController.Get(), keyboardShown );
+
+ // Just hide the grab handle when keyboard is hidden.
+ if (!keyboardShown )
+ {
+ mController->KeyboardFocusLostEvent();
+ }
+ else
+ {
+ mController->KeyboardFocusGainEvent(); // Initially called by OnKeyInputFocusGained
+ }
+}
+
+void TextEditor::OnStageConnection( int depth )
+{
+ // Call the Control::OnStageConnection() to set the depth of the background.
+ Control::OnStageConnection( depth );
+
+ // Sets the depth to the renderers inside the text's decorator.
+ mDecorator->SetTextDepth( depth );
+
+ // The depth of the text renderer is set in the RenderText() called from OnRelayout().
+}
+
+bool TextEditor::OnTouched( Actor actor, const TouchEvent& event )
+{
+ return true;
+}
+
+TextEditor::TextEditor()
+: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
+ mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
+ mHasBeenStaged( false )
+{
+}
+
+TextEditor::~TextEditor()
+{
+ mClipper.Reset();
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H__
+#define __DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/control-impl.h>
+#include <dali-toolkit/devel-api/controls/text-controls/text-editor.h>
+#include <dali-toolkit/internal/text/clipping/text-clipper.h>
+#include <dali-toolkit/internal/text/decorator/text-decorator.h>
+#include <dali-toolkit/internal/text/text-control-interface.h>
+#include <dali-toolkit/internal/text/text-controller.h>
+#include <dali-toolkit/internal/text/rendering/text-renderer.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+/**
+ * @brief A control which renders a long text string with styles.
+ */
+class TextEditor : public Control, public Text::ControlInterface
+{
+public:
+
+ /**
+ * @copydoc Dali::Toollkit::TextEditor::New()
+ */
+ static Toolkit::TextEditor New();
+
+ // Properties
+
+ /**
+ * @brief 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 );
+
+ /**
+ * @brief 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.
+ */
+ static Property::Value GetProperty( BaseObject* object, Property::Index index );
+
+ /**
+ * Connects a callback function with the object's signals.
+ * @param[in] object The object providing the signal.
+ * @param[in] tracker Used to disconnect the signal.
+ * @param[in] signalName The signal to connect to.
+ * @param[in] functor A newly allocated FunctorDelegate.
+ * @return True if the signal was connected.
+ * @post If a signal was connected, ownership of functor was passed to CallbackBase. Otherwise the caller is responsible for deleting the unused functor.
+ */
+ static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor );
+
+ /**
+ * @copydoc TextEditor::TextChangedSignal()
+ */
+ Toolkit::TextEditor::TextChangedSignalType& TextChangedSignal();
+
+private: // From Control
+
+ /**
+ * @copydoc Control::OnInitialize()
+ */
+ virtual void OnInitialize();
+
+ /**
+ * @copydoc Control::OnStyleChange()
+ */
+ virtual void OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change );
+
+ /**
+ * @copydoc Control::GetNaturalSize()
+ */
+ virtual Vector3 GetNaturalSize();
+
+ /**
+ * @copydoc Control::GetHeightForWidth()
+ */
+ virtual float GetHeightForWidth( float width );
+
+ /**
+ * @copydoc Control::OnInitialize()
+ */
+ virtual void OnRelayout( const Vector2& size, RelayoutContainer& container );
+
+ /**
+ * @copydoc Control::OnKeyInputFocusGained()
+ */
+ virtual void OnKeyInputFocusGained();
+
+ /**
+ * @copydoc Control::OnKeyInputFocusLost()
+ */
+ virtual void OnKeyInputFocusLost();
+
+ /**
+ * @copydoc Control::OnTap()
+ */
+ virtual void OnTap( const TapGesture& tap );
+
+ /**
+ * @copydoc Control::OnPan()
+ */
+ virtual void OnPan( const PanGesture& gesture );
+
+ /**
+ * @copydoc Control::OnLongPress()
+ */
+ virtual void OnLongPress( const LongPressGesture& gesture );
+
+ /**
+ * @copydoc Control::OnStageConnection()
+ */
+ virtual void OnStageConnection( int depth );
+
+ /**
+ * @copydoc Dali::CustomActorImpl::OnKeyEvent(const KeyEvent&)
+ */
+ virtual bool OnKeyEvent(const KeyEvent& event);
+
+// From ControlInterface
+
+ /**
+ * @copydoc Text::ControlInterface::AddDecoration()
+ */
+ virtual void AddDecoration( Actor& actor, bool needsClipping );
+
+ /**
+ * @copydoc Text::ControlInterface::RequestTextRelayout()
+ */
+ virtual void RequestTextRelayout();
+
+ /**
+ * @copydoc Text::ControlInterface::TextChanged()
+ */
+ virtual void TextChanged();
+
+ /**
+ * @copydoc Text::ControlInterface::MaxLengthReached()
+ */
+ virtual void MaxLengthReached();
+
+private: // Implementation
+
+ /**
+ * @copydoc Dali::Toolkit::Text::Controller::(ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent)
+ */
+ ImfManager::ImfCallbackData OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent );
+
+ /**
+ * @brief Callback when Clipboard signals an item should be pasted
+ * @param[in] clipboard handle to Clipboard Event Notifier
+ */
+ void OnClipboardTextSelected( ClipboardEventNotifier& clipboard );
+
+ /**
+ * @brief Get a Property Map for the image used for the required Handle Image
+ * @param[out] value the returned image property
+ * @param[in] handleType the type of handle
+ * @param[in] handleImageType the type of image for the given handleType
+ */
+ void GetHandleImagePropertyValue( Property::Value& value, Text::HandleType handleType, Text::HandleImageType handleImageType );
+
+ /**
+ * @brief Enable or disable clipping.
+ *
+ * @param[in] clipping True if clipping should be enabled.
+ * @param[in] size The area to clip within.
+ */
+ void EnableClipping( bool clipping, const Vector2& size );
+
+ /**
+ * @brief Callback when keyboard is shown/hidden.
+ *
+ * @param[in] keyboardShown True if keyboard is shown.
+ */
+ void KeyboardStatusChanged( bool keyboardShown );
+
+ /**
+ * @brief Callback when TextEditor is touched
+ *
+ * @param[in] actor TextEditor touched
+ * @param[in] event TouchEvent information
+ */
+ bool OnTouched( Actor actor, const TouchEvent& event );
+
+ /**
+ * Construct a new TextEditor.
+ */
+ TextEditor();
+
+ /**
+ * A reference counted object may only be deleted by calling Unreference()
+ */
+ virtual ~TextEditor();
+
+ // Undefined copy constructor and assignment operators
+ TextEditor(const TextEditor&);
+ TextEditor& operator=(const TextEditor& rhs);
+
+ /**
+ * @brief Render view, create and attach actor(s) to this text editor.
+ */
+ void RenderText();
+
+ // Connection needed to re-render text, when a text editor returns to the stage.
+ void OnStageConnect( Dali::Actor actor );
+
+private: // Data
+
+ // Signals
+ Toolkit::TextEditor::TextChangedSignalType mTextChangedSignal;
+
+ Text::ControllerPtr mController;
+ Text::RendererPtr mRenderer;
+ Text::DecoratorPtr mDecorator;
+ Text::ClipperPtr mClipper;
+ std::vector<Actor> mClippingDecorationActors; ///< Decoration actors which need clipping.
+
+ Actor mRenderableActor;
+
+ int mRenderingBackend;
+ bool mHasBeenStaged:1;
+};
+
+} // namespace Internal
+
+// Helpers for public-api forwarding methods
+
+inline Toolkit::Internal::TextEditor& GetImpl( Toolkit::TextEditor& textEditor )
+{
+ DALI_ASSERT_ALWAYS(textEditor);
+
+ Dali::RefObject& handle = textEditor.GetImplementation();
+
+ return static_cast<Toolkit::Internal::TextEditor&>(handle);
+}
+
+inline const Toolkit::Internal::TextEditor& GetImpl( const Toolkit::TextEditor& textEditor )
+{
+ DALI_ASSERT_ALWAYS(textEditor);
+
+ const Dali::RefObject& handle = textEditor.GetImplementation();
+
+ return static_cast<const Toolkit::Internal::TextEditor&>(handle);
+}
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // __DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H__
*/
virtual bool OnKeyEvent(const KeyEvent& event);
+// From ControlInterface
+
/**
* @copydoc Text::ControlInterface::AddDecoration()
*/
*/
virtual void MaxLengthReached();
+private: // Implementation
+
/**
* @copydoc Dali::Toolkit::Text::Controller::(ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent)
*/
*/
void OnClipboardTextSelected( ClipboardEventNotifier& clipboard );
-private: // Implementation
-
/**
* @brief Get a Property Map for the image used for the required Handle Image
* @param[out] value the returned image property
void KeyboardStatusChanged( bool keyboardShown );
/**
- * @brief Callback when Textfield is touched
+ * @brief Callback when TextField is touched
*
* @param[in] actor TextField touched
* @param[in] event TouchEvent information
$(toolkit_src_dir)/controls/slider/slider-impl.cpp \
$(toolkit_src_dir)/controls/super-blur-view/super-blur-view-impl.cpp \
$(toolkit_src_dir)/controls/table-view/table-view-impl.cpp \
+ $(toolkit_src_dir)/controls/text-controls/text-editor-impl.cpp \
$(toolkit_src_dir)/controls/text-controls/text-field-impl.cpp \
$(toolkit_src_dir)/controls/text-controls/text-label-impl.cpp \
$(toolkit_src_dir)/controls/text-controls/text-selection-popup-impl.cpp \
: mOrientationDegrees( 0 ), // Portrait
mDefaultFontSize( -1 ),
mDefaultFontFamily(""),
- mThemeFile( DEFAULT_THEME ),
mFeedbackStyle( NULL )
{
// Add theme builder constants
// Sound & haptic style
mFeedbackStyle = new FeedbackStyle();
-
}
StyleManager::~StyleManager()
mOrientationDegrees = orientation;
// TODO: if orientation changed, apply the new style to all controls
// dont want to really do the whole load from file again if the bundle contains both portrait & landscape
- SetTheme();
+ SetTheme( mThemeFile );
}
}
}
}
-std::string StyleManager::GetDefaultFontFamily() const
+Orientation StyleManager::GetOrientation()
{
- return mDefaultFontFamily;
+ return mOrientation;
}
-Orientation StyleManager::GetOrientation()
+std::string StyleManager::GetDefaultFontFamily() const
{
- return mOrientation;
+ return mDefaultFontFamily;
}
void StyleManager::SetStyleConstant( const std::string& key, const Property::Value& value )
return false;
}
-void StyleManager::OnOrientationChanged( Orientation orientation )
+void StyleManager::RequestThemeChange( const std::string& themeFile )
{
- mOrientation = orientation;
- // TODO: if orientation changed, apply the new style to all controls
- // dont want to really do the whole load from file again if the bundle contains both portrait & landscape
- SetTheme();
+ SetTheme( themeFile );
+}
+
+void StyleManager::RequestDefaultTheme()
+{
+ std::string empty;
+ SetTheme( empty );
+}
+
+void StyleManager::ApplyThemeStyle( Toolkit::Control control )
+{
+ if( !mThemeBuilder )
+ {
+ RequestDefaultTheme();
+ }
+
+ if( mThemeBuilder )
+ {
+ ApplyStyle( mThemeBuilder, control );
+ }
+}
+
+void StyleManager::ApplyThemeStyleAtInit( Toolkit::Control control )
+{
+ ApplyThemeStyle( control );
+
+ if(mFeedbackStyle)
+ {
+ mFeedbackStyle->ObjectCreated( control );
+ }
+}
+
+void StyleManager::ApplyStyle( Toolkit::Control control, const std::string& jsonFileName, const std::string& styleName )
+{
+ bool builderReady = false;
+
+ // First look in the cache
+ Toolkit::Builder builder = FindCachedBuilder( jsonFileName );
+ if( builder )
+ {
+ builderReady = true;
+ }
+ else
+ {
+ // Merge theme and style constants
+ Property::Map constants( mThemeBuilderConstants );
+ constants.Merge( mStyleBuilderConstants );
+
+ // Create it
+ builder = CreateBuilder( constants );
+
+ if( LoadJSON( builder, jsonFileName ) )
+ {
+ CacheBuilder( builder, jsonFileName );
+ builderReady = true;
+ }
+ }
+
+ // Apply the style to the control
+ if( builderReady )
+ {
+ builder.ApplyStyle( styleName, control );
+ }
+}
+
+Toolkit::StyleManager::StyleChangeSignalType& StyleManager::StyleChangeSignal()
+{
+ return mStyleChangeSignal;
+}
+
+void StyleManager::SetTheme( const std::string& themeFile )
+{
+ bool themeLoaded = false;
+
+ mThemeBuilder = CreateBuilder( mThemeBuilderConstants );
+
+ // Always load the default theme first, then merge in the custom theme if present
+ themeLoaded = LoadJSON( mThemeBuilder, DEFAULT_THEME );
+
+ if( ! themeFile.empty() )
+ {
+ mThemeFile = themeFile;
+ themeLoaded = LoadJSON( mThemeBuilder, mThemeFile );
+ }
+
+ if( themeLoaded )
+ {
+ if(mFeedbackStyle)
+ {
+ mFeedbackStyle->StyleChanged( mThemeFile, StyleChange::THEME_CHANGE );
+ }
+
+ mStyleChangeSignal.Emit( Toolkit::StyleManager::Get(), StyleChange::THEME_CHANGE );
+ }
+ else
+ {
+ mThemeBuilder.Reset();
+ }
+}
+
+bool StyleManager::LoadFile( const std::string& filename, std::string& stringOut )
+{
+ DALI_ASSERT_DEBUG( 0 != filename.length());
+
+ // as toolkit is platform agnostic, it cannot load files from filesystem
+ // ask style monitor to load the style sheet
+ if( mStyleMonitor )
+ {
+ return mStyleMonitor.LoadThemeFile( filename, stringOut );
+ }
+
+ return false;
}
Toolkit::Builder StyleManager::CreateBuilder( const Property::Map& constants )
}
}
-void StyleManager::ApplyThemeStyle( Toolkit::Control control )
-{
- if( !mThemeBuilder )
- {
- RequestDefaultTheme();
- }
-
- if( mThemeBuilder )
- {
- ApplyStyle( mThemeBuilder, control );
- }
-}
-
-void StyleManager::ApplyThemeStyleAtInit( Toolkit::Control control )
-{
- ApplyThemeStyle( control );
-
- if(mFeedbackStyle)
- {
- mFeedbackStyle->ObjectCreated( control );
- }
-}
-
-void StyleManager::ApplyStyle( Toolkit::Control control, const std::string& jsonFileName, const std::string& styleName )
-{
- bool builderReady = false;
-
- // First look in the cache
- Toolkit::Builder builder = FindCachedBuilder( jsonFileName );
- if( builder )
- {
- builderReady = true;
- }
- else
- {
- // Merge theme and style constants
- Property::Map constants( mThemeBuilderConstants );
- constants.Merge( mStyleBuilderConstants );
-
- // Create it
- builder = CreateBuilder( constants );
-
- if( LoadJSON( builder, jsonFileName ) )
- {
- CacheBuilder( builder, jsonFileName );
- builderReady = true;
- }
- }
-
- // Apply the style to the control
- if( builderReady )
- {
- builder.ApplyStyle( styleName, control );
- }
-}
-
-bool StyleManager::LoadFile( const std::string& filename, std::string& stringOut )
-{
- DALI_ASSERT_DEBUG( 0 != filename.length());
-
- // as toolkit is platform agnostic, it cannot load files from filesystem
- // ask style monitor to load the style sheet
- if( mStyleMonitor )
- {
- return mStyleMonitor.LoadThemeFile( filename, stringOut );
- }
-
- return false;
-}
-
-Toolkit::StyleManager::StyleChangeSignalType& StyleManager::StyleChangeSignal()
-{
- return mStyleChangeSignal;
-}
-
-void StyleManager::RequestThemeChange( const std::string& themeFile )
-{
- mThemeFile = themeFile;
-
- // need to do style change synchronously as app might create a UI control on the next line
- SetTheme();
-}
-
-void StyleManager::RequestDefaultTheme()
+void StyleManager::OnOrientationChanged( Orientation orientation )
{
- RequestThemeChange( DEFAULT_THEME );
+ mOrientation = orientation;
+ // TODO: if orientation changed, apply the new style to all controls
+ // dont want to really do the whole load from file again if the bundle contains both portrait & landscape
+ SetTheme( mThemeFile );
}
-void StyleManager::SetTheme()
-{
- mThemeBuilder = CreateBuilder( mThemeBuilderConstants );
-
- if( LoadJSON( mThemeBuilder, mThemeFile ) )
- {
- if(mFeedbackStyle)
- {
- mFeedbackStyle->StyleChanged( mThemeFile, StyleChange::THEME_CHANGE );
- }
-
- mStyleChangeSignal.Emit( Toolkit::StyleManager::Get(), StyleChange::THEME_CHANGE );
- }
- else
- {
- mThemeBuilder.Reset();
- }
-}
Toolkit::Builder StyleManager::FindCachedBuilder( const std::string& key )
{
case StyleChange::THEME_CHANGE:
{
- const std::string& newTheme = styleMonitor.GetTheme();
- if( ! newTheme.empty() )
- {
- mThemeFile = newTheme;
- }
- else
- {
- mThemeFile = DEFAULT_THEME;
- }
-
- SetTheme();
+ SetTheme( styleMonitor.GetTheme() );
break;
}
}
class StyleManager : public Dali::BaseObject, public ConnectionTracker
{
public:
-
/**
* Singleton access
*
*/
StyleManager();
+protected:
+ /**
+ * @brief Destructor
+ */
+ virtual ~StyleManager();
+
+public: // Public API
+
/**
* @copydoc Toolkit::StyleManager::SetOrientationValue
*/
void RequestDefaultTheme();
/**
- * Determine if a theme change has been requested
- * @return Whether a theme request is pending
- */
- bool IsThemeRequestPending();
-
- /**
* @brief Apply the theme style to a control.
*
* @param[in] control The control to apply style.
*/
Toolkit::StyleManager::StyleChangeSignalType& StyleChangeSignal();
-protected:
-
- /**
- * @brief Destructor
- */
- virtual ~StyleManager();
-
-
-public:
+private:
+ typedef std::vector<std::string> StringList;
/**
* @brief Set the current theme. Called only once per event processing cycle.
+ * @param[in] themeFile The name of the theme file to read.
*/
- void SetTheme();
-
-private:
-
- typedef std::vector<std::string> StringList;
+ void SetTheme( const std::string& themeFile );
/**
* @brief Internal helper method to read a file from file system.
int mOrientationDegrees; ///< Directly set value of orientation
int mDefaultFontSize; ///< Logical size, not a point-size
-
std::string mDefaultFontFamily;
-
std::string mThemeFile; ///< The full path of the current theme file
Property::Map mThemeBuilderConstants; ///< Contants to give the theme builder
} // namespace Dali
#endif // __DALI_TOOLKIT_INTERNAL_STYLE_MANAGER_H__
-
HandleImpl& grabHandle = mHandle[GRAB_HANDLE];
if( !grabHandle.actor )
{
- grabHandle.actor = ImageView::New( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] );
- GetImpl( grabHandle.actor).SetDepthIndex( DepthIndex::DECORATION );
- grabHandle.actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
- // Area that Grab handle responds to, larger than actual handle so easier to move
-#ifdef DECORATOR_DEBUG
- grabHandle.actor.SetName( "GrabHandleActor" );
- if ( Dali::Internal::gLogFilter->IsEnabledFor( Debug::Verbose ) )
- {
- grabHandle.grabArea = Control::New();
- Toolkit::Control control = Toolkit::Control::DownCast( grabHandle.grabArea );
- control.SetBackgroundColor( Vector4( 1.0f, 1.0f, 1.0f, 0.5f ) );
- grabHandle.grabArea.SetName( "GrabArea" );
- }
- else
+ if( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] )
{
- grabHandle.grabArea = Actor::New();
- grabHandle.grabArea.SetName( "GrabArea" );
- }
+ grabHandle.actor = ImageView::New( mHandleImages[GRAB_HANDLE][HANDLE_IMAGE_RELEASED] );
+ GetImpl( grabHandle.actor).SetDepthIndex( DepthIndex::DECORATION );
+ grabHandle.actor.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+
+ // Area that Grab handle responds to, larger than actual handle so easier to move
+#ifdef DECORATOR_DEBUG
+ grabHandle.actor.SetName( "GrabHandleActor" );
+ if ( Dali::Internal::gLogFilter->IsEnabledFor( Debug::Verbose ) )
+ {
+ grabHandle.grabArea = Control::New();
+ Toolkit::Control control = Toolkit::Control::DownCast( grabHandle.grabArea );
+ control.SetBackgroundColor( Vector4( 1.0f, 1.0f, 1.0f, 0.5f ) );
+ grabHandle.grabArea.SetName( "GrabArea" );
+ }
+ else
+ {
+ grabHandle.grabArea = Actor::New();
+ grabHandle.grabArea.SetName( "GrabArea" );
+ }
#else
- grabHandle.grabArea = Actor::New();
+ grabHandle.grabArea = Actor::New();
#endif
- grabHandle.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
- grabHandle.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
- grabHandle.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
- grabHandle.grabArea.SetSizeModeFactor( DEFAULT_GRAB_HANDLE_RELATIVE_SIZE );
- grabHandle.actor.Add( grabHandle.grabArea );
- grabHandle.actor.SetColor( mHandleColor );
+ grabHandle.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
+ grabHandle.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ grabHandle.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
+ grabHandle.grabArea.SetSizeModeFactor( DEFAULT_GRAB_HANDLE_RELATIVE_SIZE );
+ grabHandle.actor.Add( grabHandle.grabArea );
+ grabHandle.actor.SetColor( mHandleColor );
- grabHandle.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnGrabHandleTouched );
- mTapDetector.Attach( grabHandle.grabArea );
- mPanGestureDetector.Attach( grabHandle.grabArea );
+ grabHandle.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnGrabHandleTouched );
+ mTapDetector.Attach( grabHandle.grabArea );
+ mPanGestureDetector.Attach( grabHandle.grabArea );
- mActiveLayer.Add( grabHandle.actor );
+ mActiveLayer.Add( grabHandle.actor );
+ }
}
- if( !grabHandle.actor.GetParent() )
+ if( grabHandle.actor && !grabHandle.actor.GetParent() )
{
mActiveLayer.Add( grabHandle.actor );
}
HandleImpl& primary = mHandle[ LEFT_SELECTION_HANDLE ];
if( !primary.actor )
{
- primary.actor = ImageView::New( mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] );
+ if( mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] )
+ {
+ primary.actor = ImageView::New( mHandleImages[LEFT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] );
#ifdef DECORATOR_DEBUG
- primary.actor.SetName("SelectionHandleOne");
+ primary.actor.SetName("SelectionHandleOne");
#endif
- primary.actor.SetAnchorPoint( AnchorPoint::TOP_RIGHT ); // Change to BOTTOM_RIGHT if Look'n'Feel requires handle above text.
- GetImpl( primary.actor ).SetDepthIndex( DepthIndex::DECORATION );
- primary.actor.SetColor( mHandleColor );
+ primary.actor.SetAnchorPoint( AnchorPoint::TOP_RIGHT ); // Change to BOTTOM_RIGHT if Look'n'Feel requires handle above text.
+ GetImpl( primary.actor ).SetDepthIndex( DepthIndex::DECORATION );
+ primary.actor.SetColor( mHandleColor );
- primary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
+ primary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
#ifdef DECORATOR_DEBUG
- primary.grabArea.SetName("SelectionHandleOneGrabArea");
+ primary.grabArea.SetName("SelectionHandleOneGrabArea");
#endif
- primary.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
- primary.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
- primary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
- primary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
+ primary.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
+ primary.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
+ primary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ primary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
- mTapDetector.Attach( primary.grabArea );
- mPanGestureDetector.Attach( primary.grabArea );
- primary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleOneTouched );
+ mTapDetector.Attach( primary.grabArea );
+ mPanGestureDetector.Attach( primary.grabArea );
+ primary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleOneTouched );
- primary.actor.Add( primary.grabArea );
+ primary.actor.Add( primary.grabArea );
- CreateHandleMarker( primary, mHandleImages[LEFT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], LEFT_SELECTION_HANDLE );
+ CreateHandleMarker( primary, mHandleImages[LEFT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], LEFT_SELECTION_HANDLE );
+ }
}
- if( !primary.actor.GetParent() )
+ if( primary.actor && !primary.actor.GetParent() )
{
mActiveLayer.Add( primary.actor );
}
HandleImpl& secondary = mHandle[ RIGHT_SELECTION_HANDLE ];
if( !secondary.actor )
{
- secondary.actor = ImageView::New( mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] );
+ if( mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] )
+ {
+ secondary.actor = ImageView::New( mHandleImages[RIGHT_SELECTION_HANDLE][HANDLE_IMAGE_RELEASED] );
#ifdef DECORATOR_DEBUG
- secondary.actor.SetName("SelectionHandleTwo");
+ secondary.actor.SetName("SelectionHandleTwo");
#endif
- secondary.actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); // Change to BOTTOM_LEFT if Look'n'Feel requires handle above text.
- GetImpl( secondary.actor ).SetDepthIndex( DepthIndex::DECORATION );
- secondary.actor.SetColor( mHandleColor );
+ secondary.actor.SetAnchorPoint( AnchorPoint::TOP_LEFT ); // Change to BOTTOM_LEFT if Look'n'Feel requires handle above text.
+ GetImpl( secondary.actor ).SetDepthIndex( DepthIndex::DECORATION );
+ secondary.actor.SetColor( mHandleColor );
- secondary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
+ secondary.grabArea = Actor::New(); // Area that Grab handle responds to, larger than actual handle so easier to move
#ifdef DECORATOR_DEBUG
- secondary.grabArea.SetName("SelectionHandleTwoGrabArea");
+ secondary.grabArea.SetName("SelectionHandleTwoGrabArea");
#endif
- secondary.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
- secondary.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
- secondary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
- secondary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
+ secondary.grabArea.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
+ secondary.grabArea.SetParentOrigin( ParentOrigin::TOP_CENTER );
+ secondary.grabArea.SetAnchorPoint( AnchorPoint::TOP_CENTER );
+ secondary.grabArea.SetSizeModeFactor( DEFAULT_SELECTION_HANDLE_RELATIVE_SIZE );
- mTapDetector.Attach( secondary.grabArea );
- mPanGestureDetector.Attach( secondary.grabArea );
- secondary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleTwoTouched );
+ mTapDetector.Attach( secondary.grabArea );
+ mPanGestureDetector.Attach( secondary.grabArea );
+ secondary.grabArea.TouchedSignal().Connect( this, &Decorator::Impl::OnHandleTwoTouched );
- secondary.actor.Add( secondary.grabArea );
+ secondary.actor.Add( secondary.grabArea );
- CreateHandleMarker( secondary, mHandleImages[RIGHT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], RIGHT_SELECTION_HANDLE );
+ CreateHandleMarker( secondary, mHandleImages[RIGHT_SELECTION_HANDLE_MARKER][HANDLE_IMAGE_RELEASED], RIGHT_SELECTION_HANDLE );
+ }
}
- if( !secondary.actor.GetParent() )
+ if( secondary.actor && !secondary.actor.GetParent() )
{
mActiveLayer.Add( secondary.actor );
}
// The SetGrabHandleImage() method will change the orientation.
const float yLocalPosition = grabHandle.verticallyFlipped ? grabHandle.position.y : grabHandle.position.y + grabHandle.lineHeight;
- grabHandle.actor.SetPosition( grabHandle.position.x + floor( 0.5f * mCursorWidth ),
- yLocalPosition ); // TODO : Fix for multiline.
+ if( grabHandle.actor )
+ {
+ grabHandle.actor.SetPosition( grabHandle.position.x + floor( 0.5f * mCursorWidth ),
+ yLocalPosition ); // TODO : Fix for multiline.
+ }
}
void SetSelectionHandlePosition( HandleType type )
if( flipHandle )
{
- if( !handle.horizontallyFlipped )
+ if( handle.actor && !handle.horizontallyFlipped )
{
// Change the anchor point to flip the image.
handle.actor.SetAnchorPoint( isPrimaryHandle ? AnchorPoint::TOP_LEFT : AnchorPoint::TOP_RIGHT );
}
else
{
- if( handle.horizontallyFlipped )
+ if( handle.actor && handle.horizontallyFlipped )
{
// Reset the anchor point.
handle.actor.SetAnchorPoint( isPrimaryHandle ? AnchorPoint::TOP_RIGHT : AnchorPoint::TOP_LEFT );
// The SetHandleImage() method will change the orientation.
const float yLocalPosition = handle.verticallyFlipped ? handle.position.y : handle.position.y + handle.lineHeight;
- handle.actor.SetPosition( handle.position.x,
- yLocalPosition ); // TODO : Fix for multiline.
+ if( handle.actor )
+ {
+ handle.actor.SetPosition( handle.position.x,
+ yLocalPosition ); // TODO : Fix for multiline.
+ }
}
void SetHandleImage( HandleType type )
mController.DecorationEvent( type, HANDLE_RELEASED, x, y );
}
- handle.actor.SetImage( mHandleImages[type][HANDLE_IMAGE_RELEASED] );
+ if( handle.actor )
+ {
+ handle.actor.SetImage( mHandleImages[type][HANDLE_IMAGE_RELEASED] );
+ }
handle.pressed = false;
mHandlePanning = false;
);
const char* FRAGMENT_SHADER_L8 = MAKE_SHADER(
+uniform lowp vec4 uColor;
uniform sampler2D sTexture;
varying mediump vec2 vTexCoord;
varying mediump vec4 vColor;
void main()
{
mediump vec4 color = texture2D( sTexture, vTexCoord );
- gl_FragColor = vec4( vColor.rgb, vColor.a * color.r );
+ gl_FragColor = vec4( vColor.rgb * uColor.rgb, vColor.a * uColor.a * color.r );
}
);
}
}
-void Controller::SetMaximumNumberOfCharacters( int maxCharacters )
+void Controller::SetMaximumNumberOfCharacters( Length maxCharacters )
{
- if( maxCharacters >= 0 )
- {
- mImpl->mMaximumNumberOfCharacters = maxCharacters;
- }
+ mImpl->mMaximumNumberOfCharacters = maxCharacters;
}
int Controller::GetMaximumNumberOfCharacters()
*
* @param[in] maxCharacters maximum number of characters to be accepted
*/
- void SetMaximumNumberOfCharacters( int maxCharacters );
+ void SetMaximumNumberOfCharacters( Length maxCharacters );
/**
* @brief Sets the maximum number of characters that can be inserted into the TextModel
enum PropertyRange
{
PROPERTY_START_INDEX = Control::CONTROL_PROPERTY_END_INDEX + 1,
- PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000 ///< Reserve property indices
+ PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000, ///< Reserve property indices
+
+ ANIMATABLE_PROPERTY_START_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX, ///< @since DALi 1.1.18
+ ANIMATABLE_PROPERTY_END_INDEX = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 1000 ///< Reserve animatable property indices, @since DALi 1.1.18
};
/**
{
enum
{
+ // Event side properties
RESOURCE_URL = PROPERTY_START_INDEX, ///< name "resourceUrl", @deprecated DALi 1.1.16 Use IMAGE instead. type string
IMAGE, ///< name "image", @see SetImage(), type string if it is a url, map otherwise
+ PRE_MULTIPLIED_ALPHA, ///< name "preMultipliedAlpha", @since DALi 1.1.18 type Boolean @pre image must be initialized.
+
+ // Animatable properties
+ PIXEL_AREA = ANIMATABLE_PROPERTY_START_INDEX, ///< name "pixelArea", @since DALi 1.1.18 type Vector4, Pixel area is a relative value with the whole image area as [0.0, 0.0, 1.0, 1.0].
};
};
enum PropertyRange
{
+ PROPERTY_START_INDEX = Toolkit::Scrollable::PROPERTY_END_INDEX + 1, ///< @since DALi 1.1.18
+ PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000, ///< Reserve property indices, @since DALi 1.1.18
+
ANIMATABLE_PROPERTY_START_INDEX = Toolkit::Scrollable::ANIMATABLE_PROPERTY_END_INDEX + 1,
ANIMATABLE_PROPERTY_END_INDEX = ANIMATABLE_PROPERTY_START_INDEX + 1000 ///< Reserve animatable property indices
};
{
enum
{
- LAYOUT_POSITION = ANIMATABLE_PROPERTY_START_INDEX, ///< Property, name "layoutPosition", type float
- SCROLL_SPEED, ///< Property, name "scrollSpeed", type float
- OVERSHOOT, ///< Property, name "overshoot", type float
- SCROLL_DIRECTION, ///< Property, name "scrollDirection", type Vector2
- LAYOUT_ORIENTATION, ///< Property, name "layoutOrientation", type integer
- SCROLL_CONTENT_SIZE ///< Property, name "scrollContentSize", type float
+ // Event side properties
+ MINIMUM_SWIPE_SPEED = PROPERTY_START_INDEX, ///< Property, name "minimumSwipeSpeed", @see SetMinimumSwipeSpeed(), type float, @since DALi 1.1.18
+ MINIMUM_SWIPE_DISTANCE, ///< Property, name "minimumSwipeDistance", @see SetMinimumSwipeDistance(), type float, @since DALi 1.1.18
+ WHEEL_SCROLL_DISTANCE_STEP, ///< Property, name "wheelScrollDistanceStep", @see SetWheelScrollDistanceStep(), type float, @since DALi 1.1.18
+ SNAP_TO_ITEM_ENABLED, ///< Property, name "snapToItemEnabled", @see SetAnchoring(), type bool, @since DALi 1.1.18
+ REFRESH_INTERVAL, ///< Property, name "refreshInterval", @see SetRefreshInterval(), type float, @since DALi 1.1.18
+
+ // Animatable properties
+ LAYOUT_POSITION = ANIMATABLE_PROPERTY_START_INDEX, ///< Property, name "layoutPosition", type float
+ SCROLL_SPEED, ///< Property, name "scrollSpeed", type float
+ OVERSHOOT, ///< Property, name "overshoot", type float
+ SCROLL_DIRECTION, ///< Property, name "scrollDirection", type Vector2
+ LAYOUT_ORIENTATION, ///< Property, name "layoutOrientation", type integer
+ SCROLL_CONTENT_SIZE ///< Property, name "scrollContentSize", type float
};
};
*/
enum PropertyRange
{
+ PROPERTY_START_INDEX = Toolkit::Scrollable::PROPERTY_END_INDEX + 1, ///< @since DALi 1.1.18
+ PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000, ///< Reserve property indices, @since DALi 1.1.18
+
ANIMATABLE_PROPERTY_START_INDEX = Toolkit::Scrollable::ANIMATABLE_PROPERTY_END_INDEX + 1,
ANIMATABLE_PROPERTY_END_INDEX = ANIMATABLE_PROPERTY_START_INDEX + 1000 ///< Reserve animatable property indices
};
{
enum
{
+ // Event side properties
+ WRAP_ENABLED = PROPERTY_START_INDEX, ///< Property, name "wrapEnabled", @see SetWrapMode(), type bool, @since DALi 1.1.18
+ PANNING_ENABLED, ///< Property, name "panningEnabled", @see SetScrollSensitive(), type bool, @since DALi 1.1.18
+ AXIS_AUTO_LOCK_ENABLED, ///< Property, name "axisAutoLockEnabled", @see SetAxisAutoLock(), type bool, @since DALi 1.1.18
+ WHEEL_SCROLL_DISTANCE_STEP, ///< Property, name "wheelScrollDistanceStep", @see SetWheelScrollDistanceStep(), type Vector2, @since DALi 1.1.18
+
SCROLL_POSITION = ANIMATABLE_PROPERTY_START_INDEX, ///< Property, name "scrollPosition", type Vector2
SCROLL_PRE_POSITION, ///< Property, name "scrollPrePosition", type Vector2
SCROLL_PRE_POSITION_X, ///< Property, name "scrollPrePositionX", type float
// Event side properties
OVERSHOOT_EFFECT_COLOR = PROPERTY_START_INDEX, ///< Property, name "overshootEffectColor", @see SetOvershootEffectColor(), type Vector4
OVERSHOOT_ANIMATION_SPEED, ///< Property, name "overshootAnimationSpeed", @see SetOvershootAnimationSpeed(), type float
+ OVERSHOOT_ENABLED, ///< Property, name "overshootEnabled", @see SetOvershootEnabled(), type bool, @since DALi 1.1.18
// Animatable properties
SCROLL_RELATIVE_POSITION = ANIMATABLE_PROPERTY_START_INDEX, ///< Property, name "scrollRelativePosition", type Vector2
};
/**
- * @brief An enumeration of properties belonging to the TextLabel class.
+ * @brief An enumeration of properties belonging to the TextField class.
*/
struct Property
{
enum
{
- RENDERING_BACKEND = PROPERTY_START_INDEX, ///< name "renderingBackend", The type or rendering e.g. bitmap-based, type INT
- TEXT, ///< name "text", The text to display in UTF-8 format, type STRING
- PLACEHOLDER_TEXT, ///< name "placeholderText", The text to display when the TextField is empty and inactive, type STRING
- PLACEHOLDER_TEXT_FOCUSED, ///< name "placeholderTextFocused", The text to display when the TextField is empty with key-input focus, type STRING
- FONT_FAMILY, ///< name "fontFamily", The requested font family, type STRING
- FONT_STYLE, ///< name "fontStyle", The requested font style, type STRING
- POINT_SIZE, ///< name "pointSize", The size of font in points, type FLOAT
- MAX_LENGTH, ///< name "maxLength" The maximum number of characters that can be inserted, type INTEGER
- EXCEED_POLICY, ///< name "exceedPolicy" Specifies how the text is truncated when it does not fit, type INTEGER
- HORIZONTAL_ALIGNMENT, ///< name "horizontalAlignment", The line horizontal alignment, type STRING, values "BEGIN", "CENTER", "END"
- VERTICAL_ALIGNMENT, ///< name "verticalAlignment", The line vertical alignment, type STRING, values "TOP", "CENTER", "BOTTOM"
- TEXT_COLOR, ///< name "textColor", The text color, type VECTOR4
- PLACEHOLDER_TEXT_COLOR, ///< name "placeholderTextColor", The placeholder-text color, type VECTOR4
- SHADOW_OFFSET, ///< name "shadowOffset", The drop shadow offset 0 indicates no shadow, type VECTOR2
- SHADOW_COLOR, ///< name "shadowColor", The color of a drop shadow, type VECTOR4
- PRIMARY_CURSOR_COLOR, ///< name "primaryCursorColor", The color to apply to the primary cursor, type VECTOR4
- SECONDARY_CURSOR_COLOR, ///< name "secondaryCursorColor", The color to apply to the secondary cursor, type VECTOR4
- ENABLE_CURSOR_BLINK, ///< name "enableCursorBlink", Whether the cursor should blink or not, type BOOLEAN
- CURSOR_BLINK_INTERVAL, ///< name "cursorBlinkInterval", The time interval in seconds between cursor on/off states, type FLOAT
- CURSOR_BLINK_DURATION, ///< name "cursorBlinkDuration", The cursor will stop blinking after this number of seconds (if non-zero), type FLOAT
- CURSOR_WIDTH, ///< name "cursorWidth", The cursor width, type INTEGER
- GRAB_HANDLE_IMAGE, ///< name "grabHandleImage", The image to display for the grab handle, type STRING
- GRAB_HANDLE_PRESSED_IMAGE, ///< name "grabHandlePressedImage", The image to display when the grab handle is pressed, type STRING
- SCROLL_THRESHOLD, ///< name "scrollThreshold" Scrolling will occur if the cursor is this close to the control border, type FLOAT
- SCROLL_SPEED, ///< name "scrollSpeed" The scroll speed in pixels per second, type FLOAT
- SELECTION_HANDLE_IMAGE_LEFT, ///< name "selectionHandleImageLeft", The image to display for the left selection handle, type MAP
- SELECTION_HANDLE_IMAGE_RIGHT, ///< name "selectionHandleImageRight", The image to display for the right selection handle, type MAP
- SELECTION_HANDLE_PRESSED_IMAGE_LEFT, ///< name "selectionHandlePressedImageLeft", The image to display when the left selection handle is pressed, type MAP
- SELECTION_HANDLE_PRESSED_IMAGE_RIGHT, ///< name "selectionHandlePressedImageRight", The image to display when the right selection handle is pressed, type MAP
- SELECTION_HANDLE_MARKER_IMAGE_LEFT, ///< name "selectionHandleMarkerImageLeft", The image to display for the left selection handle marker, type MAP
- SELECTION_HANDLE_MARKER_IMAGE_RIGHT, ///< name "selectionHandleMarkerImageRight", The image to display for the right selection handle marker, type MAP
- SELECTION_HIGHLIGHT_COLOR, ///< name "selectionHighlightColor", The color of the selection highlight, type VECTOR4
- DECORATION_BOUNDING_BOX, ///< name "decorationBoundingBox", The decorations (handles etc) will positioned within this area on-screen, type RECTANGLE
- INPUT_METHOD_SETTINGS, ///< name "inputMethodSettings", The settings to relating to the System's Input Method, Key and Value type MAP
- INPUT_COLOR, ///< name "inputColor", The color of the new input text, type VECTOR4
- ENABLE_MARKUP, ///< name "enableMarkup", Whether the mark-up processing is enabled. type BOOLEAN
- INPUT_FONT_FAMILY, ///< name "inputFontFamily", The font's family of the new input text, type STRING
- INPUT_FONT_STYLE, ///< name "inputFontStyle", The font's style of the new input text, type STRING
- INPUT_POINT_SIZE ///< name "inputPointSize", The font's size of the new input text in points, type FLOAT
+ RENDERING_BACKEND = PROPERTY_START_INDEX, ///< name "renderingBackend", The type or rendering e.g. bitmap-based, type INT
+ TEXT, ///< name "text", The text to display in UTF-8 format, type STRING
+ PLACEHOLDER_TEXT, ///< name "placeholderText", The text to display when the TextField is empty and inactive, type STRING
+ PLACEHOLDER_TEXT_FOCUSED, ///< name "placeholderTextFocused", The text to display when the TextField is empty with key-input focus, type STRING
+ FONT_FAMILY, ///< name "fontFamily", The requested font family, type STRING
+ FONT_STYLE, ///< name "fontStyle", The requested font style, type STRING
+ POINT_SIZE, ///< name "pointSize", The size of font in points, type FLOAT
+ MAX_LENGTH, ///< name "maxLength" The maximum number of characters that can be inserted, type INTEGER
+ EXCEED_POLICY, ///< name "exceedPolicy" Specifies how the text is truncated when it does not fit, type INTEGER
+ HORIZONTAL_ALIGNMENT, ///< name "horizontalAlignment", The line horizontal alignment, type STRING, values "BEGIN", "CENTER", "END"
+ VERTICAL_ALIGNMENT, ///< name "verticalAlignment", The line vertical alignment, type STRING, values "TOP", "CENTER", "BOTTOM"
+ TEXT_COLOR, ///< name "textColor", The text color, type VECTOR4
+ PLACEHOLDER_TEXT_COLOR, ///< name "placeholderTextColor", The placeholder-text color, type VECTOR4
+ SHADOW_OFFSET, ///< name "shadowOffset", The drop shadow offset 0 indicates no shadow, type VECTOR2
+ SHADOW_COLOR, ///< name "shadowColor", The color of a drop shadow, type VECTOR4
+ PRIMARY_CURSOR_COLOR, ///< name "primaryCursorColor", The color to apply to the primary cursor, type VECTOR4
+ SECONDARY_CURSOR_COLOR, ///< name "secondaryCursorColor", The color to apply to the secondary cursor, type VECTOR4
+ ENABLE_CURSOR_BLINK, ///< name "enableCursorBlink", Whether the cursor should blink or not, type BOOLEAN
+ CURSOR_BLINK_INTERVAL, ///< name "cursorBlinkInterval", The time interval in seconds between cursor on/off states, type FLOAT
+ CURSOR_BLINK_DURATION, ///< name "cursorBlinkDuration", The cursor will stop blinking after this number of seconds (if non-zero), type FLOAT
+ CURSOR_WIDTH, ///< name "cursorWidth", The cursor width, type INTEGER
+ GRAB_HANDLE_IMAGE, ///< name "grabHandleImage", The image to display for the grab handle, type STRING
+ GRAB_HANDLE_PRESSED_IMAGE, ///< name "grabHandlePressedImage", The image to display when the grab handle is pressed, type STRING
+ SCROLL_THRESHOLD, ///< name "scrollThreshold" Horizontal scrolling will occur if the cursor is this close to the control border, type FLOAT
+ SCROLL_SPEED, ///< name "scrollSpeed" The scroll speed in pixels per second, type FLOAT
+ SELECTION_HANDLE_IMAGE_LEFT, ///< name "selectionHandleImageLeft", The image to display for the left selection handle, type MAP
+ SELECTION_HANDLE_IMAGE_RIGHT, ///< name "selectionHandleImageRight", The image to display for the right selection handle, type MAP
+ SELECTION_HANDLE_PRESSED_IMAGE_LEFT, ///< name "selectionHandlePressedImageLeft", The image to display when the left selection handle is pressed, type MAP
+ SELECTION_HANDLE_PRESSED_IMAGE_RIGHT, ///< name "selectionHandlePressedImageRight", The image to display when the right selection handle is pressed, type MAP
+ SELECTION_HANDLE_MARKER_IMAGE_LEFT, ///< name "selectionHandleMarkerImageLeft", The image to display for the left selection handle marker, type MAP
+ SELECTION_HANDLE_MARKER_IMAGE_RIGHT, ///< name "selectionHandleMarkerImageRight", The image to display for the right selection handle marker, type MAP
+ SELECTION_HIGHLIGHT_COLOR, ///< name "selectionHighlightColor", The color of the selection highlight, type VECTOR4
+ DECORATION_BOUNDING_BOX, ///< name "decorationBoundingBox", The decorations (handles etc) will positioned within this area on-screen, type RECTANGLE
+ INPUT_METHOD_SETTINGS, ///< name "inputMethodSettings", The settings to relating to the System's Input Method, Key and Value type MAP
+ INPUT_COLOR, ///< name "inputColor", The color of the new input text, type VECTOR4
+ ENABLE_MARKUP, ///< name "enableMarkup", Whether the mark-up processing is enabled. type BOOLEAN
+ INPUT_FONT_FAMILY, ///< name "inputFontFamily", The font's family of the new input text, type STRING
+ INPUT_FONT_STYLE, ///< name "inputFontStyle", The font's style of the new input text, type STRING
+ INPUT_POINT_SIZE ///< name "inputPointSize", The font's size of the new input text in points, type FLOAT
};
};
// Type Defs
- /// @brief Max Characters Exceed signal type;
+ /// @brief Text changed signal type.
typedef Signal<void ( TextField ) > TextChangedSignalType;
+ /// @brief Max Characters Exceed signal type.
typedef Signal<void ( TextField ) > MaxLengthReachedSignalType;
/**
- * Create the TextField control.
+ * @brief Create the TextField control.
* @return A handle to the TextField control.
*/
static TextField New();
TextField& operator=( const TextField& handle );
/**
- * @brief Destructor
+ * @brief Destructor.
*
* This is non-virtual since derived Handle types must not contain data or virtual methods.
*/
* If the BaseHandle points is a TextField the downcast returns a valid handle.
* If not the returned handle is left empty.
*
- * @param[in] handle Handle to an object
- * @return handle to a TextField or an empty handle
+ * @param[in] handle Handle to an object.
+ * @return handle to a TextField or an empty handle.
*/
static TextField DownCast( BaseHandle handle );
const unsigned int TOOLKIT_MAJOR_VERSION = 1;
const unsigned int TOOLKIT_MINOR_VERSION = 1;
-const unsigned int TOOLKIT_MICRO_VERSION = 17;
+const unsigned int TOOLKIT_MICRO_VERSION = 18;
const char * const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
{
PrintVersion()
{
- std::cout << "DALi Toolkit: " << TOOLKIT_MAJOR_VERSION << "." << TOOLKIT_MINOR_VERSION << "." << TOOLKIT_MICRO_VERSION << " (" << TOOLKIT_BUILD_DATE << ")" << std::endl;
+ std::cerr << "DALi Toolkit: " << TOOLKIT_MAJOR_VERSION << "." << TOOLKIT_MINOR_VERSION << "." << TOOLKIT_MICRO_VERSION << " (" << TOOLKIT_BUILD_DATE << ")" << std::endl;
}
};
PrintVersion TOOLKIT_VERSION;
"overshootEffectColor":"B018",
"overshootAnimationSpeed":120.0,
"overshootSize":[480.0,42.0]
+ },
+ "texteditor":
+ {
+ "pointSize":18,
+ "primaryCursorColor":[0.0,0.72,0.9,1.0],
+ "secondaryCursorColor":[0.0,0.72,0.9,1.0],
+ "cursorWidth":1,
+ "selectionHighlightColor":[0.75,0.96,1.0,1.0],
+ "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png",
+ "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" },
+ "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" }
+ },
+ "popup":
+ {
+ "popupBackgroundImage":"{DALI_IMAGE_DIR}00_popup_bg.9.png"
+ },
+ "confirmationpopup":
+ {
+ "popupBackgroundImage":"{DALI_IMAGE_DIR}00_popup_bg.9.png"
}
}
}
"overshootEffectColor":"B018",
"overshootAnimationSpeed":360.0,
"overshootSize":[720.0,130.0]
+ },
+ "texteditor":
+ {
+ "pointSize":18,
+ "primaryCursorColor":[0.0,0.72,0.9,1.0],
+ "secondaryCursorColor":[0.0,0.72,0.9,1.0],
+ "cursorWidth":3,
+ "selectionHighlightColor":[0.75,0.96,1.0,1.0],
+ "grabHandleImage" : "{DALI_STYLE_IMAGE_DIR}cursor_handler_drop_center.png",
+ "selectionHandleImageLeft" : {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_left.png" },
+ "selectionHandleImageRight": {"filename":"{DALI_STYLE_IMAGE_DIR}selection_handle_drop_right.png" }
}
}
}
+ [Popup](@ref popup)
+ [Scroll View](@ref scroll-view)
+ TableView
+ + [Text Editor](@ref text-editor)
+ [Text Field](@ref text-field)
+ [Text Label](@ref text-label)
--- /dev/null
+<!--
+/**-->
+
+# Copy and Paste (Selection) {#copy-n-paste}
+
+Text can be selected by a long press or double tapping it. Depending on certain conditions a popup could be shown giving options including [CUT][COPY][PASTE], [SELECT ALL] or [CLIPBOARD]. Below these conditions will be explained.
+
+[CUT] or [COPY] send the selected text to the clipboard ready to be pasted directly or via the clipboard UI. Pressing [PASTE] will paste the top item from the clipboard (what has just been copied, possibly from another application). If the system supports a clipboard UI this can be displayed by pressing the [CLIPBOARD] button.
+
+Empty text means the user has not inputted any text, a text-control containing special characters or purely whitespace is not empty.
+
+Below shows how the popup will look depending on the state of the text-control.
+
+| | |
+|--|--|
+| Condition: Long press/double tap when empty text but clipboard has content | Condition: Long press/double tap when text-control contains text |
+|[PASTE][CLIPBOARD] buttons shown| [CUT][COPY], [SELECT ALL] unless all text selected and [PASTE][CLIPBOARD] if content to paste. |
+| ![ ](../assets/img/text-controls/EmptyTextClipboardHasContent.png) ![ ](./EmptyTextClipboardHasContent.png) | ![ ](../assets/img/text-controls/SelectingText.png) ![ ](./SelectingText.png) |
+| Condition: Long press/double tap popup when text-control contains just whitespace | Condition: Empty text & clipboard empty |
+| Whitespace treated as regular text, [CUT][COPY] shown and [PASTE][CLIPBOARD] if content to paste. As all text is selected there is no need for [SELECT ALL] | No popup shown after longpress/double tap|
+| ![ ](../assets/img/text-controls/SelectAllWhitespace.png) ![ ](./SelectAllWhitespace.png) | ![ ](../assets/img/text-controls/EmptyTextAndNoContentToPaste.png) ![ ](./EmptyTextAndNoContentToPaste.png)|
+| Condition: Longpress/(double tap) on whitespace which is following text | Condition: Tapping text or panning grab handle |
+| [PASTE][CLIPBOARD] shown if something to paste. [SELECT ALL] as more text to select | If content in clipboard [PASTE][CLIPBOARD] popup will be shown. |
+| ![ ](../assets/img/text-controls/SelectWhitespaceAfterText.png) ![ ](./SelectWhitespaceAfterText.png) | ![ ](../assets/img/text-controls/TapAfterCopyingText.png) ![ ](./TapAfterCopyingText.png) |
+
+
+*/
--- /dev/null
+<!--
+/**-->
+
+# Input Style {#input-style}
+
+The input style can be changed through the control properties. All subsequent characters added will be rendered with the new input style.
+
+Note the input style may change if the cursor is updated by tapping in a new position.
+
+Current supported input style properties are:
+
+- *INPUT_COLOR* Sets the input color. The property expects a Vector4 with the red, green, blue and alpha values clamped between 0 and 1.
+- *INPUT_FONT_FAMILY* Sets the input font's family name. The property expects the name of the font. If the new text is not supported by the given font a suitable one will be set.
+- *INPUT_FONT_STYLE* Sets the input font's style. The property expects a json formatted string with the font's style. See the [Font Selection](@ref font-selection) section for more details.
+- *INPUT_POINT_SIZE* Sets the input font's size. The property expects a float with the font's size in points. See the [Font Selection](@ref font-selection) section for more details.
+
+*/
--- /dev/null
+<!--
+/**-->
+
+# Text Editor {#text-editor}
+
+## Overview
+
+The Dali::Toolkit::TextEditor is a control which provides a multi-line editable text.
+
+### Basic usage
+
+Add the text-editor to the stage.
+
+~~~{.cpp}
+// C++
+
+TextEditor editor = TextEditor::New();
+
+Stage::GetCurrent().Add( editor );
+~~~
+
+~~~{.js}
+// JavaScript
+
+var editor = new dali.TextEditor();
+
+dali.stage.add( editor );
+~~~
+
+When the TextEditor is tapped, it will automatically gain the keyboard focus. Key events will then result in text being inserted.
+After text has been entered, it can be retrieved from the TEXT property.
+
+~~~{.cpp}
+// C++
+
+Property::Value editorText = editor.GetProperty( TextEditor::Property::TEXT );
+std::cout << "Received text: " << editorText.Get< std::string >() << std::endl;
+~~~
+
+~~~{.js}
+// JavaScript
+
+console.log( editor.text );
+~~~
+
+### Font Selection
+
+By default TextEditor will automatically select a suitable font from the platform. However, a different font could be selected. See the [Font Selection](@ref font-selection) section for more details.
+
+### Mark-up Style
+
+Mark-up tags can be used to change the style of the text. See the [Mark-up Style](@ref markup-style) section for more details.
+
+### Input Style
+
+The input style can be changed through the control properties.See the [Input Style](@ref input-style) section for more details.
+
+### Text Alignment
+
+TextEditor displays a multi-line of text, which will scroll if there is not enough room for the text displayed.
+If there is enough room, then the text can be aligned horizontally to the beginning, end, or center of the available area:
+
+~~~{.cpp}
+// C++
+
+editor.SetProperty( TextEditor::Property::HORIZONTAL_ALIGNMENT, "BEGIN" ); // "CENTER" or "END"
+~~~
+
+~~~{.js}
+// JavaScript
+
+editor.HorizontalAlignment = "BEGIN"; // "CENTER" or "END"
+~~~
+
+### Copy and Paste (Selection)
+
+Text can be selected by a long press or double tapping it. See the [Copy and Paste](@ref copy-n-paste) section for more details.
+
+### TextEditor Decorations
+
+#### Color
+
+To change the color of the text, the recommended way is to use the TEXT_COLOR property.
+
+~~~{.cpp}
+// C++
+editor.SetProperty( TextEditor::Property::TEXT_COLOR, Color::CYAN );
+~~~
+
+~~~{.js}
+// JavaScript
+
+editor.textColor = dali.COLOR_CYAN;
+~~~
+
+### TextEditor Properties
+
+ Name (JavaScript) | Name (C++) | Type | Writable | Animatable
+-----------------------------------|--------------------------------------|--------------|--------------|-----------
+ renderingBackend | RENDERING_BACKEND | INTEGER | O | X
+ text | TEXT | STRING | O | X
+ textColor | TEXT_COLOR | VECTOR4 | O | X
+ fontFamily | FONT_FAMILY | STRING | O | X
+ fontStyle | FONT_STYLE | STRING | O | X
+ pointSize | POINT_SIZE | FLOAT | O | X
+ horizontalAlignment | HORIZONTAL_ALIGNMENT | STRING | O | X
+ verticalAlignment | VERTICAL_ALIGNMENT | STRING | O | X
+ scrollThreshold | SCROLL_THRESHOLD | FLOAT | O | X
+ scrollSpeed | SCROLL_SPEED | FLOAT | O | X
+ primaryCursorColor | PRIMARY_CURSOR_COLOR | VECTOR4 | O | X
+ secondaryCursorColor | SECONDARY_CURSOR_COLOR | VECTOR4 | O | X
+ enableCursorBlink | ENABLE_CURSOR_BLINK | BOOLEAN | O | X
+ cursorBlinkInterval | CURSOR_BLINK_INTERVAL | FLOAT | O | X
+ cursorBlinkDuration | CURSOR_BLINK_DURATION | FLOAT | O | X
+ cursorWidth | CURSOR_WIDTH | INTEGER | O | X
+ grabHandleImage | GRAB_HANDLE_IMAGE | STRING | O | X
+ grabHandlePressedImage | GRAB_HANDLE_PRESSED_IMAGE | STRING | O | X
+ selectionHandleImageLeft | SELECTION_HANDLE_IMAGE_LEFT | STRING | O | X
+ selectionHandleImageRight | SELECTION_HANDLE_IMAGE_RIGHT | STRING | O | X
+ selectionHandlePressedImageLeft | SELECTION_HANDLE_PRESSED_IMAGE_LEFT | STRING | O | X
+ selectionHandlePressedImageRight | SELECTION_HANDLE_PRESSED_IMAGE_RIGHT | STRING | O | X
+ selectionHandleMarkerImageLeft | SELECTION_HANDLE_MARKER_IMAGE_LEFT | MAP | O | X
+ selectionHandleMarkerImageRight | SELECTION_HANDLE_MARKER_IMAGE_RIGHT | MAP | O | X
+ selectionHighlightColor | SELECTION_HIGHLIGHT_COLOR | VECTOR4 | O | X
+ decorationBoundingBox | DECORATION_BOUNDING_BOX | RECTANGLE | O | X
+ enableMarkup | ENABLE_MARKUP | BOOLEAN | O | X
+ inputColor | INPUT_COLOR | VECTOR4 | O | X
+ inputFontFamily | INPUT_FONT_FAMILY | STRING | O | X
+ inputFontStyle | INPUT_FONT_STYLE | STRING | O | X
+ inputPointSize | INPUT_POINT_SIZE | FLOAT | O | X
+
+@class TextEditor
+
+*/
### Input Style
-The input style can be changed through the control properties. All subsequent characters added will be rendered with the new input style.
-
-Note the input style may change if the cursor is updated by tapping in a new position.
-
-Current supported input style properties are:
-
-- *INPUT_COLOR* Sets the input color. The property expects a Vector4 with the red, green, blue and alpha values clamped between 0 and 1.
-- *INPUT_FONT_FAMILY* Sets the input font's family name. The property expects the name of the font. If the new text is not supported by the given font a suitable one will be set.
-- *INPUT_FONT_STYLE* Sets the input font's style. The property expects a json formatted string with the font's style. See the [Font Selection](@ref font-selection) section for more details.
-- *INPUT_POINT_SIZE* Sets the input font's size. The property expects a float with the font's size in points. See the [Font Selection](@ref font-selection) section for more details.
+The input style can be changed through the control properties. See the [Input Style](@ref input-style) section for more details.
### Text Alignment
### Copy and Paste (Selection)
-Text can be selected by a long press or double tapping it. Depending on certain conditions a popup could be shown giving options including [CUT][COPY][PASTE], [SELECT ALL] or [CLIPBOARD]. Below these conditions will be explained.
-
-[CUT] or [COPY] send the selected text to the clipboard ready to be pasted directly or via the clipboard UI. Pressing [PASTE] will paste the top item from the clipboard (what has just been copied, possibly from another application). If the system supports a clipboard UI this can be displayed by pressing the [CLIPBOARD] button.
-
-Empty text means the user has not inputted any text, a TextField containing special characters or purely whitespace is not empty.
-
-Below shows how the popup will look depending on the state of the TextField
-
-| | |
-|--|--|
-| Condition: Long press/double tap when empty text but clipboard has content | Condition: Long press/double tap when TextField contains text |
-|[PASTE][CLIPBOARD] buttons shown| [CUT][COPY], [SELECT ALL] unless all text selected and [PASTE][CLIPBOARD] if content to paste. |
-| ![ ](../assets/img/text-controls/EmptyTextClipboardHasContent.png) ![ ](./EmptyTextClipboardHasContent.png) | ![ ](../assets/img/text-controls/SelectingText.png) ![ ](./SelectingText.png) |
-| Condition: Long press/double tap popup when TextField contains just whitespace | Condition: Empty text & clipboard empty |
-| Whitespace treated as regular text, [CUT][COPY] shown and [PASTE][CLIPBOARD] if content to paste. As all text is selected there is no need for [SELECT ALL] | No popup shown after longpress/double tap|
-| ![ ](../assets/img/text-controls/SelectAllWhitespace.png) ![ ](./SelectAllWhitespace.png) | ![ ](../assets/img/text-controls/EmptyTextAndNoContentToPaste.png) ![ ](./EmptyTextAndNoContentToPaste.png)|
-| Condition: Longpress/(double tap) on whitespace which is following text | Condition: Tapping text or panning grab handle |
-| [PASTE][CLIPBOARD] shown if something to paste. [SELECT ALL] as more text to select | If content in clipboard [PASTE][CLIPBOARD] popup will be shown. |
-| ![ ](../assets/img/text-controls/SelectWhitespaceAfterText.png) ![ ](./SelectWhitespaceAfterText.png) | ![ ](../assets/img/text-controls/TapAfterCopyingText.png) ![ ](./TapAfterCopyingText.png) |
+Text can be selected by a long press or double tapping it. See the [Copy and Paste](@ref copy-n-paste) section for more details.
### TextField Decorations
'<(DALI_JS_DIR)/actors/layer-api.cpp',
'<(DALI_JS_DIR)/actors/camera-actor-api.cpp',
'<(DALI_JS_DIR)/constants/constants-wrapper.cpp',
+ '<(DALI_JS_DIR)/controls/control-wrapper.cpp',
+ '<(DALI_JS_DIR)/controls/item-factory-wrapper.cpp',
+ '<(DALI_JS_DIR)/controls/item-view-api.cpp',
'<(DALI_JS_DIR)/animation/animation-api.cpp',
'<(DALI_JS_DIR)/animation/animation-wrapper.cpp',
'<(DALI_JS_DIR)/animation/constrainer-api.cpp',
'cflags': [
'-fPIC',
'-frtti',
- '<!@(pkg-config --cflags dali dali-toolkit)'
+ '<!@(pkg-config --cflags dali-core dali-adaptor-uv dali-toolkit)'
],
'cflags_cc': [
'-frtti' # needed for typeinfo with dali-any
],
'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other dali dali-toolkit)'
+ '<!@(pkg-config --libs-only-L --libs-only-other dali-core dali-adaptor-uv dali-toolkit)'
],
'libraries': [
- '<!@(pkg-config --libs-only-l dali dali-toolkit)'
+ '<!@(pkg-config --libs-only-l dali-core dali-adaptor-uv dali-toolkit)'
]
}]
}
${PLUGING_SRC_DIR}/actors/actor-api.cpp
${PLUGING_SRC_DIR}/actors/layer-api.cpp
${PLUGING_SRC_DIR}/actors/camera-actor-api.cpp
+ ${PLUGING_SRC_DIR}/controls/control-wrapper.cpp
+ ${PLUGING_SRC_DIR}/controls/item-factory-wrapper.cpp
+ ${PLUGING_SRC_DIR}/controls/item-view-api.cpp
${PLUGING_SRC_DIR}/constants/constants-wrapper.cpp
${PLUGING_SRC_DIR}/animation/animation-api.cpp
${PLUGING_SRC_DIR}/animation/animation-wrapper.cpp
set_target_properties(dali_addon PROPERTIES EXCLUDE_FROM_ALL "FALSE")
-SET(PKG_LIST dali
+SET(PKG_LIST dali-core
+ dali-adaptor-uv
dali-toolkit)
INCLUDE(FindPkgConfig)
--- /dev/null
+ var window= {
+ x:0,
+ y:0,
+ width:1920,
+ height: 1080,
+ transparent: false,
+ name:'itemview-example'
+ };
+
+ var viewMode={
+ 'stereoscopic-mode':'mono', // stereo-horizontal, stereo-vertical, stereo-interlaced,
+ 'stereoBase': 65 // Distance in millimeters between left/right cameras typically between (50-70mm)
+ };
+
+ var options= {
+ 'window': window,
+ 'viewMode': viewMode,
+ }
+
+//desktop
+//var dali = require('../build/Release/dali')( options );
+
+//target
+var dali = require('dali')( options );
+
+var items = [];
+var button;
+var stageSize;
+
+var itemView;
+var itemFactory;
+
+var currentLayoutIndex = 0;
+var totalItemCount = 100;
+
+var imageDir = "./images/";
+
+var daliApp = {};
+
+daliApp.createItemView = function() {
+
+ // Create item view data
+ var itemViewData = [];
+ for (var itemId = 0; itemId < totalItemCount; itemId++)
+ {
+ var data = {};
+ data["template"] = "template-item-list"; // Create items initially with list template
+ data["icon_path"] = imageDir + "icon-" + itemId % 3 + ".png";
+ data["title_text"] = "Item " + itemId;
+ itemViewData[itemId] = data;
+ }
+
+ // Create item factory and set the data
+ itemFactory = new dali.ItemFactory();
+ itemFactory.jsonTemplateFile = "./scripts/item-template.json";
+ itemFactory.data = itemViewData;
+
+ // Create item view
+ stageSize = dali.stage.getSize();
+ itemView = new dali.Control("ItemView", itemFactory);
+ itemView.size = [stageSize.x, stageSize.y, 0.0];
+ itemView.parentOrigin = dali.CENTER_LEFT;
+ itemView.anchorPoint = dali.CENTER_LEFT;
+ itemView.refreshInterval = 4.0;
+
+ // Add item view to the stage
+ dali.stage.add( itemView );
+
+ // Create scroll bar for item view
+ var scrollBar = new dali.Control("ScrollBar");
+ scrollBar.parentOrigin = dali.TOP_RIGHT;
+ scrollBar.anchorPoint = dali.TOP_RIGHT;
+ scrollBar.widthResizePolicy = "FIT_TO_CHILDREN";
+ scrollBar.heightResizePolicy = "FILL_TO_PARENT";
+ itemView.add(scrollBar);
+
+ // Add the list and grid layouts
+ itemView.addLayout(dali.ITEM_LAYOUT_LIST); // layout index 0
+ itemView.addLayout(dali.ITEM_LAYOUT_GRID); // layout index 1
+
+ // Set custom item size for list layout
+ itemView.setItemSize(0, [stageSize.x, stageSize.y * 0.1, 0.0]);
+
+ // Set custom item size for grid layout
+ var layoutMargin = 120;
+ itemView.setItemSize(1, [(stageSize.x - layoutMargin) / 4, stageSize.y * 0.2, 0.0]);
+
+ // Activate the list layout
+ itemView.activateLayout(0, itemView.size);
+
+ // Create button for layout switching
+ button = new dali.Control("PushButton");
+ button.size = [100.0, 60.0, 0.0];
+ button.position = [-20.0, 20.0, 0.0];
+ button.parentOrigin = dali.TOP_RIGHT;
+ button.anchorPoint = dali.TOP_RIGHT;
+ button.labelText = "Switch";
+ dali.stage.add( button );
+
+ // Connect a signal callback to button pressed signal
+ button.on("pressed", daliApp.buttonPressedEvent);
+}
+
+daliApp.buttonPressedEvent = function( button ) {
+
+ // Calculate the layout index for the next layout to switch to
+ currentLayoutIndex++;
+ currentLayoutIndex = currentLayoutIndex % itemView.getLayoutCount();
+
+ // Activate the next layout
+ itemView.activateLayout(currentLayoutIndex, [stageSize.x, stageSize.y, 0.0], 0.0);
+
+ // Change the item template in item view data as we want to change the layout of the items
+ var data = itemFactory.data;
+ for (var itemId = 0; itemId < totalItemCount; itemId++)
+ {
+ if(currentLayoutIndex == 0)
+ {
+ // List layout
+ data[itemId]["template"] = "template-item-list"; // Create items with list template
+ }
+ else
+ {
+ // Grid layout
+ data[itemId]["template"] = "template-item-grid"; // Create items with grid template
+ }
+ }
+ itemFactory.data = data;
+}
+
+function startup()
+{
+ daliApp.init();
+}
+
+daliApp.init = function()
+{
+ daliApp.createItemView();
+}
+
+startup();
+
}
// desktop
-//var dali = require('./build/Release/dali')( options );
+//var dali = require('../build/Release/dali')( options );
// target
var dali = require('dali')( options );
'view-mode': viewMode,
}
-
// desktop
-//var dali = require('./build/Release/dali')( options );
+//var dali = require('../build/Release/dali')( options );
// target
var dali = require('dali')( options );
'view-mode': viewMode,
}
-var imageDir = "./";
+var imageDir = "./images/";
// desktop
-//var dali = require('./build/Release/dali')( options );
+//var dali = require('../build/Release/dali')( options );
// target
var dali = require('dali')( options );
--- /dev/null
+{
+ "templates":
+ {
+ "template-item-list":
+ {
+ "name":"item",
+ "type":"Actor",
+ "position":[0,0,0],
+ "anchorPoint":"TOP_LEFT",
+ "parentOrigin":"TOP_LEFT",
+ "actors":
+ [
+ {
+ "name":"icon",
+ "type":"ImageView",
+ "image":
+ {
+ "rendererType" : "imageRenderer",
+ "imageUrl": "{icon_path}"
+ },
+ "position":[20.0, 0.0, 0.0],
+ "size":[70.0, 70.0, 0.0],
+ "color":[1.0,1.0,1.0,1.0],
+ "anchorPoint":"CENTER_LEFT",
+ "parentOrigin":"CENTER_LEFT",
+ "actors":
+ [
+ {
+ "name":"title",
+ "anchorPoint":"CENTER_LEFT",
+ "parentOrigin":"CENTER_RIGHT",
+ "type":"TextLabel",
+ "position": [30.0, 0.0, 0.0],
+ "size":[200.0, 70.0, 0.0],
+ "pointSize":30,
+ "fontFamily":"HelveticaNeue",
+ "fontStyle":"Bold",
+ "horizontalAlignment":"BEGIN",
+ "verticalAlignment":"CENTER",
+ "textColor": [1.0,0.0,1.0,1.0],
+ "text":"{title_text}"
+ }
+ ]
+ }
+ ]
+ },
+
+ "template-item-grid":
+ {
+ "name":"item",
+ "type":"Actor",
+ "position":[0,0,0],
+ "anchorPoint":"TOP_LEFT",
+ "parentOrigin":"TOP_LEFT",
+ "actors":
+ [
+ {
+ "name":"icon",
+ "type":"ImageView",
+ "image":
+ {
+ "rendererType" : "imageRenderer",
+ "imageUrl": "{icon_path}"
+ },
+ "position":[0.0, -10.0, 0.0],
+ "size":[70.0, 70.0, 0.0],
+ "color":[1.0,1.0,1.0,1.0],
+ "anchorPoint":"CENTER",
+ "parentOrigin":"CENTER",
+ "actors":
+ [
+ {
+ "name":"title",
+ "anchorPoint":"TOP_CENTER",
+ "parentOrigin":"BOTTOM_CENTER",
+ "type":"TextLabel",
+ "position": [0.0,10.0,0.0],
+ "size":[100.0, 100.0, 0.0],
+ "pointSize":22,
+ "fontFamily":"HelveticaNeue",
+ "fontStyle":"Bold",
+ "horizontalAlignment":"CENTER",
+ "textColor": [1.0,0.0,1.0,1.0],
+ "text":"{title_text}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
+
'view-mode': viewMode,
}
-var imageDir = "./";
+var imageDir = "./images/";
// desktop
-//var dali = require('./build/Release/dali')( options );
+//var dali = require('../build/Release/dali')( options );
// target
var dali = require('dali')( options );
--- /dev/null
+{
+ "templates":
+ {
+ "template-item-list":
+ {
+ "name":"item",
+ "type":"Actor",
+ "position":[0,0,0],
+ "anchorPoint":"TOP_LEFT",
+ "parentOrigin":"TOP_LEFT",
+ "actors":
+ [
+ {
+ "name":"icon",
+ "type":"ImageView",
+ "image":
+ {
+ "rendererType" : "imageRenderer",
+ "imageUrl": "{icon_path}"
+ },
+ "position":[20.0, 0.0, 0.0],
+ "size":[70.0, 70.0, 0.0],
+ "color":[1.0,1.0,1.0,1.0],
+ "anchorPoint":"CENTER_LEFT",
+ "parentOrigin":"CENTER_LEFT",
+ "actors":
+ [
+ {
+ "name":"title",
+ "anchorPoint":"CENTER_LEFT",
+ "parentOrigin":"CENTER_RIGHT",
+ "type":"TextLabel",
+ "position": [30.0, 0.0, 0.0],
+ "size":[200.0, 70.0, 0.0],
+ "pointSize":30,
+ "fontFamily":"HelveticaNeue",
+ "fontStyle":"Bold",
+ "horizontalAlignment":"BEGIN",
+ "verticalAlignment":"CENTER",
+ "textColor": [1.0,0.0,1.0,1.0],
+ "text":"{title_text}"
+ }
+ ]
+ }
+ ]
+ },
+
+ "template-item-grid":
+ {
+ "name":"item",
+ "type":"Actor",
+ "position":[0,0,0],
+ "anchorPoint":"TOP_LEFT",
+ "parentOrigin":"TOP_LEFT",
+ "actors":
+ [
+ {
+ "name":"icon",
+ "type":"ImageView",
+ "image":
+ {
+ "rendererType" : "imageRenderer",
+ "imageUrl": "{icon_path}"
+ },
+ "position":[0.0, -10.0, 0.0],
+ "size":[70.0, 70.0, 0.0],
+ "color":[1.0,1.0,1.0,1.0],
+ "anchorPoint":"CENTER",
+ "parentOrigin":"CENTER",
+ "actors":
+ [
+ {
+ "name":"title",
+ "anchorPoint":"TOP_CENTER",
+ "parentOrigin":"BOTTOM_CENTER",
+ "type":"TextLabel",
+ "position": [0.0,10.0,0.0],
+ "size":[100.0, 100.0, 0.0],
+ "pointSize":22,
+ "fontFamily":"HelveticaNeue",
+ "fontStyle":"Bold",
+ "horizontalAlignment":"CENTER",
+ "textColor": [1.0,0.0,1.0,1.0],
+ "text":"{title_text}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
+
URL: https://review.tizen.org/gerrit/#/q/project:platform/core/uifw/dali-toolkit
Distribution: Tizen
Source0: %{name}-%{version}.tar.gz
-Requires: dali
-# Do NOT put an adaptor here - it is an application choice which adaptor to use
BuildRequires: pkgconfig
BuildRequires: pkgconfig(dlog)
BuildRequires: cmake
-BuildRequires: pkgconfig(dali)
BuildRequires: pkgconfig(dali-core)
BuildRequires: pkgconfig(dali-toolkit)
BuildRequires: nodejs-devel
+# DALi JS applications using dali-addon always run on dali-adaptor-uv.
+BuildRequires: pkgconfig(dali-adaptor-uv)
+
%description
DALi Node.JS addon
cd "%{addonBuildDir}"
%make_install
-cp %{addonDir}/line-mesh.js %{installDir}/line-mesh.js
+cp -R %{addonDir}/examples %{installDir}/examples
%clean
Name: dali-toolkit
Summary: The OpenGLES Canvas Core Library Toolkit
-Version: 1.1.17
+Version: 1.1.18
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-2-Clause and MIT
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
-Requires: dali
-# Do NOT put an adaptor here - it is an application choice which adaptor to use
+
BuildRequires: pkgconfig
BuildRequires: pkgconfig(dlog)
-BuildRequires: pkgconfig(dali)
BuildRequires: pkgconfig(dali-core)
+# dali-toolkit only need to know the interfaces(APIs) of dali-adaptor(the devel package).
+# It doesn't need to know which adaptor will be used by applications.
+# Applications or dali-addon will decide which one they will use.
+BuildRequires: dali-adaptor-devel
+
#############################
# profile setup
#############################
|PROPERTY_ARRAY | integer value |
|PROPERTY_MAP | integer value |
|PROPERTY_INVALID_INDEX | integer value |
+|PROPERTY_READ_ONLY | integer value |
+|PROPERTY_READ_WRITE | integer value |
+|PROPERTY_ANIMATABLE | integer value |
+
+|**Item layout type ** | |
+|ITEM_LAYOUT_LIST | integer value |
+|ITEM_LAYOUT_GRID | integer value |
* @class Constants
*/
--- /dev/null
+/**
+ *
+## ItemFactory API
+
+ ItemFactory is for storing the data of {{#crossLink "ItemView"}}ItemView{{/crossLink}}
+ and creating actors for ItemView on request. Each item in ItemView is identified by a
+ unique ID, and has a linear order from 0.
+
+ A JSON file should be provided to ItemFactory which defines the templates of items
+ to be used to create the actors. Multiple templates can be defined in the JSON file
+ for different type of items.
+
+### Simple example of creating a JSON template for items
+
+```
+ {
+ "templates":
+ {
+ "template-item":
+ {
+ "name":"item",
+ "type":"Actor",
+ "position":[0,0,0],
+ "anchorPoint":"TOP_LEFT",
+ "parentOrigin":"TOP_LEFT",
+ "actors":
+ [
+ {
+ "name":"icon",
+ "type":"ImageView",
+ "image":
+ {
+ "rendererType" : "imageRenderer",
+ "imageUrl": "{icon_path}"
+ },
+ "position":[20.0, 0.0, 0.0],
+ "size":[70.0, 70.0, 0.0],
+ "color":[1.0,1.0,1.0,1.0],
+ "anchorPoint":"CENTER_LEFT",
+ "parentOrigin":"CENTER_LEFT",
+ "actors":
+ [
+ {
+ "name":"title",
+ "anchorPoint":"CENTER_LEFT",
+ "parentOrigin":"CENTER_RIGHT",
+ "type":"TextLabel",
+ "position": [30.0, 0.0, 0.0],
+ "size":[200.0, 70.0, 0.0],
+ "pointSize":30,
+ "fontFamily":"HelveticaNeue",
+ "fontStyle":"Bold",
+ "horizontalAlignment":"BEGIN",
+ "verticalAlignment":"CENTER",
+ "textColor": [1.0,0.0,1.0,1.0],
+ "text":"{title_text}"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+```
+
+ The data of items should be provided to ItemFactory as an array of property maps
+ in which each map contains the data for each item, including the template to be used
+ to build the actor and the pairs of key/value to be used to replace the constants
+ defined in the template. The order of property maps in the array represents the actual
+ order of items in ItemView.
+
+ ### Example of defining the data of an ItemView with two items
+
+```
+ var itemViewData = [
+ { "template" : "template-item",
+ "icon_path" : "icon0.png",
+ "title_text" : "Item 0" },
+ { "template" : "template-item",
+ "icon_path" : "icon1.png",
+ "title_text" : "Item 1" }
+ ];
+```
+
+ This means ItemFactory will use the template "template-item" defined in the JSON file
+ to create the item for ItemView and replace the constants "icon_path" and "title_text"
+ in the template with their actual values, e.g. "icon0.png" and "Item 0". Each item can
+ have different template and different data.
+
+ ### Example of creating an ItemFactory with the above JSON template and link it with an ItemView
+
+![ ](../assets/img/item-view/list.png)
+
+```
+ // Define the data of 100 items
+ var itemViewData = [];
+ for (var itemId = 0; itemId < 100; itemId++)
+ {
+ var itemData = {};
+ itemData["template"] = "template-item";
+ itemData["icon_path"] = "icon" + itemId + ".png";
+ itemData["title_text"] = "Item " + itemId;
+ itemViewData[itemId] = itemData;
+ }
+
+ // Create the item factory and set the JSON template file and item view data
+ var itemFactory = new dali.ItemFactory();
+ itemFactory.jsonTemplateFile = "./item-template.json"; // Set the JSON template file
+ itemFactory.data = itemViewData; // Set the ItemView data
+
+ // Create the item view with the given item factory
+ var itemView = new dali.Control("ItemView", itemFactory);
+ itemView.size = [stageSize.x, stageSize.y, 0.0];
+ itemView.parentOrigin = dali.CENTER_LEFT;
+ itemView.anchorPoint = dali.CENTER_LEFT;
+ dali.stage.add( itemView );
+
+ // Add a list layout to ItemView (multiple layouts can be added to the same ItemView)
+ itemView.addLayout(dali.ITEM_LAYOUT_LIST);
+
+ // Set custom item size for the list layout
+ // If set, this will overide the predefined item size in the list layout
+ itemView.setItemSize(0, [350, 100, 0]); // 0 means the first layout added to ItemView
+
+ // Acticate the list layout (which will layout the items as a list)
+ itemView.activateLayout(0, itemView.size); // 0 means the first layout added to ItemView
+```
+
+ ### Example of changing the data of items in ItemView dynamically
+
+```
+ var data = itemFactory.data;
+ data[itemId]["icon_path"] = "new-icon.png";
+ data[itemId]["title_text"] = "New Item";
+ itemFactory.data = data; // ItemView will update the changed items immediately
+```
+
+ @class ItemFactory
+
+*/
+
+/**
+ * Sets the file name of JSON template that contains the templates for items.
+ *
+ * @example
+ * itemFactory.jsonTemplateFile = "item-template.json"; // ItemFactory will look for the template from this JSON file
+ *
+ * @type String
+ * @property jsonTemplateFile
+ */
+JSON_TEMPLATE_FILE
+
+/**
+ * Sets the data of ItemView
+ *
+ * The data is an array of property maps in which each map contains the data
+ * for each item, including the template to be used to build the actor and
+ * the pairs of key/value to be used to replace the constants defined in the
+ * template. The order of property maps in the array represents the actual
+ * order of items in ItemView.
+ *
+ * @example
+ * var itemViewData = [
+ * { "template" : "template-item",
+ * "icon_path" : "icon0.png",
+ * "title_text" : "Item 0" },
+ * { "template" : "template-item",
+ * "icon_path" : "icon1.png",
+ * "title_text" : "Item 1" }
+ * ];
+ *
+ * itemFactory.data = itemViewData; // ItemFactory will look for the template from this JSON file
+ *
+ * @type Array
+ * @property data
+ */
+DATA
--- /dev/null
+/**
+ *
+## ItemView API
+
+ ItemView is a scrollable layout container with built-in layouts to determine
+ the logical position of each item in a layout.
+
+ Actors are provided from an external {{#crossLink "ItemFactory"}}ItemFactory{{/crossLink}},
+ to display the currently visible items. ItemFactory is for storing the data of ItemView and
+ creating actors for ItemView on request. Each item in ItemView is identified by a unique ID,
+ and has a linear order from 0.
+
+ ### Example of creating an ItemView (see {{#crossLink "ItemFactory"}}ItemFactory{{/crossLink}} API for a full example)
+
+```
+ // Define the data of 100 items
+ var itemViewData = [];
+ for (var itemId = 0; itemId < 100; itemId++)
+ {
+ var itemData = {};
+ itemData["template"] = "template-item";
+ itemData["title_text"] = "Item " + itemId;
+ itemViewData[itemId] = itemData;
+ }
+
+ // Create an item factory and set the JSON template file and item view data
+ var itemFactory = new dali.ItemFactory();
+ itemFactory.jsonTemplateFile = "./item-template.json"; // Set the JSON template file
+ itemFactory.data = itemViewData; // Set the ItemView data
+
+ // Create the item view with the given item factory
+ var itemView = new dali.Control("ItemView", itemFactory);
+ itemView.size = [stageSize.x, stageSize.y, 0.0];
+ itemView.parentOrigin = dali.CENTER_LEFT;
+ itemView.anchorPoint = dali.CENTER_LEFT;
+ dali.stage.add( itemView );
+
+ // Add a scroll bar to ItemView (optional)
+ var scrollBar = new dali.Control("ScrollBar");
+ scrollBar.parentOrigin = dali.TOP_RIGHT;
+ scrollBar.anchorPoint = dali.TOP_RIGHT;
+ scrollBar.widthResizePolicy = "FIT_TO_CHILDREN";
+ scrollBar.heightResizePolicy = "FILL_TO_PARENT";
+ scrollBar.indicatorHeightPolicy = "Fixed";
+ scrollBar.indicatorFixedHeight = 60.0;
+ itemView.add(scrollBar);
+
+ // Add a list layout to ItemView (multiple layouts can be added to the same ItemView)
+ itemView.addLayout(dali.ITEM_LAYOUT_LIST);
+
+ // Set custom item size for the list layout
+ // If set, this will overide the predefined item size in the list layout
+ itemView.setItemSize(0, [350, 100, 0]); // 0 means the first layout added to ItemView
+
+ // Acticate the list layout (which will layout the items as a list)
+ itemView.activateLayout(0, itemView.size); // 0 means the first layout added to ItemView
+```
+
+ @class ItemView
+ @extends Actor
+
+*/
$(v8_plugin_dir)/actors/actor-api.cpp \
$(v8_plugin_dir)/actors/layer-api.cpp \
$(v8_plugin_dir)/actors/camera-actor-api.cpp \
+ $(v8_plugin_dir)/controls/control-wrapper.cpp \
+ $(v8_plugin_dir)/controls/item-factory-wrapper.cpp \
+ $(v8_plugin_dir)/controls/item-view-api.cpp \
$(v8_plugin_dir)/constants/constants-wrapper.cpp \
$(v8_plugin_dir)/animation/animation-api.cpp \
$(v8_plugin_dir)/animation/animation-wrapper.cpp \
namespace // unanmed namespace
{
+
Actor GetActor( v8::Isolate* isolate, const v8::FunctionCallbackInfo<v8::Value>& args )
{
HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, args.This() );
return Actor::DownCast( handleWrapper->mHandle );
}
-} //unanmed namespace
-
-namespace TextLabelApi
-{
- Actor New( const v8::FunctionCallbackInfo< v8::Value >& args )
- {
- return Dali::Toolkit::TextLabel::New();
- }
-}
+} //unanmed namespace
/***************************************
* ACTOR API FUNCTIONS
}
/**
- * Retrieve and child actor by index.
+ * Retrieve a child actor by index.
*
* @for Actor
* @method getChildAt
namespace V8Plugin
{
-namespace TextLabelApi
-{
- /**
- * Temporary TextView constructor
- */
- Actor New( const v8::FunctionCallbackInfo< v8::Value >& args );
-}
-
namespace ActorApi
{
/**
* Lookup table to match a actor type with a constructor and supported API's.
- * HandleWrapper::ActorType is used to index this table
+ * ActorWrapper::ActorType is used to index this table
*/
const ActorApiStruct ActorApiLookup[]=
{
// create an instance of the template
v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
- // create teh actor object
+ // create the actor object
ActorWrapper* pointer = new ActorWrapper( actor, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
// assign the JavaScript object to the wrapper.
args.GetReturnValue().Set( localObject );
}
-void ActorWrapper::NewControl( const v8::FunctionCallbackInfo< v8::Value >& args)
-{
- v8::Isolate* isolate = args.GetIsolate();
- v8::HandleScope handleScope( isolate );
-
- if( !args.IsConstructCall() )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "constructor called without 'new" );
- return;
- }
-
- bool found( false );
- std::string controlName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
-
- if( !found )
- {
- DALI_SCRIPT_EXCEPTION( isolate, "missing control name" );
- return;
- }
- Actor control;
- Dali::TypeInfo typeInfo = Dali::TypeRegistry::Get().GetTypeInfo( controlName );
- if( typeInfo ) // handle, check if it has a value
- {
- Dali::BaseHandle handle = typeInfo.CreateInstance();
- if( handle )
- {
- control = Actor::DownCast( handle );
- }
- }
-
- v8::Local<v8::Object> localObject = WrapActor( isolate, control, ACTOR );
-
- args.GetReturnValue().Set( localObject );
-}
-
-
/**
* given an actor type name, e.g. CameraActor returns the type, e.g. ActorWrapper::CAMERA_ACTOR
*/
return ActorWrapper::UNKNOWN_ACTOR;
}
-
-
} // namespace V8Plugin
} // namespace Dali
static void NewActor( const v8::FunctionCallbackInfo< v8::Value >& args);
/**
- * @brief Creates a new Control wrapped inside a Javascript Object.
- * @note: the control type is passed as a parameter e.g. 'TextField'
- * @param[in] args v8 function call arguments interpreted
- */
- static void NewControl( const v8::FunctionCallbackInfo< v8::Value >& args);
-
- /**
* @brief Wraps an actor of a given type
*/
static v8::Handle<v8::Object> WrapActor(v8::Isolate* isolate, Dali::Actor actor,ActorType actorType);
*/
static ActorWrapper::ActorType GetActorType( const std::string& name );
-private:
+protected:
/**
- * Helper to make the actor template
+ * @brief Helper to make the actor template
*
*/
static v8::Handle<v8::ObjectTemplate> MakeDaliActorTemplate( v8::Isolate* isolate, ActorType actorType );
+private:
+
/**
* Helper, get an actor template given an actor type
*/
#include <dali/public-api/common/loading-state.h>
#include <dali/devel-api/rendering/material.h>
#include <dali/devel-api/rendering/geometry.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h>
namespace Dali
{
{ "PROPERTY_ARRAY", Property::ARRAY },
{ "PROPERTY_MAP", Property::MAP },
{ "PROPERTY_INVALID_INDEX", Property::INVALID_INDEX },
+ { "PROPERTY_READ_ONLY", Property::READ_ONLY },
+ { "PROPERTY_READ_WRITE", Property::READ_WRITE },
+ { "PROPERTY_ANIMATABLE", Property::ANIMATABLE },
+
+ { "ITEM_LAYOUT_LIST", Toolkit::DefaultItemLayout::LIST },
+ { "ITEM_LAYOUT_GRID", Toolkit::DefaultItemLayout::GRID },
};
const unsigned int EnumTableCount = sizeof(EnumTable)/sizeof(EnumTable[0]);
--- /dev/null
+/*
+ * Copyright (c) 2015 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 <actors/actor-wrapper.h>
+#include "control-wrapper.h"
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/object/type-registry.h>
+
+// INTERNAL INCLUDES
+#include <controls/item-view-api.h>
+#include <v8-utils.h>
+#include <dali-wrapper.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+v8::Persistent<v8::ObjectTemplate> ControlWrapper::mControlTemplate;
+v8::Persistent<v8::ObjectTemplate> ControlWrapper::mItemViewTemplate;
+
+Vector< void* > ControlWrapper::mControlGarbageContainer;
+
+namespace
+{
+
+
+/**
+ * pointer to a persistent template handle
+ */
+struct ControlTemplate
+{
+ v8::Persistent<v8::ObjectTemplate>* controlTemplate;
+};
+
+/**
+ * array of templates for each type of control
+ */
+const ControlTemplate ControlTemplateLookup[]=
+{
+ { &ControlWrapper::mControlTemplate }, // CONTROL
+ { &ControlWrapper::mItemViewTemplate } // ITEMVIEW
+};
+
+/**
+ * Bitmask of API's that an control can support
+ */
+enum ControlApiBitMask
+{
+ CONTROL_API = 1 << 0,
+ ITEMVIEW_API = 1 << 1
+};
+
+/**
+ * structure used for the ControlApiLookup.
+ */
+struct ControlApiStruct
+{
+ const char* controlName;
+ ControlWrapper::ControlType controlType;
+ Toolkit::Control (*constructor)( const v8::FunctionCallbackInfo< v8::Value >& args);
+ int supportApis;
+};
+
+/**
+ * Lookup table to match a control type with a constructor and supported API's.
+ * ControlWrapper::ControlType is used to index this table
+ */
+const ControlApiStruct ControlApiLookup[]=
+{
+ {"Control", ControlWrapper::CONTROL, NULL, CONTROL_API },
+ {"ItemView", ControlWrapper::ITEMVIEW, ItemViewApi::New, CONTROL_API | ITEMVIEW_API },
+};
+
+const unsigned int ControlApiLookupCount = sizeof(ControlApiLookup)/sizeof(ControlApiLookup[0]);
+
+
+/**
+ * Creates a control given a type name
+ * Uses the type registry to create an control of the correct type
+ */
+Toolkit::Control CreateControl( const v8::FunctionCallbackInfo< v8::Value >& args,
+ const std::string& typeName )
+{
+ Toolkit::Control control;
+
+ ControlWrapper::ControlType controlType = ControlWrapper::GetControlType( typeName );
+
+ // if we don't currently have specific binding for the given control type,
+ // try to use type registry to create it
+ if( controlType == ControlWrapper::UNKNOWN_CONTROL )
+ {
+ Dali::TypeInfo typeInfo = Dali::TypeRegistry::Get().GetTypeInfo( typeName );
+ if( typeInfo )
+ {
+ Dali::BaseHandle handle = typeInfo.CreateInstance();
+ if( handle )
+ {
+ control = Toolkit::Control::DownCast( handle );
+ if( !control )
+ {
+ DALI_SCRIPT_EXCEPTION( args.GetIsolate(), "Unknown control type" );
+ return Toolkit::Control();
+ }
+ }
+ }
+ }
+ else
+ {
+ // run the constructor for this type of control so it can pull out custom parameters
+ control = (ControlApiLookup[controlType].constructor)( args );
+ }
+
+ return control;
+}
+
+/**
+ * given a control type return what api's it supports
+ */
+int GetControlSupportedApis( ControlWrapper::ControlType type )
+{
+ return ControlApiLookup[type].supportApis;
+}
+
+/**
+ * Used for the ControlFunctionTable to map function names to functions
+ * with for a specific API
+ */
+struct ControlFunctions
+{
+ const char* name; ///< function name
+ void (*function)( const v8::FunctionCallbackInfo< v8::Value >& args);
+ ControlApiBitMask api;
+};
+
+/**
+ * Contains a list of all functions that can be called in
+ * ItemView
+ */
+const ControlFunctions ControlFunctionTable[]=
+{
+
+ /**************************************
+ * ItemView API
+ **************************************/
+ { "GetLayoutCount", ItemViewApi::GetLayoutCount, ITEMVIEW_API },
+ { "AddLayout", ItemViewApi::AddLayout, ITEMVIEW_API },
+ { "RemoveLayout", ItemViewApi::RemoveLayout, ITEMVIEW_API },
+ { "ActivateLayout", ItemViewApi::ActivateLayout, ITEMVIEW_API },
+ { "GetItemSize", ItemViewApi::GetItemSize, ITEMVIEW_API },
+ { "SetItemSize", ItemViewApi::SetItemSize, ITEMVIEW_API },
+ { "ScrollToItem", ItemViewApi::ScrollToItem, ITEMVIEW_API },
+ { "GetItem", ItemViewApi::GetItem, ITEMVIEW_API },
+ { "GetItemId", ItemViewApi::GetItemId, ITEMVIEW_API },
+ { "GetItemsRange", ItemViewApi::GetItemsRange, ITEMVIEW_API },
+
+};
+
+const unsigned int ControlFunctionTableCount = sizeof(ControlFunctionTable)/sizeof(ControlFunctionTable[0]);
+} //un-named space
+
+
+ControlWrapper::ControlWrapper( Toolkit::Control control,
+ GarbageCollectorInterface& gc )
+: ActorWrapper( control, gc ),
+ mControl( control )
+
+{
+}
+
+ControlWrapper::~ControlWrapper()
+{
+ mControlGarbageContainer.Release();
+}
+
+v8::Handle<v8::Object> ControlWrapper::WrapControl(v8::Isolate* isolate, Toolkit::Control control )
+{
+ v8::EscapableHandleScope handleScope( isolate );
+
+ // Check whether the control is a Control
+ ControlWrapper::ControlType controlType = GetControlType( control.GetTypeName() );
+
+ if( controlType == ControlWrapper::UNKNOWN_CONTROL && Toolkit::Control::DownCast(control) )
+ {
+ controlType = ControlWrapper::CONTROL;
+ }
+
+ v8::Local<v8::Object> object = WrapControl( isolate, control, controlType );
+
+ return handleScope.Escape( object );
+}
+
+Toolkit::Control ControlWrapper::GetControl()
+{
+ return mControl;
+}
+
+v8::Handle<v8::Object> ControlWrapper::WrapControl( v8::Isolate* isolate, Toolkit::Control control, ControlType controlType )
+{
+ v8::EscapableHandleScope handleScope( isolate );
+ v8::Local<v8::ObjectTemplate> objectTemplate;
+
+ objectTemplate = GetControlTemplate( isolate, controlType );
+
+ // create an instance of the template
+ v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
+
+ // create the control object
+ ControlWrapper* pointer = new ControlWrapper( control, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
+
+ // assign the JavaScript object to the wrapper.
+ // This also stores Dali object, in an internal field inside the JavaScript object.
+ pointer->SetJavascriptObject( isolate, localObject );
+
+ return handleScope.Escape( localObject );
+}
+
+v8::Local<v8::ObjectTemplate> ControlWrapper::GetControlTemplate( v8::Isolate* isolate, ControlWrapper::ControlType type )
+{
+ v8::EscapableHandleScope handleScope( isolate );
+ v8::Local<v8::ObjectTemplate> objectTemplate;
+
+ if( ControlTemplateLookup[type].controlTemplate->IsEmpty() )
+ {
+ objectTemplate = MakeDaliControlTemplate( isolate, type );
+ ControlTemplateLookup[type].controlTemplate->Reset( isolate, objectTemplate );
+ }
+ else
+ {
+ // get the object template
+ objectTemplate = v8::Local<v8::ObjectTemplate>::New( isolate, *ControlTemplateLookup[type].controlTemplate );
+ }
+
+ return handleScope.Escape( objectTemplate );
+}
+
+v8::Handle<v8::ObjectTemplate> ControlWrapper::MakeDaliControlTemplate( v8::Isolate* isolate, ControlType controlType )
+{
+ v8::EscapableHandleScope handleScope( isolate );
+
+ // all the controls support actor APIs
+ v8::Local<v8::ObjectTemplate> objTemplate = ActorWrapper::MakeDaliActorTemplate( isolate, ActorWrapper::ACTOR );
+
+ // find out what API's this control supports
+ int supportApis = GetControlSupportedApis( controlType );
+
+ // add our function properties
+ for( unsigned int i = 0; i < ControlFunctionTableCount; ++i )
+ {
+ const ControlFunctions property = ControlFunctionTable[i];
+
+ // check to see if the control supports a certain type of API
+ // e.g. ItemView will support CONTROL_API and ITEMVIEW_API
+ if( supportApis & property.api )
+ {
+ std::string funcName = V8Utils::GetJavaScriptFunctionName( property.name);
+
+ objTemplate->Set( v8::String::NewFromUtf8( isolate, funcName.c_str() ),
+ v8::FunctionTemplate::New( isolate, property.function ) );
+ }
+ }
+
+ return handleScope.Escape( objTemplate );
+}
+
+void ControlWrapper::NewControl( const v8::FunctionCallbackInfo< v8::Value >& args)
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ if( !args.IsConstructCall() )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "constructor called without 'new" );
+ return;
+ }
+
+ bool found( false );
+ std::string controlName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
+
+ Toolkit::Control control;
+ if( found && controlName != ControlApiLookup[0].controlName )
+ {
+ control = CreateControl( args, controlName ); // create the control with the given type
+ }
+ else
+ {
+ control = Toolkit::Control::New(); // no given type, so create the base type of control
+ }
+
+ if( control )
+ {
+ v8::Local<v8::Object> localObject = WrapControl( isolate, control );
+ args.GetReturnValue().Set( localObject );
+ }
+ else
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "unsupported control type" );
+ }
+}
+
+/**
+ * Given a control type name, e.g. ItemView returns the type, e.g. ControlWrapper::ITEMVIEW
+ */
+ControlWrapper::ControlType ControlWrapper::GetControlType( const std::string& name )
+{
+ for( unsigned int i = 0 ; i < ControlApiLookupCount ; i++ )
+ {
+ if( ControlApiLookup[i].controlName == name )
+ {
+ return ControlApiLookup[i].controlType;
+ }
+ }
+ return ControlWrapper::UNKNOWN_CONTROL;
+}
+
+void ControlWrapper::RegisterGarbage(void* garbage)
+{
+ mControlGarbageContainer.PushBack(garbage);
+}
+
+} // namespace V8Plugin
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_V8PLUGIN_CONTROL_WRAPPER_H__
+#define __DALI_V8PLUGIN_CONTROL_WRAPPER_H__
+
+/*
+ * Copyright (c) 2015 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 <v8.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali-toolkit/public-api/controls/control.h>
+
+// INTERNAL INCLUDES
+#include <actors/actor-wrapper.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+
+/**
+ * Wraps a Dali Control.
+ */
+class ControlWrapper : public ActorWrapper
+{
+
+public:
+
+ /**
+ * Control type used an index.
+ * These enums are used to index the ControlApiLookup table in control-wrapper.cpp.
+ * Any changes made must be reflected in the ControlApiLookup otherwise it may segfault when creating a control
+ */
+ enum ControlType
+ {
+ UNKNOWN_CONTROL = -1,
+ CONTROL = 0,
+ ITEMVIEW = 1
+ };
+
+ /**
+ * Constructor
+ * @param control DALi control
+ * @param gc garbage collection interface
+ */
+ ControlWrapper( Toolkit::Control control,
+ GarbageCollectorInterface& gc );
+
+ /**
+ * destructor
+ */
+ virtual ~ControlWrapper();
+
+ /**
+ * @brief Creates a new Control wrapped inside a Javascript Object.
+ * @note: the control type is passed as a parameter e.g. 'ItemView'
+ * @param[in] args v8 function call arguments interpreted
+ */
+ static void NewControl( const v8::FunctionCallbackInfo< v8::Value >& args);
+
+ /**
+ * @brief Wraps a control of a given type
+ */
+ static v8::Handle<v8::Object> WrapControl(v8::Isolate* isolate, Toolkit::Control control, ControlType controlType);
+
+ /**
+ * @brief Wraps a control, the type is looked up from the control
+ */
+ static v8::Handle<v8::Object> WrapControl(v8::Isolate* isolate, Toolkit::Control control );
+
+ // The Control ObjectTemplates.
+ static v8::Persistent<v8::ObjectTemplate> mControlTemplate;
+ static v8::Persistent<v8::ObjectTemplate> mItemViewTemplate;
+ static v8::Persistent<v8::ObjectTemplate> mScrollViewTemplate;
+
+ /**
+ * @return the wrapped control
+ */
+ Toolkit::Control GetControl();
+
+ /**
+ * @return the control type
+ */
+ static ControlWrapper::ControlType GetControlType( const std::string& name );
+
+ /**
+ * @brief Register the garbage to be released when the wrapped control is deleted.
+ */
+ static void RegisterGarbage(void* garbage);
+
+private:
+
+ /**
+ * Helper to make the control template
+ */
+ static v8::Handle<v8::ObjectTemplate> MakeDaliControlTemplate( v8::Isolate* isolate, ControlType controlType );
+
+ /**
+ * Helper, get a control template given a control type
+ */
+ static v8::Local<v8::ObjectTemplate> GetControlTemplate( v8::Isolate* isolate, ControlType type );
+
+ Toolkit::Control mControl;
+ static Vector< void* > mControlGarbageContainer;
+
+};
+
+} // namespace V8Plugin
+
+} // namespace Dali
+
+#endif // header
--- /dev/null
+/*
+ * Copyright (c) 2015 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 "item-factory-wrapper.h"
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+#include <dali/devel-api/object/weak-handle.h>
+#include <dali-toolkit/devel-api/builder/builder.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-view.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h>
+
+// INTERNAL INCLUDES
+#include <v8-utils.h>
+#include <dali-wrapper.h>
+#include <shared/api-function.h>
+#include <shared/object-template-helper.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+v8::Persistent<v8::ObjectTemplate> ItemFactoryWrapper::mItemFactoryTemplate;
+
+namespace
+{
+
+typedef std::vector< Property::Map > ItemDataContainer;
+
+// Implementation of ItemFactory for providing actors to ItemView
+class ItemFactory : public Toolkit::ItemFactory
+{
+public:
+
+ /**
+ * Constructor
+ * @param application class, stored as reference
+ */
+ ItemFactory()
+ : mJsonFileLoaded(false),
+ mNumberOfItems(0)
+ {
+ mBuilder = Toolkit::Builder::New();
+ }
+
+ /**
+ * Set the name of the JSON file which defines the templates of items.
+ * @param jsonFile The JSON file
+ */
+ void SetJsonTemplateFile(std::string jsonFile)
+ {
+ if(mJsonFile != jsonFile)
+ {
+ mJsonFile = jsonFile;
+ LoadJsonFile(mJsonFile);
+
+ // Check whether any layout activated in ItemView
+ Toolkit::ItemView itemView = mItemView.GetHandle();
+ if(itemView && itemView.GetActiveLayout() != NULL)
+ {
+ // Refresh ItemView if item templates are changed
+ itemView.Refresh();
+ }
+ }
+ }
+
+ /**
+ * Returns the name of the JSON file.
+ * @return The JSON file name
+ */
+ std::string GetJsonTemplate()
+ {
+ return mJsonFile;
+ }
+
+ /**
+ * Set the data to be used to create new items.
+ *
+ * If ItemView is already created, this will immediately update ItemView with the
+ * new data.
+ *
+ * The data is an array of property maps in which each map contains the data for
+ * each item, including the template to be used to build the actor and the pairs
+ * of key/value to be used to replace the constants defined in the template.
+ * The order of property maps in the array represents the actual order of items
+ * in ItemView.
+ *
+ * @param data The array of property maps
+ */
+ void SetData(ItemDataContainer data)
+ {
+ ItemDataContainer currentData = mData;
+ mData = data;
+ mNumberOfItems = mData.size();
+
+ // Check whether any layout activated in ItemView
+ Toolkit::ItemView itemView = mItemView.GetHandle();
+ if(itemView && itemView.GetActiveLayout() != NULL)
+ {
+ unsigned int currentNumberOfItems = currentData.size();
+ unsigned int newNumberOfItems = data.size();
+
+ // Check whether any items added or deleted from the data
+ // which requires ItemView to be refreshed with the new data
+ if(currentNumberOfItems != newNumberOfItems)
+ {
+ itemView.Refresh();
+ }
+ else
+ {
+ for( unsigned int itemId = 0; itemId < newNumberOfItems; itemId++)
+ {
+ // Check whether the item is already built in ItemView
+ Actor itemActor = itemView.GetItem(itemId);
+ if(itemActor)
+ {
+ // Check if the item needs to be rebuilt
+ if( !V8Utils::IsPropertyMapIdentical(currentData[itemId], data[itemId]) )
+ {
+ // Rebuild the item with the new data
+ Actor newItemActor = NewItem(itemId);
+
+ // Replace the old item with the new one
+ itemView.ReplaceItem( Toolkit::Item( itemId, newItemActor ), 0.0f );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Retrieve the data.
+ * @return the data.
+ */
+ ItemDataContainer GetData()
+ {
+ return mData;
+ }
+
+ /**
+ * Store a weak handle of ItemView in order to access ItemView APIs
+ * from this ItemFactory implementation
+ * @return the data.
+ */
+ void SetItemView(Toolkit::ItemView itemView)
+ {
+ mItemView = itemView;
+ }
+
+public: // From Toolkit::ItemFactory
+
+ /**
+ * Query the number of items available from the factory.
+ * The maximum available item has an ID of GetNumberOfItems() - 1.
+ */
+ virtual unsigned int GetNumberOfItems()
+ {
+ return mJsonFileLoaded ? mNumberOfItems : 0;
+ }
+
+ /**
+ * Create an Actor to represent a visible item.
+ * @param itemId
+ * @return the created actor.
+ */
+ virtual Actor NewItem(unsigned int itemId)
+ {
+ std::string itemTemplate;
+
+ Property::Map constantsMap = mData[itemId];
+ for ( unsigned int i = 0, count = constantsMap.Count(); i < count; ++i )
+ {
+ Property::Value& constantValue = constantsMap.GetValue(i);
+ if(constantsMap.GetKey(i) == "template")
+ {
+ constantValue.Get(itemTemplate);
+ }
+ else
+ {
+ mBuilder.AddConstant( constantsMap.GetKey(i), constantValue );
+ }
+ }
+
+ Actor item = Actor::DownCast( mBuilder.Create(itemTemplate) );
+ return item;
+ }
+
+private:
+
+ /**
+ * Load the JSON file.
+ * @param The JSON file name
+ */
+ void LoadJsonFile(std::string jsonFile)
+ {
+ try
+ {
+ std::string data;
+ V8Utils::GetFileContents(jsonFile, data);
+
+ mBuilder.LoadFromString(data);
+
+ mJsonFileLoaded = true;
+ }
+ catch(...)
+ {
+// printf("invalid JSON data\n");
+ mJsonFileLoaded = false;
+ }
+ }
+
+private:
+
+ std::string mJsonFile;
+ bool mJsonFileLoaded;
+ Toolkit::Builder mBuilder;
+ unsigned int mNumberOfItems;
+ ItemDataContainer mData;
+ WeakHandle< Toolkit::ItemView > mItemView;
+};
+
+} //un-named space
+
+ItemFactoryWrapper::ItemFactoryWrapper( Toolkit::ItemFactory& factory, GarbageCollectorInterface& gc )
+: BaseWrappedObject( BaseWrappedObject::ITEMFACTORY , gc ),
+ mItemFactory( factory )
+{
+}
+
+ItemFactoryWrapper::~ItemFactoryWrapper()
+{
+}
+
+v8::Handle<v8::Object> ItemFactoryWrapper::WrapItemFactory(v8::Isolate* isolate, Toolkit::ItemFactory& factory )
+{
+ v8::EscapableHandleScope handleScope( isolate );
+ v8::Local<v8::ObjectTemplate> objectTemplate;
+
+ objectTemplate = GetItemFactoryTemplate( isolate );
+
+ // create an instance of the template
+ v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
+
+ // create the ItemFactory wrapper
+ ItemFactoryWrapper* pointer = new ItemFactoryWrapper( factory, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
+
+ // assign the JavaScript object to the wrapper.
+ pointer->SetJavascriptObject( isolate, localObject );
+
+ return handleScope.Escape( localObject );
+}
+
+v8::Local<v8::ObjectTemplate> ItemFactoryWrapper::GetItemFactoryTemplate( v8::Isolate* isolate)
+{
+ v8::EscapableHandleScope handleScope( isolate );
+ v8::Local<v8::ObjectTemplate> objectTemplate;
+
+ if( mItemFactoryTemplate.IsEmpty() )
+ {
+ objectTemplate = MakeItemFactoryTemplate( isolate );
+ mItemFactoryTemplate.Reset( isolate, objectTemplate );
+ }
+ else
+ {
+ // get the object template
+ objectTemplate = v8::Local<v8::ObjectTemplate>::New( isolate, mItemFactoryTemplate );
+ }
+ return handleScope.Escape( objectTemplate );
+}
+
+v8::Handle<v8::ObjectTemplate> ItemFactoryWrapper::MakeItemFactoryTemplate( v8::Isolate* isolate )
+{
+ v8::EscapableHandleScope handleScope( isolate );
+
+ v8::Local<v8::ObjectTemplate> objTemplate = v8::ObjectTemplate::New();
+
+ objTemplate->SetInternalFieldCount( BaseWrappedObject::FIELD_COUNT );
+
+ // set property setter and getter
+ objTemplate->SetNamedPropertyHandler( ItemFactoryWrapper::PropertyGet, ItemFactoryWrapper::PropertySet);
+
+ return handleScope.Escape( objTemplate );
+}
+
+void ItemFactoryWrapper::NewItemFactory( const v8::FunctionCallbackInfo< v8::Value >& args)
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate);
+
+ if( !args.IsConstructCall() )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "ItemFactory constructor called without 'new'" );
+ return;
+ }
+
+ Toolkit::ItemFactory* factory = new ItemFactory();
+
+ v8::Local<v8::Object> localObject = WrapItemFactory( isolate, *factory );
+ args.GetReturnValue().Set( localObject );
+}
+
+Toolkit::ItemFactory& ItemFactoryWrapper::GetItemFactoryFromParams( int paramIndex,
+ bool& found,
+ v8::Isolate* isolate,
+ const v8::FunctionCallbackInfo< v8::Value >& args )
+{
+ found = false;
+
+ v8::HandleScope handleScope( isolate );
+ BaseWrappedObject* wrappedObject = V8Utils::GetWrappedDaliObjectParameter( paramIndex, BaseWrappedObject::ITEMFACTORY, isolate, args );
+ if( wrappedObject )
+ {
+ found = true;
+ ItemFactoryWrapper* wrapper = static_cast< ItemFactoryWrapper *>(wrappedObject);
+ return wrapper->GetItemFactory();
+ }
+ else
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "no valid ItemFactory parameter" );
+ Toolkit::ItemFactory* dummyFactory = new ItemFactory();
+ return *dummyFactory; // avoid build error
+ }
+}
+
+ItemFactoryWrapper* ItemFactoryWrapper::Unwrap( v8::Isolate* isolate, v8::Handle< v8::Object> obj)
+{
+ v8::HandleScope handleScope( isolate );
+
+ v8::Local<v8::External> field = v8::Local<v8::External>::Cast( obj->GetInternalField(0) );
+ void* ptr = field->Value();
+ return static_cast< ItemFactoryWrapper *>(ptr);
+}
+
+void ItemFactoryWrapper::PropertyGet( v8::Local<v8::String> propertyName,
+ const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+ v8::Isolate* isolate = info.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ // get the property name
+ std::string name = V8Utils::v8StringToStdString( propertyName );
+
+ if( std::isupper( name[0] ))
+ {
+ return;
+ }
+
+ // unwrap the object
+ ItemFactoryWrapper* itemFactoryWrapper = Unwrap( isolate, info.This() );
+ if( !itemFactoryWrapper )
+ {
+ return;
+ }
+
+ ItemFactory& factory = static_cast<ItemFactory&>( itemFactoryWrapper->GetItemFactory() );
+
+ if( name == "jsonTemplateFile" )
+ {
+ std::string jsonTemplateFile = factory.GetJsonTemplate();
+ info.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, jsonTemplateFile.c_str()));
+ }
+ else if( name == "data" )
+ {
+ ItemDataContainer data = factory.GetData();
+ unsigned int itemCount = data.size();
+
+ v8::Local<v8::Array> array= v8::Array::New( isolate, itemCount );
+ for( unsigned int i = 0; i < itemCount; i++)
+ {
+ v8::Local<v8::Object> mapObject = v8::Object::New( isolate );
+ V8Utils::CreatePropertyMap( isolate, data[i], mapObject );
+
+ array->Set( i, mapObject);
+ }
+
+ info.GetReturnValue().Set(array);
+ }
+ else
+ {
+ std::string error="Invalid property Get for "+name + "\n";
+ DALI_SCRIPT_EXCEPTION( isolate, error );
+ }
+}
+
+void ItemFactoryWrapper::PropertySet( v8::Local<v8::String> propertyName,
+ v8::Local<v8::Value> javaScriptValue,
+ const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+
+ v8::Isolate* isolate = info.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ // get the property name
+ std::string name = V8Utils::v8StringToStdString( propertyName );
+
+ // unwrap the object
+ ItemFactoryWrapper* itemFactoryWrapper = Unwrap( isolate, info.This() );
+ if( !itemFactoryWrapper )
+ {
+ return;
+ }
+
+ ItemFactory& factory = static_cast<ItemFactory&>( itemFactoryWrapper->GetItemFactory() );
+
+ if( name == "jsonTemplateFile" && javaScriptValue->IsString() )
+ {
+ std::string jsonTemplateFile = V8Utils::v8StringToStdString( javaScriptValue );
+ factory.SetJsonTemplateFile(jsonTemplateFile);
+ }
+ else if( name == "data" && javaScriptValue->IsArray() )
+ {
+ v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(javaScriptValue);
+
+ ItemDataContainer data;
+
+ for( unsigned int i = 0; i < array->Length(); ++i )
+ {
+ v8::Local<v8::Value> itemData = array->Get(i);
+
+ if( itemData->IsObject() )
+ {
+ Dali::Property::Map map = V8Utils::GetPropertyMapFromObject( isolate, itemData->ToObject() );
+ data.push_back(map);
+ }
+ }
+
+ factory.SetData(data);
+ }
+ else
+ {
+ std::string error = "Invalid property Set for " + name + "\n";
+ DALI_SCRIPT_EXCEPTION( isolate, error );
+ }
+}
+
+Toolkit::ItemFactory& ItemFactoryWrapper::GetItemFactory()
+{
+ return mItemFactory;
+}
+
+void ItemFactoryWrapper::SetItemView(Toolkit::ItemFactory& itemFactory, Toolkit::ItemView itemView)
+{
+ ItemFactory& factory = static_cast<ItemFactory&>( itemFactory );
+ factory.SetItemView(itemView);
+}
+
+} // namespace V8Plugin
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_V8PLUGIN_ITEM_FACTORY_WRAPPER_H__
+#define __DALI_V8PLUGIN_ITEM_FACTORY_WRAPPER_H__
+
+/*
+ * Copyright (c) 2015 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 <v8.h>
+#include <dali/public-api/common/dali-vector.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-factory.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-view.h>
+
+// INTERNAL INCLUDES
+#include <shared/base-wrapped-object.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+
+/**
+ * Wraps a Dali ItemFactory.
+ */
+class ItemFactoryWrapper : public BaseWrappedObject
+{
+
+public:
+
+ /**
+ * Constructor
+ * @param factory DALi ItemFactory
+ * @param gc garbage collection interface
+ */
+ ItemFactoryWrapper( Toolkit::ItemFactory& factory,
+ GarbageCollectorInterface& gc );
+
+ /**
+ * destructor
+ */
+ virtual ~ItemFactoryWrapper();
+
+ /**
+ * @brief Creates a new ItemFactory wrapped inside a Javascript Object.
+ * @note: the item template and data are passed as a parameter e.g. 'template'
+ * @param[in] args v8 function call arguments interpreted
+ */
+ static void NewItemFactory( const v8::FunctionCallbackInfo< v8::Value >& args);
+
+ /**
+ * @brief Wraps an ItemFactory
+ */
+ static v8::Handle<v8::Object> WrapItemFactory(v8::Isolate* isolate, Toolkit::ItemFactory& factory );
+
+ // The ItemFactory ObjectTemplates.
+ static v8::Persistent<v8::ObjectTemplate> mItemFactoryTemplate;
+
+ /**
+ * @brief Helper to get ItemFactory from the JavaScript object held in the given function argument
+ * @param[in] paramIndex Argument index the object is held in
+ * @param[in] found Whether ItemFactory is found in the given function parameter
+ * @param[in] isolate v8 isolated instance
+ * @param[in] args v8 function call arguments interpreted
+ */
+ static Toolkit::ItemFactory& GetItemFactoryFromParams( int paramIndex,
+ bool& found,
+ v8::Isolate* isolate,
+ const v8::FunctionCallbackInfo< v8::Value >& args );
+
+ /**
+ * @brief Helper to store a weak handle of ItemView in the given ItemFactory
+ * @param[in] itemFactory The item factory used to provide items to the given item view
+ * @param[in] itemView The ItemView which uses the given item factory to create items
+ */
+ static void SetItemView(Toolkit::ItemFactory& itemFactory, Toolkit::ItemView itemView);
+
+ /**
+ * @return the wrapped item factory
+ */
+ Toolkit::ItemFactory& GetItemFactory();
+
+private:
+
+ /**
+ * Helper to make the item factory template
+ */
+ static v8::Handle<v8::ObjectTemplate> MakeItemFactoryTemplate( v8::Isolate* isolate );
+
+ /**
+ * Helper, get a item factory template
+ */
+ static v8::Local<v8::ObjectTemplate> GetItemFactoryTemplate( v8::Isolate* isolate );
+
+ /**
+ * @brief get the value for a property for JavaScript object than contains a Dali ItemFactory.
+ * E.g. Get( "data", JavaScript object that wraps a Dali ItemFactory )
+ * @param[in] propertyName property name
+ * @param[in] info reference to PropertyCallbackInfo structure (contains the Javascript
+ * object and the return value).
+ */
+ static void PropertyGet( v8::Local<v8::String> propertyName,
+ const v8::PropertyCallbackInfo<v8::Value>& info);
+
+ /**
+ * @brief Set the value for a property for JavaScript object than contains a Dali ItemFactory.
+ * E.g. Set( "data", itemData, JavaScript object that wraps a Dali ItemFactory)
+ * @param[in] propertyName property name
+ * @param[in] javaScriptValue javascript value to set, this is typically a number
+ * @param[in] info reference to PropertyCallbackInfo structure (contains the Javascript
+ * object).
+ */
+ static void PropertySet( v8::Local<v8::String> propertyName,
+ v8::Local<v8::Value> javaScriptValue,
+ const v8::PropertyCallbackInfo<v8::Value>& info);
+
+
+ /**
+ * @brief Extract a item factory wrapper from a javascript object
+ * @return item factory wrapper
+ */
+ static ItemFactoryWrapper* Unwrap( v8::Isolate* isolate, v8::Handle< v8::Object> obj);
+
+ Toolkit::ItemFactory& mItemFactory;
+
+};
+
+} // namespace V8Plugin
+
+} // namespace Dali
+
+#endif // header
--- /dev/null
+/*
+ * Copyright (c) 2015 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 "item-view-api.h"
+
+// EXTERNAL INCLUDES
+#include <fstream>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-factory.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/default-item-layout.h>
+
+// INTERNAL INCLUDES
+#include <v8-utils.h>
+#include <actors/actor-wrapper.h>
+#include <controls/control-wrapper.h>
+#include <controls/item-factory-wrapper.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+namespace // unanmed namespace
+{
+
+Toolkit::ItemView GetItemView( v8::Isolate* isolate, const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+ HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, args.This() );
+ return Toolkit::ItemView::DownCast( handleWrapper->mHandle );
+}
+
+} //unanmed namespace
+
+/***************************************
+ * ITEMVIEW API FUNCTIONS
+ ***************************************/
+
+/**
+ * Constructor
+ *
+ * @for ItemView
+ * @constructor
+ * @method ItemView
+ * @return {Object} itemView
+ */
+Toolkit::Control ItemViewApi::New( const v8::FunctionCallbackInfo< v8::Value >& args )
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ bool found( false );
+ Toolkit::ItemFactory& factory = ItemFactoryWrapper::GetItemFactoryFromParams( 1, found, isolate, args );
+ if( !found )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "invalid ItemFactory parameter" );
+ return Toolkit::Control();
+ }
+ else
+ {
+ Toolkit::ItemView itemView = Toolkit::ItemView::New(factory);
+ ItemFactoryWrapper::SetItemView(factory, itemView);
+ return itemView;
+ }
+}
+
+/**
+ * Query the number of layouts.
+ *
+ * @for ItemView
+ * @method getLayoutCount
+ * @return {Integer} The number of layouts.
+ */
+void ItemViewApi::GetLayoutCount( const v8::FunctionCallbackInfo< v8::Value >& args)
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+ args.GetReturnValue().Set( v8::Integer::New( isolate, itemView.GetLayoutCount() ) );
+}
+
+/**
+ * Add a layout
+ *
+ * @for ItemView
+ * @method addLayout
+ * @param {Integer} layout The layout to be added
+ * @example
+ * // layout is one of the following
+ * dali.ITEM_LAYOUT_LIST
+ * dali.ITEM_LAYOUT_GRID
+ *
+ * itemView.addLayout( dali.ITEM_LAYOUT_LIST );
+ */
+void ItemViewApi::AddLayout( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+ bool found( false );
+ int layout = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+ if( !found )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "invalid layout parameter" );
+ return;
+ }
+
+ Toolkit::ItemLayoutPtr layoutPtr = Toolkit::DefaultItemLayout::New( static_cast<Toolkit::DefaultItemLayout::Type>(layout) );
+ itemView.AddLayout( *layoutPtr );
+}
+
+/**
+ * Remove a layout.
+ *
+ * @for ItemView
+ * @method removeLayout
+ * @param {Integer} layoutIndex The index of the ItemView layouts which must be less than getLayoutCount().
+ */
+void ItemViewApi::RemoveLayout( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+ bool found( false );
+ int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+ if( !found )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "invalid index parameter" );
+ return;
+ }
+
+ itemView.RemoveLayout( layoutIndex );
+}
+
+/**
+ * Activate one of the layouts. This will resize the ItemView and relayout actors within the ItemView.
+ *
+ * @for ItemView
+ * @method activateLayout
+ * @param {Integer} layoutIndex The index of the ItemView layout which must be less than getLayoutCount().
+ * @param {Object} targetSize An array of 3 numbers for the target ItemView and layout size.
+ * @param {Float} [durationSeconds] The time taken to relayout in seconds (0 by default for immediate).
+ */
+void ItemViewApi::ActivateLayout( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+ bool found( false );
+ int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 );
+ if( !found )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "invalid layout index parameter" );
+ return;
+ }
+
+ found = false;
+ Vector3 targetSize = V8Utils::GetVector3Parameter( PARAMETER_1, found, isolate, args );
+ if( !found )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "Vector3 targetSize size parameter missing" );
+ return;
+ }
+
+ found = false;
+ float durationSeconds = V8Utils::GetFloatParameter( PARAMETER_2, found, isolate, args, 0.0f ); // 0 by default for immediate activation
+
+ itemView.ActivateLayout( layoutIndex, targetSize, durationSeconds );
+}
+
+/**
+ * Retrieve the target size of an item in the given layout.
+ * This will return the default size for the layout unless overridden by calling setLayoutItemSize().
+ *
+ * @for ItemView
+ * @method getItemSize
+ * @param {Integer} layoutIndex The index of the ItemView layout which must be less than getLayoutCount().
+ * @param {Integer} itemId The ID of an item in the layout.
+ * @param {Object} targetLayoutSize An array of 3 numbers for the target ItemView and layout size.
+ * @return {Object} The target size of the item {x, y, z}.
+ */
+void ItemViewApi::GetItemSize( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+ bool found( false );
+ int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+ if( !found )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "invalid layout index parameter" );
+ return;
+ }
+
+ found = false;
+ int itemId = V8Utils::GetIntegerParameter( PARAMETER_1, found, isolate, args, 0 /* default */);
+ if( !found )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "invalid item ID parameter" );
+ return;
+ }
+
+ found = false;
+ Vector3 targetLayoutSize = V8Utils::GetVector3Parameter( PARAMETER_2, found, isolate, args );
+ if( found )
+ {
+ Toolkit::ItemLayoutPtr layoutPtr = itemView.GetLayout(layoutIndex);
+ Vector3 itemSize;
+ layoutPtr->GetItemSize( itemId, targetLayoutSize, itemSize );
+
+ v8::Local<v8::Object> itemSizeObject = v8::Object::New( isolate );
+
+ itemSizeObject->Set( v8::String::NewFromUtf8( isolate, "x" ), v8::Integer::New( isolate, itemSize.width ) );
+ itemSizeObject->Set( v8::String::NewFromUtf8( isolate, "y" ), v8::Integer::New( isolate, itemSize.height ) );
+ itemSizeObject->Set( v8::String::NewFromUtf8( isolate, "z" ), v8::Integer::New( isolate, itemSize.depth ) );
+
+ args.GetReturnValue().Set( itemSizeObject );
+ }
+ else
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "invalid Vector3 target size parameter" );
+ }
+}
+
+/**
+ * Set the size of the item for the given layout which overrides the default item size for the layout.
+ *
+ * @for ItemView
+ * @method setItemSize
+ * @param {Integer} layoutIndex The index of the ItemView layout which must be less than getLayoutCount().
+ * @param {Object} itemSize An array of 3 numbers for the size of the item.
+ * @example
+ * itemView.setLayoutItemSize( 0, [100.0, 50.0, 0.0] );
+ */
+void ItemViewApi::SetItemSize( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+ bool found( false );
+ int layoutIndex = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+ if( !found )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "invalid layout index parameter" );
+ return;
+ }
+
+ found = false;
+ Vector3 itemSize = V8Utils::GetVector3Parameter( PARAMETER_1, found, isolate, args );
+ if( found )
+ {
+ Toolkit::ItemLayoutPtr layoutPtr = itemView.GetLayout(layoutIndex);
+ layoutPtr->SetItemSize( itemSize );
+ }
+ else
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "invalid item size parameter" );
+ }
+}
+
+/**
+ * Scroll the current layout to a particular item.
+ * If calling this with zero second of duration immediately after calling activateLayout(),
+ * it will not work unless the duration of relayout animation for activateLayout is also
+ * set to zero.
+ *
+ * @for ItemView
+ * @method scrollToItem
+ * @param {Integer} itemId The ID of an item in the layout.
+ * @param {Float} [durationSeconds] How long the scrolling takes in seconds (0 by default for instant scrolling to the particular item).
+ */
+void ItemViewApi::ScrollToItem( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+ bool found( false );
+ int itemId = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+ if( !found )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "invalid item Id parameter" );
+ return;
+ }
+
+ found = false;
+ float durationSeconds = V8Utils::GetFloatParameter( PARAMETER_1, found, isolate, args, 0.0f ); // 0 by default for instant scrolling
+
+ itemView.ScrollToItem( itemId, durationSeconds );
+}
+
+/**
+ * Given the Item ID, this returns the accompanying actor.
+ *
+ * @for ItemView
+ * @method getItem
+ * @param {Integer} itemId The Item ID of the actor required.
+ * @return {Object} The Actor corresponding to the Item ID.
+ */
+void ItemViewApi::GetItem( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+ bool found( false );
+ int itemId = V8Utils::GetIntegerParameter( PARAMETER_0, found, isolate, args, 0 /* default */);
+ if( found )
+ {
+ found = false;
+ Actor actor = itemView.GetItem( itemId );
+ if( actor )
+ {
+ found = true;
+ // wrap the actor
+ v8::Handle < v8::Object > wrappedActor = ActorWrapper::WrapActor( isolate, actor );
+ args.GetReturnValue().Set( wrappedActor );
+ }
+ }
+
+ if( !found )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "invalid item ID" );
+ return;
+ }
+}
+
+/**
+ * Returns the Item ID of the specified actor. The actor must be an item of ItemView.
+ *
+ * @for ItemView
+ * @method getItemId
+ * @param {Object} actor The actor whose Item ID is required.
+ * @return {Integer} The Item ID of the item.
+ */
+void ItemViewApi::GetItemId( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+ bool found( false );
+ Actor actor = V8Utils::GetActorParameter( 0, found, isolate, args );
+ if( found )
+ {
+ args.GetReturnValue().Set( itemView.GetItemId(actor) );
+ }
+ else
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "invalid item actor parameter" );
+ return;
+ }
+}
+
+/**
+ * Get the range of items that are currently in ItemView.
+ *
+ * @for ItemView
+ * @method getItemsRange
+ * @return {Object} The range of items in the item ID {begin, end}.
+ */
+void ItemViewApi::GetItemsRange( const v8::FunctionCallbackInfo<v8::Value>& args )
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ Toolkit::ItemView itemView = GetItemView( isolate, args );
+
+ Toolkit::ItemRange range(0, 0);
+ itemView.GetItemsRange(range);
+
+ v8::Local<v8::Object> itemRangeObject = v8::Object::New( isolate );
+
+ itemRangeObject->Set( v8::String::NewFromUtf8( isolate, "begin" ), v8::Integer::New( isolate, range.begin ) );
+ itemRangeObject->Set( v8::String::NewFromUtf8( isolate, "end" ), v8::Integer::New( isolate, range.end ) );
+
+ args.GetReturnValue().Set( itemRangeObject );
+}
+
+} // namespace V8Plugin
+
+} // namespace Dali
--- /dev/null
+#ifndef __DALI_V8PLUGIN_ITEM_VIEW_API_H__
+#define __DALI_V8PLUGIN_ITEM_VIEW_API_H__
+
+/*
+ * Copyright (c) 2015 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 <v8.h>
+#include <dali-toolkit/public-api/controls/scrollable/item-view/item-view.h>
+
+namespace Dali
+{
+
+namespace V8Plugin
+{
+
+namespace ItemViewApi
+{
+
+ /**
+ * constructor
+ */
+ Toolkit::Control New( const v8::FunctionCallbackInfo< v8::Value >& args );
+
+ /**
+ * ItemView API. See item-view.h for description of functions
+ */
+ void GetLayoutCount( const v8::FunctionCallbackInfo< v8::Value >& args);
+ void AddLayout( const v8::FunctionCallbackInfo< v8::Value >& args );
+ void RemoveLayout( const v8::FunctionCallbackInfo< v8::Value >& args );
+ void ActivateLayout( const v8::FunctionCallbackInfo< v8::Value >& args);
+ void GetItemSize( const v8::FunctionCallbackInfo< v8::Value >& args);
+ void SetItemSize( const v8::FunctionCallbackInfo< v8::Value >& args);
+ void ScrollToItem( const v8::FunctionCallbackInfo< v8::Value >& args);
+ void GetItem( const v8::FunctionCallbackInfo< v8::Value >& args);
+ void GetItemId( const v8::FunctionCallbackInfo< v8::Value >& args);
+ void GetItemsRange( const v8::FunctionCallbackInfo< v8::Value >& args);
+
+}; // namespace ItemViewApi
+
+} // namespace V8Plugin
+
+} // namespace Dali
+
+#endif // header __DALI_V8PLUGIN_ITEM_VIEW_API_H__
#include <object/property-value-wrapper.h>
#include <dali/integration-api/debug.h>
#include <actors/actor-wrapper.h>
+#include <controls/control-wrapper.h>
#include <stage/stage-wrapper.h>
#include <image/image-wrapper.h>
#include <animation/linear-constrainer-wrapper.h>
#include <animation/path-constrainer-wrapper.h>
#include <animation/path-wrapper.h>
#include <animation/animation-wrapper.h>
+#include <controls/item-factory-wrapper.h>
#include <events/pan-gesture-detector-wrapper.h>
#include <object/property-buffer-wrapper.h>
#include <rendering/geometry-wrapper.h>
{ "Actor", ActorWrapper::NewActor },
{ "CameraActor", ActorWrapper::NewActor },
{ "Layer", ActorWrapper::NewActor },
- { "Control", ActorWrapper::NewControl },
+ { "Control", ControlWrapper::NewControl },
{ "ResourceImage", ImageWrapper::NewImage },
{ "BufferImage", ImageWrapper::NewImage },
{ "FrameBufferImage", ImageWrapper::NewImage },
{ "Animation", AnimationWrapper::NewAnimation},
+ { "ItemFactory", ItemFactoryWrapper::NewItemFactory},
{ "Shader", ShaderWrapper::NewShader},
{ "Sampler", SamplerWrapper::NewSampler},
{ "Material", MaterialWrapper::NewMaterial},
const ApiFunction HandleFunctionTable[]=
{
{ "RegisterAnimatableProperty", HandleWrapper::RegisterAnimatableProperty },
+ { "RegisterCustomProperty", HandleWrapper::RegisterCustomProperty },
};
const unsigned int HandleFunctionTableCount = sizeof(HandleFunctionTable)/sizeof(HandleFunctionTable[0]);
* @return {integer} The index of the property or dali.PROPERTY_INVALID_INDEX if registration failed
* @example
*
- * var morphPropertyIdex = actor.registerAnimatableProperty("uMorphAmount", 0.0f);
- * var fadeColorPropertyIdex = handle.registerAnimatableProperty("uFadeColor", [1.0, 0.0, 0.0, 1.0]);
+ * var morphPropertyIndex = actor.registerAnimatableProperty("uMorphAmount", 0.0f);
+ * var fadeColorPropertyIndex = handle.registerAnimatableProperty("uFadeColor", [1.0, 0.0, 0.0, 1.0]);
*
*/
void HandleWrapper::RegisterAnimatableProperty( const v8::FunctionCallbackInfo< v8::Value >& args )
}
}
+/**
+ * Register a new custom property.
+ *
+ * The object should support dynamic properties.
+ * Property names must be unused.
+ * Property indices are unique to each registered custom property in a given object.
+ * Properties can be set as non animatable using property attributes.
+ * returns dali.PROPERTY_INVALID_INDEX if registration failed.
+ *
+ * @method registerCustomProperty
+ * @for Handle
+ * @param {string} name The name of the property.
+ * @param {Object} propertyValue The new value of the property.
+ * @param {integer} accessMode The property access mode (writable, animatable etc).
+ * @return {integer} The index of the property or dali.PROPERTY_INVALID_INDEX if registration failed
+ * @example
+ *
+ * // access mode is one of the following
+ * dali.PROPERTY_READ_ONLY
+ * dali.PROPERTY_READ_WRITE
+ * dali.PROPERTY_ANIMATABLE
+ *
+ * var cellIndexPropertyIndex = actor.registerCustomProperty("cellIndex", 2, dali.PROPERTY_READ_WRITE);
+ * var myCustomPropertyIndex = handle.registerCustomProperty("myCustomProperty", [10.0, 25.0, 0.0], dali.PROPERTY_READ_ONLY);
+ *
+ */
+void HandleWrapper::RegisterCustomProperty( const v8::FunctionCallbackInfo< v8::Value >& args )
+{
+ v8::Isolate* isolate = args.GetIsolate();
+ v8::HandleScope handleScope( isolate );
+
+ // unwrap the object
+ HandleWrapper* handleWrapper = Unwrap( isolate, args.This() );
+ if( !handleWrapper )
+ {
+ return;
+ }
+
+ Handle handle = handleWrapper->mHandle;
+
+ bool found( false );
+ std::string propertyName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
+ if( !found )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "bad property name parameter" );
+ return;
+ }
+
+ found = false;
+ Dali::Property::Value daliPropertyValue = V8Utils::GetPropertyValueParameter(PARAMETER_1, found, isolate, args );
+ if( !found || Dali::Property::NONE == daliPropertyValue.GetType() )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "bad property value parameter" );
+ return;
+ }
+
+ found = false;
+ int accessMode = V8Utils::GetIntegerParameter( PARAMETER_2, found, isolate, args, 0 /* default */);
+ if( !found )
+ {
+ DALI_SCRIPT_EXCEPTION( isolate, "invalid access mode parameter" );
+ return;
+ }
+ else
+ {
+ args.GetReturnValue().Set( v8::Integer::New( isolate, handle.RegisterProperty( propertyName, daliPropertyValue, static_cast<Property::AccessMode>(accessMode) ) ) );
+ }
+}
+
} // namespace V8Plugin
} // namespace Dali
*/
static void RegisterAnimatableProperty( const v8::FunctionCallbackInfo< v8::Value >& args );
+ /**
+ * @brief Register a custom property for a JavaScript object that
+ * contains a Dali Handle.
+ * @param[in] args v8 function call arguments interpreted
+ */
+ static void RegisterCustomProperty( const v8::FunctionCallbackInfo< v8::Value >& args );
+
Handle GetHandle() { return mHandle; }
Handle mHandle;
ConnectionTracker mConnectionTracker;
IMAGE_ATTRIBUTES,
ACTOR,
ACTOR_PROPERTY,
+ ITEMVIEW,
+ ITEMFACTORY,
RENDER_TASK,
RENDER_TASK_LIST,
TIMER,
}
}
+bool IsPropertyMapIdentical(Property::Map map1, Property::Map map2)
+{
+ bool dirty = false;
+
+ // Compare number of properties
+ if ( map1.Count() != map2.Count() )
+ {
+ dirty = true;
+ }
+ else
+ {
+ for ( unsigned int i = 0, count = map1.Count(); i < count; ++i )
+ {
+ // Compare the key first
+ if(map1.GetKey(i) != map2.GetKey(i))
+ {
+ dirty = true;
+ }
+ else
+ {
+ Property::Value& value = map1.GetValue(i);
+ Property::Value& newValue = map2.GetValue(i);
+
+ // Compare the value type
+ if(value.GetType() != newValue.GetType())
+ {
+ dirty = true;
+ }
+ else
+ {
+ // Compare the value
+ switch( value.GetType() )
+ {
+ case Property::BOOLEAN:
+ {
+ dirty = ( value.Get<bool>() != newValue.Get<bool>() );
+ break;
+ }
+ case Property::FLOAT:
+ {
+ dirty = ( value.Get<float>() != newValue.Get<float>() );
+ break;
+ }
+ case Property::INTEGER:
+ {
+ dirty = ( value.Get<int>() != newValue.Get<int>() );
+ break;
+ }
+ case Property::RECTANGLE:
+ {
+ dirty = ( value.Get< Rect<int> >() != newValue.Get< Rect<int> >() );
+ break;
+ }
+ case Property::VECTOR2:
+ {
+ dirty = ( value.Get<Vector2>() != newValue.Get<Vector2>() );
+ break;
+ }
+ case Property::VECTOR3:
+ {
+ dirty = ( value.Get<Vector3>() != newValue.Get<Vector3>() );
+ break;
+ }
+ case Property::VECTOR4:
+ {
+ dirty = ( value.Get<Vector4>() != newValue.Get<Vector4>() );
+ break;
+ }
+ case Property::MATRIX3:
+ {
+ dirty = ( value.Get<Matrix3>() != newValue.Get<Matrix3>() );
+ break;
+ }
+ case Property::MATRIX:
+ {
+ dirty = ( value.Get<Matrix>() != newValue.Get<Matrix>() );
+ break;
+ }
+ case Property::ROTATION:
+ {
+ dirty = ( value.Get<Quaternion>() != newValue.Get<Quaternion>() );
+ break;
+ }
+ case Property::STRING:
+ {
+ dirty = ( value.Get<std::string>() != newValue.Get<std::string>() );
+ break;
+ }
+ case Property::MAP:
+ {
+ dirty = ( !IsPropertyMapIdentical( value.Get<Property::Map>(), newValue.Get<Property::Map>() ) );
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ if(dirty)
+ {
+ // Different already, no need any further comparison
+ break;
+ }
+ }
+ }
+
+ return !dirty;
+}
+
void ReportException( v8::Isolate* isolate, v8::TryCatch* tryCatch)
{
v8::HandleScope handleScope( isolate );
return;
}
- for( unsigned int index = 0; index < map.Count() - 1; ++index )
+ for( unsigned int index = 0; index < map.Count(); ++index )
{
const std::string& key = map.GetKey( index );
Property::Value& value = map.GetValue( index );
void GetModuleName( const std::string& fileName, std::string& moduleName );
/**
+ * Compare whether two DALi property maps are identical
+ * @param[in] map1 The first property map to be compared
+ * @param[in] map2 The second property map to be compared
+ * @return true if the two specified property maps are identical or false if not.
+ */
+bool IsPropertyMapIdentical(Property::Map map1, Property::Map map2);
+
+/**
* Report an exception by writing as a warning to the Dali Log
*
* @param[in] try_catch The v8 TryCatch exception object