From: David Steele Date: Fri, 13 Jan 2017 14:36:28 +0000 (+0000) Subject: [dali_1.2.22] Merge branch 'devel/master' X-Git-Tag: dali_1.9.8~5^2~165 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=0e462103c222ad05916840bc7d7c902cf5fc82a1;hp=e54f982e0aaf23db4c3002a3d9fe47a19737bb71 [dali_1.2.22] Merge branch 'devel/master' Change-Id: Ia0fea2310111418861f2f63a9935cd5c8ca8cdff --- diff --git a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp index e8c266d..ed4d02c 100644 --- a/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp +++ b/automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * 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. @@ -207,12 +207,12 @@ void DummyControlImplOverride::OnPinch(const PinchGesture& pinch) { pinchCalled void DummyControlImplOverride::OnPan(const PanGesture& pan) { panCalled = true; } void DummyControlImplOverride::OnTap(const TapGesture& tap) { tapCalled = true; } void DummyControlImplOverride::OnLongPress(const LongPressGesture& longPress) { longPressCalled = true; } -void DummyControlImplOverride::OnStageConnection( int depth ) { Control::OnStageConnection( depth ); stageConnectionCalled = true; } +void DummyControlImplOverride::OnStageConnection( int depth ) { stageConnectionCalled = true; Control::OnStageConnection( depth ); } void DummyControlImplOverride::OnStageDisconnection() { stageDisconnectionCalled = true; Control::OnStageDisconnection(); } -void DummyControlImplOverride::OnChildAdd(Actor& child) { childAddCalled = true; } -void DummyControlImplOverride::OnChildRemove(Actor& child) { childRemoveCalled = true; } -void DummyControlImplOverride::OnSizeSet(const Vector3& targetSize) { Control::OnSizeSet( targetSize ); sizeSetCalled = true; } -void DummyControlImplOverride::OnSizeAnimation(Animation& animation, const Vector3& targetSize) { Control::OnSizeAnimation( animation, targetSize ); sizeAnimationCalled = true; } +void DummyControlImplOverride::OnChildAdd(Actor& child) { childAddCalled = true; Control::OnChildAdd( child ); } +void DummyControlImplOverride::OnChildRemove(Actor& child) { childRemoveCalled = true; Control::OnChildRemove( child ); } +void DummyControlImplOverride::OnSizeSet(const Vector3& targetSize) { sizeSetCalled = true; Control::OnSizeSet( targetSize ); } +void DummyControlImplOverride::OnSizeAnimation(Animation& animation, const Vector3& targetSize) { sizeAnimationCalled = true; Control::OnSizeAnimation( animation, targetSize ); } bool DummyControlImplOverride::OnTouchEvent(const TouchEvent& event) { touchEventCalled = true; return false; } bool DummyControlImplOverride::OnHoverEvent(const HoverEvent& event) { hoverEventCalled = true; return false; } bool DummyControlImplOverride::OnWheelEvent(const WheelEvent& event) { wheelEventCalled = true; return false; } diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Button.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Button.cpp index a2bf49d..9452649 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Button.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Button.cpp @@ -59,6 +59,23 @@ static bool ButtonCallback( Button button ) return false; } +static std::string GetButtonText( Button button ) +{ + Property::Value value = button.GetProperty( Toolkit::Button::Property::LABEL ); + + Property::Map *labelProperty = value.GetMap(); + + std::string textLabel; + + if ( labelProperty ) + { + Property::Value* value = labelProperty->Find( Toolkit::TextVisual::Property::TEXT ); + value->Get( textLabel ); + } + + return textLabel; +} + struct CallbackFunctor { CallbackFunctor(bool* callbackFlag) @@ -472,7 +489,7 @@ int UtcDaliButtonSetAnimationTimeP(void) END_TEST; } -int UtcDaliButtonSetLabelStringP(void) +int UtcDaliButtonSetLabelStringWithPropertyMapP(void) { ToolkitTestApplication application; @@ -480,11 +497,28 @@ int UtcDaliButtonSetLabelStringP(void) button.SetProperty( Toolkit::Button::Property::LABEL, Property::Map().Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT ) .Add( Toolkit::TextVisual::Property::POINT_SIZE, 15.0f ) + .Add( Toolkit::TextVisual::Property::TEXT, "Button Label") ); - button.SetLabelText( "Button Label" ); + DALI_TEST_EQUALS( GetButtonText( button ), "Button Label", TEST_LOCATION ); + END_TEST; +} + +int UtcDaliButtonSetLabelWithStringP(void) +{ + ToolkitTestApplication application; + + Button button = PushButton::New(); + + // Set default point size for text visual as style sheet not available. + button.SetProperty( Toolkit::Button::Property::LABEL, + Property::Map().Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT ) + .Add( Toolkit::TextVisual::Property::POINT_SIZE, 15.0f ) + ); + + button.SetProperty( Toolkit::Button::Property::LABEL, "Button Label" ); - DALI_TEST_EQUALS( button.GetLabelText(), "Button Label", TEST_LOCATION ); + DALI_TEST_EQUALS( GetButtonText( button ), "Button Label", TEST_LOCATION ); END_TEST; } @@ -492,6 +526,9 @@ int UtcDaliButtonSetLabelPropertyP(void) { ToolkitTestApplication application; + tet_infoline(" UtcDaliButtonSetLabelPropertyP Set text label and then set again with new text"); + + const std::string TEST_LABEL1 = "test label one"; const std::string TEST_LABEL2 = "test label two"; @@ -500,13 +537,10 @@ int UtcDaliButtonSetLabelPropertyP(void) button.SetProperty( Toolkit::Button::Property::LABEL, Property::Map().Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT ) .Add( Toolkit::TextVisual::Property::POINT_SIZE, 15.0f ) + .Add( Toolkit::TextVisual::Property::TEXT, TEST_LABEL1 ) ); - button.SetProperty( Button::Property::LABEL_TEXT, TEST_LABEL1 ); - - std::string labelText = button.GetProperty( Button::Property::LABEL_TEXT ); - - DALI_TEST_EQUALS( labelText, TEST_LABEL1, TEST_LOCATION ); + DALI_TEST_EQUALS( GetButtonText( button ), TEST_LABEL1, TEST_LOCATION ); Property::Map propertyMap; propertyMap.Insert( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT ); @@ -515,9 +549,7 @@ int UtcDaliButtonSetLabelPropertyP(void) propertyMap.Insert( Toolkit::TextVisual::Property::POINT_SIZE, 15.0f ); button.SetProperty( Button::Property::LABEL, propertyMap ); - labelText = button.GetProperty( Button::Property::LABEL_TEXT ); - - DALI_TEST_EQUALS( labelText, TEST_LABEL2, TEST_LOCATION ); + DALI_TEST_EQUALS( GetButtonText( button ), TEST_LABEL2, TEST_LOCATION ); END_TEST; } @@ -1238,3 +1270,38 @@ int UtcDaliButtonSetGetDepreciatedPropertiesWithURL(void) END_TEST; } + +int UtcDaliButtonSetLabelTextDeprecatedPropertyP(void) +{ + ToolkitTestApplication application; + tet_infoline(" UtcDaliButtonSetLabelTextDeprecatedPropertyP"); + + const std::string TEST_LABEL1 = "test label one"; + const std::string TEST_LABEL2 = "test label two"; + + Button button = PushButton::New(); + + button.SetProperty( Toolkit::Button::Property::LABEL, + Property::Map().Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT ) + .Add( Toolkit::TextVisual::Property::POINT_SIZE, 15.0f ) + ); + + button.SetProperty( Button::Property::LABEL_TEXT, TEST_LABEL1 ); + + std::string labelText = button.GetProperty( Button::Property::LABEL_TEXT ); + + DALI_TEST_EQUALS( labelText, TEST_LABEL1, TEST_LOCATION ); + + Property::Map propertyMap; + propertyMap.Insert( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT ); + propertyMap.Insert( Toolkit::TextVisual::Property::TEXT, TEST_LABEL2 ); + propertyMap.Insert( Toolkit::TextVisual::Property::TEXT_COLOR, Color::BLUE ); + propertyMap.Insert( Toolkit::TextVisual::Property::POINT_SIZE, 15.0f ); + button.SetProperty( Button::Property::LABEL, propertyMap ); + + labelText = button.GetProperty( Button::Property::LABEL_TEXT ); + + DALI_TEST_EQUALS( labelText, TEST_LABEL2, TEST_LOCATION ); + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp b/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp index 81a5781..93ee34e 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-Control.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -607,3 +607,117 @@ int UtcDaliControlImplGetControlExtensionP(void) END_TEST; } + +int UtcDaliControlAutoClipping(void) +{ + ToolkitTestApplication application; + Control control = Control::New(); + + tet_infoline( "Test to see if a renderer gets added when we are clipping children" ); + + DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION ); + + control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + + Stage::GetCurrent().Add( control ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( 1, control.GetRendererCount(), TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliControlAutoClippingN(void) +{ + ToolkitTestApplication application; + Control control = Control::New(); + control.SetProperty( Control::Property::BACKGROUND, Property::Map().Add( Visual::Property::TYPE, Visual::COLOR ) + .Add( ColorVisual::Property::MIX_COLOR, Color::RED ) ); + + tet_infoline( "Test to ensure that a renderer does NOT get added when we are clipping children and already have renderers/visuals" ); + + DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION ); + + control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + + Stage::GetCurrent().Add( control ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( 1, control.GetRendererCount(), TEST_LOCATION ); // Only 1, not 2 + + // Ensure the background color is still RED rather than what's set by the automatic clipping + Property::Value value = control.GetProperty( Control::Property::BACKGROUND ); + Property::Map* map = value.GetMap(); + DALI_TEST_CHECK( map ); + Property::Value* colorValue = map->Find(ColorVisual::Property::MIX_COLOR ); + DALI_TEST_CHECK( colorValue ); + DALI_TEST_EQUALS( colorValue->Get< Vector4 >(), Color::RED, TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliControlAutoClippingWhenAlreadyOnStage(void) +{ + ToolkitTestApplication application; + Control control = Control::New(); + + tet_infoline( "Test to see if a renderer gets added when we are clipping children and when already on stage" ); + + DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION ); + + Stage::GetCurrent().Add( control ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION ); + + control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( 1, control.GetRendererCount(), TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliControlAutoClippingWhenAlreadyOnStageN(void) +{ + ToolkitTestApplication application; + Control control = Control::New(); + control.SetProperty( Control::Property::BACKGROUND, Property::Map().Add( Visual::Property::TYPE, Visual::COLOR ) + .Add( ColorVisual::Property::MIX_COLOR, Color::RED ) ); + + tet_infoline( "Test to ensure that a renderer does NOT get added when we are clipping children and already have renderers/visuals and when already on stage" ); + + DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION ); + + Stage::GetCurrent().Add( control ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( 1, control.GetRendererCount(), TEST_LOCATION ); + + control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( 1, control.GetRendererCount(), TEST_LOCATION ); // Still should be 1 + + // Ensure the background color is still RED rather than what's set by the automatic clipping + Property::Value value = control.GetProperty( Control::Property::BACKGROUND ); + Property::Map* map = value.GetMap(); + DALI_TEST_CHECK( map ); + Property::Value* colorValue = map->Find(ColorVisual::Property::MIX_COLOR ); + DALI_TEST_CHECK( colorValue ); + DALI_TEST_EQUALS( colorValue->Get< Vector4 >(), Color::RED, TEST_LOCATION ); + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-ControlImpl.cpp b/automated-tests/src/dali-toolkit/utc-Dali-ControlImpl.cpp index 4a29efc..77c2436 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-ControlImpl.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-ControlImpl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * 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. @@ -1351,3 +1351,69 @@ int UtcDaliControlImplRegisterTwoVisualsAndEnableOnlyOne(void) END_TEST; } +int UtcDaliControlImplAutoClippingWithVisuals(void) +{ + ToolkitTestApplication application; + + tet_infoline( "Test to ensure a renderer does NOT get added when we've already registered a visual which we haven't enabled" ); + + DummyControl control = DummyControl::New(); + DummyControlImpl& controlImpl = static_cast( control.GetImplementation() ); + + Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get(); + Toolkit::Visual::Base visual; + Property::Map map; + map[Visual::Property::TYPE] = Visual::COLOR; + map[ColorVisual::Property::MIX_COLOR] = Color::RED; + visual = visualFactory.CreateVisual( map ); + DALI_TEST_CHECK(visual); + controlImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual, false ); + + DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION ); + + control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + + Stage::GetCurrent().Add( control ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION ); + + END_TEST; +} + +int UtcDaliControlImplAutoClippingWithVisualsAlreadyOnStage(void) +{ + ToolkitTestApplication application; + + tet_infoline( "Test to ensure a renderer does NOT get added when we've already registered a visual which we haven't enabled and we're already on the stage" ); + + DummyControl control = DummyControl::New(); + DummyControlImpl& controlImpl = static_cast( control.GetImplementation() ); + + Toolkit::VisualFactory visualFactory = Toolkit::VisualFactory::Get(); + Toolkit::Visual::Base visual; + Property::Map map; + map[Visual::Property::TYPE] = Visual::COLOR; + map[ColorVisual::Property::MIX_COLOR] = Color::RED; + visual = visualFactory.CreateVisual( map ); + DALI_TEST_CHECK(visual); + controlImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual, false ); + + DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION ); + + Stage::GetCurrent().Add( control ); + + application.SendNotification(); + application.Render(); + + control.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); + + application.SendNotification(); + application.Render(); + + DALI_TEST_EQUALS( 0, control.GetRendererCount(), TEST_LOCATION ); + + END_TEST; +} diff --git a/automated-tests/src/dali-toolkit/utc-Dali-TableView.cpp b/automated-tests/src/dali-toolkit/utc-Dali-TableView.cpp index 7beeb96..590614e 100644 --- a/automated-tests/src/dali-toolkit/utc-Dali-TableView.cpp +++ b/automated-tests/src/dali-toolkit/utc-Dali-TableView.cpp @@ -915,3 +915,127 @@ int UtcDaliTableViewKeyboardFocus(void) END_TEST; } + +int UtcDaliTableViewKeyboardFocusInNestedTableView(void) +{ + ToolkitTestApplication application; + + TableView tableView = TableView::New(3, 3); + tableView.SetKeyboardFocusable( true ); + tableView.SetName( "TableView"); + + for ( int row = 0; row < 3; ++row ) + { + for ( int col = 0; col < 3; ++col ) + { + std::ostringstream str; + str << row << "-" << col; + + if (row == 1 && col ==1) + { + // Add a nested 2x2 table view in the middle cell of the parent table view + TableView childTableView = TableView::New(2, 2); + childTableView.SetName( str.str() ); + + for(int childRow = 0; childRow < 2; childRow++) + { + for(int childCol = 0; childCol < 2; childCol++) + { + Control control = Control::New(); + std::ostringstream nameStr; + nameStr << row << "-" << col << "-" << childRow << "-" << childCol; + control.SetName( nameStr.str() ); + control.SetKeyboardFocusable( true ); + childTableView.AddChild( control, TableView::CellPosition( childRow, childCol ) ); + } + } + tableView.AddChild( childTableView, TableView::CellPosition( row, col ) ); + } + else + { + Control control = Control::New(); + control.SetName( str.str() ); + control.SetKeyboardFocusable( true ); + tableView.AddChild( control, TableView::CellPosition( row, col ) ); + } + } + } + + Stage::GetCurrent().Add( tableView ); + + application.SendNotification(); + application.Render(); + + Actor firstFocusActor = Toolkit::Internal::GetImplementation( tableView ).GetNextKeyboardFocusableActor( Actor(), Control::KeyboardFocus::RIGHT, true ); + DALI_TEST_CHECK( firstFocusActor ); + DALI_TEST_CHECK( firstFocusActor.GetName() == "0-0" ); + + KeyboardFocusManager manager = KeyboardFocusManager::Get(); + manager.SetFocusGroupLoop( false ); + manager.SetCurrentFocusActor( firstFocusActor ); + + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-0" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-1" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-2" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-0" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-0" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-1" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-0" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-1" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-2" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-0" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-1" ); + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-2" ); + + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-1" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-0" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-2" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-1" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-0" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-1" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-0" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-0" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-2" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-1" ); + manager.MoveFocus( Control::KeyboardFocus::LEFT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-0" ); + + manager.MoveFocus( Control::KeyboardFocus::RIGHT ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-1" ); + manager.MoveFocus( Control::KeyboardFocus::DOWN ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-0" ); + manager.MoveFocus( Control::KeyboardFocus::DOWN ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-0" ); + manager.MoveFocus( Control::KeyboardFocus::DOWN ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "2-1" ); + + manager.MoveFocus( Control::KeyboardFocus::UP ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-1-1" ); + manager.MoveFocus( Control::KeyboardFocus::UP ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "1-1-0-1" ); + manager.MoveFocus( Control::KeyboardFocus::UP ); + DALI_TEST_CHECK( manager.GetCurrentFocusActor().GetName() == "0-1" ); + + END_TEST; +} diff --git a/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp b/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp index 9bfb68c..085772e 100644 --- a/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp +++ b/dali-toolkit/internal/controls/bloom-view/bloom-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -277,8 +277,6 @@ void BloomView::OnInitialize() void BloomView::OnSizeSet(const Vector3& targetSize) { - Control::OnSizeSet( targetSize ); - mTargetSize = Vector2(targetSize); mChildrenRoot.SetSize(targetSize); mCompositeImageView.SetSize(targetSize); @@ -300,16 +298,18 @@ void BloomView::OnSizeSet(const Vector3& targetSize) Deactivate(); Activate(); } + + Control::OnSizeSet( targetSize ); } void BloomView::OnChildAdd( Actor& child ) { - Control::OnChildAdd( child ); - if( child != mChildrenRoot && child != mInternalRoot) { mChildrenRoot.Add( child ); } + + Control::OnChildAdd( child ); } void BloomView::OnChildRemove( Actor& child ) diff --git a/dali-toolkit/internal/controls/buttons/button-impl.cpp b/dali-toolkit/internal/controls/buttons/button-impl.cpp index 0c7005b..ed9b2c8 100644 --- a/dali-toolkit/internal/controls/buttons/button-impl.cpp +++ b/dali-toolkit/internal/controls/buttons/button-impl.cpp @@ -348,11 +348,7 @@ bool Button::IsSelected() const void Button::SetLabelText( const std::string& label ) { - Property::Map labelProperty; - labelProperty.Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT) - .Add( Toolkit::TextVisual::Property::TEXT, label ); - - Self().SetProperty( Toolkit::Button::Property::LABEL, labelProperty ); + Self().SetProperty( Toolkit::Button::Property::LABEL, label ); } std::string Button::GetLabelText() const @@ -372,7 +368,7 @@ std::string Button::GetLabelText() const return textLabel; } -void Button::MergeLabelProperties( const Property::Map& inMap, Property::Map& outMap ) +void Button::MergeWithExistingLabelProperties( const Property::Map& inMap, Property::Map& outMap ) { DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "MergeLabelProperties with %d properties\n", inMap.Count() ); @@ -1224,13 +1220,32 @@ void Button::SetProperty( BaseObject* object, Property::Index index, const Prope case Toolkit::Button::Property::LABEL: { - // Get a Property::Map from the property if possible. - Property::Map* setPropertyMap = value.GetMap(); - if( setPropertyMap ) + Property::Map outTextVisualProperties; + std::string textString; + + if ( value.Get( textString ) ) + { + DALI_LOG_INFO( gLogButtonFilter, Debug::Verbose, "Button::SetProperty Setting TextVisual with string[%s]\n", textString.c_str() ); + + Property::Map setPropertyMap; + setPropertyMap.Add( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::TEXT) + .Add( Toolkit::TextVisual::Property::TEXT, textString ); + + GetImplementation( button ).MergeWithExistingLabelProperties( setPropertyMap, outTextVisualProperties ); + } + else + { + // Get a Property::Map from the property if possible. + Property::Map* setPropertyMap = value.GetMap(); + if( setPropertyMap ) + { + GetImplementation( button ).MergeWithExistingLabelProperties( *setPropertyMap, outTextVisualProperties ); + } + } + + if( !outTextVisualProperties.Empty() ) { - Property::Map textVisualProperties; - GetImplementation( button ).MergeLabelProperties( *setPropertyMap, textVisualProperties ); - GetImplementation( button ).CreateVisualsForComponent( index, textVisualProperties, DepthIndex::CONTENT ); + GetImplementation( button ).CreateVisualsForComponent( index, outTextVisualProperties, DepthIndex::CONTENT ); GetImplementation( button ).RelayoutRequest(); } break; diff --git a/dali-toolkit/internal/controls/buttons/button-impl.h b/dali-toolkit/internal/controls/buttons/button-impl.h index a079cd5..e0b7d50 100644 --- a/dali-toolkit/internal/controls/buttons/button-impl.h +++ b/dali-toolkit/internal/controls/buttons/button-impl.h @@ -149,13 +149,13 @@ public: std::string GetLabelText() const; /** - * @brief Produces a Property::Map of Text properties to create a Text Visual + * @brief Produces a Property::Map of Text properties to create a Text Visual, merging existing properties with supplied map * If the label does not exist yet, it is created. * The derived buttons are notified if any properties are changed. * @param[in] properties A Property::Map of key-value pairs of properties to set. - * @param[out] properties A Property::Map of text visual properties to set. + * @param[out] properties A Property::Map of text visual properties to set after merging inMap with existing maps */ - void MergeLabelProperties( const Property::Map& inMap, Property::Map& outMap ); + void MergeWithExistingLabelProperties( const Property::Map& inMap, Property::Map& outMap ); /** * Performs actions as requested using the action name. diff --git a/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp b/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp index 44bc39b..08cfc16 100644 --- a/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp +++ b/dali-toolkit/internal/controls/effects-view/effects-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -289,8 +289,6 @@ void EffectsView::OnInitialize() void EffectsView::OnSizeSet(const Vector3& targetSize) { - Control::OnSizeSet( targetSize ); - mTargetSize = Vector2(targetSize); // if we are already on stage, need to update render target sizes now to reflect the new size of this actor @@ -304,13 +302,15 @@ void EffectsView::OnSizeSet(const Vector3& targetSize) } mChildrenRoot.SetSize( targetSize ); + + Control::OnSizeSet( targetSize ); } void EffectsView::OnStageConnection( int depth ) { - Control::OnStageConnection( depth ); - Enable(); + + Control::OnStageConnection( depth ); } void EffectsView::OnStageDisconnection() @@ -328,12 +328,12 @@ void EffectsView::OnStageDisconnection() void EffectsView::OnChildAdd( Actor& child ) { - Control::OnChildAdd( child ); - if( child != mChildrenRoot && child != mCameraForChildren ) { mChildrenRoot.Add( child ); } + + Control::OnChildAdd( child ); } void EffectsView::OnChildRemove( Actor& child ) diff --git a/dali-toolkit/internal/controls/flex-container/flex-container-impl.cpp b/dali-toolkit/internal/controls/flex-container/flex-container-impl.cpp index 94a92a7..03d4583 100644 --- a/dali-toolkit/internal/controls/flex-container/flex-container-impl.cpp +++ b/dali-toolkit/internal/controls/flex-container/flex-container-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -465,8 +465,6 @@ Property::Value FlexContainer::GetProperty( BaseObject* object, Property::Index void FlexContainer::OnChildAdd( Actor& child ) { - Control::OnChildAdd( child ); - // Anchor actor to top left of the container child.SetAnchorPoint( AnchorPoint::TOP_LEFT ); child.SetParentOrigin( ParentOrigin::TOP_LEFT ); @@ -478,6 +476,8 @@ void FlexContainer::OnChildAdd( Actor& child ) childNode.node->get_child = GetChildNodeAtIndex; childNode.node->is_dirty = IsNodeDirty; mChildrenNodes.push_back(childNode); + + Control::OnChildAdd( child ); } void FlexContainer::OnChildRemove( Actor& child ) @@ -562,11 +562,8 @@ void FlexContainer::OnSizeSet( const Vector3& size ) RelayoutRequest(); } -} -void FlexContainer::OnSizeAnimation( Animation& animation, const Vector3& targetSize ) -{ - // @todo Animate the children to their target size and position + Control::OnSizeSet( size ); } void FlexContainer::ComputeLayout() diff --git a/dali-toolkit/internal/controls/flex-container/flex-container-impl.h b/dali-toolkit/internal/controls/flex-container/flex-container-impl.h index f89c1f4..ce09e23 100644 --- a/dali-toolkit/internal/controls/flex-container/flex-container-impl.h +++ b/dali-toolkit/internal/controls/flex-container/flex-container-impl.h @@ -2,7 +2,7 @@ #define __DALI_TOOLKIT_INTERNAL_FLEX_CONTAINER_H__ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -205,11 +205,6 @@ private: // From Control */ virtual void OnSizeSet( const Vector3& size ); - /** - * @copydoc CustomActorImpl::OnSizeAnimation(Animation&, const Vector3&) - */ - virtual void OnSizeAnimation(Animation& animation, const Vector3& targetSize); - private: // Implementation /** diff --git a/dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.cpp b/dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.cpp index a202236..2dddad7 100644 --- a/dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.cpp +++ b/dali-toolkit/internal/controls/gaussian-blur-view/gaussian-blur-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -330,8 +330,6 @@ void GaussianBlurView::OnInitialize() void GaussianBlurView::OnSizeSet(const Vector3& targetSize) { - Control::OnSizeSet( targetSize ); - mTargetSize = Vector2(targetSize); mChildrenRoot.SetSize(targetSize); @@ -356,16 +354,18 @@ void GaussianBlurView::OnSizeSet(const Vector3& targetSize) Deactivate(); Activate(); } + + Control::OnSizeSet( targetSize ); } void GaussianBlurView::OnChildAdd( Actor& child ) { - Control::OnChildAdd( child ); - if( child != mChildrenRoot && child != mInternalRoot) { mChildrenRoot.Add( child ); } + + Control::OnChildAdd( child ); } void GaussianBlurView::OnChildRemove( Actor& child ) diff --git a/dali-toolkit/internal/controls/magnifier/magnifier-impl.cpp b/dali-toolkit/internal/controls/magnifier/magnifier-impl.cpp index 12205a6..bb48404 100644 --- a/dali-toolkit/internal/controls/magnifier/magnifier-impl.cpp +++ b/dali-toolkit/internal/controls/magnifier/magnifier-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -288,8 +288,6 @@ void Magnifier::SetFrameVisibility(bool visible) void Magnifier::OnSizeSet(const Vector3& targetSize) { - Control::OnSizeSet( targetSize ); - // TODO: Once Camera/CameraActor properties function as proper animatable properties // this code can disappear. // whenever the size of the magnifier changes, the field of view needs to change @@ -297,6 +295,8 @@ void Magnifier::OnSizeSet(const Vector3& targetSize) // a constraint yet as Camera/CameraActor properties are not animatable/constrainable. mActorSize = targetSize; Update(); + + Control::OnSizeSet( targetSize ); } float Magnifier::GetMagnificationFactor() const diff --git a/dali-toolkit/internal/controls/model3d-view/model3d-view-impl.cpp b/dali-toolkit/internal/controls/model3d-view/model3d-view-impl.cpp index dd90747..9c22982 100644 --- a/dali-toolkit/internal/controls/model3d-view/model3d-view-impl.cpp +++ b/dali-toolkit/internal/controls/model3d-view/model3d-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -428,8 +428,6 @@ Property::Value Model3dView::GetProperty( BaseObject* object, Property::Index in void Model3dView::OnStageConnection( int depth ) { - Control::OnStageConnection( depth ); - CustomActor self = Self(); self.AddRenderer( mRenderer ); @@ -449,6 +447,8 @@ void Model3dView::OnStageConnection( int depth ) constraint.AddSource( Source( self, Toolkit::Model3dView::Property::LIGHT_POSITION ) ); constraint.Apply(); } + + Control::OnStageConnection( depth ); } /////////////////////////////////////////////////////////// diff --git a/dali-toolkit/internal/controls/navigation-view/navigation-view-impl.cpp b/dali-toolkit/internal/controls/navigation-view/navigation-view-impl.cpp index 1d15650..5ddf48c 100644 --- a/dali-toolkit/internal/controls/navigation-view/navigation-view-impl.cpp +++ b/dali-toolkit/internal/controls/navigation-view/navigation-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -74,6 +74,8 @@ Toolkit::NavigationView NavigationView::New() void NavigationView::OnStageConnection( int depth ) { Self().SetSensitive(true); + + Control::OnStageConnection( depth ); } void NavigationView::Push( Actor& actor ) diff --git a/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.cpp b/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.cpp index dc60e63..a66813a 100644 --- a/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.cpp +++ b/dali-toolkit/internal/controls/page-turn-view/page-turn-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -473,9 +473,9 @@ void PageTurnView::SetupShadowView() void PageTurnView::OnStageConnection( int depth ) { - Control::OnStageConnection( depth ); - SetupShadowView(); + + Control::OnStageConnection( depth ); } void PageTurnView::OnStageDisconnection() diff --git a/dali-toolkit/internal/controls/popup/popup-impl.cpp b/dali-toolkit/internal/controls/popup/popup-impl.cpp index d12e273..9794921 100644 --- a/dali-toolkit/internal/controls/popup/popup-impl.cpp +++ b/dali-toolkit/internal/controls/popup/popup-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -1574,16 +1574,14 @@ bool Popup::OnDialogTouched( Actor actor, const TouchData& touch ) void Popup::OnStageConnection( int depth ) { - Control::OnStageConnection( depth ); - mLayoutDirty = true; RelayoutRequest(); + + Control::OnStageConnection( depth ); } void Popup::OnChildAdd( Actor& child ) { - Control::OnChildAdd( child ); - // Re-parent any children added by user to the body layer. if( mAlterAddedChild ) { @@ -1594,6 +1592,8 @@ void Popup::OnChildAdd( Actor& child ) mLayoutDirty = true; RelayoutRequest(); } + + Control::OnChildAdd( child ); } void Popup::LayoutContext( const Vector2& size ) diff --git a/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp b/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp index 2192d5e..6e301cb 100755 --- a/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp +++ b/dali-toolkit/internal/controls/scroll-bar/scroll-bar-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -496,6 +496,8 @@ void ScrollBar::OnSizeSet( const Vector3& size ) { mIndicator.SetSize(size.width, mIndicatorFixedHeight); } + + Control::OnSizeSet( size ); } void ScrollBar::SetScrollDirection( Toolkit::ScrollBar::Direction direction ) diff --git a/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp b/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp index 7770147..a5741ab 100755 --- a/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp +++ b/dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -997,6 +997,8 @@ void ItemView::OnChildAdd(Actor& child) Toolkit::ItemView::Property::SCROLL_CONTENT_SIZE); } } + + Scrollable::OnChildAdd( child ); } bool ItemView::OnWheelEvent(const WheelEvent& event) diff --git a/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp b/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp index 0d8becc..0da1660 100644 --- a/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp +++ b/dali-toolkit/internal/controls/scrollable/scroll-view/scroll-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * 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. @@ -701,8 +701,6 @@ void ScrollView::OnInitialize() void ScrollView::OnStageConnection( int depth ) { - ScrollBase::OnStageConnection( depth ); - DALI_LOG_SCROLL_STATE("[0x%X]", this); if ( mSensitive ) @@ -710,11 +708,14 @@ void ScrollView::OnStageConnection( int depth ) SetScrollSensitive( false ); SetScrollSensitive( true ); } + if(IsOvershootEnabled()) { // try and make sure property notifications are set EnableScrollOvershoot(true); } + + ScrollBase::OnStageConnection( depth ); } void ScrollView::OnStageDisconnection() @@ -1941,6 +1942,8 @@ void ScrollView::OnSizeSet( const Vector3& size ) { mOvershootIndicator->Reset(); } + + ScrollBase::OnSizeSet( size ); } void ScrollView::OnChildAdd(Actor& child) diff --git a/dali-toolkit/internal/controls/shadow-view/shadow-view-impl.cpp b/dali-toolkit/internal/controls/shadow-view/shadow-view-impl.cpp index b486fbb..c8605c1 100644 --- a/dali-toolkit/internal/controls/shadow-view/shadow-view-impl.cpp +++ b/dali-toolkit/internal/controls/shadow-view/shadow-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -297,12 +297,12 @@ void ShadowView::OnInitialize() void ShadowView::OnChildAdd( Actor& child ) { - Control::OnChildAdd( child ); - if( child != mChildrenRoot && child != mBlurRootActor) { mChildrenRoot.Add( child ); } + + Control::OnChildAdd( child ); } void ShadowView::OnChildRemove( Actor& child ) diff --git a/dali-toolkit/internal/controls/slider/slider-impl.cpp b/dali-toolkit/internal/controls/slider/slider-impl.cpp index 1d2e001..f322618 100755 --- a/dali-toolkit/internal/controls/slider/slider-impl.cpp +++ b/dali-toolkit/internal/controls/slider/slider-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * 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. @@ -205,10 +205,6 @@ void Slider::OnInitialize() self.TouchSignal().Connect( this, &Slider::OnTouch ); } -void Slider::OnSizeSet( const Vector3& size ) -{ -} - void Slider::OnRelayout( const Vector2& size, RelayoutContainer& container ) { SetHitRegion( Vector2( size.x, GetHitRegion().y ) ); diff --git a/dali-toolkit/internal/controls/slider/slider-impl.h b/dali-toolkit/internal/controls/slider/slider-impl.h index 7879f37..cbb23b0 100755 --- a/dali-toolkit/internal/controls/slider/slider-impl.h +++ b/dali-toolkit/internal/controls/slider/slider-impl.h @@ -2,7 +2,7 @@ #define __DALI_TOOLKIT_INTERNAL_SLIDER_H__ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * 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. @@ -282,11 +282,6 @@ protected: virtual ~Slider(); /** - * @copydoc CustomActorImpl::OnSizeSet( const Vector3& size ) - */ - virtual void OnSizeSet( const Vector3& size ); - - /** * @copydoc CustomActorImpl::OnRelayout */ virtual void OnRelayout( const Vector2& size, RelayoutContainer& container ); diff --git a/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp b/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp index 4e74276..a93257d 100644 --- a/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp +++ b/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -292,6 +292,8 @@ void SuperBlurView::OnSizeSet( const Vector3& targetSize ) SetImage( mInputImage ); } } + + Control::OnSizeSet( targetSize ); } void SuperBlurView::OnStageConnection( int depth ) @@ -301,7 +303,7 @@ void SuperBlurView::OnStageConnection( int depth ) return; } - // Chaining up first ensures visuals have SetOnStage called to create their renderers + // Exception to the rule, chaining up first ensures visuals have SetOnStage called to create their renderers Control::OnStageConnection( depth ); Actor self = Self(); @@ -310,6 +312,7 @@ void SuperBlurView::OnStageConnection( int depth ) // Note that the renderer indices are depending on the order they been added to the actor // which might be different from the blur level of its texture. // We can check the depth index of the renderer to know which blurred image it renders. + // All visuals WILL have renderers at this point as we are simply creating visuals with an Image handle. Renderer renderer = self.GetRendererAt( i ); int depthIndex = renderer.GetProperty(Renderer::Property::DEPTH_INDEX); if( depthIndex > 0 ) @@ -322,11 +325,6 @@ void SuperBlurView::OnStageConnection( int depth ) } } -void SuperBlurView::OnStageDisconnection( ) -{ - Control::OnStageDisconnection(); -} - Vector3 SuperBlurView::GetNaturalSize() { if( mInputImage ) diff --git a/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.h b/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.h index 4380a6e..0c782c9 100644 --- a/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.h +++ b/dali-toolkit/internal/controls/super-blur-view/super-blur-view-impl.h @@ -2,7 +2,7 @@ #define __DALI_TOOLKIT_INTERNAL_SUPER_BLUR_VIEW_H__ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -132,11 +132,6 @@ private: // from Control virtual void OnStageConnection( int depth ); /** - * @copydoc CustomActorImpl::OnStageDisconnection() - */ - virtual void OnStageDisconnection(); - - /** * @copydoc CustomActorImpl::GetNaturalSize() */ virtual Vector3 GetNaturalSize(); diff --git a/dali-toolkit/internal/controls/table-view/table-view-impl.cpp b/dali-toolkit/internal/controls/table-view/table-view-impl.cpp index dea576c..a674abb 100644 --- a/dali-toolkit/internal/controls/table-view/table-view-impl.cpp +++ b/dali-toolkit/internal/controls/table-view/table-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * 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. @@ -795,6 +795,8 @@ void TableView::OnSizeSet( const Vector3& size ) // rows and columns must be recalculated or the new size will not take effect. mRowDirty = mColumnDirty = true; RelayoutRequest(); + + Control::OnSizeSet( size ); } void TableView::OnRelayout( const Vector2& size, RelayoutContainer& container ) @@ -961,98 +963,101 @@ Property::Value TableView::GetProperty( BaseObject* object, Property::Index inde void TableView::OnChildAdd( Actor& child ) { - Control::OnChildAdd( child ); - - if( mLayoutingChild ) + if( ! mLayoutingChild ) { - // we're in the middle of laying out children so no point doing anything here - return; - } + // Ensure we're not in the middle of laying out children - // Check child properties on actor to decide its position inside the table - HorizontalAlignment::Type horizontalAlignment = HorizontalAlignment::LEFT; - VerticalAlignment::Type verticalAlignment = VerticalAlignment::TOP; + // Check child properties on actor to decide its position inside the table + HorizontalAlignment::Type horizontalAlignment = HorizontalAlignment::LEFT; + VerticalAlignment::Type verticalAlignment = VerticalAlignment::TOP; - if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_HORIZONTAL_ALIGNMENT ) != Property::NONE ) - { - std::string value = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_HORIZONTAL_ALIGNMENT ).Get(); - Scripting::GetEnumeration< HorizontalAlignment::Type >( value.c_str(), - HORIZONTAL_ALIGNMENT_STRING_TABLE, - HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT, - horizontalAlignment ); - } + if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_HORIZONTAL_ALIGNMENT ) != Property::NONE ) + { + std::string value = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_HORIZONTAL_ALIGNMENT ).Get(); + Scripting::GetEnumeration< HorizontalAlignment::Type >( value.c_str(), + HORIZONTAL_ALIGNMENT_STRING_TABLE, + HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT, + horizontalAlignment ); + } - if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_VERTICAL_ALIGNMENT ) != Property::NONE ) - { - std::string value = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_VERTICAL_ALIGNMENT ).Get(); - Scripting::GetEnumeration< VerticalAlignment::Type >( value.c_str(), - VERTICAL_ALIGNMENT_STRING_TABLE, - VERTICAL_ALIGNMENT_STRING_TABLE_COUNT, - verticalAlignment ); - } + if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_VERTICAL_ALIGNMENT ) != Property::NONE ) + { + std::string value = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_VERTICAL_ALIGNMENT ).Get(); + Scripting::GetEnumeration< VerticalAlignment::Type >( value.c_str(), + VERTICAL_ALIGNMENT_STRING_TABLE, + VERTICAL_ALIGNMENT_STRING_TABLE_COUNT, + verticalAlignment ); + } - Toolkit::TableView::CellPosition cellPosition; - if( child.GetPropertyType( Toolkit::TableView::ChildProperty::ROW_SPAN ) != Property::NONE ) - { - cellPosition.rowSpan = static_cast( child.GetProperty( Toolkit::TableView::ChildProperty::ROW_SPAN ).Get() ); - } + Toolkit::TableView::CellPosition cellPosition; + if( child.GetPropertyType( Toolkit::TableView::ChildProperty::ROW_SPAN ) != Property::NONE ) + { + cellPosition.rowSpan = static_cast( child.GetProperty( Toolkit::TableView::ChildProperty::ROW_SPAN ).Get() ); + } - if( child.GetPropertyType( Toolkit::TableView::ChildProperty::COLUMN_SPAN ) != Property::NONE ) - { - cellPosition.columnSpan = static_cast( child.GetProperty( Toolkit::TableView::ChildProperty::COLUMN_SPAN ).Get() ); - } + if( child.GetPropertyType( Toolkit::TableView::ChildProperty::COLUMN_SPAN ) != Property::NONE ) + { + cellPosition.columnSpan = static_cast( child.GetProperty( Toolkit::TableView::ChildProperty::COLUMN_SPAN ).Get() ); + } - if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_INDEX ) != Property::NONE ) - { - Vector2 indices = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_INDEX ).Get(); - cellPosition.rowIndex = static_cast( indices.x ); - cellPosition.columnIndex = static_cast( indices.y ); + if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_INDEX ) != Property::NONE ) + { + Vector2 indices = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_INDEX ).Get(); + cellPosition.rowIndex = static_cast( indices.x ); + cellPosition.columnIndex = static_cast( indices.y ); - AddChild( child, cellPosition ); - SetCellAlignment(cellPosition, horizontalAlignment, verticalAlignment); + AddChild( child, cellPosition ); + SetCellAlignment(cellPosition, horizontalAlignment, verticalAlignment); + } + else + { + bool availableCellFound = false; - // Do not continue - return; - } + // Find the first available cell to store the actor in + const unsigned int rowCount = mCellData.GetRows(); + const unsigned int columnCount = mCellData.GetColumns(); + for( unsigned int row = 0; row < rowCount && !availableCellFound; ++row ) + { + for( unsigned int column = 0; column < columnCount && !availableCellFound; ++column ) + { + if( !(mCellData[ row ][ column ].actor) ) + { + // Put the actor in the cell + CellData data; + data.actor = child; + data.position.columnIndex = column; + data.position.rowIndex = row; + data.horizontalAlignment = horizontalAlignment; + data.verticalAlignment = verticalAlignment; + mCellData[ row ][ column ] = data; + + availableCellFound = true; + break; + } + } + } - // Find the first available cell to store the actor in - const unsigned int rowCount = mCellData.GetRows(); - const unsigned int columnCount = mCellData.GetColumns(); - for( unsigned int row = 0; row < rowCount; ++row ) - { - for( unsigned int column = 0; column < columnCount; ++column ) - { - if( !(mCellData[ row ][ column ].actor) ) + if( ! availableCellFound ) { - // Put the actor in the cell + // No empty cells, so increase size of the table + unsigned int newColumnCount = ( columnCount > 0 ) ? columnCount : 1; + ResizeContainers( rowCount + 1, newColumnCount ); + + // Put the actor in the first cell of the new row CellData data; data.actor = child; - data.position.columnIndex = column; - data.position.rowIndex = row; + data.position.rowIndex = rowCount; + data.position.columnIndex = 0; data.horizontalAlignment = horizontalAlignment; data.verticalAlignment = verticalAlignment; - mCellData[ row ][ column ] = data; - - // Don't continue - RelayoutRequest(); - return; + mCellData[ rowCount ][ 0 ] = data; } + + RelayoutRequest(); } } - // No empty cells, so increase size of the table - unsigned int newColumnCount = ( columnCount > 0 ) ? columnCount : 1; - ResizeContainers( rowCount + 1, newColumnCount ); - - // Put the actor in the first cell of the new row - CellData data; - data.actor = child; - data.position.rowIndex = rowCount; - data.position.columnIndex = 0; - data.horizontalAlignment = horizontalAlignment; - data.verticalAlignment = verticalAlignment; - mCellData[ rowCount ][ 0 ] = data; - RelayoutRequest(); + Control::OnChildAdd( child ); } void TableView::OnChildRemove( Actor& child ) @@ -1077,6 +1082,8 @@ TableView::TableView( unsigned int initialRows, unsigned int initialColumns ) mRowDirty( true ), // Force recalculation first time mColumnDirty( true ) { + mCurrentColumn = 0; + mCurrentRow = 0; SetKeyboardNavigationSupport( true ); ResizeContainers( initialRows, initialColumns ); } @@ -1398,13 +1405,42 @@ Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolki // Move the focus if we haven't lost it. if(!focusLost) { + // Save the new focus cell positions of TableView. + mCurrentColumn = currentColumn; + mCurrentRow = currentRow; + nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(currentRow, currentColumn)); } } else { - // The current focused actor is not within table view, so the child in the first cell should be focused. - nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(0, 0)); + // The current focused actor is not within TableView. + // This means that the TableView has gained the Focus again. + + unsigned int numberOfColumns = GetColumns(); + unsigned int numberOfRows = GetRows(); + + if( (mCurrentRow != 0 && mCurrentColumn != 0) && // Last saved cell was not the first cell + (mCurrentRow != numberOfRows - 1 && mCurrentColumn != numberOfColumns - 1) ) // Last saved cell was not the last cell + { + // This condition handles the cases when parent TableView gained the focus again after the child layout + // container (i.e. TableView) has no more items (i.e. actors) to be focused on in a given direction. + + // Move the focus to next cell towards the given direction in a TableView if the last saved cell was not the first or last cell. + nextFocusableActor = GetNextKeyboardFocusableActor(GetChildAt(Toolkit::TableView::CellPosition(mCurrentRow, mCurrentColumn)), direction, loopEnabled); + } + else + { + // Otherwise, move the focus to either the first or the last cell according to the given direction. + if(direction == Toolkit::Control::KeyboardFocus::LEFT || direction == Toolkit::Control::KeyboardFocus::UP) + { + nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(numberOfRows - 1, numberOfColumns - 1)); + } + else + { + nextFocusableActor = GetChildAt(Toolkit::TableView::CellPosition(0, 0)); + } + } } } diff --git a/dali-toolkit/internal/controls/table-view/table-view-impl.h b/dali-toolkit/internal/controls/table-view/table-view-impl.h index d6e62b6..be1f702 100644 --- a/dali-toolkit/internal/controls/table-view/table-view-impl.h +++ b/dali-toolkit/internal/controls/table-view/table-view-impl.h @@ -497,6 +497,8 @@ private: // Data Size mFixedTotals; ///< Accumulated totals for fixed width and height Size mPadding; ///< Padding to apply to each cell + unsigned int mCurrentRow; ///< Last / current focused row + unsigned int mCurrentColumn; ///< Last / current focused column bool mLayoutingChild; ///< Can't be a bitfield due to Relayouting lock bool mRowDirty : 1; ///< Flag to indicate the row data is dirty bool mColumnDirty : 1; ///< Flag to indicate the column data is dirty diff --git a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp index fec052a..aab4f95 100644 --- a/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -1374,13 +1374,13 @@ void TextEditor::KeyboardStatusChanged(bool keyboardShown) void TextEditor::OnStageConnection( int depth ) { - // Call the Control::OnStageConnection() to set the depth of the background. - Control::OnStageConnection( depth ); - // Sets the depth to the visuals inside the text's decorator. mDecorator->SetTextDepth( depth ); // The depth of the text renderer is set in the RenderText() called from OnRelayout(). + + // Call the Control::OnStageConnection() to set the depth of the background. + Control::OnStageConnection( depth ); } bool TextEditor::OnTouched( Actor actor, const TouchData& touch ) diff --git a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp index 44dc851..63568e6 100644 --- a/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-field-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -1572,13 +1572,13 @@ void TextField::KeyboardStatusChanged(bool keyboardShown) void TextField::OnStageConnection( int depth ) { - // Call the Control::OnStageConnection() to set the depth of the background. - Control::OnStageConnection( depth ); - // Sets the depth to the visuals inside the text's decorator. mDecorator->SetTextDepth( depth ); // The depth of the text renderer is set in the RenderText() called from OnRelayout(). + + // Call the Control::OnStageConnection() to set the depth of the background. + Control::OnStageConnection( depth ); } bool TextField::OnTouched( Actor actor, const TouchData& touch ) diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp index e4a8b53..9f7863f 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -790,14 +790,6 @@ void TextLabel::OnStageConnect( Dali::Actor actor ) } } -void TextLabel::OnStageConnection( int depth ) -{ - // Call the Control::OnStageConnection() to set the depth of the background. - Control::OnStageConnection( depth ); - - // The depth of the text renderer is set in the RenderText() called from OnRelayout(). -} - void TextLabel::ScrollingFinished() { // Pure Virtual from TextScroller Interface diff --git a/dali-toolkit/internal/controls/text-controls/text-label-impl.h b/dali-toolkit/internal/controls/text-controls/text-label-impl.h index c928763..bc2459f 100644 --- a/dali-toolkit/internal/controls/text-controls/text-label-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-label-impl.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -95,11 +95,6 @@ private: // From Control */ virtual float GetHeightForWidth( float width ); - /** - * @copydoc Control::OnStageConnection() - */ - virtual void OnStageConnection( int depth ); - // From ControlInterface /** diff --git a/dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp index c91f71d..459e534 100644 --- a/dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -394,15 +394,6 @@ void TextSelectionPopup::OnInitialize() self.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN ); } -void TextSelectionPopup::OnStageConnection( int depth ) -{ - DALI_LOG_INFO( gLogFilter, Debug::General, "TextSelectionPopup::OnStageConnection\n" ); - // Call the Control::OnStageConnection() to set the depth of the background. - Control::OnStageConnection( depth ); - - // TextSelectionToolbar::OnStageConnection() will set the depths of all the popup's components. -} - void TextSelectionPopup::HideAnimationFinished( Animation& animation ) { Actor self = Self(); diff --git a/dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h b/dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h index e2a9497..419720f 100644 --- a/dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h @@ -2,7 +2,7 @@ #define __DALI_TOOLKIT_INTERNAL_TEXT_SELECTION_POPUP_H__ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * 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. @@ -142,11 +142,6 @@ private: // From Control */ virtual void OnInitialize(); - /** - * @copydoc Control::OnStageConnection() - */ - virtual void OnStageConnection( int depth ); - private: // Implementation void HideAnimationFinished( Animation& animation ); diff --git a/dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.cpp b/dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.cpp index 00c74f4..cdd2226 100644 --- a/dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.cpp +++ b/dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -151,15 +151,6 @@ void TextSelectionToolbar::OnRelayout( const Vector2& size, RelayoutContainer& c mScrollView.SetRulerX( mRulerX ); } -void TextSelectionToolbar::OnStageConnection( int depth ) -{ - // Call the Control::OnStageConnection() to set the depth of the background. - Control::OnStageConnection( depth ); - - // Texts are controls, they have their own OnStageConnection() implementation. - // Icons are inside a TableView. It has it's own OnStageConnection() implementation. -} - void TextSelectionToolbar::SetPopupMaxSize( const Size& maxSize ) { mMaxSize = maxSize; diff --git a/dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.h b/dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.h index 46e633b..d44daf0 100644 --- a/dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.h +++ b/dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_INTERNAL_TEXT_SELECTION_TOOLBAR_H /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -97,11 +97,6 @@ private: // From Control virtual void OnRelayout( const Vector2& size, RelayoutContainer& container ); /** - * @copydoc Control::OnStageConnection() - */ - virtual void OnStageConnection( int depth ); - - /** * @brief Set max size of Popup * @param[in] maxSize Size (Vector2) */ diff --git a/dali-toolkit/internal/controls/tool-bar/tool-bar-impl.cpp b/dali-toolkit/internal/controls/tool-bar/tool-bar-impl.cpp index 851945d..441b640 100644 --- a/dali-toolkit/internal/controls/tool-bar/tool-bar-impl.cpp +++ b/dali-toolkit/internal/controls/tool-bar/tool-bar-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * 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. @@ -317,8 +317,6 @@ void ToolBar::OnInitialize() void ToolBar::OnChildAdd(Actor& child) { - Control::OnChildAdd( child ); - if( !mInitializing ) { // An actor is being added through the Actor's API. @@ -335,6 +333,8 @@ void ToolBar::OnChildAdd(Actor& child) // No OnChildRemove method required because Actors are added to the mLayout table view, so if an // actor is removed using the Actor::RemoveChild method it will not remove anything because the // actor is in mLayout not in Self(). + + Control::OnChildAdd( child ); } } // namespace Internal diff --git a/dali-toolkit/internal/controls/video-view/video-view-impl.cpp b/dali-toolkit/internal/controls/video-view/video-view-impl.cpp index 51bf9a2..2ec07ef 100644 --- a/dali-toolkit/internal/controls/video-view/video-view-impl.cpp +++ b/dali-toolkit/internal/controls/video-view/video-view-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -439,13 +439,13 @@ void VideoView::SetDepthIndex( int depthIndex ) void VideoView::OnStageConnection( int depth ) { - Control::OnStageConnection( depth ); - if( mVisual ) { CustomActor self = Self(); Toolkit::GetImplementation(mVisual).SetOnStage( self ); } + + Control::OnStageConnection( depth ); } void VideoView::OnStageDisconnection() diff --git a/dali-toolkit/internal/transition-effects/cube-transition-effect-impl.cpp b/dali-toolkit/internal/transition-effects/cube-transition-effect-impl.cpp index ffa43e0..460ea31 100644 --- a/dali-toolkit/internal/transition-effects/cube-transition-effect-impl.cpp +++ b/dali-toolkit/internal/transition-effects/cube-transition-effect-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * 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. @@ -246,8 +246,6 @@ void CubeTransitionEffect::Initialize() void CubeTransitionEffect::OnStageConnection( int depth ) { - Control::OnStageConnection( depth ); - Geometry geometry = VisualFactoryCache::CreateQuadGeometry(); Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER ); @@ -262,6 +260,8 @@ void CubeTransitionEffect::OnStageConnection( int depth ) mCurrentRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, depth ); Self().AddRenderer( mCurrentRenderer ); + + Control::OnStageConnection( depth ); } void CubeTransitionEffect::OnStageDisconnection() diff --git a/dali-toolkit/public-api/controls/buttons/button.h b/dali-toolkit/public-api/controls/buttons/button.h index 3ccf2d4..e447554 100644 --- a/dali-toolkit/public-api/controls/buttons/button.h +++ b/dali-toolkit/public-api/controls/buttons/button.h @@ -192,7 +192,7 @@ public: SELECTED_COLOR, /** - * @brief name "label", type Property::Map + * @brief name "label", type Property::Map or std::string * @SINCE_1_0.0 */ LABEL, diff --git a/dali-toolkit/public-api/controls/control-impl.cpp b/dali-toolkit/public-api/controls/control-impl.cpp index 5103060..c62684f 100644 --- a/dali-toolkit/public-api/controls/control-impl.cpp +++ b/dali-toolkit/public-api/controls/control-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -63,6 +64,11 @@ namespace Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_CONTROL_VISUALS"); #endif +DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE ) +DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED ) +DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN ) +DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE ) + /** * Struct used to store Visual within the control, index is a unique key for each visual. */ @@ -1149,16 +1155,33 @@ void Control::OnStageConnection( int depth ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::OnStageConnection number of registered visuals(%d)\n", mImpl->mVisuals.Size() ); + Actor self( Self() ); + for(RegisteredVisualContainer::Iterator iter = mImpl->mVisuals.Begin(); iter!= mImpl->mVisuals.End(); iter++) { // Check whether the visual is empty and enabled if( (*iter)->visual && (*iter)->enabled ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::OnStageConnection Setting visual(%d) on stage\n", (*iter)->index ); - Actor self( Self() ); Toolkit::GetImplementation((*iter)->visual).SetOnStage( self ); } } + + if( mImpl->mVisuals.Empty() && ! self.GetRendererCount() ) + { + Property::Value clippingValue = self.GetProperty( Actor::Property::CLIPPING_MODE ); + int clippingMode = ClippingMode::DISABLED; + if( clippingValue.Get( clippingMode ) ) + { + // Add a transparent background if we do not have any renderers or visuals so we clip our children + + if( clippingMode == ClippingMode::CLIP_CHILDREN ) + { + // Create a transparent background visual which will also get staged. + SetBackgroundColor( Color::TRANSPARENT ); + } + } + } } void Control::OnStageDisconnection() @@ -1197,6 +1220,29 @@ void Control::OnChildRemove(Actor& child) OnControlChildRemove( child ); } +void Control::OnPropertySet( Property::Index index, Property::Value propertyValue ) +{ + Actor self( Self() ); + if( index == Actor::Property::CLIPPING_MODE ) + { + // Only set the background if we're already on the stage and have no renderers or visuals + + if( mImpl->mVisuals.Empty() && ! self.GetRendererCount() && self.OnStage() ) + { + ClippingMode::Type clippingMode = ClippingMode::DISABLED; + if( Scripting::GetEnumerationProperty< ClippingMode::Type >( propertyValue, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, clippingMode ) ) + { + // Add a transparent background if we do not have one so we clip children + + if( clippingMode == ClippingMode::CLIP_CHILDREN ) + { + SetBackgroundColor( Color::TRANSPARENT ); + } + } + } + } +} + void Control::OnSizeSet(const Vector3& targetSize) { Toolkit::Visual::Base visual = GetVisual( Toolkit::Control::Property::BACKGROUND ); diff --git a/dali-toolkit/public-api/controls/control-impl.h b/dali-toolkit/public-api/controls/control-impl.h index 541d489..d850eb4 100644 --- a/dali-toolkit/public-api/controls/control-impl.h +++ b/dali-toolkit/public-api/controls/control-impl.h @@ -2,7 +2,7 @@ #define DALI_TOOLKIT_CONTROL_IMPL_H /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * 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. @@ -393,7 +393,7 @@ protected: // From CustomActorImpl, not to be used by application developers /** * @copydoc CustomActorImpl::OnStageConnection() - * @note If overridden, then an up-call to Control::OnStageConnection MUST be made at the start. + * @note If overridden, then an up-call to Control::OnStageConnection MUST be made at the end. */ virtual void OnStageConnection( int depth ); @@ -405,7 +405,7 @@ protected: // From CustomActorImpl, not to be used by application developers /** * @copydoc CustomActorImpl::OnChildAdd() - * @note If overridden, then an up-call to Control::OnChildAdd MUST be made at the start. + * @note If overridden, then an up-call to Control::OnChildAdd MUST be made at the end. */ virtual void OnChildAdd( Actor& child ); @@ -416,14 +416,20 @@ protected: // From CustomActorImpl, not to be used by application developers virtual void OnChildRemove( Actor& child ); /** + * @copydoc CustomActorImpl::OnPropertySet() + * @note If overridden, then an up-call to Control::OnChildRemove MUST be made at the end. + */ + virtual void OnPropertySet( Property::Index index, Property::Value propertyValue ); + + /** * @copydoc CustomActorImpl::OnSizeSet() - * @note If overridden, then an up-call to Control::OnSizeSet MUST be made at the start. + * @note If overridden, then an up-call to Control::OnSizeSet MUST be made at the end. */ virtual void OnSizeSet( const Vector3& targetSize ); /** * @copydoc CustomActorImpl::OnSizeAnimation() - * @note If overridden, then an up-call to Control::OnSizeAnimation MUST be made at the start. + * @note If overridden, then an up-call to Control::OnSizeAnimation MUST be made at the end. */ virtual void OnSizeAnimation( Animation& animation, const Vector3& targetSize ); diff --git a/dali-toolkit/public-api/controls/control.cpp b/dali-toolkit/public-api/controls/control.cpp index 415ffb6..b882c1d 100644 --- a/dali-toolkit/public-api/controls/control.cpp +++ b/dali-toolkit/public-api/controls/control.cpp @@ -109,8 +109,6 @@ const std::string& Control::GetStyleName() const void Control::SetBackgroundColor( const Vector4& color ) { - DALI_LOG_WARNING_NOFN("DEPRECATION WARNING: SetBackgroundColor() is deprecated and will be removed from next release. use Property::BACKGROUND instead.\n" ); - Internal::GetImplementation(*this).SetBackgroundColor( color ); } @@ -123,6 +121,8 @@ Vector4 Control::GetBackgroundColor() const void Control::SetBackgroundImage( Image image ) { + DALI_LOG_WARNING_NOFN("DEPRECATION WARNING: SetBackgroundImage() is deprecated and will be removed from next release. use Property::BACKGROUND instead.\n" ); + Internal::GetImplementation(*this).SetBackgroundImage( image ); } diff --git a/dali-toolkit/public-api/controls/scrollable/item-view/item-view.h b/dali-toolkit/public-api/controls/scrollable/item-view/item-view.h index d49d32c..60dba05 100755 --- a/dali-toolkit/public-api/controls/scrollable/item-view/item-view.h +++ b/dali-toolkit/public-api/controls/scrollable/item-view/item-view.h @@ -82,13 +82,13 @@ public: }; /** - * @brief An enumeration of properties belonging to the ScrollView class. + * @brief Enumeration for the instance of properties belonging to the ScrollView class. * @SINCE_1_0.0 */ struct Property { /** - * @brief An enumeration of properties belonging to the ScrollView class. + * @brief Enumeration for the instance of properties belonging to the ScrollView class. * @SINCE_1_0.0 */ enum @@ -422,11 +422,12 @@ public: * * A relayout will occur for the remaining actors; for example if RemoveItem(Item(2, ActorZ), 0) is called, * the items with ID 3 or greater will be moved: - * Initial actors: After remove: - * ID 1 - ActorA ID 1 - ActorA - * ID 2 - ActorB ID 2 - ActorC (previously ID 3) - * ID 3 - ActorC ID 3 - ActorB (previously ID 4) - * ID 4 - ActorD + * | Initial actors: | After remove: | + * |:------------------ |:-------------- | + * | ID 1 - ActorA | ID 1 - ActorA | + * | ID 2 - ActorB | ID 2 - ActorC (previously ID 3) | + * | ID 3 - ActorC | ID 3 - ActorB (previously ID 4) | + * | ID 4 - ActorD | | * @SINCE_1_0.0 * @param[in] itemId The Item ID of the item to remove. * @param[in] durationSeconds How long the relayout takes in seconds. diff --git a/dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h b/dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h index 0028cd7..cb24960 100644 --- a/dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h +++ b/dali-toolkit/public-api/controls/scrollable/scroll-view/scroll-view.h @@ -492,13 +492,13 @@ public: }; /** - * @brief An enumeration of properties belonging to the ScrollView class. + * @brief Enumeration for the instance of properties belonging to the ScrollView class. * @SINCE_1_0.0 */ struct Property { /** - * @brief An enumeration of properties belonging to the ScrollView class. + * @brief Enumeration for the instance of properties belonging to the ScrollView class. * @SINCE_1_0.0 */ enum diff --git a/dali-toolkit/public-api/controls/table-view/table-view.h b/dali-toolkit/public-api/controls/table-view/table-view.h index be37f50..fb7dd53 100644 --- a/dali-toolkit/public-api/controls/table-view/table-view.h +++ b/dali-toolkit/public-api/controls/table-view/table-view.h @@ -383,7 +383,7 @@ public: void SetFitHeight( unsigned int rowIndex ); /** - * @brief Is the row a fit row + * @brief Check if the row is a fit row. * * @SINCE_1_0.0 * @param[in] rowIndex The row to check @@ -400,7 +400,7 @@ public: void SetFitWidth( unsigned int columnIndex ); /** - * @brief Is the column a fit column + * @brief Check if the column is a fit column. * * @SINCE_1_0.0 * @param[in] columnIndex The column to check diff --git a/dali-toolkit/public-api/dali-toolkit-version.cpp b/dali-toolkit/public-api/dali-toolkit-version.cpp index 4d7751b..0d03d34 100644 --- a/dali-toolkit/public-api/dali-toolkit-version.cpp +++ b/dali-toolkit/public-api/dali-toolkit-version.cpp @@ -31,7 +31,7 @@ namespace Toolkit const unsigned int TOOLKIT_MAJOR_VERSION = 1; const unsigned int TOOLKIT_MINOR_VERSION = 2; -const unsigned int TOOLKIT_MICRO_VERSION = 21; +const unsigned int TOOLKIT_MICRO_VERSION = 22; const char * const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__; #ifdef DEBUG_ENABLED diff --git a/dali-toolkit/public-api/enums.h b/dali-toolkit/public-api/enums.h index 70bddb0..dd8da9b 100644 --- a/dali-toolkit/public-api/enums.h +++ b/dali-toolkit/public-api/enums.h @@ -42,7 +42,7 @@ namespace ControlOrientation { /** - * @brief The internal orientation of a control. + * @brief Enumeration for the internal orientation of a control. * @SINCE_1_0.0 */ enum Type @@ -59,7 +59,7 @@ enum Type * @brief Query whether an orientation is vertical. * * @param[in] orientation The orientation. - * @return True if the orientation is vertical. + * @return true if the orientation is vertical. */ DALI_IMPORT_API bool IsVertical(ControlOrientation::Type orientation); @@ -68,7 +68,7 @@ DALI_IMPORT_API bool IsVertical(ControlOrientation::Type orientation); * * @SINCE_1_0.0 * @param[in] orientation The orientation. - * @return True if the orientation is horizontal. + * @return true if the orientation is horizontal. */ DALI_IMPORT_API bool IsHorizontal(ControlOrientation::Type orientation); diff --git a/dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json b/dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json index 69abfe1..85d168f 100644 --- a/dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json +++ b/dali-toolkit/styles/720x1280/dali-toolkit-default-theme.json @@ -233,7 +233,7 @@ { "visualType": "TEXT", "horizontalAlignment": "CENTER", - "pointSize" : 12.0, // Point size must always be provided to Text Visual + "pointSize" : 10.0, // Point size must always be provided to Text Visual "verticalAlignment": "CENTER" }, "unselectedBackgroundVisual": @@ -264,7 +264,7 @@ "label": { "visualType": "TEXT", - "pointSize" : 12.0, // Point size must always be provided to Text Visual + "pointSize" : 10.0, // Point size must always be provided to Text Visual "verticalAlignment": "CENTER" }, "unselectedVisual": @@ -295,7 +295,7 @@ "label": { "visualType": "TEXT", - "pointSize" : 12.0, // Point size must always be provided to Text Visual + "pointSize" : 10.0, // Point size must always be provided to Text Visual "verticalAlignment": "CENTER" }, "unselectedVisual": diff --git a/docs/content/shared-javascript-and-cpp-documentation/creating-custom-controls.md b/docs/content/shared-javascript-and-cpp-documentation/creating-custom-controls.md index a1451ee..54a0220 100644 --- a/docs/content/shared-javascript-and-cpp-documentation/creating-custom-controls.md +++ b/docs/content/shared-javascript-and-cpp-documentation/creating-custom-controls.md @@ -341,10 +341,10 @@ An up call to the Control class is necessary if these methods are overridden. // C++ void MyUIControlImpl::OnChildAdd( Actor& child ); { - // Up call to Control first - Control::OnChildAdd( child ); - // Do any other operations required upon child addition + + // Up call to Control at the end + Control::OnChildAdd( child ); } ~~~ ~~~{.cpp} @@ -371,10 +371,10 @@ An up call to the Control class is necessary if these methods are overridden. // C++ void MyUIControlImpl::OnStageConnection( int depth ) { - // Up call to Control first - Control::OnStageConnection( depth ); - // Do any other operations required upon stage connection + + // Up call to Control at the end + Control::OnStageConnection( depth ); } ~~~ ~~~{.cpp} @@ -449,6 +449,18 @@ More information on size negotiation can be found [here](@ref size-negotiation-c ___________________________________________________________________________________________________ +### Clipping Support {#creating-controls-clipping} + +When an Actor is set to clip its children, the renderers have to be added manually in order to specify what its children need to clip to. +The Control base class automates the creation of the renderers/visuals when it is set to clip its children. + +This is only done if the application or custom control writer has not added any renderers to the Control or registered any visuals +(regardless of whether these visuals are enabled or not). + +If custom control writers want to define the clipping visuals themselves, then they should register all required visuals before the control is staged. + +___________________________________________________________________________________________________ + ### Other Features {#creating-controls-other} + [Background](@ref background) diff --git a/packaging/dali-addon.spec b/packaging/dali-addon.spec index 66af4d1..81f942c 100644 --- a/packaging/dali-addon.spec +++ b/packaging/dali-addon.spec @@ -1,6 +1,6 @@ Name: dali-addon Summary: DALi module for Node.JS -Version: 1.2.21 +Version: 1.2.22 Release: 1 Group: Development/Libraries License: Apache License, Version 2.0 diff --git a/packaging/dali-toolkit.spec b/packaging/dali-toolkit.spec index 35d0ed9..0853246 100644 --- a/packaging/dali-toolkit.spec +++ b/packaging/dali-toolkit.spec @@ -1,6 +1,6 @@ Name: dali-toolkit Summary: The OpenGLES Canvas Core Library Toolkit -Version: 1.2.21 +Version: 1.2.22 Release: 1 Group: System/Libraries License: Apache-2.0 and BSD-2-Clause and MIT diff --git a/plugins/dali-swig/.gitignore b/plugins/dali-swig/.gitignore index 43660d7..2263391 100644 --- a/plugins/dali-swig/.gitignore +++ b/plugins/dali-swig/.gitignore @@ -4,6 +4,5 @@ autom4te.cache/ aclocal.m4 config/ config.* -cpp/dali_wrap.cpp -cpp/dali_wrap.h +automatic/* configure diff --git a/plugins/dali-swig/Makefile.am b/plugins/dali-swig/Makefile.am index 991c0ee..e1520bf 100755 --- a/plugins/dali-swig/Makefile.am +++ b/plugins/dali-swig/Makefile.am @@ -39,14 +39,16 @@ manual/cpp/callbackbase_wrap.o: $(BUILT_SOURCES) g++ -c -fpic $(CXXFLAGS) $(DALICORE_CFLAGS) $(DALIADAPTOR_CFLAGS) $(DALITOOLKIT_CFLAGS) manual/cpp/callbackbase_wrap.cpp -o manual/cpp/callbackbase_wrap.o NDali.dll: $(BUILT_SOURCES) - $(MCS) -nologo -target:library -out:NDali.dll automatic/csharp/*.cs manual/csharp/*.cs + $(MCS) -nologo -target:library -out:NDali.dll automatic/csharp/*.cs manual/csharp/*.cs views/*.cs check-local: examples/dali-test.exe \ examples/hello-world.exe \ examples/scroll-view.exe \ examples/custom-control.exe \ - examples/spin-control.exe \ + examples/date-picker.exe \ examples/control-dashboard.exe \ + examples/date-picker-using-json.exe \ + examples/json-loader.exe \ examples/user-alphafunction.exe \ examples/image-view.exe \ examples/libNDalic.so examples/NDali.dll diff --git a/plugins/dali-swig/SWIG/dali-core.i b/plugins/dali-swig/SWIG/dali-core.i index 5535ee9..73ce8cc 100755 --- a/plugins/dali-swig/SWIG/dali-core.i +++ b/plugins/dali-swig/SWIG/dali-core.i @@ -84,6 +84,7 @@ %ignore *::AnchorPoint::DEFAULT; %ignore *::SetPositionInheritanceMode(PositionInheritanceMode); %ignore *::GetKeyValue(SizeType) const; +%ignore *::TypeInfo::GetCreator() const; %rename(ParentOriginTop) Dali::ParentOrigin::TOP; %rename(ParentOriginBottom) Dali::ParentOrigin::BOTTOM; @@ -209,6 +210,8 @@ typedef std::pair< Dali::Radian, Dali::Radian > AngleThresholdPair; %include %include %include +%include +%include %include %include diff --git a/plugins/dali-swig/SWIG/dali.i b/plugins/dali-swig/SWIG/dali.i index 1f5149b..e4da86b 100755 --- a/plugins/dali-swig/SWIG/dali.i +++ b/plugins/dali-swig/SWIG/dali.i @@ -53,6 +53,8 @@ #include #include #include +#include +#include #include #include @@ -165,8 +167,67 @@ return $null; %} + + + +// Type registry type maps +%typemap(cstype) Dali::TypeInfo::CreateFunction "System.Delegate" +%typemap(csin, pre ="System.IntPtr ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate($csinput); ") + Dali::TypeInfo::CreateFunction "new System.Runtime.InteropServices.HandleRef(null, ip)" // null was this + +%typemap(cstype) Dali::CSharpTypeInfo::CreateFunction "System.Delegate" +%typemap(csin, pre ="System.IntPtr ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate($csinput); ") + Dali::CSharpTypeInfo::CreateFunction "new System.Runtime.InteropServices.HandleRef(null, ip)" // null was this + + + +%typemap(cstype) Dali::CSharpTypeInfo::SetPropertyFunction "System.Delegate" +%typemap(csin, pre ="System.IntPtr ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate($csinput); ") + Dali::CSharpTypeInfo::SetPropertyFunction "new System.Runtime.InteropServices.HandleRef(null, ip)" // null was this + + + +%typemap(cstype) Dali::CSharpTypeInfo::GetPropertyFunction "System.Delegate" +%typemap(csin, pre ="System.IntPtr ip2 = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate($csinput); ") + Dali::CSharpTypeInfo::GetPropertyFunction "new System.Runtime.InteropServices.HandleRef(null, ip2)" // null was this + + + + + + + #endif + + +/** + * Extend the type registry to allow for registering of C# controls and custom properties + */ +%extend Dali::TypeRegistration { + + + static void RegisterControl( const std::string& controlName, Dali::CSharpTypeInfo::CreateFunction createFunc ) + { + Dali::CSharpTypeRegistry::RegisterType( controlName, typeid( Dali::Toolkit::Control), createFunc ); + }; + + + static void RegisterProperty( const std::string& controlName, + const std::string& propertyName, + int index, + Property::Type type, + Dali::CSharpTypeInfo::SetPropertyFunction setFunc, + Dali::CSharpTypeInfo::GetPropertyFunction getFunc ) + { + Dali::CSharpTypeRegistry::RegisterProperty( controlName, propertyName, index, type, setFunc, getFunc ); + }; + +}; + + + + %ignore operator<<; %ignore *::GetImplementation(); %ignore *::GetImplementation(Dali::BaseHandle&); @@ -219,7 +280,7 @@ using namespace Dali::Toolkit; %include alphafunction.i %include name-changed.i - +%include property-value.i %include dali-operator.i %include dali-core.i %include dali-adaptor.i diff --git a/plugins/dali-swig/SWIG/events/application-event.i b/plugins/dali-swig/SWIG/events/application-event.i index bc81dec..3db23f4 100644 --- a/plugins/dali-swig/SWIG/events/application-event.i +++ b/plugins/dali-swig/SWIG/events/application-event.i @@ -1018,6 +1018,9 @@ public static Application NewApplication(string stylesheet, Application.WINDOW_MODE windowMode) { + // register all Views with the type registry, so that can be created / styled via JSON + ViewRegistryHelper.Initialize(); + Application ret = New(1, stylesheet, windowMode); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); diff --git a/plugins/dali-swig/SWIG/events/builder-event.i b/plugins/dali-swig/SWIG/events/builder-event.i index db58063..268b7d7 100644 --- a/plugins/dali-swig/SWIG/events/builder-event.i +++ b/plugins/dali-swig/SWIG/events/builder-event.i @@ -80,6 +80,29 @@ } } + /// + public void LoadFromFile( string fileName ) + { + try + { + string json = System.IO.File.ReadAllText( fileName ); + if( json.Length > 0 ) + { + LoadFromString( json ); + } + else + { + throw new global::System.InvalidOperationException("Failed to load file " +fileName); + + } + } + catch ( System.Exception e) + { + throw new global::System.InvalidOperationException("Failed to parse " +fileName); + } + } + + %} %enddef diff --git a/plugins/dali-swig/SWIG/property-value.i b/plugins/dali-swig/SWIG/property-value.i new file mode 100644 index 0000000..290b4a1 --- /dev/null +++ b/plugins/dali-swig/SWIG/property-value.i @@ -0,0 +1,100 @@ +/* + * 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. + * + */ + +#if defined(SWIGCSHARP) + + + %typemap(cscode) Dali::Property::Value %{ + + // Extension to property value class that allows us to create a + // PropertyValue from a C# object, e.g. int, float, string + static public Property.Value CreateFromObject( System.Object obj) + { + System.Type type = obj.GetType (); + + Property.Value value; + + if ( type.Equals (typeof(int)) ) + { + System.Console.WriteLine (" got an int property value "); + value = new Property.Value ((int) obj ); + } + if ( type.Equals (typeof(System.Int32)) ) + { + System.Console.WriteLine (" got an int property value "); + value = new Property.Value ((int) obj ); + } + else if ( type.Equals (typeof(bool)) ) + { + System.Console.WriteLine (" got an bool property value "); + value = new Property.Value ((bool) obj ); + } + else if ( type.Equals (typeof(float)) ) + { + System.Console.WriteLine (" got an float property value "); + value = new Property.Value ((float) obj ); + } + else if ( type.Equals (typeof(string)) ) + { + System.Console.WriteLine (" got a string property value "); + value = new Property.Value ((string) obj ); + } + else if ( type.Equals (typeof(Vector2)) ) + { + System.Console.WriteLine (" got an Vector2 property value "); + value = new Property.Value ((Vector2) obj ); + } + else if ( type.Equals (typeof(Vector3)) ) + { + System.Console.WriteLine (" got an Vector3 property value "); + value = new Property.Value ((Vector3) obj ); + } + else if ( type.Equals (typeof(Vector4)) ) + { + System.Console.WriteLine (" got an Vector4 property value "); + + value = new Property.Value ((Vector4) obj ); + } + else if ( type.Equals (typeof(Position)) ) + { + System.Console.WriteLine (" got an Position property value "); + value = new Property.Value ((Position) obj ); + } + else if ( type.Equals (typeof(Size)) ) + { + System.Console.WriteLine (" got an Size property value "); + value = new Property.Value ((Size) obj ); + } + else if ( type.Equals (typeof(Color)) ) + { + System.Console.WriteLine (" got an Color property value "); + value = new Property.Value ((Color) obj ); + } + else + { + throw new global::System.InvalidOperationException("Unimplemented type for Property Value"); + } + return value; + } + + + %} + + + + +#endif \ No newline at end of file diff --git a/plugins/dali-swig/examples/date-picker-using-json.cs b/plugins/dali-swig/examples/date-picker-using-json.cs new file mode 100644 index 0000000..dbc388c --- /dev/null +++ b/plugins/dali-swig/examples/date-picker-using-json.cs @@ -0,0 +1,170 @@ +/* + * 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. + * + */ + +using System; +using System.Runtime.InteropServices; +using Dali; + +namespace MyCSharpExample +{ + // A spin control (for continously changing values when users can easily predict a set of values) + + class Example + { + private Dali.Application _application; + private Spin _spinYear; // spin control for year + private Spin _spinMonth; // spin control for month + private Spin _spinDay; // spin control for day + private Builder _builder; // DALi Builder + + public Example(Dali.Application application) + { + _application = application; + _application.Initialized += Initialize; + } + + public void Initialize(object source, NUIApplicationInitEventArgs e) + { + + Stage stage = Stage.GetCurrent(); + stage.BackgroundColor = Color.White; + + // load date JSON template... + + _builder = new Builder (); + + // Optional constant to see logging information coming out + // of DALi JSON parser (builder) + Property.Map constants = new Property.Map(); + constants.Insert( "CONFIG_SCRIPT_LOG_LEVEL", new Property.Value( "Verbose") ); + _builder.AddConstants( constants ); + + _builder.LoadFromFile( "./json/date-picker.json" ); + + // create the date-picker from the template in the json file + BaseHandle handle = _builder.Create( "date-picker"); + + Actor actorTree = Actor.DownCast( handle ); + + stage.Add( actorTree ); + + Actor year = actorTree.FindChildByName("Year"); + Actor month = actorTree.FindChildByName("Month" ); + Actor day = actorTree.FindChildByName("Day"); + + // need to get the actual C# View associated with the actor, + _spinYear = (Spin ) ViewRegistry.GetCustomViewFromActor( year ); + _spinMonth = (Spin ) ViewRegistry.GetCustomViewFromActor( month ); + _spinDay = (Spin ) ViewRegistry.GetCustomViewFromActor( day ); + + _spinYear.Value = 2099; + _spinMonth.Value = 5; + _spinDay.Value = 23; + + + _spinYear.SetKeyboardFocusable(true); + _spinMonth.SetKeyboardFocusable(true); + _spinDay.SetKeyboardFocusable(true); + + + FocusManager keyboardFocusManager = FocusManager.Instance; + keyboardFocusManager.PreFocusChange += OnKeyboardPreFocusChange; + keyboardFocusManager.FocusedActorEnterKeyPressed += OnFocusedActorEnterKeyPressed; + + } + + private Actor OnKeyboardPreFocusChange(object source, FocusManager.PreFocusChangeEventArgs e) + { + Actor nextFocusActor = e.Proposed; + + // When nothing has been focused initially, focus the text field in the first spin + if (!e.Current && !e.Proposed) + { + nextFocusActor = _spinYear.SpinText; + } + else if(e.Direction == View.KeyboardFocus.Direction.LEFT) + { + // Move the focus to the spin in the left of the current focused spin + if(e.Current == _spinMonth.SpinText) + { + nextFocusActor = _spinYear.SpinText; + } + else if(e.Current == _spinDay.SpinText) + { + nextFocusActor = _spinMonth.SpinText; + } + } + else if(e.Direction == View.KeyboardFocus.Direction.RIGHT) + { + // Move the focus to the spin in the right of the current focused spin + if(e.Current == _spinYear.SpinText) + { + nextFocusActor = _spinMonth.SpinText; + } + else if(e.Current == _spinMonth.SpinText) + { + nextFocusActor = _spinDay.SpinText; + } + } + + return nextFocusActor; + } + + private void OnFocusedActorEnterKeyPressed(object source, FocusManager.FocusedActorEnterKeyEventArgs e) + { + // Make the text field in the current focused spin to take the key input + KeyInputFocusManager manager = KeyInputFocusManager.Get(); + + if (e.Actor == _spinYear.SpinText) + { + if (manager.GetCurrentFocusControl() != _spinYear.SpinText) + { + manager.SetFocus(_spinYear.SpinText); + } + } + else if (e.Actor == _spinMonth.SpinText) + { + if (manager.GetCurrentFocusControl() != _spinMonth.SpinText) + { + manager.SetFocus(_spinMonth.SpinText); + } + } + else if (e.Actor == _spinDay.SpinText) + { + if (manager.GetCurrentFocusControl() != _spinDay.SpinText) + { + manager.SetFocus(_spinDay.SpinText); + } + } + } + + public void MainLoop() + { + _application.MainLoop (); + } + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(string[] args) + { + Example example = new Example(Application.NewApplication()); + example.MainLoop (); + } + } +} diff --git a/plugins/dali-swig/examples/date-picker.cs b/plugins/dali-swig/examples/date-picker.cs new file mode 100644 index 0000000..c9701cf --- /dev/null +++ b/plugins/dali-swig/examples/date-picker.cs @@ -0,0 +1,196 @@ +/* + * 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. + * + */ + +using System; +using System.Runtime.InteropServices; +using Dali; + +namespace MyCSharpExample +{ + // A spin control (for continously changing values when users can easily predict a set of values) + + class Example + { + private Dali.Application _application; + private FlexContainer _container; // Flex container to hold spin controls + private Spin _spinYear; // spin control for year + private Spin _spinMonth; // spin control for month + private Spin _spinDay; // spin control for day + + public Example(Dali.Application application) + { + _application = application; + _application.Initialized += Initialize; + } + + public void Initialize(object source, NUIApplicationInitEventArgs e) + { + + Stage stage = Stage.GetCurrent(); + stage.BackgroundColor = Color.White; + + // Create a container for the spins + _container = new FlexContainer(); + + _container.ParentOrigin = NDalic.ParentOriginCenter; + _container.AnchorPoint = NDalic.AnchorPointCenter; + _container.FlexDirection = (int)FlexContainer.FlexDirectionType.ROW; + _container.Size = new Vector3(480.0f, 150.0f, 0.0f); + + stage.Add(_container); + + // Create a Spin control for year + _spinYear = new Spin(); + _spinYear.ParentOrigin = NDalic.ParentOriginCenter; + _spinYear.AnchorPoint = NDalic.AnchorPointCenter; + _spinYear.Flex = 0.3f; + _spinYear.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f); + _container.Add(_spinYear); + + _spinYear.MinValue = 1900; + _spinYear.MaxValue = 2100; + _spinYear.Value = 2016; + _spinYear.Step = 1; + _spinYear.MaxTextLength = 4; + _spinYear.TextPointSize = 26; + _spinYear.TextColor = Color.White; + _spinYear.SetKeyboardFocusable(true); + _spinYear.Name = "_spinYear"; + + // Create a Spin control for month + _spinMonth = new Spin(); + _spinMonth.ParentOrigin = NDalic.ParentOriginCenter; + _spinMonth.AnchorPoint = NDalic.AnchorPointCenter; + _spinMonth.Flex = 0.3f; + _spinMonth.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f); + _container.Add(_spinMonth); + + _spinMonth.MinValue = 1; + _spinMonth.MaxValue = 12; + _spinMonth.Value = 10; + _spinMonth.Step = 1; + _spinMonth.MaxTextLength = 2; + _spinMonth.TextPointSize = 26; + _spinMonth.TextColor = Color.White; + _spinMonth.SetKeyboardFocusable(true); + _spinMonth.Name = "_spinMonth"; + + // Create a Spin control for day + _spinDay = new Spin(); + _spinDay.ParentOrigin = NDalic.ParentOriginCenter; + _spinDay.AnchorPoint = NDalic.AnchorPointCenter; + _spinDay.Flex = 0.3f; + _spinDay.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f); + _container.Add(_spinDay); + + _spinDay.MinValue = 1; + _spinDay.MaxValue = 31; + _spinDay.Value = 26; + _spinDay.Step = 1; + _spinDay.MaxTextLength = 2; + _spinDay.TextPointSize = 26; + _spinDay.TextColor = Color.White; + _spinDay.SetKeyboardFocusable(true); + _spinDay.Name = "_spinDay"; + + FocusManager keyboardFocusManager = FocusManager.Instance; + keyboardFocusManager.PreFocusChange += OnKeyboardPreFocusChange; + keyboardFocusManager.FocusedActorEnterKeyPressed += OnFocusedActorEnterKeyPressed; + + } + + private Actor OnKeyboardPreFocusChange(object source, FocusManager.PreFocusChangeEventArgs e) + { + Actor nextFocusActor = e.Proposed; + + // When nothing has been focused initially, focus the text field in the first spin + if (!e.Current && !e.Proposed) + { + nextFocusActor = _spinYear.SpinText; + } + else if(e.Direction == View.KeyboardFocus.Direction.LEFT) + { + // Move the focus to the spin in the left of the current focused spin + if(e.Current == _spinMonth.SpinText) + { + nextFocusActor = _spinYear.SpinText; + } + else if(e.Current == _spinDay.SpinText) + { + nextFocusActor = _spinMonth.SpinText; + } + } + else if(e.Direction == View.KeyboardFocus.Direction.RIGHT) + { + // Move the focus to the spin in the right of the current focused spin + if(e.Current == _spinYear.SpinText) + { + nextFocusActor = _spinMonth.SpinText; + } + else if(e.Current == _spinMonth.SpinText) + { + nextFocusActor = _spinDay.SpinText; + } + } + + return nextFocusActor; + } + + private void OnFocusedActorEnterKeyPressed(object source, FocusManager.FocusedActorEnterKeyEventArgs e) + { + // Make the text field in the current focused spin to take the key input + KeyInputFocusManager manager = KeyInputFocusManager.Get(); + + if (e.Actor == _spinYear.SpinText) + { + if (manager.GetCurrentFocusControl() != _spinYear.SpinText) + { + manager.SetFocus(_spinYear.SpinText); + } + } + else if (e.Actor == _spinMonth.SpinText) + { + if (manager.GetCurrentFocusControl() != _spinMonth.SpinText) + { + manager.SetFocus(_spinMonth.SpinText); + } + } + else if (e.Actor == _spinDay.SpinText) + { + if (manager.GetCurrentFocusControl() != _spinDay.SpinText) + { + manager.SetFocus(_spinDay.SpinText); + } + } + } + + public void MainLoop() + { + _application.MainLoop (); + } + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(string[] args) + { + Example example = new Example(Application.NewApplication()); + example.MainLoop (); + } + } +} diff --git a/plugins/dali-swig/examples/json-loader.cs b/plugins/dali-swig/examples/json-loader.cs new file mode 100644 index 0000000..388b077 --- /dev/null +++ b/plugins/dali-swig/examples/json-loader.cs @@ -0,0 +1,94 @@ +/* + * 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. + * + */ + +using System; +using System.Runtime.InteropServices; +using Dali; + +namespace MyExampleApp +{ + class Example + { + private Dali.Application _application; + private Builder _builder; + private string _jsonFileName; + + public Example(Dali.Application application, string fileName) + { + _application = application; + _jsonFileName = fileName; + _application.Initialized += Initialize; + } + + public void Initialize(object source, NUIApplicationInitEventArgs e) + { + if( _jsonFileName.Length == 0) + { + Console.WriteLine("Please specify JSON file to load"); + return; + } + + _builder = new Builder (); + + Property.Map constants = new Property.Map(); + + // In dali-demo we have some JSON files that can be loaded, but they need 3 different macros defining. + // The JSON folder is typically installed into dali-env/opt/share/com.samsung.dali-demo/res: + // + //string demoDirectory = ".../dali-env/opt/share/com.samsung.dali-demo/res"; + //constants.Insert( "DEMO_IMAGE_DIR" , new Property.Value( demoDirectory+"/images") ); + //constants.Insert( "DEMO_MODEL_DIR" , new Property.Value( demoDirectory+"/models") ); + //constants.Insert( "DEMO_SCRIPT_DIR", new Property.Value( demoDirectory+"/scripts") ); + constants.Insert( "CONFIG_SCRIPT_LOG_LEVEL", new Property.Value( "Verbose") ); + + _builder.AddConstants( constants ); + + + Stage stage = Stage.GetCurrent(); + stage.BackgroundColor = Color.White; + + _builder.LoadFromFile( _jsonFileName ); + + _builder.AddActors( stage.GetRootLayer() ); + + } + + + public void MainLoop() + { + _application.MainLoop (); + } + + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main(string[] args) + { + string fileName= ""; + + if( args.Length > 0) + { + fileName = args[0]; + } + + Console.WriteLine("arguments = " + args.Length); + Example example = new Example(Application.NewApplication(), fileName); + example.MainLoop (); + } + } +} diff --git a/plugins/dali-swig/examples/json/date-picker-template.json b/plugins/dali-swig/examples/json/date-picker-template.json new file mode 100644 index 0000000..dd01d8f --- /dev/null +++ b/plugins/dali-swig/examples/json/date-picker-template.json @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2014 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. + * + */ +{ + // Data picker loaded directly on to the stage + // + "templates": { + "date-picker": + { + "type":"FlexContainer", + "name":"exampleDatePicker", + "parentOrigin": "CENTER", + "anchorPoint": "CENTER", + "flexDirection":"ROW", + "size":[480.0, 150, 0 ], + "actors": [ + { + + "type": "Spin", + "name": "Year", + "parentOrigin": "CENTER", + "anchorPoint": "CENTER", + "Value":2017, + "MinValue":1900, + "MaxValue":2100, + "Step":1, + "TextColor":[0.0,0.0,1.0,1.0], + "properties": { // properties registered dynamically + "flex":0.3, + "flexMargin": [5.0,0.0,5.0,0.0] + } + }, + { + + "type": "Spin", + "name": "Month", + "parentOrigin": "CENTER", + "anchorPoint": "CENTER", + "parentOrigin": "CENTER", + "Value":10, + "Step":1, + "MinValue":1, + "MaxValue":12, + "TextColor":[1.0,1.0,1.0,1.0], + "properties": { // properties registered dynamically + "flex":0.3, + "flexMargin": [5.0,0.0,5.0,0.0] + } + + }, + { + + "type": "Spin", + "name": "Day", + "parentOrigin": "CENTER", + "anchorPoint": "CENTER", + "Value":1, + "MinValue":1, + "MaxValue":31, + "TextColor":[1.0,0.0,0.0,1.0], + "properties": { // properties registered dynamically + "flex":0.3, + "flexMargin": [5.0,0.0,5.0,0.0] + } + }] + + } +} + +} + diff --git a/plugins/dali-swig/examples/json/date-picker.json b/plugins/dali-swig/examples/json/date-picker.json new file mode 100644 index 0000000..3126aa3 --- /dev/null +++ b/plugins/dali-swig/examples/json/date-picker.json @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2014 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. + * + */ +{ + // Data picker loaded directly on to the stage + // + "stage": [{ + + "type":"FlexContainer", + "name":"exampleDatePicker", + "parentOrigin": "CENTER", + "anchorPoint": "CENTER", + "flexDirection":"ROW", + "size":[480.0, 150, 0 ], + "actors": [ + { + + "type": "Spin", + "name": "Year", + "parentOrigin": "CENTER", + "anchorPoint": "CENTER", + "MinValue":1900, + "MaxValue":2100, + "Value":2017, + "Step":1, + "TextColor":[0.0,0.0,1.0,1.0], + "properties": { // properties registered dynamically + "flex":0.3, + "flexMargin": [5.0,0.0,5.0,0.0] + } + }, + { + + "type": "Spin", + "name": "Month", + "parentOrigin": "CENTER", + "anchorPoint": "CENTER", + "parentOrigin": "CENTER", + "Step":1, + "MinValue":1, + "MaxValue":12, + "Value":10, + "TextColor":[1.0,1.0,1.0,1.0], + "properties": { // properties registered dynamically + "flex":0.3, + "flexMargin": [5.0,0.0,5.0,0.0] + } + + }, + { + + "type": "Spin", + "name": "Day", + "parentOrigin": "CENTER", + "anchorPoint": "CENTER", + "MinValue":1, + "MaxValue":31, + "Value":1, + "TextColor":[1.0,0.0,0.0,1.0], + "properties": { // properties registered dynamically + "flex":0.3, + "flexMargin": [5.0,0.0,5.0,0.0] + } + }] + +}] + +} + diff --git a/plugins/dali-swig/examples/json/spin.json b/plugins/dali-swig/examples/json/spin.json new file mode 100644 index 0000000..df9b10c --- /dev/null +++ b/plugins/dali-swig/examples/json/spin.json @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2014 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. + * + */ +{ + // a tree of actors + "stage": [ + // You can add an array of Actors / Views here + // Lets add a spin to the stage + { + "type":"Spin", + "parentOrigin":"CENTER", + "size":[120,120,0] + // now lets use the C# app json-loader.exe to load it + } + + ] +} diff --git a/plugins/dali-swig/examples/spin-control.cs b/plugins/dali-swig/examples/spin-control.cs deleted file mode 100755 index f385852..0000000 --- a/plugins/dali-swig/examples/spin-control.cs +++ /dev/null @@ -1,460 +0,0 @@ -/* - * 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. - * - */ - -using System; -using System.Runtime.InteropServices; -using Dali; - -namespace MyCSharpExample -{ - // A spin control (for continously changing values when users can easily predict a set of values) - class Spin : CustomView - { - private VisualBase _arrowVisual; - private TextField _textField; - private int _arrowVisualPropertyIndex; - private string _arrowImage; - private int _currentValue; - private int _minValue; - private int _maxValue; - private int _singleStep; - private bool _wrappingEnabled; - private string _fontFamily; - private string _fontStyle; - private int _pointSize; - private Color _textColor; - private Color _textBackgroundColor; - private int _maxTextLength; - - public Spin() : base(ViewWrapperImpl.CustomViewBehaviour.REQUIRES_KEYBOARD_NAVIGATION_SUPPORT | ViewWrapperImpl.CustomViewBehaviour.DISABLE_STYLE_CHANGE_SIGNALS) - { - } - - public override void OnInitialize() - { - // Initialize the properties - _arrowImage = "./images/arrow.png"; - _textBackgroundColor = new Color(0.6f, 0.6f, 0.6f, 1.0f); - _currentValue = 0; - _minValue = 0; - _maxValue = 0; - _singleStep = 1; - _maxTextLength = 0; - - // Create image visual for the arrow keys - _arrowVisualPropertyIndex = RegisterProperty("ArrowImage", new Dali.Property.Value(_arrowImage), Dali.Property.AccessMode.READ_WRITE); - _arrowVisual = VisualFactory.Get().CreateVisual( _arrowImage, new Uint16Pair(150, 150) ); - RegisterVisual( _arrowVisualPropertyIndex, _arrowVisual ); - - // Create a text field - _textField = new TextField(); - _textField.ParentOrigin = NDalic.ParentOriginCenter; - _textField.AnchorPoint = NDalic.AnchorPointCenter; - _textField.WidthResizePolicy = "SIZE_RELATIVE_TO_PARENT"; - _textField.HeightResizePolicy = "SIZE_RELATIVE_TO_PARENT"; - _textField.SizeModeFactor = new Vector3( 1.0f, 0.45f, 1.0f ); - _textField.PlaceholderText = "----"; - _textField.BackgroundColor = _textBackgroundColor; - _textField.HorizontalAlignment = "Center"; - _textField.VerticalAlignment = "Center"; - _textField.SetKeyboardFocusable(true); - _textField.Name = "_textField"; - - this.Add(_textField); - - _textField.KeyInputFocusGained += TextFieldKeyInputFocusGained; - _textField.KeyInputFocusLost += TextFieldKeyInputFocusLost; - } - - public override Vector3 GetNaturalSize() - { - return new Vector3(150.0f, 150.0f, 0.0f); - } - - public void TextFieldKeyInputFocusGained(object source, KeyInputFocusGainedEventArgs e) - { - // Make sure when the current spin that takes input focus also takes the keyboard focus - // For example, when you tap the spin directly - FocusManager.Instance.SetCurrentFocusActor(_textField); - } - - public void TextFieldKeyInputFocusLost(object source, KeyInputFocusLostEventArgs e) - { - int previousValue = _currentValue; - - // If the input value is invalid, change it back to the previous valid value - if(int.TryParse(_textField.Text, out _currentValue)) - { - if (_currentValue < _minValue || _currentValue > _maxValue) - { - _currentValue = previousValue; - } - } - else - { - _currentValue = previousValue; - } - - // Otherwise take the new value - this.Value = _currentValue; - } - - public override Actor GetNextKeyboardFocusableActor(Actor currentFocusedActor, View.KeyboardFocus.Direction direction, bool loopEnabled) - { - // Respond to Up/Down keys to change the value while keeping the current spin focused - Actor nextFocusedActor = currentFocusedActor; - if (direction == View.KeyboardFocus.Direction.UP) - { - this.Value += this.Step; - nextFocusedActor = _textField; - } - else if (direction == View.KeyboardFocus.Direction.DOWN) - { - this.Value -= this.Step; - nextFocusedActor = _textField; - } - else - { - // Return a native empty handle as nothing can be focused in the left or right - nextFocusedActor = new Actor(); - nextFocusedActor.Reset(); - } - - return nextFocusedActor; - } - - // Value property of type int: - public int Value - { - get - { - return _currentValue; - } - set - { - _currentValue = value; - - // Make sure no invalid value is accepted - if (_currentValue < _minValue) - { - _currentValue = _minValue; - } - - if (_currentValue > _maxValue) - { - _currentValue = _maxValue; - } - - _textField.Text = _currentValue.ToString(); - } - } - - // MinValue property of type int: - public int MinValue - { - get - { - return _minValue; - } - set - { - _minValue = value; - } - } - - // MaxValue property of type int: - public int MaxValue - { - get - { - return _maxValue; - } - set - { - _maxValue = value; - } - } - - // Step property of type int: - public int Step - { - get - { - return _singleStep; - } - set - { - _singleStep = value; - } - } - - // WrappingEnabled property of type bool: - public bool WrappingEnabled - { - get - { - return _wrappingEnabled; - } - set - { - _wrappingEnabled = value; - } - } - - // TextPointSize property of type int: - public int TextPointSize - { - get - { - return _pointSize; - } - set - { - _pointSize = value; - _textField.PointSize = _pointSize; - } - } - - // TextColor property of type Color: - public Color TextColor - { - get - { - return _textColor; - } - set - { - _textColor = value; - _textField.TextColor = _textColor; - } - } - - // MaxTextLength property of type int: - public int MaxTextLength - { - get - { - return _maxTextLength; - } - set - { - _maxTextLength = value; - _textField.MaxLength = _maxTextLength; - } - } - - public TextField SpinText - { - get - { - return _textField; - } - set - { - _textField = value; - } - } - - // Indicator property of type string: - public string IndicatorImage - { - get - { - return _arrowImage; - } - set - { - _arrowImage = value; - _arrowVisual = VisualFactory.Get().CreateVisual( _arrowImage, new Uint16Pair(150, 150) ); - RegisterVisual( _arrowVisualPropertyIndex, _arrowVisual ); - } - } - } - - class Example - { - private Dali.Application _application; - private FlexContainer _container; - private Spin _spinYear; - private Spin _spinMonth; - private Spin _spinDay; - - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - delegate void CallbackDelegate(); - - public Example(Dali.Application application) - { - _application = application; - _application.Initialized += Initialize; - } - - public void Initialize(object source, NUIApplicationInitEventArgs e) - { - Stage stage = Stage.GetCurrent(); - stage.BackgroundColor = Color.White; - - // Create a container for the spins - _container = new FlexContainer(); - - _container.ParentOrigin = NDalic.ParentOriginCenter; - _container.AnchorPoint = NDalic.AnchorPointCenter; - _container.FlexDirection = (int)FlexContainer.FlexDirectionType.ROW; - _container.Size = new Vector3(480.0f, 150.0f, 0.0f); - - stage.Add(_container); - - // Create a Spin control for year - _spinYear = new Spin(); - _spinYear.ParentOrigin = NDalic.ParentOriginCenter; - _spinYear.AnchorPoint = NDalic.AnchorPointCenter; - _spinYear.Flex = 0.3f; - _spinYear.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f); - _container.Add(_spinYear); - - _spinYear.MinValue = 1900; - _spinYear.MaxValue = 2100; - _spinYear.Value = 2016; - _spinYear.Step = 1; - _spinYear.MaxTextLength = 4; - _spinYear.TextPointSize = 26; - _spinYear.TextColor = Color.White; - _spinYear.SetKeyboardFocusable(true); - _spinYear.Name = "_spinYear"; - - // Create a Spin control for month - _spinMonth = new Spin(); - _spinMonth.ParentOrigin = NDalic.ParentOriginCenter; - _spinMonth.AnchorPoint = NDalic.AnchorPointCenter; - _spinMonth.Flex = 0.3f; - _spinMonth.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f); - _container.Add(_spinMonth); - - _spinMonth.MinValue = 1; - _spinMonth.MaxValue = 12; - _spinMonth.Value = 10; - _spinMonth.Step = 1; - _spinMonth.MaxTextLength = 2; - _spinMonth.TextPointSize = 26; - _spinMonth.TextColor = Color.White; - _spinMonth.SetKeyboardFocusable(true); - _spinMonth.Name = "_spinMonth"; - - // Create a Spin control for day - _spinDay = new Spin(); - _spinDay.ParentOrigin = NDalic.ParentOriginCenter; - _spinDay.AnchorPoint = NDalic.AnchorPointCenter; - _spinDay.Flex = 0.3f; - _spinDay.FlexMargin = new Vector4(5.0f, 0.0f, 5.0f, 0.0f); - _container.Add(_spinDay); - - _spinDay.MinValue = 1; - _spinDay.MaxValue = 31; - _spinDay.Value = 26; - _spinDay.Step = 1; - _spinDay.MaxTextLength = 2; - _spinDay.TextPointSize = 26; - _spinDay.TextColor = Color.White; - _spinDay.SetKeyboardFocusable(true); - _spinDay.Name = "_spinDay"; - - FocusManager keyboardFocusManager = FocusManager.Instance; - keyboardFocusManager.PreFocusChange += OnKeyboardPreFocusChange; - keyboardFocusManager.FocusedActorEnterKeyPressed += OnFocusedActorEnterKeyPressed; - - } - - private Actor OnKeyboardPreFocusChange(object source, FocusManager.PreFocusChangeEventArgs e) - { - Actor nextFocusActor = e.Proposed; - - // When nothing has been focused initially, focus the text field in the first spin - if (!e.Current && !e.Proposed) - { - nextFocusActor = _spinYear.SpinText; - } - else if(e.Direction == View.KeyboardFocus.Direction.LEFT) - { - // Move the focus to the spin in the left of the current focused spin - if(e.Current == _spinMonth.SpinText) - { - nextFocusActor = _spinYear.SpinText; - } - else if(e.Current == _spinDay.SpinText) - { - nextFocusActor = _spinMonth.SpinText; - } - } - else if(e.Direction == View.KeyboardFocus.Direction.RIGHT) - { - // Move the focus to the spin in the right of the current focused spin - if(e.Current == _spinYear.SpinText) - { - nextFocusActor = _spinMonth.SpinText; - } - else if(e.Current == _spinMonth.SpinText) - { - nextFocusActor = _spinDay.SpinText; - } - } - - return nextFocusActor; - } - - private void OnFocusedActorEnterKeyPressed(object source, FocusManager.FocusedActorEnterKeyEventArgs e) - { - // Make the text field in the current focused spin to take the key input - KeyInputFocusManager manager = KeyInputFocusManager.Get(); - - if (e.Actor == _spinYear.SpinText) - { - if (manager.GetCurrentFocusControl() != _spinYear.SpinText) - { - manager.SetFocus(_spinYear.SpinText); - } - } - else if (e.Actor == _spinMonth.SpinText) - { - if (manager.GetCurrentFocusControl() != _spinMonth.SpinText) - { - manager.SetFocus(_spinMonth.SpinText); - } - } - else if (e.Actor == _spinDay.SpinText) - { - if (manager.GetCurrentFocusControl() != _spinDay.SpinText) - { - manager.SetFocus(_spinDay.SpinText); - } - } - } - - public void MainLoop() - { - _application.MainLoop (); - } - - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main(string[] args) - { - Example example = new Example(Application.NewApplication()); - example.MainLoop (); - } - } -} diff --git a/plugins/dali-swig/manual/csharp/PropertyRangeManager.cs b/plugins/dali-swig/manual/csharp/PropertyRangeManager.cs new file mode 100644 index 0000000..7e6c4d4 --- /dev/null +++ b/plugins/dali-swig/manual/csharp/PropertyRangeManager.cs @@ -0,0 +1,138 @@ +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +namespace Dali +{ + /// + /// Helper class for calculating what property indexes should be assigned to C# View (view) classes. + /// + public class PropertyRangeManager + { + private Dictionary _propertyRange; + + /// + /// Initializes a new instance of the class. + /// + public PropertyRangeManager () + { + _propertyRange = new Dictionary (); + } + + /// + /// Only called if a View has scriptable properties + /// + private PropertyRange RegisterView( string viewName, System.Type viewType ) + { + PropertyRange range; + + if ( _propertyRange.TryGetValue (viewName, out range) ) + { + // already registered + return range; + } + + // Find out the event and animatable start indexes for the type + range = new PropertyRange(); + + GetPropertyStartRange( viewType, ref range); + + // add it to our dictionary + _propertyRange.Add( viewName, range ); + + return range; + + } + + /// + /// Gets the index of the property. + /// Each property has to have unique index for this view type + /// + /// The property index. + /// View name + /// View type + /// Type. + public int GetPropertyIndex( string viewName, System.Type viewType, ScriptableProperty.ScriptableType type ) + { + + PropertyRange range; + + if (! _propertyRange.TryGetValue (viewName, out range) ) + { + // view not found, register it now + range = RegisterView( viewName, viewType); + } + + int index = range.GetNextFreePropertyIndex ( type ); + + // update the dictionary + _propertyRange[viewName]=range; + + return index; + + } + + /// + /// We calculate the start property indices, based on the type and it's class heirachy, e.g. DateView (70,000)- > Spin (60,000) -> View (50,000) + /// + private void GetPropertyStartRange( System.Type viewType, ref PropertyRange range ) + { + const int maxCountPerDerivation = 1000; // For child and animtable properties we use a gap of 1000 between each + // views property range in the heirachy + + // custom views start there property index, at view_PROPERTY_END_INDEX + // we add 1000, just incase View class (our C# custom view base) starts using scriptable properties + int startEventPropertyIndex = (int)View.PropertyRange.CONTROL_PROPERTY_END_INDEX+maxCountPerDerivation; + + // for animatable properties current range starts at ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX, + // we add 1000, just incase View class starts using animatable properties + int startAnimatablePropertyIndex = (int)Dali.PropertyRanges.ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX +maxCountPerDerivation; + + while ( viewType.BaseType.Name != "CustomView" ) // custom view is our C# view base class. we don't go any deeper. + { + // for every base class increase property start index + startEventPropertyIndex += (int)Dali.PropertyRanges.DEFAULT_PROPERTY_MAX_COUNT_PER_DERIVATION; // DALi uses 10,000 + startAnimatablePropertyIndex += maxCountPerDerivation; + + //Console.WriteLine ("getStartPropertyIndex = " + viewType.Name +"current index " + startEventPropertyIndex); + viewType = viewType.BaseType; + } + + range.startEventIndex = startEventPropertyIndex; + range.lastUsedEventIndex = startEventPropertyIndex; + + range.startAnimationIndex = startAnimatablePropertyIndex; + range.lastUsedAnimationIndex = startAnimatablePropertyIndex; + + } + + + public struct PropertyRange + { + + public int GetNextFreePropertyIndex( ScriptableProperty.ScriptableType type) + { + if ( type == ScriptableProperty.ScriptableType.Default ) + { + lastUsedEventIndex++; + return lastUsedEventIndex; + } + else + { + lastUsedAnimationIndex++; + return lastUsedAnimationIndex ; + } + } + + + public int startEventIndex; /// start of the property range + public int lastUsedEventIndex; /// last used of the property index + + public int startAnimationIndex; /// start of the property range + public int lastUsedAnimationIndex; /// last used of the property index + }; + + + +} +} diff --git a/plugins/dali-swig/manual/csharp/ViewRegistry.cs b/plugins/dali-swig/manual/csharp/ViewRegistry.cs new file mode 100644 index 0000000..29ece3a --- /dev/null +++ b/plugins/dali-swig/manual/csharp/ViewRegistry.cs @@ -0,0 +1,507 @@ +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +namespace Dali +{ + /// + /// Add this attribute to any property belonging to a View (control) you want to be scriptable from JSON + /// + /// + /// Example: + /// + /// class MyView : public CustomView + /// { + /// [ScriptableProperty()] + /// public int MyProperty + /// { + /// get + /// { + /// return _myProperty; + /// } + /// set + /// { + /// _myProperty = value; + /// } + /// } + /// } + /// + /// Internally the following occurs for property registration ( this only occurs once per Type, not per Instance): + /// + /// - The controls static constructor should call ViewRegistry.Register() (only called once for the lifecycle of the app) + /// - Within Register() the code will introspect the Controls properties, looking for the ScriptableProperty() attribute + /// - For every property with the ScriptableProperty() attribute, TypeRegistration.RegisterProperty is called. + /// - TypeRegistration.RegisterProperty calls in to DALi C++ Code Dali::CSharpTypeRegistry::RegisterProperty() + /// - DALi C++ now knows the existance of the property and will try calling SetProperty, if it finds the property in a JSON file (loaded using builder). + /// + /// The DALi C# example + /// + /// class MyView : public CustomView + /// { + /// + /// [ScriptableProperty()] + /// public double Hours + /// { + /// get { return seconds / 3600; } + /// set { seconds = value * 3600; } + /// } + /// } + /// + /// Equivalent code in DALi C++: + /// in MyControl.h + /// class MyControl : public Control + /// { + /// struct Property + /// { + /// enum + /// { + /// HOURS = Control::CONTROL_PROPERTY_END_INDEX + 1 + /// } + /// } + /// + /// + /// in MyControl-impl.cpp + /// + /// DALI_TYPE_REGISTRATION_BEGIN( Toolkit::MyControl, Toolkit::Control, Create ); + /// DALI_PROPERTY_REGISTRATION( Toolkit, MyControl, "Hours", INTEGER, DISABLED ) + /// DALI_TYPE_REGISTRATION_END() + /// + /// + /// + public class ScriptableProperty : System.Attribute + { + public enum ScriptableType + { + Default, // Read Writable, non-animatable property, event thread only + // Animatable // Animatable property, Currently disabled, UK + } + public readonly ScriptableType type; + + public ScriptableProperty(ScriptableType type = ScriptableType.Default ) + { + this.type = type; + } + } + + /// + /// View Registry singleton. + /// Used for registering controls and any scriptable properties they have ( see ScriptableProperty ) + /// + /// Internal Design from C# to C++ + /// + /// - Each custom C# view should have it's static constructor called before any JSON file is loaded. + /// Static constructors for a class will only run once ( they are run per control type, not per instance). + /// Example of running a static constructor: + /// System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (typeof(Spin).TypeHandle); + /// Inside the static constructor the control should register it's type with the ViewRegistry + /// e.g. + /// + /// static Spin() + /// { + /// ViewRegistry.Instance.RegisterControl("Spin", CreateInstance, typeof(Spin) ); + /// } + /// + /// The control should also provide a CreateInstance function, which gets passed to the ViewRegistry + /// // Eventually it will be called if DALi Builderfinds a Spin control in a JSON file + /// static CustomView CreateInstance() + /// { + /// return new Spin(); + /// } + /// + /// + /// + /// The DALi C++ equivalent of this is + /// + /// TypeRegistration mType( typeid(Toolkit::Spin), typeid(Toolkit::Control), CreateInstance ); + /// + /// + /// + /// + public sealed class ViewRegistry + { + /// + /// ViewRegistry is a singleton + /// + private static ViewRegistry instance = null; + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + delegate IntPtr CreateControlDelegate( IntPtr cPtrControlName ); + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + delegate IntPtr GetPropertyDelegate( IntPtr controlPtr, IntPtr propertyName ); + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + delegate void SetPropertyDelegate( IntPtr controlPtr, IntPtr propertyName, IntPtr propertyValue ); + + private CreateControlDelegate _createCallback; + private SetPropertyDelegate _setPropertyCallback; + private GetPropertyDelegate _getPropertyCallback; + private PropertyRangeManager _propertyRangeManager; + + /// + /// Given a C++ custom control the dictionary allows us to find what CustomView it belongs to + /// + private Dictionary _controlMap; + + /// + // Maps the name of a custom view to a create instance function + /// E.g. given a string "Spin", we can get a function used to create the Spin View. + /// + private Dictionary > _constructorMap; + + /// + /// Lookup table to match C# types to DALi types, used for the automatic property registration + /// + private static readonly Dictionary _daliPropertyTypeLookup + = new Dictionary< string, Dali.Property.Type > + { + { "float", Property.Type.FLOAT }, + { "int", Property.Type.INTEGER }, + { "Int32", Property.Type.INTEGER }, + { "Boolean", Property.Type.BOOLEAN }, + { "string", Property.Type.STRING }, + { "Vector2", Property.Type.VECTOR2 }, + { "Vector3", Property.Type.VECTOR3 }, + { "Vector4", Property.Type.VECTOR4 }, + { "Size", Property.Type.VECTOR2 }, + { "Position",Property.Type.VECTOR3 }, + { "Color", Property.Type.VECTOR4 }, + // { "Matrix3", Property.Type.MATRIX3 }, commented out until we need to use Matrices from JSON + // { "Matrix", Property.Type.MATRIX }, + }; + + + public ViewRegistry() + { + _createCallback = new CreateControlDelegate( CreateControl ); + _getPropertyCallback = new GetPropertyDelegate (GetProperty); + _setPropertyCallback = new SetPropertyDelegate (SetProperty); + + _controlMap = new Dictionary(); + _constructorMap = new Dictionary>(); + _propertyRangeManager = new PropertyRangeManager(); + + } + + private Dali.Property.Type GetDaliPropertyType( string cSharpTypeName ) + { + Dali.Property.Type daliType; + if ( _daliPropertyTypeLookup.TryGetValue (cSharpTypeName, out daliType) ) + { + //Console.WriteLine("mapped "+ cSharpTypeName + " to dAli type " +daliType ); + return daliType; + } + else + { + // Console.WriteLine("Failed to find a mapping between C# property" + cSharpTypeName +" and DALi type"); + return Property.Type.NONE; + } + } + + /// + /// Called directly from DALi C++ type registry to create a control (View) uses no marshalling. + /// + /// Pointer to the Control (Views) handle + /// C pointer to the Control (View) name + private static IntPtr CreateControl( IntPtr cPtrControlName ) + { + string controlName = System.Runtime.InteropServices.Marshal.PtrToStringAnsi (cPtrControlName); + // Console.WriteLine ("Create controlled called from C++ create a " + controlName); + + Func< CustomView > controlConstructor; + + // find the control constructor + if ( Instance._constructorMap.TryGetValue (controlName, out controlConstructor) ) + { + // Create the control + CustomView newControl = controlConstructor (); + + // Store the mapping between this instance of the custom control and native part + // We store a pointer to the RefObject for the control + IntPtr cPtr = newControl.GetPtrfromActor(); + RefObject refObj = newControl.GetObjectPtr (); + IntPtr refCptr = (IntPtr) RefObject.getCPtr(refObj); + + //Console.WriteLine ("________Storing ref object cptr in control map Hex: {0:X}", refCptr); + Instance._controlMap.Add (refCptr , newControl ); + + return cPtr; // return pointer to handle + } + else + { + throw new global::System.InvalidOperationException("C# View not registererd with ViewRegistry"+ controlName ); + return IntPtr.Zero; + } + } + + private static IntPtr GetProperty( IntPtr controlPtr, IntPtr propertyName ) + { + string name = System.Runtime.InteropServices.Marshal.PtrToStringAnsi (propertyName); + return Instance.GetPropertyValue ( controlPtr, name); + } + + private static void SetProperty( IntPtr controlPtr, IntPtr propertyName, IntPtr propertyValue ) + { + string name = System.Runtime.InteropServices.Marshal.PtrToStringAnsi (propertyName); + //Console.WriteLine ( SetControlProperty called for:" + name ); + Instance.SetPropertyValue ( controlPtr, name, propertyValue); + + } + + public static ViewRegistry Instance + { + get + { + if (instance==null) + { + instance = new ViewRegistry(); + } + return instance; + } + } + + public static CustomView GetCustomViewFromActor( Actor actor ) + { + // we store a dictionary of ref-obects (C++ land) to custom views (C# land) + Dali.CustomView view; + + RefObject refObj = actor.GetObjectPtr (); + IntPtr refObjectPtr = (IntPtr) RefObject.getCPtr(refObj); + + if ( Instance._controlMap.TryGetValue ( refObjectPtr, out view) ) + { + + // call the get property function + + return view; + } + else + { + return null; + } + } + + + /// + /// Function which registers a view and all it's scriptable properties with DALi's type registry. + /// Means the View can be created / configured from a JSON script. + /// + /// The function uses introspection to scan a Views C# properties, then selects the ones with + ///[ScriptableProperty] attribute to be registered. + /// Example of a Spin view registering itself + /// static Spin() + /// { + /// ViewRegistry registers control type with DALi type registery + /// also uses introspection to find any properties that need to be registered with type registry + /// ViewRegistry.Instance.Register("Spin", CreateInstance, typeof(Spin) ); + /// } + /// + /// + public void Register(string viewName, Func< CustomView > createFunction, System.Type viewType ) + { + // add the mapping between the view name and it's create function + _constructorMap.Add (viewName, createFunction); + + // Call into DALi C++ to register the control with the type registry + TypeRegistration.RegisterControl( viewName, _createCallback ); + + // Cycle through each property in the class + foreach (System.Reflection.PropertyInfo propertyInfo in viewType.GetProperties()) + { + + if ( propertyInfo.CanRead ) + { + + System.Attribute[] attrs = System.Attribute.GetCustomAttributes(propertyInfo); + foreach (System.Attribute attr in attrs) + { + // If the Scriptable attribute exists, then register it with the type registry. + if (attr is ScriptableProperty) + { + //Console.WriteLine ("Got a DALi JSON scriptable property = " + propertyInfo.Name +", of type " + propertyInfo.PropertyType.Name); + + // first get the attribute type, ( default, or animatable) + ScriptableProperty scriptableProp = attr as ScriptableProperty; + + // we get the start property index, based on the type and it's heirachy, e.g. DateView (70,000)-> Spin (60,000) -> View (50,000) + int propertyIndex = _propertyRangeManager.GetPropertyIndex( viewName, viewType, scriptableProp.type ); + + // get the enum for the property type... E.g. registering a string property returns Dali.PropertyType.String + Dali.Property.Type propertyType = GetDaliPropertyType( propertyInfo.PropertyType.Name ); + + // Example RegisterProperty("spin","maxValue", 50001, FLOAT, set, get ); + // Native call to register the property + TypeRegistration.RegisterProperty (viewName, propertyInfo.Name , propertyIndex, propertyType, _setPropertyCallback, _getPropertyCallback); + } + } + // Console.WriteLine ("property name = " + propertyInfo.Name); + } + } + } + + /// + /// Get a property value from a View + /// + /// + private IntPtr GetPropertyValue ( IntPtr controlPtr, string propertyName) + { + // Get the C# control that maps to the C++ control + Dali.CustomView view; + + BaseHandle baseHandle = new BaseHandle (controlPtr, false); + + RefObject refObj = baseHandle.GetObjectPtr (); + + IntPtr refObjectPtr = (IntPtr) RefObject.getCPtr(refObj); + + if ( _controlMap.TryGetValue ( refObjectPtr, out view) ) + { + + // call the get property function + System.Object val = view.GetType ().GetProperty (propertyName).GetAccessors () [0].Invoke (view, null); + + Property.Value value = Property.Value.CreateFromObject (val); + + return (IntPtr)Property.Value.getCPtr (value); + } + else + { + return IntPtr.Zero; + } + } + + /// + /// Set a property value on a View + /// + /// + private void SetPropertyValue ( IntPtr controlPtr, string propertyName, IntPtr propertyValuePtr) + { + // Get the C# control that maps to the C++ control + Dali.CustomView view; + + //Console.WriteLine ("SetPropertyValue refObjectPtr = {0:X}", controlPtr); + + Property.Value propValue = new Property.Value (propertyValuePtr, false); + + if ( _controlMap.TryGetValue ( controlPtr, out view) ) + { + + System.Reflection.PropertyInfo propertyInfo = view.GetType().GetProperty(propertyName); + + // We know the property name, we know it's type, we just need to convert from a DALi property value to native C# type + System.Type type = propertyInfo.PropertyType; + bool ok = false; + + if ( type.Equals (typeof(Int32)) ) + { + int value = 0; + ok = propValue.Get( ref value ); + if ( ok ) + { + propertyInfo.SetValue (view, value); + } + } + else if ( type.Equals (typeof(bool)) ) + { + bool value = false; + ok = propValue.Get( ref value ); + if ( ok ) + { + propertyInfo.SetValue (view, value); + } + } + else if ( type.Equals (typeof(float)) ) + { + float value = 0; + ok = propValue.Get( ref value ); + if ( ok ) + { + propertyInfo.SetValue (view, value); + } + } + else if ( type.Equals (typeof(string)) ) + { + string value = ""; + ok = propValue.Get( out value ); + if ( ok ) + { + propertyInfo.SetValue (view, value); + } + } + else if ( type.Equals (typeof(Vector2)) ) + { + Vector2 value = new Vector2 (); + ok = propValue.Get( value ); + if ( ok ) + { + propertyInfo.SetValue (view, value); + } + } + else if ( type.Equals (typeof(Vector3)) ) + { + Vector3 value = new Vector3 (); + ok = propValue.Get( value ); + if ( ok ) + { + propertyInfo.SetValue (view, value); + } + } + else if ( type.Equals (typeof(Vector4)) ) + { + Vector4 value = new Vector4 (); + ok = propValue.Get( value ); + + if ( ok ) + { + propertyInfo.SetValue (view, value); + } + } + else if ( type.Equals (typeof(Position)) ) + { + Position value = new Position (); + ok = propValue.Get( value ); + if ( ok ) + { + propertyInfo.SetValue (view, value); + } + } + else if ( type.Equals (typeof(Size)) ) + { + // DALi sizes are Vector3 + Vector3 value = new Vector3(); + ok = propValue.Get( value ); + if ( ok ) + { + propertyInfo.SetValue(view, new Size(value.X,value.Y)); + }; + } + else if ( type.Equals (typeof(Color)) ) + { + // Colors are stored as Vector4's in DALi + Vector4 value = new Vector4(); + ok = propValue.Get( value ); + if ( ok ) + { + propertyInfo.SetValue (view, (Color)value); + }; + } + else + { + throw new global::System.InvalidOperationException("SetPropertyValue Unimplemented type for Property Value"); + } + if ( !ok ) + { + throw new global::System.InvalidOperationException("SetPropertyValue propValue.Get failed"); + } + } + else + { + throw new global::System.InvalidOperationException("failed to find the control to write a property to: cptr = " + controlPtr); + } + + } + + } + + +} \ No newline at end of file diff --git a/plugins/dali-swig/manual/csharp/ViewRegistryHelper.cs b/plugins/dali-swig/manual/csharp/ViewRegistryHelper.cs new file mode 100644 index 0000000..8e9e19a --- /dev/null +++ b/plugins/dali-swig/manual/csharp/ViewRegistryHelper.cs @@ -0,0 +1,15 @@ +using System; + +// include all custom views here which will be +namespace Dali +{ + public class ViewRegistryHelper + { + static public void Initialize() + { + // Register all views with the type registry + System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (typeof(Dali.Spin).TypeHandle); + } + } +} + diff --git a/plugins/dali-swig/property-wrapper.rb b/plugins/dali-swig/property-wrapper.rb index 4abc698..fe2e91c 100755 --- a/plugins/dali-swig/property-wrapper.rb +++ b/plugins/dali-swig/property-wrapper.rb @@ -335,9 +335,9 @@ def writeCSharpData hasChildProperties = true end - property.csharpGetter =" public #{propertyType} #{property.name} \n"\ - " { \n"\ - " get \n" \ + property.csharpGetter =" public #{propertyType} #{property.name}\n"\ + " {\n"\ + " get\n" \ " {\n"\ " #{tempDeclaration}\n"\ " GetProperty( #{propertyName}).Get( #{propertyArg} temp );\n"\ @@ -346,8 +346,8 @@ def writeCSharpData if property.writable #text.SetProperty(TextLabel.Property.HORIZONTAL_ALIGNMENT, new Property.Value("CENTER")); - property.csharpSetter = " set \n" \ - " { \n"\ + property.csharpSetter = " set\n" \ + " {\n"\ " SetProperty( #{propertyName}, new Dali.Property.Value( value ) );\n" \ " }\n"\ " }\n" diff --git a/plugins/dali-swig/views/spin.cs b/plugins/dali-swig/views/spin.cs new file mode 100644 index 0000000..06a0210 --- /dev/null +++ b/plugins/dali-swig/views/spin.cs @@ -0,0 +1,313 @@ +/* + * 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. + * + */ + +using System; +using System.Runtime.InteropServices; +using Dali; + +// A spin control (for continously changing values when users can easily predict a set of values) + +namespace Dali +{ +public class Spin : CustomView + { + private VisualBase _arrowVisual; + private TextField _textField; + private int _arrowVisualPropertyIndex; + private string _arrowImage; + private int _currentValue; + private int _minValue; + private int _maxValue; + private int _singleStep; + private bool _wrappingEnabled; + private string _fontFamily; + private string _fontStyle; + private int _pointSize; + private Color _textColor; + private Color _textBackgroundColor; + private int _maxTextLength; + + // Called by DALi Builder if it finds a Spin control in a JSON file + static CustomView CreateInstance() + { + return new Spin(); + } + + // static constructor registers the control type (only runs once) + static Spin() + { + // ViewRegistry registers control type with DALi type registery + // also uses introspection to find any properties that need to be registered with type registry + ViewRegistry.Instance.Register("Spin", CreateInstance, typeof(Spin) ); + } + public Spin() : base(ViewWrapperImpl.CustomViewBehaviour.REQUIRES_KEYBOARD_NAVIGATION_SUPPORT | ViewWrapperImpl.CustomViewBehaviour.DISABLE_STYLE_CHANGE_SIGNALS) + { + + } + + public override void OnInitialize() + { + // Initialize the propertiesControl + _arrowImage = "./images/arrow.png"; + _textBackgroundColor = new Color(0.6f, 0.6f, 0.6f, 1.0f); + _currentValue = 0; + _minValue = 0; + _maxValue = 0; + _singleStep = 1; + _maxTextLength = 0; + + // Create image visual for the arrow keys + _arrowVisualPropertyIndex = RegisterProperty("ArrowImage", new Dali.Property.Value(_arrowImage), Dali.Property.AccessMode.READ_WRITE); + _arrowVisual = VisualFactory.Get().CreateVisual( _arrowImage, new Uint16Pair(150, 150) ); + RegisterVisual( _arrowVisualPropertyIndex, _arrowVisual ); + + // Create a text field + _textField = new TextField(); + _textField.ParentOrigin = NDalic.ParentOriginCenter; + _textField.AnchorPoint = NDalic.AnchorPointCenter; + _textField.WidthResizePolicy = "SIZE_RELATIVE_TO_PARENT"; + _textField.HeightResizePolicy = "SIZE_RELATIVE_TO_PARENT"; + _textField.SizeModeFactor = new Vector3( 1.0f, 0.45f, 1.0f ); + _textField.PlaceholderText = "----"; + _textField.BackgroundColor = _textBackgroundColor; + _textField.HorizontalAlignment = "Center"; + _textField.VerticalAlignment = "Center"; + _textField.SetKeyboardFocusable(true); + _textField.Name = "_textField"; + + this.Add(_textField); + + _textField.KeyInputFocusGained += TextFieldKeyInputFocusGained; + _textField.KeyInputFocusLost += TextFieldKeyInputFocusLost; + } + + public override Vector3 GetNaturalSize() + { + return new Vector3(150.0f, 150.0f, 0.0f); + } + + public void TextFieldKeyInputFocusGained(object source, KeyInputFocusGainedEventArgs e) + { + // Make sure when the current spin that takes input focus also takes the keyboard focus + // For example, when you tap the spin directly + FocusManager.Instance.SetCurrentFocusActor(_textField); + } + + public void TextFieldKeyInputFocusLost(object source, KeyInputFocusLostEventArgs e) + { + int previousValue = _currentValue; + + // If the input value is invalid, change it back to the previous valid value + if(int.TryParse(_textField.Text, out _currentValue)) + { + if (_currentValue < _minValue || _currentValue > _maxValue) + { + _currentValue = previousValue; + } + } + else + { + _currentValue = previousValue; + } + + // Otherwise take the new value + this.Value = _currentValue; + } + + public override Actor GetNextKeyboardFocusableActor(Actor currentFocusedActor, View.KeyboardFocus.Direction direction, bool loopEnabled) + { + // Respond to Up/Down keys to change the value while keeping the current spin focused + Actor nextFocusedActor = currentFocusedActor; + if (direction == View.KeyboardFocus.Direction.UP) + { + this.Value += this.Step; + nextFocusedActor = _textField; + } + else if (direction == View.KeyboardFocus.Direction.DOWN) + { + this.Value -= this.Step; + nextFocusedActor = _textField; + } + else + { + // Return a native empty handle as nothing can be focused in the left or right + nextFocusedActor = new Actor(); + nextFocusedActor.Reset(); + } + + return nextFocusedActor; + } + + + [ScriptableProperty()] + public int Value + { + get + { + return _currentValue; + } + set + { + + Console.WriteLine ("Value set to " + value ); + _currentValue = value; + + // Make sure no invalid value is accepted + if (_currentValue < _minValue) + { + _currentValue = _minValue; + } + + if (_currentValue > _maxValue) + { + _currentValue = _maxValue; + } + + _textField.Text = _currentValue.ToString(); + } + } + // MinValue property of type int: + [ScriptableProperty()] + public int MinValue + { + get + { + return _minValue; + } + set + { + _minValue = value; + } + } + + // MaxValue property of type int: + [ScriptableProperty()] + public int MaxValue + { + get + { + return _maxValue; + } + set + { + _maxValue = value; + } + } + + // Step property of type int: + [ScriptableProperty()] + public int Step + { + get + { + return _singleStep; + } + set + { + _singleStep = value; + } + } + + // WrappingEnabled property of type bool: + [ScriptableProperty()] + public bool WrappingEnabled + { + get + { + return _wrappingEnabled; + } + set + { + _wrappingEnabled = value; + } + } + + // TextPointSize property of type int: + [ScriptableProperty()] + public int TextPointSize + { + get + { + return _pointSize; + } + set + { + _pointSize = value; + _textField.PointSize = _pointSize; + } + } + + // TextColor property of type Color: + [ScriptableProperty()] + public Color TextColor + { + get + { + return _textColor; + } + set + { + Console.WriteLine ("TextColor set to " + value.R + "," + value.G + ","+ value.B); + + _textColor = value; + _textField.TextColor = _textColor; + } + } + + // MaxTextLength property of type int: + [ScriptableProperty()] + public int MaxTextLength + { + get + { + return _maxTextLength; + } + set + { + _maxTextLength = value; + _textField.MaxLength = _maxTextLength; + } + } + + public TextField SpinText + { + get + { + return _textField; + } + set + { + _textField = value; + } + } + + // Indicator property of type string: + public string IndicatorImage + { + get + { + return _arrowImage; + } + set + { + _arrowImage = value; + _arrowVisual = VisualFactory.Get().CreateVisual( _arrowImage, new Uint16Pair(150, 150) ); + RegisterVisual( _arrowVisualPropertyIndex, _arrowVisual ); + } + } +} +} \ No newline at end of file