From: xb.teng Date: Fri, 2 Dec 2016 07:07:55 +0000 (+0800) Subject: Add native dali toggle button, base on latest button using visual. X-Git-Tag: dali_1.2.25~9 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=3da85989734c01ef8767835c06f4f5b4bcf0fc54;hp=0c61136cd848c8541ae41e374588b42cbe11ac52 Add native dali toggle button, base on latest button using visual. Change-Id: Ib4b7974fdf7f2d81d704b926a840126440aa345a Signed-off-by: xb.teng --- diff --git a/automated-tests/src/dali-toolkit/CMakeLists.txt b/automated-tests/src/dali-toolkit/CMakeLists.txt old mode 100644 new mode 100755 index 1297575..97975d1 --- a/automated-tests/src/dali-toolkit/CMakeLists.txt +++ b/automated-tests/src/dali-toolkit/CMakeLists.txt @@ -48,6 +48,7 @@ SET(TC_SOURCES utc-Dali-ProgressBar.cpp utc-Dali-PushButton.cpp utc-Dali-RadioButton.cpp + utc-Dali-ToggleButton.cpp utc-Dali-ScrollViewEffect.cpp utc-Dali-SuperBlurView.cpp utc-Dali-Toolkit.cpp diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ToggleButton.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ToggleButton.cpp new file mode 100755 index 0000000..2f75b37 --- /dev/null +++ b/automated-tests/src/dali-toolkit/utc-Dali-ToggleButton.cpp @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2017 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 +#include +#include +#include +#include +#include + + +using namespace Dali; +using namespace Dali::Toolkit; + +void dali_toggle_button_startup(void) +{ + test_return_value = TET_UNDEF; +} + +void dali_toggle_button_cleanup(void) +{ + test_return_value = TET_PASS; +} + +namespace +{ +static const char* TEST_IMAGE_ONE = TEST_RESOURCE_DIR "/icon-delete.png"; +static const char* TEST_IMAGE_TWO = TEST_RESOURCE_DIR "/icon-edit.png"; +static const char* TEST_IMAGE_THREE = TEST_RESOURCE_DIR "/popup_tail_down.png"; +static const char* TEST_IMAGE_FOUR = TEST_RESOURCE_DIR "/popup_tail_up.png"; + +static const Vector2 INSIDE_TOUCH_POINT_POSITON = Vector2( 240, 400 ); +static const Vector3 BUTTON_POSITON_TO_GET_INSIDE_TOUCH_EVENTS = Vector3( 200, 360, 0 ); +static const Size BUTTON_SIZE_TO_GET_INSIDE_TOUCH_EVENTS = Size( 100, 100 ); + +static bool gObjectCreatedCallBackCalled; + +static void TestCallback(BaseHandle handle) +{ + gObjectCreatedCallBackCalled = true; +} + +Dali::Integration::Point GetPointDownInside() +{ + Dali::Integration::Point point; + point.SetState( PointState::DOWN ); + point.SetScreenPosition( INSIDE_TOUCH_POINT_POSITON ); + return point; +} + +Dali::Integration::Point GetPointUpInside() +{ + Dali::Integration::Point point; + point.SetState( PointState::UP ); + point.SetScreenPosition( INSIDE_TOUCH_POINT_POSITON ); + return point; +} + +} + +int UtcDaliToggleButtonConstructorP(void) +{ + TestApplication application; + tet_infoline(" UtcDaliToggleButtonConstructorP"); + + ToggleButton button; + DALI_TEST_CHECK( !button ); + END_TEST; +} + +int UtcDaliToggleButtonCopyConstructorP(void) +{ + TestApplication application; + tet_infoline(" UtcDaliToggleButtonCopyConstructorP"); + + // Initialize an object, ref count == 1 + ToggleButton button = ToggleButton::New(); + + ToggleButton copy( button ); + DALI_TEST_CHECK( copy ); + END_TEST; +} + +int UtcDaliToggleButtonAssignmentOperatorP(void) +{ + TestApplication application; + tet_infoline(" UtcDaliToggleButtonAssignmentOperatorP"); + + ToggleButton button = ToggleButton::New(); + + ToggleButton copy( button ); + DALI_TEST_CHECK( copy ); + + DALI_TEST_CHECK( button == copy ); + END_TEST; +} + +int UtcDaliToggleButtonNewP(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliToggleButtonNewP"); + + // Create the Slider actor + ToggleButton toggleButton; + + DALI_TEST_CHECK( !toggleButton ); + + toggleButton = ToggleButton::New(); + + DALI_TEST_CHECK( toggleButton ); + + ToggleButton toggleButton2(toggleButton); + + DALI_TEST_CHECK( toggleButton2 == toggleButton ); + + //Additional check to ensure object is created by checking if it's registered + ObjectRegistry registry = Stage::GetCurrent().GetObjectRegistry(); + DALI_TEST_CHECK( registry ); + + gObjectCreatedCallBackCalled = false; + registry.ObjectCreatedSignal().Connect( &TestCallback ); + { + ToggleButton toggleButton = ToggleButton::New(); + } + DALI_TEST_CHECK( gObjectCreatedCallBackCalled ); + END_TEST; +} + +int UtcDaliToggleButtonDestructorP(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliToggleButtonDestructorP"); + + ToggleButton* toggleButton = new ToggleButton(); + delete toggleButton; + + DALI_TEST_CHECK( true ); + END_TEST; +} + +int UtcDaliToggleButtonDownCast(void) +{ + ToolkitTestApplication application; + tet_infoline("UtcDaliToggleButtonDownCast"); + + Handle handle = ToggleButton::New(); + ToggleButton toggleButton = ToggleButton::DownCast( handle ); + + DALI_TEST_CHECK( toggleButton == handle ); + END_TEST; +} + +int UtcDaliToggleButtonToggleStatesProperty(void) +{ + ToolkitTestApplication application; // Exceptions require ToolkitTestApplication + tet_infoline(" UtcDaliToggleButtonToggleStatesProperty"); + + // Create the ToggleButton actor + ToggleButton toggleButton = ToggleButton::New(); + Stage::GetCurrent().Add( toggleButton ); + toggleButton.SetParentOrigin(ParentOrigin::TOP_LEFT); + toggleButton.SetAnchorPoint(ParentOrigin::TOP_LEFT); + toggleButton.SetPosition( 0.0f, 0.0f ); + + {// Check empty array + Property::Array toggleIcons; + toggleButton.SetProperty( Toolkit::ToggleButton::Property::STATE_VISUALS, toggleIcons ); + + application.SendNotification(); + application.Render(); + + Property::Array resultIcons; + resultIcons = toggleButton.GetProperty( Toolkit::ToggleButton::Property::STATE_VISUALS ).Get(); + DALI_TEST_CHECK( resultIcons.Count() == 0 ); + } + + {// Check non-empty Array + Property::Array toggleIcons; + toggleIcons.PushBack( TEST_IMAGE_ONE ); //Icons path + toggleIcons.PushBack( TEST_IMAGE_TWO ); + toggleIcons.PushBack( TEST_IMAGE_THREE ); + toggleIcons.PushBack( TEST_IMAGE_FOUR ); + toggleButton.SetProperty( Toolkit::ToggleButton::Property::STATE_VISUALS, toggleIcons ); + + application.SendNotification(); + application.Render(); + + Property::Array resultIcons; + resultIcons = toggleButton.GetProperty( Toolkit::ToggleButton::Property::STATE_VISUALS ).Get(); + + // Check that the result is the same as + DALI_TEST_EQUALS( toggleIcons.Count(), resultIcons.Count(), TEST_LOCATION ); + DALI_TEST_CHECK( toggleIcons[0].Get() == resultIcons[0].Get() ); + DALI_TEST_CHECK( toggleIcons[1].Get() == resultIcons[1].Get() ); + DALI_TEST_CHECK( toggleIcons[2].Get() == resultIcons[2].Get() ); + DALI_TEST_CHECK( toggleIcons[3].Get() == resultIcons[3].Get() ); + } + + {// Check property::map + Property::Map propertyMap1; + Vector4 testColor1( 1.f, 0.5f, 0.3f, 0.2f ); + propertyMap1.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR); + propertyMap1.Insert(Toolkit::ColorVisual::Property::MIX_COLOR, testColor1); + + Property::Map propertyMap2; + Vector4 testColor2( 0.5f, 1.f, 0.3f, 0.2f ); + propertyMap2.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR); + propertyMap2.Insert(Toolkit::ColorVisual::Property::MIX_COLOR, testColor2); + + Property::Map propertyMap3; + Vector4 testColor3( 1.f, 0.5f, 1.f, 0.2f ); + propertyMap3.Insert(Toolkit::Visual::Property::TYPE, Toolkit::Visual::COLOR); + propertyMap3.Insert(Toolkit::ColorVisual::Property::MIX_COLOR, testColor3); + + Property::Array toggleMaps; + toggleMaps.Add( propertyMap1 ); + toggleMaps.Add( propertyMap2 ); + toggleMaps.Add( propertyMap3 ); + toggleButton.SetProperty( Toolkit::ToggleButton::Property::STATE_VISUALS, toggleMaps ); + + application.SendNotification(); + application.Render(); + + Property::Array resultMaps; + resultMaps = toggleButton.GetProperty( Toolkit::ToggleButton::Property::STATE_VISUALS ).Get(); + + // Check that the result + DALI_TEST_EQUALS( toggleMaps.Count(), resultMaps.Count(), TEST_LOCATION ); + } + + END_TEST; +} + +int UtcDaliToggleButtonToggleTipsProperty( void ) +{ + ToolkitTestApplication application; // Exceptions require ToolkitTestApplication + tet_infoline(" UtcDaliToggleButtonToggleTipsProperty"); + + // Create the ToggleButton actor + ToggleButton toggleButton = ToggleButton::New(); + Stage::GetCurrent().Add( toggleButton ); + toggleButton.SetParentOrigin(ParentOrigin::TOP_LEFT); + toggleButton.SetAnchorPoint(ParentOrigin::TOP_LEFT); + toggleButton.SetPosition( 0.0f, 0.0f ); + + { // Check empty tip array + Property::Array toggleIcons; + toggleIcons.PushBack( TEST_IMAGE_ONE ); //Icons path + toggleIcons.PushBack( TEST_IMAGE_TWO ); + toggleIcons.PushBack( TEST_IMAGE_THREE ); + toggleButton.SetProperty( Toolkit::ToggleButton::Property::STATE_VISUALS, toggleIcons ); + + Property::Array toggleTips; + toggleButton.SetProperty( Toolkit::ToggleButton::Property::TOOLTIPS, toggleTips ); + + application.SendNotification(); + application.Render(); + + Property::Array resultTips; + resultTips = toggleButton.GetProperty( Toolkit::ToggleButton::Property::TOOLTIPS ).Get(); + DALI_TEST_CHECK( resultTips.Count() == 0 ); + } + + { // Check non-empty tip array + Property::Array toggleIcons; + toggleIcons.PushBack( TEST_IMAGE_ONE ); //Icons path + toggleIcons.PushBack( TEST_IMAGE_TWO ); + toggleIcons.PushBack( TEST_IMAGE_THREE ); + toggleButton.SetProperty( Toolkit::ToggleButton::Property::STATE_VISUALS, toggleIcons ); + + Property::Array toggleTips; + toggleTips.PushBack( "Button State A" ); //Tooltip string + toggleTips.PushBack( "Button State B" ); + toggleTips.PushBack( "Button State C" ); + toggleButton.SetProperty( Toolkit::ToggleButton::Property::TOOLTIPS, toggleTips ); + + application.SendNotification(); + application.Render(); + + Property::Array resultTips; + resultTips = toggleButton.GetProperty( Toolkit::ToggleButton::Property::TOOLTIPS ).Get(); + + //Check that the result is the same as + DALI_TEST_EQUALS( toggleTips.Count(), resultTips.Count(), TEST_LOCATION ); + DALI_TEST_CHECK( toggleTips[0].Get() == resultTips[0].Get() ); + DALI_TEST_CHECK( toggleTips[1].Get() == resultTips[1].Get() ); + DALI_TEST_CHECK( toggleTips[2].Get() == resultTips[2].Get() ); + DALI_TEST_CHECK( toggleTips[3].Get() == resultTips[3].Get() ); + } + END_TEST; +} + +int UtcDaliToggleButtonStateChange(void) +{ + ToolkitTestApplication application; // Exceptions require ToolkitTestApplication + tet_infoline(" UtcDaliToggleButtonStateChange"); + + // Create the ToggleButton actor + ToggleButton toggleButton = ToggleButton::New(); + Stage::GetCurrent().Add( toggleButton ); + toggleButton.SetParentOrigin(ParentOrigin::TOP_LEFT); + toggleButton.SetAnchorPoint(ParentOrigin::TOP_LEFT); + toggleButton.SetPosition( BUTTON_POSITON_TO_GET_INSIDE_TOUCH_EVENTS ); + toggleButton.SetSize( BUTTON_SIZE_TO_GET_INSIDE_TOUCH_EVENTS ); + + Property::Array toggleIcons; + toggleIcons.PushBack( TEST_IMAGE_ONE ); //Icons path + toggleIcons.PushBack( TEST_IMAGE_TWO ); + toggleIcons.PushBack( TEST_IMAGE_THREE ); + toggleButton.SetProperty( Toolkit::ToggleButton::Property::STATE_VISUALS, toggleIcons ); + + Property::Array toggleTips; + toggleTips.PushBack( "Button State A" ); //Tooltip string + toggleTips.PushBack( "Button State B" ); + toggleTips.PushBack( "Button State C" ); + toggleButton.SetProperty( Toolkit::ToggleButton::Property::TOOLTIPS, toggleTips ); + + application.SendNotification(); + application.Render(); + + Property::Array resultIcons; + resultIcons = toggleButton.GetProperty( Toolkit::ToggleButton::Property::STATE_VISUALS ).Get(); + DALI_TEST_EQUALS( toggleIcons.Count(), resultIcons.Count(), TEST_LOCATION ); + + Property::Array resultTips; + resultTips = toggleButton.GetProperty( Toolkit::ToggleButton::Property::TOOLTIPS ).Get(); + DALI_TEST_EQUALS( toggleTips.Count(), resultTips.Count(), TEST_LOCATION ); + + int index; + DALI_TEST_CHECK( toggleButton.GetProperty( Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX ).Get( index ) ); + DALI_TEST_EQUALS( index, 0, TEST_LOCATION ); + + Dali::Integration::TouchEvent event; + + // Touch point down and up inside the button 3 times. + event = Dali::Integration::TouchEvent(); + event.AddPoint( GetPointDownInside() ); + application.ProcessEvent( event ); + + event = Dali::Integration::TouchEvent(); + event.AddPoint( GetPointUpInside() ); + application.ProcessEvent( event ); + + DALI_TEST_CHECK( toggleButton.GetProperty( Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX ).Get( index ) ); + DALI_TEST_EQUALS( index, 1, TEST_LOCATION ); + + event = Dali::Integration::TouchEvent(); + event.AddPoint( GetPointDownInside() ); + application.ProcessEvent( event ); + + event = Dali::Integration::TouchEvent(); + event.AddPoint( GetPointUpInside() ); + application.ProcessEvent( event ); + + DALI_TEST_CHECK( toggleButton.GetProperty( Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX ).Get( index ) ); + DALI_TEST_EQUALS( index, 2, TEST_LOCATION ); + + event = Dali::Integration::TouchEvent(); + event.AddPoint( GetPointDownInside() ); + application.ProcessEvent( event ); + + event = Dali::Integration::TouchEvent(); + event.AddPoint( GetPointUpInside() ); + application.ProcessEvent( event ); + + DALI_TEST_CHECK( toggleButton.GetProperty( Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX ).Get( index ) ); + DALI_TEST_EQUALS( index, 0, TEST_LOCATION ); + + END_TEST; +} \ No newline at end of file diff --git a/dali-toolkit/devel-api/controls/buttons/toggle-button.cpp b/dali-toolkit/devel-api/controls/buttons/toggle-button.cpp new file mode 100644 index 0000000..39f1845 --- /dev/null +++ b/dali-toolkit/devel-api/controls/buttons/toggle-button.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2017 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 + +// INTERNAL INCLUDES + +#include + +namespace Dali +{ + +namespace Toolkit +{ + +ToggleButton::ToggleButton() +: Button() +{ +} + +ToggleButton::ToggleButton( Internal::ToggleButton& implementation ) +: Button( implementation ) +{ +} + +ToggleButton::ToggleButton( const ToggleButton& toggleButton ) +: Button( toggleButton ) +{ +} + +ToggleButton& ToggleButton::operator=( const ToggleButton& toggleButton ) +{ + if( &toggleButton != this ) + { + Button::operator=( toggleButton ); + } + return *this; +} + +ToggleButton::ToggleButton( Dali::Internal::CustomActor* internal ) +: Button( internal ) +{ + VerifyCustomActorPointer(internal); +} + +ToggleButton::~ToggleButton() +{ +} + +ToggleButton ToggleButton::New() +{ + return Internal::ToggleButton::New(); +} + +ToggleButton ToggleButton::DownCast( BaseHandle handle ) +{ + return Control::DownCast(handle); +} + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/devel-api/controls/buttons/toggle-button.h b/dali-toolkit/devel-api/controls/buttons/toggle-button.h new file mode 100644 index 0000000..2e61901 --- /dev/null +++ b/dali-toolkit/devel-api/controls/buttons/toggle-button.h @@ -0,0 +1,223 @@ +#ifndef __DALI_TOOLKIT_TOGGLE_BUTTON_H__ +#define __DALI_TOOLKIT_TOGGLE_BUTTON_H__ + +/* + * Copyright (c) 2017 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 + +namespace Dali +{ + +namespace Toolkit +{ + +// Forward declarations + +namespace Internal DALI_INTERNAL +{ +// Forward declarations + +class ToggleButton; +} +/** + * @addtogroup dali_toolkit_controls_buttons + * @{ + */ + +/** + * @brief A ToggleButton allows the user to change a setting between two or more states. + * + * By default a ToggleButton emits a Button::StateChangedSignal() signal when it's clicked. + * + * Usage example: - + * + * @code + * + * void ToggleButtonExample::Create( Application& application ) + * { + * ToggleButton button = ToggleButton::New(); + * button.SetProperty( Toolkit::ToggleButton::Property::STATE_VISUALS, Property::Array() + * .Add( "A.png" ) + * .Add( "B.png" ) + * .Add( "C.png" )); + * or + * + * Property::Map propertyMap1; + * Vector4 testColor1( 1.f, 0.5f, 0.3f, 0.2f ); + * propertyMap1.Insert(Visual::Property::TYPE, Visual::COLOR); + * propertyMap1.Insert(ColorVisual::Property::MIX_COLOR, testColor1); + * + * Property::Map propertyMap2; + * Vector4 testColor2( 0.5f, 1.f, 0.3f, 0.2f ); + * propertyMap2.Insert(Visual::Property::TYPE, Visual::COLOR); + * propertyMap2.Insert(ColorVisual::Property::MIX_COLOR, testColor2); + * + * Property::Map propertyMap3; + * Vector4 testColor3( 1.f, 0.5f, 1.f, 0.2f ); + * propertyMap3.Insert(Visual::Property::TYPE, Visual::COLOR); + * propertyMap3.Insert(ColorVisual::Property::MIX_COLOR, testColor3); + * + * button.SetProperty( Toolkit::ToggleButton::Property::STATE_VISUALS, Property::Array() + * .Add( propertyMap1 ) + * .Add( propertyMap2 ) + * .Add( propertyMap3 )); + * + * button.SetProperty( Toolkit::ToggleButton::Property::TOOLTIPS, Property::Array() + * .Add( "STATE A" ) + * .Add( "STATE B" ) + * .Add( "STATE C" )); + * + * Stage::GetCurrent().Add( button ); + * + * // Connect to button signals emitted by the button + * button.ClickedSignal().Connect( this, &ToggleButtonExample::OnButtonClicked ); + * } + * + * bool ToggleButtonExample::OnButtonClicked( Button button ) + * { + * // Do something when the button is clicked + * return true; + * } + * @endcode + * + * See Button for more detail on signals and modifying states via properties. + */ +class DALI_IMPORT_API ToggleButton : public Button +{ +public: + /** + * @brief The start and end property ranges for this control. + */ + enum PropertyRange + { + PROPERTY_START_INDEX = Button::PROPERTY_END_INDEX + 1, ///< Toggle button start index + PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000 ///< Reserving 1000 property indices + }; + + /** + * @brief An enumeration of properties belonging to the ToggleButton class. + */ + struct Property + { + enum + { + /** + * @brief The state visual array of toggle button. + * @details Name "stateVisuals", type Property::Array. + * It's a property array of property-maps or a property array of strings, + * property map expects a description of visual and + * string represents an image url. + * @note Mandatory + */ + STATE_VISUALS = PROPERTY_START_INDEX, + + /** + * @brief The tooltips of toggle button. + * @details Name "tooltips", type Property::Array. + * It's an array of toggle state tooltip strings. + * Each tooltip string should match a toggle state strictly. + * @note Mandatory + */ + TOOLTIPS, + + /** + * @brief The current state index of toggle button. + * @details Name "currentStateIndex", type integer. + * It just provides a property to get current state index. + * @note Optional + * @note The index is automatically changed when toggle button is clicked. + */ + CURRENT_STATE_INDEX + }; + }; + +public: + + /** + * @brief Create an uninitialized ToggleButton; this can be initialized with ToggleButton::New(). + * + * Calling member functions with an uninitialized Dali::Object is not allowed. + */ + ToggleButton(); + + /** + * @brief Copy constructor. + * @param[in] toggleButton Handle to an object + */ + ToggleButton( const ToggleButton& toggleButton ); + + /** + * @brief Assignment operator. + * @param[in] toggleButton Handle to an object + * @return A reference to this + */ + ToggleButton& operator=( const ToggleButton& toggleButton ); + + /** + * @brief Destructor + * + * This is non-virtual since derived Handle types must not contain data or virtual methods. + */ + ~ToggleButton(); + + /** + * @brief Create an initialized ToggleButton. + * + * @return A handle to a newly allocated Dali resource. + */ + static ToggleButton New(); + + /** + * @brief Downcast a handle to ToggleButton handle. + * + * If handle points to a ToggleButton the downcast produces valid + * handle. If not the returned handle is left uninitialized. + * + * @param[in] handle Handle to an object + * @return handle to a ToggleButton or an uninitialized handle + */ + static ToggleButton DownCast( BaseHandle handle ); + +public: // Not intended for application developers + + /// @cond internal + /** + * @brief Creates a handle using the Toolkit::Internal implementation. + * + * @param[in] implementation The Control implementation. + */ + DALI_INTERNAL ToggleButton( Internal::ToggleButton& implementation ); + + /** + * @brief Allows the creation of this Control from an Internal::CustomActor pointer. + * + * @param[in] internal A pointer to the internal CustomActor. + */ + DALI_INTERNAL ToggleButton( Dali::Internal::CustomActor* internal ); + /// @endcond +}; + +/** + * @} + */ +} // namespace Toolkit + +} // namespace Dali + +#endif // __DALI_TOOLKIT_TOGGLE_BUTTON_H__ diff --git a/dali-toolkit/devel-api/file.list b/dali-toolkit/devel-api/file.list old mode 100644 new mode 100755 index a67e25b..c8e9f29 --- a/dali-toolkit/devel-api/file.list +++ b/dali-toolkit/devel-api/file.list @@ -8,6 +8,7 @@ devel_api_src_files = \ $(devel_api_src_dir)/controls/control-wrapper-impl.cpp \ $(devel_api_src_dir)/controls/bloom-view/bloom-view.cpp \ $(devel_api_src_dir)/controls/bubble-effect/bubble-emitter.cpp \ + $(devel_api_src_dir)/controls/buttons/toggle-button.cpp \ $(devel_api_src_dir)/controls/effects-view/effects-view.cpp \ $(devel_api_src_dir)/controls/magnifier/magnifier.cpp \ $(devel_api_src_dir)/controls/navigation-view/navigation-view.cpp \ @@ -53,7 +54,8 @@ devel_api_bubble_emitter_header_files = \ $(devel_api_src_dir)/controls/bubble-effect/bubble-emitter.h devel_api_buttons_header_files = \ - $(devel_api_src_dir)/controls/buttons/button-devel.h + $(devel_api_src_dir)/controls/buttons/button-devel.h \ + $(devel_api_src_dir)/controls/buttons/toggle-button.h devel_api_builder_header_files = \ $(devel_api_src_dir)/builder/builder.h \ diff --git a/dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp b/dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp new file mode 100755 index 0000000..555cb7b --- /dev/null +++ b/dali-toolkit/internal/controls/buttons/toggle-button-impl.cpp @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2017 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 "toggle-button-impl.h" + +// EXTERNAL INCLUDES +#include +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(DEBUG_ENABLED) + extern Debug::Filter* gLogButtonFilter; +#endif + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +namespace +{ + +BaseHandle Create() +{ + return Toolkit::ToggleButton::New(); +} + +// Properties +DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ToggleButton, Toolkit::Button, Create ) + +DALI_PROPERTY_REGISTRATION( Toolkit, ToggleButton, "stateVisuals", ARRAY, STATE_VISUALS ) +DALI_PROPERTY_REGISTRATION( Toolkit, ToggleButton, "tooltips", ARRAY, TOOLTIPS ) +DALI_PROPERTY_REGISTRATION( Toolkit, ToggleButton, "currentStateIndex", INTEGER, CURRENT_STATE_INDEX ) + +DALI_TYPE_REGISTRATION_END() + +} // unnamed namespace + +Dali::Toolkit::ToggleButton ToggleButton::New() +{ + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "ToggleButton::New\n" ); + // Create the implementation, temporarily owned on stack + IntrusivePtr< ToggleButton > internalToggleButton = new ToggleButton(); + + // Pass ownership to CustomActor + Dali::Toolkit::ToggleButton toggleButton( *internalToggleButton ); + + // Second-phase init of the implementation + // This can only be done after the CustomActor connection has been made... + internalToggleButton->Initialize(); + + return toggleButton; +} + +ToggleButton::ToggleButton() +: Button(), + mToggleStates(), + mToggleVisuals(), + mToggleSelectedVisuals(), + mToggleDisabledVisuals(), + mToggleDisabledSelectedVisuals(), + mToggleTooltips(), + mCurrentToggleIndex(0) +{ + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "ToggleButton::Constructor\n" ); + SetTogglableButton( false ); +} + +ToggleButton::~ToggleButton() +{ +} + +void ToggleButton::OnInitialize() +{ + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "ToggleButton::OnInitialize\n" ); + Button::OnInitialize(); + + // Toggle button requires the Leave event. + Actor self = Self(); + self.SetLeaveRequired( true ); +} + +void ToggleButton::SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value ) +{ + Toolkit::ToggleButton toggleButton = Toolkit::ToggleButton::DownCast( Dali::BaseHandle( object ) ); + + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "ToggleButton::SetProperty index[%d]\n", propertyIndex ); + + if ( toggleButton ) + { + ToggleButton& toggleButtonImpl( GetImplementation( toggleButton ) ); + + switch ( propertyIndex ) + { + case Toolkit::ToggleButton::Property::STATE_VISUALS: + { + Property::Array stateArray; + if( value.Get( stateArray ) ) + { + toggleButtonImpl.SetToggleStates( stateArray ); + } + + break; + } + case Toolkit::ToggleButton::Property::TOOLTIPS: + { + Property::Array* tipArray = value.GetArray(); + if( tipArray ) + { + std::vector tips; + size_t tipsCount = tipArray->Count(); + tips.resize( tipsCount ); + for( size_t i = 0; i != tipsCount; ++i ) + { + tipArray->GetElementAt( i ).Get( tips[i] ); + } + toggleButtonImpl.SetToggleTooltips(tips); + } + break; + } + default : + { + break; + } + } // end of switch + } +} + +Property::Value ToggleButton::GetProperty( BaseObject* object, Property::Index propertyIndex ) +{ + Property::Value value; + + Toolkit::ToggleButton toggleButton = Toolkit::ToggleButton::DownCast( Dali::BaseHandle( object ) ); + + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "ToggleButton::GetProperty index[%d]\n", propertyIndex ); + + if ( toggleButton ) + { + ToggleButton& toggleButtonImpl( GetImplementation( toggleButton ) ); + + switch ( propertyIndex ) + { + case Toolkit::ToggleButton::Property::STATE_VISUALS: + { + Property::Array array = toggleButtonImpl.GetToggleStates(); + value = Property::Value( array ); + break; + } + case Toolkit::ToggleButton::Property::TOOLTIPS: + { + Property::Value value1( Property::ARRAY ); + Property::Array* tipArray = value1.GetArray(); + + if( tipArray ) + { + std::vector tips = toggleButtonImpl.GetToggleTooltips(); + size_t tipsCount( tips.size() ); + for( size_t i( 0 ); i != tipsCount; ++i ) + { + tipArray->PushBack( tips[i] ); + } + } + value = value1; + break; + } + case Toolkit::ToggleButton::Property::CURRENT_STATE_INDEX: + { + value = static_cast(toggleButtonImpl.mCurrentToggleIndex); + break; + } + } // end of switch + } + + return value; +} + +void ToggleButton::CreateVisualsForAllStates( const Property::Array& states, std::vector& visuals ) +{ + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "ToggleButton::CreateVisualsForAllStates\n" ); + + visuals.clear(); + + for ( unsigned int i = 0; i < states.Count(); i++ ) + { + Property::Value value( states[i] ); + + Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get(); + Toolkit::Visual::Base stateVisual; + + if ( value.GetType() == Property::MAP ) + { + Property::Map *map = value.GetMap(); + if( map && !map->Empty() ) // Empty map results in current visual removal. + { + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "ToggleButton::CreateVisuals Using Map\n" ); + stateVisual = visualFactory.CreateVisual( *map ); + } + } + else if ( value.GetType() == Property::STRING ) + { + std::string imageUrl = value.Get(); + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "ToggleButton::CreateVisuals Using image URL\n" ); + if ( !imageUrl.empty() ) + { + stateVisual = visualFactory.CreateVisual( imageUrl, ImageDimensions() ); + } + } + + if ( stateVisual ) + { + stateVisual.SetDepthIndex( DepthIndex::CONTENT ); + visuals.push_back( stateVisual ); + } + } // end of for + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "ToggleButton::CreateVisuals mToggleVisuals:%d\n", mToggleVisuals.size() ); +} + +void ToggleButton::SetToggleStates( const Property::Array& states ) +{ //this should really be generalized to be either string or maps so that any visual can be created. + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "ToggleButton::SetToggleStates\n" ); + if ( !states.Empty() ) + { + mToggleStates.Clear(); + mToggleStates = states; + /* New toggle button index from 0. */ + mCurrentToggleIndex = 0; + + // Create all visuals, save to mToggleVisuals. + CreateVisualsForAllStates( states, mToggleVisuals ); + CreateVisualsForAllStates( states, mToggleSelectedVisuals ); + CreateVisualsForAllStates( states, mToggleDisabledVisuals ); + CreateVisualsForAllStates( states, mToggleDisabledSelectedVisuals ); + + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "ToggleButton::Began to register visual.\n" ); + + PrepareVisual( Toolkit::DevelButton::Property::UNSELECTED_VISUAL, mToggleVisuals[mCurrentToggleIndex] ); + PrepareVisual( Toolkit::DevelButton::Property::SELECTED_VISUAL, mToggleSelectedVisuals[mCurrentToggleIndex] ); + PrepareVisual( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL, mToggleDisabledVisuals[mCurrentToggleIndex] ); + PrepareVisual( Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL, mToggleDisabledSelectedVisuals[mCurrentToggleIndex] ); + + RelayoutRequest(); + } +} + +Property::Array ToggleButton::GetToggleStates() const +{ + return mToggleStates; +} + +void ToggleButton::SetToggleTooltips( std::vector& tips ) +{ + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "ToggleButton::SetToggleTooltips\n" ); + if ( !tips.empty() ) + { + mToggleTooltips.clear(); + mToggleTooltips.swap( tips ); + } + + if ( !mToggleTooltips.empty() && ( mCurrentToggleIndex < mToggleTooltips.size() ) ) + { + Self().SetProperty( Toolkit::DevelControl::Property::TOOLTIP, mToggleTooltips[mCurrentToggleIndex] ); + } + + RelayoutRequest(); +} + +const std::vector& ToggleButton::GetToggleTooltips() const +{ + return mToggleTooltips; +} + +void ToggleButton::PrepareVisual(Property::Index index, Toolkit::Visual::Base& visual) +{ + RegisterVisual( index, visual, true ); + EnableVisual( index, false ); +} + +void ToggleButton::RelayoutVisual( Property::Index index, const Vector2& size ) +{ + Toolkit::Visual::Base visual = GetVisual( index ); + if ( visual ) + { + Size visualSize = Size::ZERO; + Vector2 visualPosition = Vector2::ZERO; + + visual.GetNaturalSize( visualSize ); + + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "ToggleButton::OnRelayout Setting visual size to(%f,%f)\n", visualSize.width, visualSize.height ); + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "ToggleButton::OnRelayout Setting visual position to(%f,%f)\n", visualPosition.x, visualPosition.y ); + + Property::Map visualTransform; + visualTransform.Add( Toolkit::DevelVisual::Transform::Property::SIZE, visualSize ) + .Add( Toolkit::DevelVisual::Transform::Property::OFFSET, visualPosition ) + .Add( Toolkit::DevelVisual::Transform::Property::OFFSET_SIZE_MODE, Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) ) // Use absolute size + .Add( Toolkit::DevelVisual::Transform::Property::ORIGIN, Toolkit::Align::CENTER ) + .Add( Toolkit::DevelVisual::Transform::Property::ANCHOR_POINT, Toolkit::Align::CENTER ); + + visual.SetTransformAndSize( visualTransform, size ); + } +} + +void ToggleButton::OnRelayout( const Vector2& size, RelayoutContainer& container ) +{ + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "ToggleButton::OnRelayout targetSize(%f,%f) ptr(%p)\n", size.width, size.height, this ); + + RelayoutVisual( Toolkit::DevelButton::Property::UNSELECTED_VISUAL, size ); + RelayoutVisual( Toolkit::DevelButton::Property::SELECTED_VISUAL, size ); + RelayoutVisual( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL, size ); + RelayoutVisual( Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL, size ); +} + +void ToggleButton::OnPressed() +{ + DALI_LOG_INFO( gLogButtonFilter, Debug::General, "ToggleButton::OnPressed\n" ); + // State index will add 1 only when button is pressed. + mCurrentToggleIndex = ( mCurrentToggleIndex + 1 ) % mToggleVisuals.size(); + + // Both create SelectedVisual and UnselectedVisual + PrepareVisual( Toolkit::DevelButton::Property::UNSELECTED_VISUAL, mToggleVisuals[mCurrentToggleIndex] ); + PrepareVisual( Toolkit::DevelButton::Property::SELECTED_VISUAL, mToggleSelectedVisuals[mCurrentToggleIndex] ); + PrepareVisual( Toolkit::DevelButton::Property::DISABLED_UNSELECTED_VISUAL, mToggleDisabledVisuals[mCurrentToggleIndex] ); + PrepareVisual( Toolkit::DevelButton::Property::DISABLED_SELECTED_VISUAL, mToggleDisabledSelectedVisuals[mCurrentToggleIndex] ); + + //Need to check mCurrentToggleIndex, it must less than the size of mToggleTooltips. + if ( !mToggleTooltips.empty() && ( mCurrentToggleIndex < mToggleTooltips.size() ) ) + { + Self().SetProperty( Toolkit::DevelControl::Property::TOOLTIP, mToggleTooltips[mCurrentToggleIndex] ); + } + + RelayoutRequest(); +} + +} // namespace Internal + +} // namespace Toolkit + +} // namespace Dali diff --git a/dali-toolkit/internal/controls/buttons/toggle-button-impl.h b/dali-toolkit/internal/controls/buttons/toggle-button-impl.h new file mode 100644 index 0000000..8c76eb4 --- /dev/null +++ b/dali-toolkit/internal/controls/buttons/toggle-button-impl.h @@ -0,0 +1,194 @@ +#ifndef __DALI_TOOLKIT_INTERNAL_TOGGLE_BUTTON_H__ +#define __DALI_TOOLKIT_INTERNAL_TOGGLE_BUTTON_H__ + +/* + * Copyright (c) 2017 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 +#include +#include + + +// INTERNAL INCLUDES +#include +#include "button-impl.h" + +namespace Dali +{ + +namespace Toolkit +{ + +namespace Internal +{ + +/** + * ToggleButton implementation class. + * + * \sa Dali::Toolkit::ToggleButton + */ +class ToggleButton : public Button +{ +public: + + /** + * Create a new ToggleButton. + * @return A smart-pointer to the newly allocated ToggleButton. + */ + static Dali::Toolkit::ToggleButton New(); + +protected: + + /** + * Construct a new ToggleButton. + */ + ToggleButton(); + + /** + * A reference counted object may only be deleted by calling Unreference() + */ + virtual ~ToggleButton(); + +public: + + /** + * 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 propertyIndex ); + +private: + + /** + * Called to create all toggle visuals and save them to mToggleVisuals. + * @param[in] states The array store toggle states. + * @param[out] visuals The created state visual vector. + */ + void CreateVisualsForAllStates( const Property::Array& states, std::vector& visuals ); + + /** + * Called to set toggle states when TOGGLE_STATES is set in SetProperty function. + * @param[in] states The array store toggle states. + */ + void SetToggleStates( const Property::Array& states ); + + /** + * Called to retrieve toggle states. + * @return The toggle states array. + */ + Property::Array GetToggleStates() const; + + /** + * Called to set toggle tooltips when TOGGLE_TIPS is set in SetProperty function. + * @param[in] tips The array store toggle tips. + */ + void SetToggleTooltips( std::vector& tips ); + + /** + * Called to retrieve toggle tips. + * @return The toggle tips array. + */ + const std::vector& GetToggleTooltips() const; + + /** + * Called to prepare visual for next state. + * @param[in] index The property index to set. + * @param[in] visual The visual to set. + */ + void PrepareVisual(Property::Index index, Toolkit::Visual::Base& visual); + + /** + * Called to relayout visual. + * @param[in] index The index of visual to relayout. + * @param[in] size The size of control. + */ + void RelayoutVisual( Property::Index index, const Vector2& size ); + +private: // From Button + + /** + * @copydoc Toolkit::Internal::Button::OnInitialize + */ + virtual void OnInitialize(); + + /** + * @copydoc Toolkit::Internal::Button::OnRelayout + */ + virtual void OnRelayout( const Vector2& size, RelayoutContainer& container ); + + /** + * This method is called when the button is pressed. + */ + virtual void OnPressed(); + +private: + + // Undefined + ToggleButton( const ToggleButton& ); + + // Undefined + ToggleButton& operator=( const ToggleButton& ); + +private: + + Property::Array mToggleStates; ///< Toggle states, string or map. + std::vector mToggleVisuals; ///< Save all unselected visuals. + std::vector mToggleSelectedVisuals; ///< Save all selected visuals. + std::vector mToggleDisabledVisuals; ///< Save all disabled unselected visuals. + std::vector mToggleDisabledSelectedVisuals; ///< Save all disabled selected visuals. + std::vector mToggleTooltips; ///< Toggle tooltips. + unsigned int mCurrentToggleIndex; ///< The index of state. +}; + +} // namespace Internal + +// Helpers for public-api forwarding methods + +inline Toolkit::Internal::ToggleButton& GetImplementation( Toolkit::ToggleButton& button ) +{ + DALI_ASSERT_ALWAYS( button ); + + Dali::RefObject& handle = button.GetImplementation(); + + return static_cast( handle ); +} + +inline const Toolkit::Internal::ToggleButton& GetImplementation( const Toolkit::ToggleButton& button ) +{ + DALI_ASSERT_ALWAYS( button ); + + const Dali::RefObject& handle = button.GetImplementation(); + + return static_cast( handle ); +} + +} // namespace Toolkit + +} // namespace Dali + +#endif // __DALI_TOOLKIT_INTERNAL_TOGGLE_BUTTON_H__ diff --git a/dali-toolkit/internal/file.list b/dali-toolkit/internal/file.list old mode 100644 new mode 100755 index f003ce2..7f39ff6 --- a/dali-toolkit/internal/file.list +++ b/dali-toolkit/internal/file.list @@ -42,6 +42,7 @@ toolkit_src_files = \ $(toolkit_src_dir)/controls/buttons/check-box-button-impl.cpp \ $(toolkit_src_dir)/controls/buttons/push-button-impl.cpp \ $(toolkit_src_dir)/controls/buttons/radio-button-impl.cpp \ + $(toolkit_src_dir)/controls/buttons/toggle-button-impl.cpp \ $(toolkit_src_dir)/controls/effects-view/effects-view-impl.cpp \ $(toolkit_src_dir)/controls/flex-container/flex-container-impl.cpp \ $(toolkit_src_dir)/controls/gaussian-blur-view/gaussian-blur-view-impl.cpp \