/*
- * 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.
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; }
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)
END_TEST;
}
-int UtcDaliButtonSetLabelStringP(void)
+int UtcDaliButtonSetLabelStringWithPropertyMapP(void)
{
ToolkitTestApplication application;
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;
}
{
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";
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<std::string>( 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 );
propertyMap.Insert( Toolkit::TextVisual::Property::POINT_SIZE, 15.0f );
button.SetProperty( Button::Property::LABEL, propertyMap );
- labelText = button.GetProperty<std::string>( Button::Property::LABEL_TEXT );
-
- DALI_TEST_EQUALS( labelText, TEST_LABEL2, TEST_LOCATION );
+ DALI_TEST_EQUALS( GetButtonText( button ), TEST_LABEL2, TEST_LOCATION );
END_TEST;
}
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<std::string>( 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<std::string>( Button::Property::LABEL_TEXT );
+
+ DALI_TEST_EQUALS( labelText, TEST_LABEL2, TEST_LOCATION );
+
+ END_TEST;
+}
/*
- * 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.
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;
+}
/*
- * 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.
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<DummyControlImpl&>( 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<DummyControlImpl&>( 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;
+}
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;
+}
/*
- * 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.
void BloomView::OnSizeSet(const Vector3& targetSize)
{
- Control::OnSizeSet( targetSize );
-
mTargetSize = Vector2(targetSize);
mChildrenRoot.SetSize(targetSize);
mCompositeImageView.SetSize(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 )
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
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() );
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;
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.
/*
- * 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.
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
}
mChildrenRoot.SetSize( targetSize );
+
+ Control::OnSizeSet( targetSize );
}
void EffectsView::OnStageConnection( int depth )
{
- Control::OnStageConnection( depth );
-
Enable();
+
+ Control::OnStageConnection( depth );
}
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 )
/*
- * 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.
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 );
childNode.node->get_child = GetChildNodeAtIndex;
childNode.node->is_dirty = IsNodeDirty;
mChildrenNodes.push_back(childNode);
+
+ Control::OnChildAdd( child );
}
void FlexContainer::OnChildRemove( Actor& child )
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()
#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.
*/
virtual void OnSizeSet( const Vector3& size );
- /**
- * @copydoc CustomActorImpl::OnSizeAnimation(Animation&, const Vector3&)
- */
- virtual void OnSizeAnimation(Animation& animation, const Vector3& targetSize);
-
private: // Implementation
/**
/*
- * 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.
void GaussianBlurView::OnSizeSet(const Vector3& targetSize)
{
- Control::OnSizeSet( targetSize );
-
mTargetSize = Vector2(targetSize);
mChildrenRoot.SetSize(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 )
/*
- * 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.
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
// a constraint yet as Camera/CameraActor properties are not animatable/constrainable.
mActorSize = targetSize;
Update();
+
+ Control::OnSizeSet( targetSize );
}
float Magnifier::GetMagnificationFactor() const
/*
- * 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.
void Model3dView::OnStageConnection( int depth )
{
- Control::OnStageConnection( depth );
-
CustomActor self = Self();
self.AddRenderer( mRenderer );
constraint.AddSource( Source( self, Toolkit::Model3dView::Property::LIGHT_POSITION ) );
constraint.Apply();
}
+
+ Control::OnStageConnection( depth );
}
///////////////////////////////////////////////////////////
/*
- * 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.
void NavigationView::OnStageConnection( int depth )
{
Self().SetSensitive(true);
+
+ Control::OnStageConnection( depth );
}
void NavigationView::Push( Actor& actor )
/*
- * 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.
void PageTurnView::OnStageConnection( int depth )
{
- Control::OnStageConnection( depth );
-
SetupShadowView();
+
+ Control::OnStageConnection( depth );
}
void PageTurnView::OnStageDisconnection()
/*
- * 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.
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 )
{
mLayoutDirty = true;
RelayoutRequest();
}
+
+ Control::OnChildAdd( child );
}
void Popup::LayoutContext( const Vector2& size )
/*
- * 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.
{
mIndicator.SetSize(size.width, mIndicatorFixedHeight);
}
+
+ Control::OnSizeSet( size );
}
void ScrollBar::SetScrollDirection( Toolkit::ScrollBar::Direction direction )
/*
- * 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.
Toolkit::ItemView::Property::SCROLL_CONTENT_SIZE);
}
}
+
+ Scrollable::OnChildAdd( child );
}
bool ItemView::OnWheelEvent(const WheelEvent& event)
/*
- * 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.
void ScrollView::OnStageConnection( int depth )
{
- ScrollBase::OnStageConnection( depth );
-
DALI_LOG_SCROLL_STATE("[0x%X]", this);
if ( mSensitive )
SetScrollSensitive( false );
SetScrollSensitive( true );
}
+
if(IsOvershootEnabled())
{
// try and make sure property notifications are set
EnableScrollOvershoot(true);
}
+
+ ScrollBase::OnStageConnection( depth );
}
void ScrollView::OnStageDisconnection()
{
mOvershootIndicator->Reset();
}
+
+ ScrollBase::OnSizeSet( size );
}
void ScrollView::OnChildAdd(Actor& child)
/*
- * 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.
void ShadowView::OnChildAdd( Actor& child )
{
- Control::OnChildAdd( child );
-
if( child != mChildrenRoot && child != mBlurRootActor)
{
mChildrenRoot.Add( child );
}
+
+ Control::OnChildAdd( child );
}
void ShadowView::OnChildRemove( Actor& child )
/*
- * 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.
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 ) );
#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.
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 );
/*
- * 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.
SetImage( mInputImage );
}
}
+
+ Control::OnSizeSet( targetSize );
}
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();
// 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<int>(Renderer::Property::DEPTH_INDEX);
if( depthIndex > 0 )
}
}
-void SuperBlurView::OnStageDisconnection( )
-{
- Control::OnStageDisconnection();
-}
-
Vector3 SuperBlurView::GetNaturalSize()
{
if( mInputImage )
#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.
virtual void OnStageConnection( int depth );
/**
- * @copydoc CustomActorImpl::OnStageDisconnection()
- */
- virtual void OnStageDisconnection();
-
- /**
* @copydoc CustomActorImpl::GetNaturalSize()
*/
virtual Vector3 GetNaturalSize();
/*
- * 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.
// 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 )
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<std::string >();
- 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<std::string >();
+ 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<std::string >();
- 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<std::string >();
+ 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<unsigned int>( child.GetProperty( Toolkit::TableView::ChildProperty::ROW_SPAN ).Get<float>() );
- }
+ Toolkit::TableView::CellPosition cellPosition;
+ if( child.GetPropertyType( Toolkit::TableView::ChildProperty::ROW_SPAN ) != Property::NONE )
+ {
+ cellPosition.rowSpan = static_cast<unsigned int>( child.GetProperty( Toolkit::TableView::ChildProperty::ROW_SPAN ).Get<float>() );
+ }
- if( child.GetPropertyType( Toolkit::TableView::ChildProperty::COLUMN_SPAN ) != Property::NONE )
- {
- cellPosition.columnSpan = static_cast<unsigned int>( child.GetProperty( Toolkit::TableView::ChildProperty::COLUMN_SPAN ).Get<float>() );
- }
+ if( child.GetPropertyType( Toolkit::TableView::ChildProperty::COLUMN_SPAN ) != Property::NONE )
+ {
+ cellPosition.columnSpan = static_cast<unsigned int>( child.GetProperty( Toolkit::TableView::ChildProperty::COLUMN_SPAN ).Get<float>() );
+ }
- if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_INDEX ) != Property::NONE )
- {
- Vector2 indices = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_INDEX ).Get<Vector2 >();
- cellPosition.rowIndex = static_cast<unsigned int>( indices.x );
- cellPosition.columnIndex = static_cast<unsigned int>( indices.y );
+ if( child.GetPropertyType( Toolkit::TableView::ChildProperty::CELL_INDEX ) != Property::NONE )
+ {
+ Vector2 indices = child.GetProperty( Toolkit::TableView::ChildProperty::CELL_INDEX ).Get<Vector2 >();
+ cellPosition.rowIndex = static_cast<unsigned int>( indices.x );
+ cellPosition.columnIndex = static_cast<unsigned int>( 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 )
mRowDirty( true ), // Force recalculation first time
mColumnDirty( true )
{
+ mCurrentColumn = 0;
+ mCurrentRow = 0;
SetKeyboardNavigationSupport( true );
ResizeContainers( initialRows, initialColumns );
}
// 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));
+ }
+ }
}
}
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
/*
- * 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.
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 )
/*
- * 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.
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 )
/*
- * 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.
}
}
-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
#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.
*/
virtual float GetHeightForWidth( float width );
- /**
- * @copydoc Control::OnStageConnection()
- */
- virtual void OnStageConnection( int depth );
-
// From ControlInterface
/**
/*
- * 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.
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();
#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.
*/
virtual void OnInitialize();
- /**
- * @copydoc Control::OnStageConnection()
- */
- virtual void OnStageConnection( int depth );
-
private: // Implementation
void HideAnimationFinished( Animation& animation );
/*
- * 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.
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;
#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.
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)
*/
/*
- * 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.
void ToolBar::OnChildAdd(Actor& child)
{
- Control::OnChildAdd( child );
-
if( !mInitializing )
{
// An actor is being added through the Actor's API.
// 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
/*
- * 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.
void VideoView::OnStageConnection( int depth )
{
- Control::OnStageConnection( depth );
-
if( mVisual )
{
CustomActor self = Self();
Toolkit::GetImplementation(mVisual).SetOnStage( self );
}
+
+ Control::OnStageConnection( depth );
}
void VideoView::OnStageDisconnection()
/*
- * 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.
void CubeTransitionEffect::OnStageConnection( int depth )
{
- Control::OnStageConnection( depth );
-
Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
Shader shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
mCurrentRenderer.SetProperty( Renderer::Property::DEPTH_INDEX, depth );
Self().AddRenderer( mCurrentRenderer );
+
+ Control::OnStageConnection( depth );
}
void CubeTransitionEffect::OnStageDisconnection()
SELECTED_COLOR,
/**
- * @brief name "label", type Property::Map
+ * @brief name "label", type Property::Map or std::string
* @SINCE_1_0.0
*/
LABEL,
/*
- * 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.
#include <dali/public-api/size-negotiation/relayout-container.h>
#include <dali/devel-api/common/owner-container.h>
#include <dali/devel-api/object/handle-devel.h>
+#include <dali/devel-api/scripting/enum-helper.h>
#include <dali/devel-api/scripting/scripting.h>
#include <dali/integration-api/debug.h>
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.
*/
{
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()
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 );
#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.
/**
* @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 );
/**
* @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 );
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 );
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 );
}
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 );
}
};
/**
- * @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
*
* 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.
};
/**
- * @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
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
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
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
{
/**
- * @brief The internal orientation of a control.
+ * @brief Enumeration for the internal orientation of a control.
* @SINCE_1_0.0
*/
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);
*
* @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);
{
"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":
"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":
"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":
// 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}
// 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}
___________________________________________________________________________________________________
+### 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)
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
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
aclocal.m4
config/
config.*
-cpp/dali_wrap.cpp
-cpp/dali_wrap.h
+automatic/*
configure
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
%ignore *::AnchorPoint::DEFAULT;
%ignore *::SetPositionInheritanceMode(PositionInheritanceMode);
%ignore *::GetKeyValue(SizeType) const;
+%ignore *::TypeInfo::GetCreator() const;
%rename(ParentOriginTop) Dali::ParentOrigin::TOP;
%rename(ParentOriginBottom) Dali::ParentOrigin::BOTTOM;
%include <dali/public-api/object/handle.h>
%include <dali/public-api/object/type-info.h>
%include <dali/public-api/object/type-registry.h>
+%include <dali/devel-api/object/csharp-type-info.h>
+%include <dali/devel-api/object/csharp-type-registry.h>
%include <dali/public-api/common/constants.h>
%include <dali/public-api/actors/actor-enumerations.h>
#include <dali/public-api/math/matrix3.h>
#include <dali/public-api/math/viewport.h>
#include <dali/public-api/object/property-key.h>
+#include <dali/devel-api/object/csharp-type-info.h>
+#include <dali/devel-api/object/csharp-type-registry.h>
#include <dali/public-api/adaptor-framework/timer.h>
#include <dali/public-api/adaptor-framework/window.h>
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&);
%include alphafunction.i
%include name-changed.i
-
+%include property-value.i
%include dali-operator.i
%include dali-core.i
%include dali-adaptor.i
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();
}
}
+ ///
+ 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
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#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
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+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 ();
+ }
+
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static void Main(string[] args)
+ {
+ Example example = new Example(Application.NewApplication());
+ example.MainLoop ();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+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 ();
+ }
+
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [STAThread]
+ static void Main(string[] args)
+ {
+ Example example = new Example(Application.NewApplication());
+ example.MainLoop ();
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+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 ();
+ }
+
+ /// <summary>
+ /// The main entry point for the application.
+ /// </summary>
+ [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 ();
+ }
+ }
+}
--- /dev/null
+/*
+ * 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]
+ }
+ }]
+
+ }
+}
+
+}
+
--- /dev/null
+/*
+ * 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]
+ }
+ }]
+
+}]
+
+}
+
--- /dev/null
+/*
+ * 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
+ }
+
+ ]
+}
+++ /dev/null
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-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 ();
- }
-
- /// <summary>
- /// The main entry point for the application.
- /// </summary>
- [STAThread]
- static void Main(string[] args)
- {
- Example example = new Example(Application.NewApplication());
- example.MainLoop ();
- }
- }
-}
--- /dev/null
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Dali
+{
+ /// <summary>
+ /// Helper class for calculating what property indexes should be assigned to C# View (view) classes.
+ /// </summary>
+ public class PropertyRangeManager
+ {
+ private Dictionary<String, PropertyRange > _propertyRange;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Dali.PropertyRangeManager"/> class.
+ /// </summary>
+ public PropertyRangeManager ()
+ {
+ _propertyRange = new Dictionary<String, PropertyRange > ();
+ }
+
+ /// <summary>
+ /// Only called if a View has scriptable properties
+ /// </summary>
+ 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;
+
+ }
+
+ /// <summary>
+ /// Gets the index of the property.
+ /// Each property has to have unique index for this view type
+ /// </summary>
+ /// <returns>The property index.</returns>
+ /// <param name="viewName">View name</param>
+ /// <param name="viewType">View type</param>
+ /// <param name="type">Type.</param>
+ 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;
+
+ }
+
+ ///<summary>
+ /// 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)
+ /// </summary>
+ 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
+ };
+
+
+
+}
+}
--- /dev/null
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Dali
+{
+ /// <summary>
+ /// Add this attribute to any property belonging to a View (control) you want to be scriptable from JSON
+ /// </summary>
+ /// <remarks>
+ /// 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()
+ /// </remarks>
+ ///
+ ///
+ 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;
+ }
+ }
+
+ /// <summary>
+ /// 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 );
+ ///
+ ///
+ ///
+ /// </summary>
+ public sealed class ViewRegistry
+ {
+ /// <summary>
+ /// ViewRegistry is a singleton
+ /// </summary>
+ 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;
+
+ /// <summary>
+ /// Given a C++ custom control the dictionary allows us to find what CustomView it belongs to
+ /// </summary>
+ private Dictionary<IntPtr, Dali.CustomView> _controlMap;
+
+ ///<summary>
+ // 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.
+ ///</summary>
+ private Dictionary<String, Func< CustomView > > _constructorMap;
+
+ /// <summary>
+ /// Lookup table to match C# types to DALi types, used for the automatic property registration
+ /// </summary>
+ private static readonly Dictionary<string, Dali.Property.Type> _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<IntPtr, CustomView>();
+ _constructorMap = new Dictionary<string, Func<CustomView>>();
+ _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;
+ }
+ }
+
+ /// <summary>
+ /// Called directly from DALi C++ type registry to create a control (View) uses no marshalling.
+ /// </summary>
+ /// <returns>Pointer to the Control (Views) handle </returns>
+ /// <param name="cPtrControlName"> C pointer to the Control (View) name</param>
+ 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;
+ }
+ }
+
+
+ /// <summary>
+ /// 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) );
+ /// }
+ ///
+ /// </summary>
+ 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);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Get a property value from a View
+ ///
+ /// </summary>
+ 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;
+ }
+ }
+
+ /// <summary>
+ /// Set a property value on a View
+ ///
+ /// </summary>
+ 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
--- /dev/null
+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);
+ }
+ }
+}
+
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"\
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"
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+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