From 08849cfa427e4aad392b8f982037ae03e6a1c758 Mon Sep 17 00:00:00 2001 From: David Steele Date: Mon, 16 May 2016 14:00:45 +0100 Subject: [PATCH] [3.0] Added a simple application for testing Styling Added a simple application that has examples of different button types, sliders and popups, that can all be themed. Change-Id: I6d74357b79def0c8d0f7195adf0be7c1270fe9ce Signed-off-by: David Steele --- build/tizen/CMakeLists.txt | 28 +- com.samsung.dali-demo.xml | 3 + demo/dali-demo.cpp | 1 + examples/line-mesh/line-mesh-example.cpp | 2 +- examples/styling/image-channel-control-impl.cpp | 218 +++++++ examples/styling/image-channel-control-impl.h | 120 ++++ examples/styling/image-channel-control.cpp | 80 +++ examples/styling/image-channel-control.h | 123 ++++ examples/styling/style-example.cpp | 53 ++ examples/styling/styling-application.cpp | 641 +++++++++++++++++++++ examples/styling/styling-application.h | 97 ++++ packaging/com.samsung.dali-demo.spec | 1 + resources/po/as.po | 5 +- resources/po/de.po | 3 + resources/po/en_GB.po | 3 + resources/po/en_US.po | 3 + resources/po/es.po | 3 + resources/po/ko.po | 3 + resources/po/ml.po | 3 + resources/po/ur.po | 3 + resources/po/zn_CH.po | 3 + resources/style/.gitignore | 4 + resources/style/images/.gitignore | 1 + resources/style/images/radio-button-selected.png | Bin 0 -> 3825 bytes .../images/radio-button-unselected-disabled.png | Bin 0 -> 2677 bytes resources/style/images/radio-button-unselected.png | Bin 0 -> 3148 bytes .../style/images/slider-skin-progress-blue.9.png | Bin 0 -> 405 bytes .../style/images/slider-skin-progress-green.9.png | Bin 0 -> 425 bytes .../style/images/slider-skin-progress-red.9.png | Bin 0 -> 424 bytes .../style/mobile/images/radio-button-selected.png | Bin 0 -> 3825 bytes .../images/radio-button-unselected-disabled.png | Bin 0 -> 2677 bytes .../mobile/images/radio-button-unselected.png | Bin 0 -> 3148 bytes .../mobile/images/slider-skin-progress-blue.9.png | Bin 0 -> 405 bytes .../mobile/images/slider-skin-progress-green.9.png | Bin 0 -> 425 bytes .../mobile/images/slider-skin-progress-red.9.png | Bin 0 -> 424 bytes .../style/mobile/style-example-theme-one.json.in | 67 +++ .../style/mobile/style-example-theme-three.json.in | 51 ++ .../style/mobile/style-example-theme-two.json.in | 97 ++++ resources/style/style-example-theme-one.json.in | 67 +++ resources/style/style-example-theme-three.json.in | 51 ++ resources/style/style-example-theme-two.json.in | 97 ++++ shared/dali-demo-strings.h | 2 + 42 files changed, 1824 insertions(+), 9 deletions(-) create mode 100644 examples/styling/image-channel-control-impl.cpp create mode 100644 examples/styling/image-channel-control-impl.h create mode 100644 examples/styling/image-channel-control.cpp create mode 100644 examples/styling/image-channel-control.h create mode 100644 examples/styling/style-example.cpp create mode 100644 examples/styling/styling-application.cpp create mode 100644 examples/styling/styling-application.h create mode 100644 resources/style/.gitignore create mode 100644 resources/style/images/.gitignore create mode 100644 resources/style/images/radio-button-selected.png create mode 100644 resources/style/images/radio-button-unselected-disabled.png create mode 100644 resources/style/images/radio-button-unselected.png create mode 100644 resources/style/images/slider-skin-progress-blue.9.png create mode 100644 resources/style/images/slider-skin-progress-green.9.png create mode 100644 resources/style/images/slider-skin-progress-red.9.png create mode 100644 resources/style/mobile/images/radio-button-selected.png create mode 100644 resources/style/mobile/images/radio-button-unselected-disabled.png create mode 100644 resources/style/mobile/images/radio-button-unselected.png create mode 100644 resources/style/mobile/images/slider-skin-progress-blue.9.png create mode 100644 resources/style/mobile/images/slider-skin-progress-green.9.png create mode 100644 resources/style/mobile/images/slider-skin-progress-red.9.png create mode 100644 resources/style/mobile/style-example-theme-one.json.in create mode 100644 resources/style/mobile/style-example-theme-three.json.in create mode 100644 resources/style/mobile/style-example-theme-two.json.in create mode 100644 resources/style/style-example-theme-one.json.in create mode 100644 resources/style/style-example-theme-three.json.in create mode 100644 resources/style/style-example-theme-two.json.in diff --git a/build/tizen/CMakeLists.txt b/build/tizen/CMakeLists.txt index 75b8a55..89df63b 100644 --- a/build/tizen/CMakeLists.txt +++ b/build/tizen/CMakeLists.txt @@ -35,7 +35,7 @@ SET(IMAGES_DIR ${APP_DATA_DIR}/images/) SET(VIDEOS_DIR ${APP_DATA_DIR}/videos/) SET(MODELS_DIR ${APP_DATA_DIR}/models/) SET(SCRIPTS_DIR ${APP_DATA_DIR}/scripts/) -SET(STYLE_DIR ${APP_DATA_DIR}/style/) +SET(STYLE_DIR ${APP_DATA_DIR}style/) IF(NOT DEFINED LOCALE_DIR) SET(LOCALE_DIR ${PREFIX}/share/locale) @@ -46,11 +46,13 @@ SET(DEMO_VIDEO_DIR \\"${VIDEOS_DIR}\\") SET(DEMO_MODEL_DIR \\"${MODELS_DIR}\\") SET(DEMO_SCRIPT_DIR \\"${SCRIPTS_DIR}\\") SET(DEMO_STYLE_DIR \\"${STYLE_DIR}\\") -SET(DEMO_THEME_PATH \\"${STYLE_DIR}/demo-theme.json\\") +SET(DEMO_THEME_PATH \\"${STYLE_DIR}demo-theme.json\\") SET(DEMO_EXAMPLE_BIN \\"${BINDIR}/\\") SET(DEMO_LOCALE_DIR \\"${LOCALE_DIR}\\") SET(DEMO_LANG \\"${LANG}\\") +SET(DEMO_STYLE_IMAGE_DIR ${STYLE_DIR}images) + FILE(GLOB LOCAL_IMAGES_PNG RELATIVE "${LOCAL_IMAGES_DIR}" "${LOCAL_IMAGES_DIR}/*.png") FILE(GLOB LOCAL_IMAGES_JPG RELATIVE "${LOCAL_IMAGES_DIR}" "${LOCAL_IMAGES_DIR}/*.jpg") FILE(GLOB LOCAL_IMAGES_GIF RELATIVE "${LOCAL_IMAGES_DIR}" "${LOCAL_IMAGES_DIR}/*.gif") @@ -82,11 +84,23 @@ FOREACH(flag ${LOCAL_SCRIPTS_LIST}) ENDFOREACH(flag) #Replace @DEMO_STYLE_IMAGE_DIR@ in following files -SET(DEMO_STYLE_IMAGE_DIR ${IMAGES_DIR}) CONFIGURE_FILE( ${LOCAL_STYLE_DIR}/demo-theme.json.in ${LOCAL_STYLE_DIR}/demo-theme.json ) -INSTALL(FILES ${LOCAL_STYLE_DIR}/demo-theme.json DESTINATION ${STYLE_DIR}) -CONFIGURE_FILE( ${LOCAL_SCRIPTS_DIR}/simple-image-wall.js.in ${LOCAL_SCRIPTS_DIR}/simple-image-wall.js ) -INSTALL(FILES ${LOCAL_SCRIPTS_DIR}/simple-image-wall.js DESTINATION ${SCRIPTS_DIR}) +CONFIGURE_FILE( ${LOCAL_STYLE_DIR}/style-example-theme-one.json.in ${LOCAL_STYLE_DIR}/style-example-theme-one.json ) +CONFIGURE_FILE( ${LOCAL_STYLE_DIR}/style-example-theme-two.json.in ${LOCAL_STYLE_DIR}/style-example-theme-two.json ) +CONFIGURE_FILE( ${LOCAL_STYLE_DIR}/style-example-theme-three.json.in ${LOCAL_STYLE_DIR}/style-example-theme-three.json ) +MESSAGE("Configured ${LOCAL_STYLE_DIR}/style-example-theme<>.json files") + +FILE(GLOB LOCAL_STYLES_LIST "${LOCAL_STYLE_DIR}/*.json") +FOREACH(flag ${LOCAL_STYLES_LIST}) + INSTALL(FILES ${flag} DESTINATION ${STYLE_DIR}) +ENDFOREACH(flag) +MESSAGE("Installed ${LOCAL_STYLES_LIST} to ${STYLE_DIR}") + +FILE(GLOB LOCAL_STYLE_IMAGES_LIST "${LOCAL_STYLE_DIR}/images/*.png") +FOREACH(flag ${LOCAL_STYLE_IMAGES_LIST}) + INSTALL(FILES ${flag} DESTINATION ${STYLE_DIR}/images) +ENDFOREACH(flag) +MESSAGE("Installed style resources ${LOCAL_STYLE_IMAGES_LIST} to ${STYLE_DIR}/images") SET(PKG_LIST dali-core dali-adaptor @@ -99,7 +113,7 @@ FOREACH(flag ${REQUIRED_PKGS_CFLAGS}) SET(REQUIRED_CFLAGS "${REQUIRED_CFLAGS} ${flag}") ENDFOREACH(flag) -SET(DALI_DEMO_CFLAGS "-DDEMO_IMAGE_DIR=${DEMO_IMAGE_DIR} -DDEMO_VIDEO_DIR=${DEMO_VIDEO_DIR} -DDEMO_MODEL_DIR=${DEMO_MODEL_DIR} -DDEMO_SCRIPT_DIR=${DEMO_SCRIPT_DIR} -DDEMO_THEME_PATH=${DEMO_THEME_PATH} -DDEMO_EXAMPLE_BIN=${DEMO_EXAMPLE_BIN} -DDEMO_LOCALE_DIR=${DEMO_LOCALE_DIR} -fvisibility=hidden -DHIDE_DALI_INTERNALS -DDEMO_LANG=${DEMO_LANG}") +SET(DALI_DEMO_CFLAGS "-DDEMO_IMAGE_DIR=${DEMO_IMAGE_DIR} -DDEMO_VIDEO_DIR=${DEMO_VIDEO_DIR} -DDEMO_MODEL_DIR=${DEMO_MODEL_DIR} -DDEMO_SCRIPT_DIR=${DEMO_SCRIPT_DIR} -DDEMO_STYLE_DIR=${DEMO_STYLE_DIR} -DDEMO_THEME_PATH=${DEMO_THEME_PATH} -DDEMO_EXAMPLE_BIN=${DEMO_EXAMPLE_BIN} -DDEMO_LOCALE_DIR=${DEMO_LOCALE_DIR} -fvisibility=hidden -DHIDE_DALI_INTERNALS -DDEMO_LANG=${DEMO_LANG}") ########################################################################### # Internationalization diff --git a/com.samsung.dali-demo.xml b/com.samsung.dali-demo.xml index 6c856c3..4dbcc91 100644 --- a/com.samsung.dali-demo.xml +++ b/com.samsung.dali-demo.xml @@ -169,4 +169,7 @@ + + + diff --git a/demo/dali-demo.cpp b/demo/dali-demo.cpp index d9444a5..28b1082 100644 --- a/demo/dali-demo.cpp +++ b/demo/dali-demo.cpp @@ -80,6 +80,7 @@ int DALI_EXPORT_API main(int argc, char **argv) demo.AddExample(Example("native-image-source.example", DALI_DEMO_STR_TITLE_NATIVE_IMAGE_SOURCE)); demo.AddExample(Example("mesh-visual.example", DALI_DEMO_STR_TITLE_MESH_VISUAL)); demo.AddExample(Example("primitive-shapes.example", DALI_DEMO_STR_TITLE_PRIMITIVE_SHAPES)); + demo.AddExample(Example("styling.example", DALI_DEMO_STR_TITLE_STYLING)); demo.SortAlphabetically( true ); diff --git a/examples/line-mesh/line-mesh-example.cpp b/examples/line-mesh/line-mesh-example.cpp index 53f0fe8..a56f1b5 100644 --- a/examples/line-mesh/line-mesh-example.cpp +++ b/examples/line-mesh/line-mesh-example.cpp @@ -234,7 +234,7 @@ public: Dali::Toolkit::RadioButton radio = Dali::Toolkit::RadioButton::New(); - radio.SetProperty( Dali::Toolkit::RadioButton::Property::LABEL, labelMap ); + radio.SetProperty( Dali::Toolkit::Button::Property::LABEL, labelMap ); radio.SetParentOrigin( ParentOrigin::TOP_LEFT ); radio.SetAnchorPoint( AnchorPoint::TOP_LEFT ); radio.SetSelected( i == 0 ); diff --git a/examples/styling/image-channel-control-impl.cpp b/examples/styling/image-channel-control-impl.cpp new file mode 100644 index 0000000..dc133d1 --- /dev/null +++ b/examples/styling/image-channel-control-impl.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "image-channel-control-impl.h" +#include +#include +#include + +using namespace Dali; // Needed for macros + +namespace Demo +{ +namespace Internal +{ + +namespace +{ + +const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER( + varying mediump vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform mediump vec4 uColor;\n + uniform mediump vec3 uChannels;\n + \n + void main()\n + {\n + gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor * vec4(uChannels, 1.0) ;\n + }\n +); + +Dali::BaseHandle Create() +{ + return Demo::ImageChannelControl::New(); +} + +DALI_TYPE_REGISTRATION_BEGIN( ImageChannelControl, Dali::Toolkit::Control, Create ); + +DALI_PROPERTY_REGISTRATION( Demo, ImageChannelControl, "url", STRING, RESOURCE_URL ); +DALI_PROPERTY_REGISTRATION( Demo, ImageChannelControl, "redChannel", FLOAT, RED_CHANNEL ); +DALI_PROPERTY_REGISTRATION( Demo, ImageChannelControl, "greenChannel", FLOAT, GREEN_CHANNEL ); +DALI_PROPERTY_REGISTRATION( Demo, ImageChannelControl, "blueChannel", FLOAT, BLUE_CHANNEL ); + +DALI_TYPE_REGISTRATION_END(); + +} // anonymous namespace + + +Internal::ImageChannelControl::ImageChannelControl() +: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ), + mChannels( 1.0f, 1.0f, 1.0f ) +{ +} + +Internal::ImageChannelControl::~ImageChannelControl() +{ +} + +Demo::ImageChannelControl Internal::ImageChannelControl::New() +{ + IntrusivePtr impl = new Internal::ImageChannelControl(); + Demo::ImageChannelControl handle = Demo::ImageChannelControl( *impl ); + impl->Initialize(); + return handle; +} + +void ImageChannelControl::SetImage( const std::string& url ) +{ + mUrl = url; + + Actor self = Self(); + + Property::Map properties; + Property::Map shader; + shader[Dali::Toolkit::Visual::Shader::Property::FRAGMENT_SHADER] = FRAGMENT_SHADER; + properties[Dali::Toolkit::Visual::Property::TYPE] = Dali::Toolkit::Visual::IMAGE; + properties[Dali::Toolkit::Visual::Property::SHADER]=shader; + properties[Dali::Toolkit::ImageVisual::Property::URL] = url; + + Dali::Toolkit::InitializeVisual( self, mVisual, properties ); + + RelayoutRequest(); +} + +void ImageChannelControl::OnInitialize() +{ + Actor self = Self(); + mChannelIndex = self.RegisterProperty( "uChannels", Vector3(1.0f, 1.0f, 1.0f) ); +} + +void ImageChannelControl::OnStageConnection( int depth ) +{ + Control::OnStageConnection( depth ); + + if( mVisual ) + { + CustomActor self = Self(); + mVisual.SetOnStage( self ); + } +} + +void ImageChannelControl::OnStageDisconnection() +{ + if( mVisual ) + { + CustomActor self = Self(); + mVisual.SetOffStage( self ); + } + + Control::OnStageDisconnection(); +} + +void ImageChannelControl::OnSizeSet( const Vector3& targetSize ) +{ + Control::OnSizeSet( targetSize ); + + if( mVisual ) + { + Vector2 size( targetSize ); + mVisual.SetSize( size ); + } +} + +Vector3 ImageChannelControl::GetNaturalSize() +{ + if( mVisual ) + { + Vector2 naturalSize; + mVisual.GetNaturalSize(naturalSize); + return Vector3(naturalSize); + } + return Vector3::ZERO; +} + + +/////////////////////////////////////////////////////////// +// +// Properties +// + +void ImageChannelControl::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value ) +{ + Demo::ImageChannelControl imageChannelControl = Demo::ImageChannelControl::DownCast( Dali::BaseHandle( object ) ); + + if ( imageChannelControl ) + { + ImageChannelControl& impl = GetImpl( imageChannelControl ); + Actor self = impl.Self(); + switch ( index ) + { + case Demo::ImageChannelControl::Property::RED_CHANNEL: + { + impl.mChannels[0] = value.Get(); + self.SetProperty( impl.mChannelIndex, impl.mChannels ); + break; + } + case Demo::ImageChannelControl::Property::GREEN_CHANNEL: + { + impl.mChannels[1] = value.Get(); + self.SetProperty( impl.mChannelIndex, impl.mChannels ); + break; + } + case Demo::ImageChannelControl::Property::BLUE_CHANNEL: + { + impl.mChannels[2] = value.Get(); + self.SetProperty( impl.mChannelIndex, impl.mChannels ); + break; + } + } + } +} + +Property::Value ImageChannelControl::GetProperty( BaseObject* object, Property::Index propertyIndex ) +{ + Property::Value value; + + Demo::ImageChannelControl imageChannelControl = Demo::ImageChannelControl::DownCast( Dali::BaseHandle( object ) ); + + if ( imageChannelControl ) + { + ImageChannelControl& impl = GetImpl( imageChannelControl ); + switch ( propertyIndex ) + { + case Demo::ImageChannelControl::Property::RED_CHANNEL: + { + value = impl.mChannels[0]; + break; + } + case Demo::ImageChannelControl::Property::GREEN_CHANNEL: + { + value = impl.mChannels[1]; + break; + } + case Demo::ImageChannelControl::Property::BLUE_CHANNEL: + { + value = impl.mChannels[2]; + break; + } + } + } + + return value; +} + +} // Internal +} // Demo diff --git a/examples/styling/image-channel-control-impl.h b/examples/styling/image-channel-control-impl.h new file mode 100644 index 0000000..a733dfd --- /dev/null +++ b/examples/styling/image-channel-control-impl.h @@ -0,0 +1,120 @@ +#ifndef DALI_DEMO_INTERNAL_IMAGE_CHANNEL_CONTROL_IMPL_H +#define DALI_DEMO_INTERNAL_IMAGE_CHANNEL_CONTROL_IMPL_H + +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "image-channel-control.h" +#include +#include + +namespace Demo +{ + +namespace Internal // To use TypeRegistry, handle and body classes need the same name +{ + +class ImageChannelControl : public Dali::Toolkit::Internal::Control +{ +public: + /** + * Instantiate a new ImageChannelControl object + */ + static Demo::ImageChannelControl New(); + ImageChannelControl(); + ~ImageChannelControl(); + +public: // API + /** + * @copydoc ImageChannelControl::SetImage + */ + void SetImage( const std::string& url ); + +public: // Properties + /** + * Called when a property of an object of this type is set. + * @param[in] object The object whose property is set. + * @param[in] index The property index. + * @param[in] value The new property value. + */ + static void SetProperty( Dali::BaseObject* object, Dali::Property::Index index, const Dali::Property::Value& value ); + + /** + * Called to retrieve a property of an object of this type. + * @param[in] object The object whose property is to be retrieved. + * @param[in] index The property index. + * @return The current value of the property. + */ + static Dali::Property::Value GetProperty( Dali::BaseObject* object, Dali::Property::Index propertyIndex ); + +private: // From Control + /** + * @copydoc Toolkit::Control::OnInitialize() + */ + virtual void OnInitialize(); + + /** + * @copydoc Toolkit::Control::OnStageConnect() + */ + virtual void OnStageConnection( int depth ); + + /** + * @copydoc Toolkit::Control::OnStageDisconnection() + */ + virtual void OnStageDisconnection(); + + /** + * @copydoc Toolkit::Control::OnSizeSet() + */ + virtual void OnSizeSet( const Dali::Vector3& targetSize ); + + /** + * @copydoc Toolkit::Control::GetNaturalSize + */ + virtual Dali::Vector3 GetNaturalSize(); + +private: + //undefined + ImageChannelControl( const ImageChannelControl& ); + ImageChannelControl& operator=( const ImageChannelControl& ); + +private: + // Implementation details + std::string mUrl; + Dali::Toolkit::Visual::Base mVisual; + Dali::Vector3 mChannels; + Dali::Property::Index mChannelIndex; +}; + +} // Internal + +inline Internal::ImageChannelControl& GetImpl( Demo::ImageChannelControl& handle ) +{ + DALI_ASSERT_ALWAYS( handle ); + Dali::RefObject& object = handle.GetImplementation(); + return static_cast(object); +} + +inline const Internal::ImageChannelControl& GetImpl( const Demo::ImageChannelControl& handle ) +{ + DALI_ASSERT_ALWAYS( handle ); + const Dali::RefObject& object = handle.GetImplementation(); + return static_cast(object); +} + +} // Demo + +#endif // DALI_DEMO_IMAGE_CHANNEL_CONTROL_IMPL_H diff --git a/examples/styling/image-channel-control.cpp b/examples/styling/image-channel-control.cpp new file mode 100644 index 0000000..afe870d --- /dev/null +++ b/examples/styling/image-channel-control.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "image-channel-control.h" +#include "image-channel-control-impl.h" + +namespace Demo +{ + +ImageChannelControl::ImageChannelControl() +{ +} + +ImageChannelControl::ImageChannelControl( const ImageChannelControl& imageChannelControl ) +: Control( imageChannelControl ) +{ +} + +ImageChannelControl& ImageChannelControl::operator= ( const ImageChannelControl& rhs ) +{ + if( &rhs != this ) + { + Control::operator=( rhs ); + } + return *this; +} + +ImageChannelControl::~ImageChannelControl() +{ +} + +ImageChannelControl ImageChannelControl::New() +{ + ImageChannelControl imageChannelControl = Internal::ImageChannelControl::New(); + return imageChannelControl; +} + +ImageChannelControl ImageChannelControl::New( const std::string& url ) +{ + ImageChannelControl imageChannelControl = Internal::ImageChannelControl::New(); + imageChannelControl.SetImage( url ); + return imageChannelControl; +} + +ImageChannelControl ImageChannelControl::DownCast( BaseHandle handle ) +{ + return Control::DownCast< ImageChannelControl, Internal::ImageChannelControl > ( handle ); +} + +void ImageChannelControl::SetImage( const std::string& url ) +{ + GetImpl( *this ).SetImage( url ); +} + +ImageChannelControl::ImageChannelControl( Internal::ImageChannelControl& implementation ) +: Control( implementation ) +{ +} + +ImageChannelControl::ImageChannelControl( Dali::Internal::CustomActor* internal ) +: Control( internal ) +{ + VerifyCustomActorPointer< Internal::ImageChannelControl >( internal ) ; +} + + +} //namespace Demo diff --git a/examples/styling/image-channel-control.h b/examples/styling/image-channel-control.h new file mode 100644 index 0000000..12eb5de --- /dev/null +++ b/examples/styling/image-channel-control.h @@ -0,0 +1,123 @@ +#ifndef DALI_DEMO_IMAGE_CHANNEL_CONTROL_H +#define DALI_DEMO_IMAGE_CHANNEL_CONTROL_H + +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +namespace Demo +{ + +namespace Internal +{ +// All type registered types need to have the same name for the body and the handle +class ImageChannelControl; +} + +/** + * Control that allows the RGB channels of an image to be altered. + */ +class ImageChannelControl : public Dali::Toolkit::Control +{ +public: + /** + * The start and end property ranges for this control + */ + enum PropertyRange + { + PROPERTY_START_INDEX = Dali::Toolkit::Control::CONTROL_PROPERTY_END_INDEX + 1, + PROPERTY_END_INDEX = PROPERTY_START_INDEX + 1000, + + ANIMATABLE_PROPERTY_START_INDEX = Dali::ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX, + ANIMATABLE_PROPERTY_END_INDEX = ANIMATABLE_PROPERTY_START_INDEX+1000 + }; + + struct Property + { + enum + { + + RESOURCE_URL = PROPERTY_START_INDEX, + RED_CHANNEL, + GREEN_CHANNEL, + BLUE_CHANNEL + }; + }; + +public: // Construction / destruction + + /** + * Create an uninitialized handle + */ + ImageChannelControl(); + + /** + * Create a new image channel control without an image. Use + * SetImage to give this control an image + */ + static ImageChannelControl New(); + + /** + * Create a new image channel control from a given URL + */ + static ImageChannelControl New( const std::string& url ); + + /** + * Destructor. This is non-virtual since derived Handle types must not + * contain data or virtual methods + */ + ~ImageChannelControl(); + + /** + * Copy Constructor + */ + ImageChannelControl( const ImageChannelControl& imageChannelControl ); + + /** + * Assignment Operator + */ + ImageChannelControl& operator=( const ImageChannelControl& imageChannelControl ); + + /** + * Downcast + */ + static ImageChannelControl DownCast( BaseHandle handle ); + +public: // API + + /** + * Set the image for this ImageChannelControl + * @param[in] url The url of the image resource + */ + void SetImage( const std::string& url ); + +public: // Not for public use + /** + * Create a handle from an implementation + */ + ImageChannelControl( Internal::ImageChannelControl& implementation ); + + /** + * Allow the creation of an ImageChannelControl handle from an internal CustomActor pointer + */ + ImageChannelControl( Dali::Internal::CustomActor* internal ); +}; + +} // namespace Demo + +#endif // DALI_DEMO_IMAGE_CHANNEL_CONTROL_H diff --git a/examples/styling/style-example.cpp b/examples/styling/style-example.cpp new file mode 100644 index 0000000..cbdecf6 --- /dev/null +++ b/examples/styling/style-example.cpp @@ -0,0 +1,53 @@ +/* + * 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. + */ + +/** + * @file style-example.cpp + * @brief Example of styling Toolkit controls. + */ + +// External includes +#include + +// Internal includes +#include "styling-application.h" + + +/// Entry point for applications +int DALI_EXPORT_API main( int argc, char** argv ) +{ + const char* themeName = Demo::StylingApplication::DEMO_THEME_ONE_PATH; + + if( argc > 1 ) + { + int theme = atoi(argv[1]); + if( theme == 2 ) + { + themeName = Demo::StylingApplication::DEMO_THEME_TWO_PATH; + } + else if( theme == 3 ) + { + themeName = Demo::StylingApplication::DEMO_THEME_THREE_PATH; + } + } + + Application application = Application::New( &argc, &argv, themeName ); + { + Demo::StylingApplication stylingApplication( application ); + application.MainLoop(); + } + return 0; +} diff --git a/examples/styling/styling-application.cpp b/examples/styling/styling-application.cpp new file mode 100644 index 0000000..b37279c --- /dev/null +++ b/examples/styling/styling-application.cpp @@ -0,0 +1,641 @@ +/* + * 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. + */ + +/** + * @file style-example.cpp + * @brief Example of styling Toolkit controls. + */ + +// Class include +#include "styling-application.h" + +// External includes +#include +//#include +#include +#include "image-channel-control.h" +#include +#include + +// Internal includes + +using namespace Dali; +using namespace Dali::Toolkit; + +namespace Demo +{ + +const char* StylingApplication::DEMO_THEME_ONE_PATH( DEMO_STYLE_DIR "style-example-theme-one.json" ); +const char* StylingApplication::DEMO_THEME_TWO_PATH( DEMO_STYLE_DIR "style-example-theme-two.json" ); +const char* StylingApplication::DEMO_THEME_THREE_PATH( DEMO_STYLE_DIR "style-example-theme-three.json" ); + +namespace +{ +#define DP(x) x + +const char* DEFAULT_CONTROL_AREA_IMAGE_PATH( DEMO_IMAGE_DIR "popup_button_background.9.png" ); + +const char* POPUP_CONTROL_OK_NAME( "PopupControlOk" ); +const char* POPUP_CONTROL_CANCEL_NAME( "PopupControlCancel" ); +const char* BORDER_IMAGE( DEMO_IMAGE_DIR "border-4px.9.png" ); +const char* RESIZE_HANDLE_IMAGE( DEMO_IMAGE_DIR "resize-handle.png" ); + +const int NUMBER_OF_THEMES(3); // The default theme is considered. + +const Vector4 BACKGROUND_COLOUR( 1.0f, 1.0f, 1.0f, 0.15f ); +const int BORDER_WIDTH( 4 ); + +const char* const SMALL_IMAGE_1 = DEMO_IMAGE_DIR "gallery-small-14.jpg"; +const char* const BIG_IMAGE_1 = DEMO_IMAGE_DIR "gallery-large-4.jpg"; + +const char* const SMALL_IMAGE_2 = DEMO_IMAGE_DIR "gallery-small-39.jpg"; +const char* const BIG_IMAGE_2 = DEMO_IMAGE_DIR "gallery-large-7.jpg"; + +const char* const SMALL_IMAGE_3 = DEMO_IMAGE_DIR "gallery-small-20.jpg"; +const char* const BIG_IMAGE_3 = DEMO_IMAGE_DIR "gallery-large-11.jpg"; + +// Layout +const int MARGIN_SIZE = 10; + +const int RADIO_LABEL_THUMBNAIL_SIZE = 60; +const int RADIO_LABEL_THUMBNAIL_SIZE_SMALL = 40; +const int RADIO_IMAGE_SPACING = 8; +const int BUTTON_HEIGHT = 48; + +Property::Index GetChannelProperty( int index ) +{ + Property::Index channelIndex = Property::INVALID_INDEX; + switch(index) + { + case 0: { channelIndex = ImageChannelControl::Property::RED_CHANNEL; break; } + case 1: { channelIndex = ImageChannelControl::Property::GREEN_CHANNEL; break; } + case 2: { channelIndex = ImageChannelControl::Property::BLUE_CHANNEL; break; } + } + return channelIndex; +} + +} // anonymous namespace + + + +StylingApplication::StylingApplication( Application& application ) +: mApplication( application ) +{ + application.InitSignal().Connect( this, &StylingApplication::Create ); +} + +StylingApplication::~StylingApplication() +{ +} + +void StylingApplication::Create( Application& application ) +{ + Stage stage = Stage::GetCurrent(); + stage.KeyEventSignal().Connect(this, &StylingApplication::OnKeyEvent); + stage.SetBackgroundColor( Vector4( 0.1f, 0.1f, 0.1f, 1.0f ) ); + + // Hide the indicator bar + application.GetWindow().ShowIndicator( Dali::Window::INVISIBLE ); + + mContentPane = CreateContentPane(); + stage.Add( mContentPane ); + mContentPane.SetSize( stage.GetSize() ); + + // Content panes: + TableView contentLayout = TableView::New( 5, 1 ); + contentLayout.SetName("ContentLayout"); + contentLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); + contentLayout.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + contentLayout.SetParentOrigin( ParentOrigin::TOP_LEFT ); + contentLayout.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE ) ); + + // Assign all rows the size negotiation property of fitting to children + for( unsigned int i = 0; i < contentLayout.GetRows(); ++i ) + { + if( i != 1 ) + { + contentLayout.SetFitHeight(i); // Row 1 should fill + } + } + + mContentPane.Add( contentLayout ); + + mTitle = TextLabel::New( "Styling Example" ); + mTitle.SetName( "Title" ); + mTitle.SetStyleName("title"); + mTitle.SetAnchorPoint( AnchorPoint::TOP_CENTER ); + mTitle.SetParentOrigin( ParentOrigin::TOP_CENTER ); + mTitle.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); + mTitle.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT ); + mTitle.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" ); + contentLayout.Add( mTitle ); + + // Buttons: + + TableView imageSelectLayout = TableView::New( 1, 2 ); + imageSelectLayout.SetName("ImageSelectLayout"); + + imageSelectLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); + imageSelectLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT ); + imageSelectLayout.SetAnchorPoint( AnchorPoint::CENTER ); + imageSelectLayout.SetParentOrigin( ParentOrigin::CENTER ); + imageSelectLayout.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE ) ); + + // Fit radio button column to child width, leave image to fill remainder + imageSelectLayout.SetFitWidth( 0 ); + + contentLayout.Add( imageSelectLayout ); + + TableView radioButtonsLayout = TableView::New( 3, 2 ); + radioButtonsLayout.SetName("RadioButtonsLayout"); + radioButtonsLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT ); + // Leave each row to fill to parent height + // Set each column to fit to child width + radioButtonsLayout.SetFitWidth(0); + radioButtonsLayout.SetFitWidth(1); + radioButtonsLayout.SetCellPadding( Vector2( 6.0f, 0.0f ) ); + + imageSelectLayout.AddChild( radioButtonsLayout, TableView::CellPosition(0, 0) ); + imageSelectLayout.SetCellAlignment( TableView::CellPosition( 0, 0 ), HorizontalAlignment::LEFT, VerticalAlignment::CENTER ); + + const char* images[] = { SMALL_IMAGE_1, SMALL_IMAGE_2, SMALL_IMAGE_3 }; + + for( int i=0; i<3; ++i ) + { + std::ostringstream thumbnailName; thumbnailName << "thumbnail" << i+1; + ImageView image = ImageView::New( ResourceImage::New( images[i] ) ); + image.SetName( thumbnailName.str() ); + image.SetSize( DP(RADIO_LABEL_THUMBNAIL_SIZE), DP(RADIO_LABEL_THUMBNAIL_SIZE) ); + + std::ostringstream label; label << (i+1); + std::ostringstream radioButtonStyleName; + radioButtonStyleName << "imageSelectButton" << i+1; + mRadioButtons[i] = RadioButton::New( label.str() ); + mRadioButtons[i].SetName( radioButtonStyleName.str() ); + mRadioButtons[i].SetParentOrigin( ParentOrigin::TOP_LEFT ); + mRadioButtons[i].SetAnchorPoint( AnchorPoint::TOP_LEFT ); + mRadioButtons[i].SetSelected( false ); + mRadioButtons[i].StateChangedSignal().Connect( this, &StylingApplication::OnButtonStateChange ); + + radioButtonsLayout.AddChild( mRadioButtons[i], TableView::CellPosition( i, 0 ) ); + radioButtonsLayout.AddChild( image, TableView::CellPosition( i, 1 ) ); + radioButtonsLayout.SetCellAlignment( TableView::CellPosition( i, 0 ), HorizontalAlignment::CENTER, VerticalAlignment::CENTER ); + radioButtonsLayout.SetCellAlignment( TableView::CellPosition( i, 1 ), HorizontalAlignment::CENTER, VerticalAlignment::CENTER ); + } + + mRadioButtons[0].SetSelected( true ); + + mImageChannelControl = ImageChannelControl::New( BIG_IMAGE_1 ); + mImageChannelControl.SetName("ImageChannelControl"); + mImageChannelControl.SetResizePolicy( ResizePolicy::FILL_TO_PARENT , Dimension::ALL_DIMENSIONS ); + mImageChannelControl.SetSizeScalePolicy( SizeScalePolicy::FIT_WITH_ASPECT_RATIO ); + imageSelectLayout.AddChild( mImageChannelControl, TableView::CellPosition( 0, 1 ) ); + + imageSelectLayout.SetCellAlignment( TableView::CellPosition( 0, 1 ), HorizontalAlignment::RIGHT, VerticalAlignment::CENTER ); + + + TableView channelSliderLayout = TableView::New( 3, 3 ); + channelSliderLayout.SetName("ChannelSliderLayout"); + + // Contains a column of check buttons and a column of sliders for R/G/B + channelSliderLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); + channelSliderLayout.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT ); + channelSliderLayout.SetAnchorPoint( AnchorPoint::CENTER ); + channelSliderLayout.SetParentOrigin( ParentOrigin::CENTER ); + channelSliderLayout.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE ) ); + + // Set each row to fit to child height + channelSliderLayout.SetFitHeight( 0 ); + channelSliderLayout.SetFitHeight( 1 ); + channelSliderLayout.SetFitHeight( 2 ); + + // Set each column to fit to child width + channelSliderLayout.SetFitWidth( 0 ); + channelSliderLayout.SetFitWidth( 1 ); + + contentLayout.Add( channelSliderLayout ); + const char *checkboxLabels[3] = {"R", "G", "B"}; + + for( int i=0; i<3; ++i ) + { + std::ostringstream checkBoxStyleName; + checkBoxStyleName << "channelActiveCheckBox" << i+1; + mCheckButtons[i] = CheckBoxButton::New(); + mCheckButtons[i].SetName( checkBoxStyleName.str() ); + mCheckButtons[i].SetParentOrigin( ParentOrigin::CENTER ); + mCheckButtons[i].SetAnchorPoint( AnchorPoint::CENTER ); + mCheckButtons[i].SetSelected( true ); + + mCheckButtons[i].StateChangedSignal().Connect( this, &StylingApplication::OnCheckButtonChange ); + mCheckButtons[i].RegisterProperty( "channel", i, Property::READ_WRITE ); + + channelSliderLayout.AddChild( mCheckButtons[i], TableView::CellPosition( i, 0 ) ); + channelSliderLayout.SetCellAlignment( TableView::CellPosition( i, 0 ), HorizontalAlignment::CENTER, VerticalAlignment::CENTER ); + + TextLabel label = TextLabel::New( checkboxLabels[i] ); + std::ostringstream labelStyleName; labelStyleName << "colorLabel" << i+1; + label.SetName( labelStyleName.str() ); + label.SetStyleName( labelStyleName.str() ); + label.SetParentOrigin( ParentOrigin::CENTER ); + label.SetAnchorPoint ( AnchorPoint::CENTER ); + label.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::WIDTH ); + label.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT ); + + channelSliderLayout.AddChild( label, TableView::CellPosition( i, 1 ) ); + channelSliderLayout.SetCellAlignment( TableView::CellPosition( i, 1 ), HorizontalAlignment::CENTER, VerticalAlignment::CENTER ); + + mChannelSliders[i] = Slider::New(); + std::ostringstream sliderStyleName; sliderStyleName << "colorSlider" << i+1; + mChannelSliders[i].SetName( sliderStyleName.str() ); + mChannelSliders[i].SetStyleName( sliderStyleName.str() ); + mChannelSliders[i].SetParentOrigin( ParentOrigin::CENTER ); + mChannelSliders[i].SetAnchorPoint ( AnchorPoint::CENTER ); + mChannelSliders[i].SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); + mChannelSliders[i].SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN , Dimension::HEIGHT ); + mChannelSliders[i].SetProperty( Slider::Property::LOWER_BOUND, 0.0f ); + mChannelSliders[i].SetProperty( Slider::Property::UPPER_BOUND, 100.0f ); + mChannelSliders[i].SetProperty( Slider::Property::VALUE_PRECISION, 0 ); + mChannelSliders[i].SetProperty( Slider::Property::VALUE, 100.0f ); + mChannelSliders[i].SetProperty( Slider::Property::SHOW_POPUP, true ); + mChannelSliders[i].SetProperty( Slider::Property::SHOW_VALUE, true ); + + mChannelSliders[i].RegisterProperty( "channel", i, Property::READ_WRITE ); + + channelSliderLayout.AddChild( mChannelSliders[i], TableView::CellPosition( i, 2 ) ); + channelSliderLayout.SetCellAlignment( TableView::CellPosition( i, 2 ), HorizontalAlignment::RIGHT, VerticalAlignment::CENTER ); + + mChannelSliders[i].ValueChangedSignal().Connect( this, &StylingApplication::OnSliderChanged ); + } + + mResetButton = PushButton::New(); + mResetButton.SetLabelText( "Reset" ); + mResetButton.SetName("ResetButton"); + mResetButton.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS ); + mResetButton.ClickedSignal().Connect( this, &StylingApplication::OnResetClicked ); + + contentLayout.Add( mResetButton ); + contentLayout.SetCellAlignment( TableView::CellPosition( 3, 0 ), HorizontalAlignment::CENTER, VerticalAlignment::CENTER ); + + TableView themeButtonLayout = TableView::New( 1, 4 ); + themeButtonLayout.SetName("ThemeButtonsLayout"); + themeButtonLayout.SetCellPadding( Vector2( 6.0f, 0.0f ) ); + + themeButtonLayout.SetAnchorPoint( AnchorPoint::CENTER ); + themeButtonLayout.SetParentOrigin( ParentOrigin::CENTER ); + themeButtonLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); + themeButtonLayout.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::HEIGHT ); + themeButtonLayout.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE ) ); + themeButtonLayout.SetFitHeight( 0 ); + + TextLabel label = TextLabel::New( "Theme: "); + label.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS ); + label.SetStyleName("themelabel"); + label.SetAnchorPoint( AnchorPoint::TOP_CENTER ); + label.SetParentOrigin( ParentOrigin::TOP_CENTER ); + themeButtonLayout.AddChild( label, TableView::CellPosition( 0, 0 ) ); + themeButtonLayout.SetCellAlignment( TableView::CellPosition( 0, 0 ), HorizontalAlignment::LEFT, VerticalAlignment::CENTER ); + + for( int i=0; i<3; ++i ) + { + mThemeButtons[i] = PushButton::New(); + mThemeButtons[i].SetName("ThemeButton"); + mThemeButtons[i].SetStyleName("ThemeButton"); + mThemeButtons[i].SetParentOrigin( ParentOrigin::CENTER ); + mThemeButtons[i].SetAnchorPoint( ParentOrigin::CENTER ); + mThemeButtons[i].SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); + mThemeButtons[i].SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT ); + mThemeButtons[i].RegisterProperty( "theme", i, Property::READ_WRITE ); + mThemeButtons[i].ClickedSignal().Connect( this, &StylingApplication::OnThemeButtonClicked ); + themeButtonLayout.AddChild( mThemeButtons[i], TableView::CellPosition( 0, 1+i ) ); + } + mThemeButtons[0].SetLabelText( "Lite" ); // Lightweight changes on top of Dali + mThemeButtons[1].SetLabelText( "App1" ); // Different application style + mThemeButtons[2].SetLabelText( "App2" ); + + contentLayout.Add( themeButtonLayout ); +} + +Actor StylingApplication::CreateContentPane() +{ + Toolkit::ImageView contentPane = Toolkit::ImageView::New( BORDER_IMAGE ); + contentPane.SetName("ContentPane"); + contentPane.SetParentOrigin( ParentOrigin::CENTER ); + contentPane.SetAnchorPoint( AnchorPoint::CENTER ); + contentPane.SetPadding( Padding( BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH ) ); + return contentPane; +} + +Actor StylingApplication::CreateResizableContentPane() +{ + Toolkit::ImageView contentPane = Toolkit::ImageView::New( BORDER_IMAGE ); + contentPane.SetName("ContentPane"); + contentPane.SetParentOrigin( ParentOrigin::CENTER ); + contentPane.SetAnchorPoint( AnchorPoint::CENTER ); + contentPane.SetPadding( Padding( BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH, BORDER_WIDTH ) ); + + Toolkit::ImageView grabHandle = Toolkit::ImageView::New( RESIZE_HANDLE_IMAGE ); + grabHandle.SetName("GrabHandle"); + grabHandle.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS ); + grabHandle.SetParentOrigin( ParentOrigin::BOTTOM_RIGHT ); + grabHandle.SetAnchorPoint( AnchorPoint::BOTTOM_RIGHT ); + grabHandle.SetPosition( -BORDER_WIDTH, -BORDER_WIDTH ); + grabHandle.SetOpacity( 0.6f ); + + Layer grabCornerLayer = Layer::New(); + grabCornerLayer.SetName("GrabCornerLayer"); + grabCornerLayer.SetParentOrigin( ParentOrigin::BOTTOM_RIGHT ); + grabCornerLayer.SetAnchorPoint( AnchorPoint::BOTTOM_RIGHT ); + grabCornerLayer.Add( grabHandle ); + contentPane.Add( grabCornerLayer ); + + mPanGestureDetector = PanGestureDetector::New(); + mPanGestureDetector.Attach( grabHandle ); + mPanGestureDetector.DetectedSignal().Connect( this, &StylingApplication::OnPan ); + + return contentPane; +} + +Popup StylingApplication::CreateResetPopup() +{ + Stage stage = Stage::GetCurrent(); + + Popup popup= Popup::New(); + popup.SetName("ResetPopup"); + popup.SetStyleName("ResetPopup"); + popup.SetParentOrigin( ParentOrigin::CENTER ); + popup.SetAnchorPoint( AnchorPoint::CENTER ); + popup.SetSize( stage.GetSize().width * 0.75f, 0.0f ); + popup.SetProperty( Popup::Property::TAIL_VISIBILITY, false ); + popup.OutsideTouchedSignal().Connect( this, &StylingApplication::HidePopup ); + popup.HiddenSignal().Connect( this, &StylingApplication::PopupHidden ); + + popup.SetTitle( CreateTitle( "Reset channels" ) ); + + TextLabel text = TextLabel::New( "This will reset the channel data to full value. Are you sure?" ); + text.SetName( "PopupContentText" ); + text.SetStyleName( "popupBody" ); + text.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); + text.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT ); + text.SetProperty( TextLabel::Property::MULTI_LINE, true ); + text.SetPadding( Padding( 10.0f, 10.0f, 20.0f, 0.0f ) ); + popup.SetContent( text ); + + ImageView footer = ImageView::New( DEFAULT_CONTROL_AREA_IMAGE_PATH ); + footer.SetName( "PopupFooter" ); + footer.SetStyleName( "PopupFooter" ); + footer.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH ); + footer.SetResizePolicy( ResizePolicy::FIXED, Dimension::HEIGHT ); + footer.SetSize( 0.0f, 80.0f ); + footer.SetAnchorPoint( AnchorPoint::CENTER ); + footer.SetParentOrigin( ParentOrigin::CENTER ); + + TableView footerLayout = TableView::New( 1, 2 ); + footerLayout.SetParentOrigin( ParentOrigin::CENTER ); + footerLayout.SetAnchorPoint ( AnchorPoint::CENTER ); + footerLayout.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); + + PushButton okayButton = PushButton::New(); + okayButton.SetName( POPUP_CONTROL_OK_NAME ); + okayButton.SetStyleName( POPUP_CONTROL_OK_NAME ); + okayButton.SetLabelText( "Ok!" ); + okayButton.ClickedSignal().Connect( this, &StylingApplication::OnReset ); + okayButton.SetParentOrigin( ParentOrigin::CENTER ); + okayButton.SetAnchorPoint( AnchorPoint::CENTER ); + okayButton.SetResizePolicy( ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS ); + okayButton.SetSizeModeFactor( Vector3( -20.0f, -20.0f, 0.0f ) ); + + PushButton cancelButton = PushButton::New(); + cancelButton.SetName( POPUP_CONTROL_CANCEL_NAME ); + cancelButton.SetStyleName( POPUP_CONTROL_CANCEL_NAME ); + cancelButton.SetLabelText( "Cancel" ); + cancelButton.ClickedSignal().Connect( this, &StylingApplication::OnResetCancelled ); + cancelButton.SetParentOrigin( ParentOrigin::CENTER ); + cancelButton.SetAnchorPoint( AnchorPoint::CENTER ); + cancelButton.SetResizePolicy( ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS ); + cancelButton.SetSizeModeFactor( Vector3( -20.0f, -20.0f, 0.0f ) ); + + footerLayout.SetCellAlignment( TableView::CellPosition( 0, 0 ), HorizontalAlignment::CENTER, VerticalAlignment::CENTER ); + footerLayout.SetCellAlignment( TableView::CellPosition( 0, 1 ), HorizontalAlignment::CENTER, VerticalAlignment::CENTER ); + footerLayout.AddChild( okayButton, TableView::CellPosition( 0, 0 ) ); + footerLayout.AddChild( cancelButton, TableView::CellPosition( 0, 1 ) ); + footerLayout.SetCellPadding( Size( 10.f, 10.f ) ); + footer.Add( footerLayout ); + + popup.SetFooter( footer ); + return popup; +} + +TextLabel StylingApplication::CreateTitle( std::string title ) +{ + TextLabel titleActor = TextLabel::New( title ); + titleActor.SetName( "titleActor" ); + titleActor.SetStyleName( "popupTitle" ); + titleActor.SetProperty( TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" ); + titleActor.SetProperty( TextLabel::Property::MULTI_LINE, false ); + + return titleActor; +} + +bool StylingApplication::OnButtonStateChange( Button button ) +{ + // Todo: save / restore slider states per image + + if( mImageChannelControl ) + { + if( mRadioButtons[0].IsSelected() ) + { + mImageChannelControl.SetImage( BIG_IMAGE_1 ); + } + else if( mRadioButtons[1].IsSelected() ) + { + mImageChannelControl.SetImage( BIG_IMAGE_2 ); + } + else if( mRadioButtons[2].IsSelected() ) + { + mImageChannelControl.SetImage( BIG_IMAGE_3 ); + } + } + return true; +} + +bool StylingApplication::OnCheckButtonChange( Button button ) +{ + Property::Index index = button.GetPropertyIndex("channel"); + if( index != Property::INVALID_INDEX ) + { + int channel = button.GetProperty( index ); + float value = mChannelSliders[channel].GetProperty( Slider::Property::VALUE ); + if( !button.IsSelected() ) + { + // "Turn off" the channel's contribution + value = 0.0f; + } + Property::Index channelIndex = GetChannelProperty( channel ); + mImageChannelControl.SetProperty(channelIndex, value/100.0f); + } + return true; +} + +bool StylingApplication::OnThemeButtonClicked( Button button ) +{ + int theme = button.GetProperty(button.GetPropertyIndex("theme")); + const char* themePath=NULL; + + switch( theme ) + { + case 0: + { + themePath = DEMO_THEME_ONE_PATH; + break; + } + case 1: + { + themePath = DEMO_THEME_TWO_PATH; + break; + } + case 2: + { + themePath = DEMO_THEME_THREE_PATH; + break; + } + } + StyleManager::Get().ApplyTheme( themePath ); + + return true; +} + +bool StylingApplication::OnResetClicked( Button button ) +{ + if( ! mResetPopup ) + { + mResetPopup = CreateResetPopup (); + } + + Stage::GetCurrent().Add( mResetPopup ); + + mResetPopup.SetDisplayState( Popup::SHOWN ); + return true; +} + +bool StylingApplication::OnReset( Button button ) +{ + // todo: Reset the sliders for this image + for( int i=0; i<3; ++i ) + { + mChannelSliders[i].SetProperty( Slider::Property::VALUE, 100.0f ); + } + HidePopup(); + return true; +} + +bool StylingApplication::OnResetCancelled( Button button ) +{ + HidePopup(); + return true; +} + +bool StylingApplication::OnSliderChanged( Slider slider, float value ) +{ + // todo - change color channel's saturation + Property::Index index = slider.GetPropertyIndex("channel"); + if( index != Property::INVALID_INDEX ) + { + int channel = slider.GetProperty( index ); + if( mCheckButtons[channel].IsSelected() ) + { + Property::Index channelIndex = GetChannelProperty( channel ); + mImageChannelControl.SetProperty(channelIndex, value/100.0f); + } + } + return true; +} + +void StylingApplication::HidePopup() +{ + if( mResetPopup ) + { + mResetPopup.SetDisplayState( Popup::HIDDEN ); + } +} + +void StylingApplication::PopupHidden() +{ + if( mResetPopup ) + { + // Clear down resources + mResetPopup.Unparent(); + mResetPopup.Reset(); + } +} + +void StylingApplication::OnPan( Actor actor, const PanGesture& gesture ) +{ + Vector3 size = mContentPane.GetTargetSize(); + mContentPane.SetSize( size.GetVectorXY() + gesture.displacement * 2.0f ); +} + +void StylingApplication::OnKeyEvent( const KeyEvent& keyEvent ) +{ + static int keyPressed = 0; + + if( keyEvent.state == KeyEvent::Down) + { + if( keyPressed == 0 ) // Is this the first down event? + { + printf("Key pressed: %s %d\n", keyEvent.keyPressedName.c_str(), keyEvent.keyCode ); + + if( IsKey( keyEvent, DALI_KEY_ESCAPE) || IsKey( keyEvent, DALI_KEY_BACK ) ) + { + mApplication.Quit(); + } + else if( keyEvent.keyPressedName.compare("Return") == 0 ) + { + mCurrentTheme++; + mCurrentTheme %= NUMBER_OF_THEMES; + + StyleManager styleManager = StyleManager::Get(); + switch( mCurrentTheme ) + { + case 0: + { + styleManager.ApplyTheme( DEMO_THEME_ONE_PATH ); + printf("Changing to theme One\n"); + break; + } + case 1: + { + styleManager.ApplyTheme( DEMO_THEME_TWO_PATH ); + printf("Changing to theme Two\n"); + break; + } + case 2: + { + styleManager.ApplyDefaultTheme(); + printf("Changing to Toolkit theme\n"); + break; + } + } + } + } + keyPressed = 1; + } + else if( keyEvent.state == KeyEvent::Up ) + { + keyPressed = 0; + } +} + +} // namespace Demo diff --git a/examples/styling/styling-application.h b/examples/styling/styling-application.h new file mode 100644 index 0000000..8dbb395 --- /dev/null +++ b/examples/styling/styling-application.h @@ -0,0 +1,97 @@ +#ifndef DALI_DEMO_STYLING_APPLICATION_H +#define DALI_DEMO_STYLING_APPLICATION_H + +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// External includes +#include +//#include +#include +#include "image-channel-control.h" +#include +#include + +// Internal includes + +using namespace Dali; +using namespace Dali::Toolkit; + +namespace Demo +{ + +class StylingApplication : public ConnectionTracker +{ +public: + // Constructor + StylingApplication( Application& application ); + + // Destructor + ~StylingApplication(); + + // Init signal handler + void Create( Application& application ); + + // Create the GUI components + Actor CreateContentPane(); + Actor CreateResizableContentPane(); + Toolkit::Popup CreateResetPopup(); + Toolkit::TextLabel CreateTitle( std::string title ); + + // Key event handler + void OnKeyEvent( const KeyEvent& event ); + + // Button event handlers + bool OnButtonStateChange( Toolkit::Button button ); + bool OnCheckButtonChange( Toolkit::Button button ); + bool OnResetClicked( Toolkit::Button button ); + bool OnThemeButtonClicked( Toolkit::Button button ); + + // Slider event handler + bool OnSliderChanged( Toolkit::Slider slider, float value ); + + // Popup event handlers + void HidePopup(); + void PopupHidden(); + bool OnReset(Button button); + bool OnResetCancelled(Button button); + + // Grab handle handler + void OnPan( Actor actor, const PanGesture& gesture ); + + static const char* DEMO_THEME_ONE_PATH; + static const char* DEMO_THEME_TWO_PATH; + static const char* DEMO_THEME_THREE_PATH; + +private: + Application& mApplication; + int mCurrentTheme; + Actor mContentPane; + TextLabel mTitle; + RadioButton mRadioButtons[3]; // 3 demo images + CheckBoxButton mCheckButtons[3]; // rgb buttons + Slider mChannelSliders[3]; // rgb sliders + PushButton mThemeButtons[3]; + PushButton mResetButton; + ImageChannelControl mImageChannelControl; + Popup mResetPopup; + PanGestureDetector mPanGestureDetector; +}; + +} // Namespace Demo + + +#endif // DALI_DEMO_STYLING_APPLICATION_H diff --git a/packaging/com.samsung.dali-demo.spec b/packaging/com.samsung.dali-demo.spec index 5b604dc..cbf8e0f 100755 --- a/packaging/com.samsung.dali-demo.spec +++ b/packaging/com.samsung.dali-demo.spec @@ -138,6 +138,7 @@ exit 0 %{dali_app_ro_dir}/models/* %{dali_app_ro_dir}/scripts/* %{dali_app_ro_dir}/style/* +%{dali_app_ro_dir}/style/images/* %{dali_xml_file_dir}/%{name}.xml %{dali_icon_dir}/* %{locale_dir}/* diff --git a/resources/po/as.po b/resources/po/as.po index 3d30f88..5accc36 100755 --- a/resources/po/as.po +++ b/resources/po/as.po @@ -106,6 +106,9 @@ msgstr "লিপি" msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW" msgstr "স্ক্ৰ'ল কৰক" +msgid "DALI_DEMO_STR_TITLE_STYLING" +msgstr "শৈলী" + msgid "DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM" msgstr "অস্পষ্টকৈ অপুষ্পক" @@ -128,4 +131,4 @@ msgid "DALI_DEMO_STR_TITLE_TEXT_SCROLLING" msgstr "অকনিষ্ঠ অৰ্জুন বঁটা" msgid "DALI_DEMO_STR_TITLE_TILT_SENSOR" -msgstr "টিল্ট অনুভূতি" \ No newline at end of file +msgstr "টিল্ট অনুভূতি" diff --git a/resources/po/de.po b/resources/po/de.po index 8524b05..0aea6b5 100755 --- a/resources/po/de.po +++ b/resources/po/de.po @@ -106,6 +106,9 @@ msgstr "Scripting" msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW" msgstr "Scroll-Ansicht" +msgid "DALI_DEMO_STR_TITLE_STYLING" +msgstr "Styling" + msgid "DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM" msgstr "Unschärfe und blühen" diff --git a/resources/po/en_GB.po b/resources/po/en_GB.po index 3cbc74c..a62e46a 100755 --- a/resources/po/en_GB.po +++ b/resources/po/en_GB.po @@ -106,6 +106,9 @@ msgstr "Script-based UI" msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW" msgstr "Scroll View" +msgid "DALI_DEMO_STR_TITLE_STYLING" +msgstr "Styling" + msgid "DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM" msgstr "Super Blur and Bloom" diff --git a/resources/po/en_US.po b/resources/po/en_US.po index aab93ba..217b42f 100755 --- a/resources/po/en_US.po +++ b/resources/po/en_US.po @@ -106,6 +106,9 @@ msgstr "Script-based UI" msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW" msgstr "Scroll View" +msgid "DALI_DEMO_STR_TITLE_STYLING" +msgstr "Styling" + msgid "DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM" msgstr "Super Blur and Bloom" diff --git a/resources/po/es.po b/resources/po/es.po index d3216e8..3611ed6 100755 --- a/resources/po/es.po +++ b/resources/po/es.po @@ -106,6 +106,9 @@ msgstr "Interfaz definida por Script" msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW" msgstr "Vista de desplazamiento" +msgid "DALI_DEMO_STR_TITLE_STYLING" +msgstr "Estilo" + msgid "DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM" msgstr "Efecto blur y bloom" diff --git a/resources/po/ko.po b/resources/po/ko.po index b7cdee7..8e1bac0 100755 --- a/resources/po/ko.po +++ b/resources/po/ko.po @@ -106,6 +106,9 @@ msgstr "스크립팅" msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW" msgstr "스크롤 뷰" +msgid "DALI_DEMO_STR_TITLE_STYLING" +msgstr "" + msgid "DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM" msgstr "" diff --git a/resources/po/ml.po b/resources/po/ml.po index 1f477a5..eabc095 100755 --- a/resources/po/ml.po +++ b/resources/po/ml.po @@ -106,6 +106,9 @@ msgstr "സ്ക്രിപ്റ്റ്" msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW" msgstr "സ്ക്രോള്ചെയ്യുക കാഴ്ച" +msgid "DALI_DEMO_STR_TITLE_STYLING" +msgstr "ശൈലി" + msgid "DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM" msgstr "മങ്ങൽ പൂക്കൽ" diff --git a/resources/po/ur.po b/resources/po/ur.po index 935a8ab..a3b8d12 100755 --- a/resources/po/ur.po +++ b/resources/po/ur.po @@ -106,6 +106,9 @@ msgstr "سکرپٹ" msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW" msgstr "سکرول ویو" +msgid "DALI_DEMO_STR_TITLE_STYLING" +msgstr "سٹائل" + msgid "DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM" msgstr "دھندلاپن اور بلوم" diff --git a/resources/po/zn_CH.po b/resources/po/zn_CH.po index 17c43ab..c340d63 100755 --- a/resources/po/zn_CH.po +++ b/resources/po/zn_CH.po @@ -106,6 +106,9 @@ msgstr "脚本用户界面" msgid "DALI_DEMO_STR_TITLE_SCROLL_VIEW" msgstr "滚动视图" +msgid "DALI_DEMO_STR_TITLE_STYLING" +msgstr "样式" + msgid "DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM" msgstr "模糊及泛光" diff --git a/resources/style/.gitignore b/resources/style/.gitignore new file mode 100644 index 0000000..59620cc --- /dev/null +++ b/resources/style/.gitignore @@ -0,0 +1,4 @@ +demo-theme.json +style-example-theme-three.json +style-example-theme-two.json +style-example-theme-one.json diff --git a/resources/style/images/.gitignore b/resources/style/images/.gitignore new file mode 100644 index 0000000..01b9fd9 --- /dev/null +++ b/resources/style/images/.gitignore @@ -0,0 +1 @@ +*.xcf diff --git a/resources/style/images/radio-button-selected.png b/resources/style/images/radio-button-selected.png new file mode 100644 index 0000000000000000000000000000000000000000..96411bcd1c1c5314362a0adea1526813a4e50026 GIT binary patch literal 3825 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 literal 0 HcmV?d00001 diff --git a/resources/style/images/radio-button-unselected.png b/resources/style/images/radio-button-unselected.png new file mode 100644 index 0000000000000000000000000000000000000000..bdf4abd8e854b94060961a79e1a17428414099af GIT binary patch literal 3148 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 literal 0 HcmV?d00001 diff --git a/resources/style/images/slider-skin-progress-green.9.png b/resources/style/images/slider-skin-progress-green.9.png new file mode 100644 index 0000000000000000000000000000000000000000..6738075da5cf112d75cc796991796709ceaca2de GIT binary patch literal 425 zcmV;a0apHrP)I%J~0pG_g^Iq8S<;Ok`<>#3S(lP4gcO3N$l_Q=<7L1)5oIP-62b zvNbdQXF0&Y#6q6tD|TCU{!-I9Pp-2W*sh%@`L3+|n=H*&?T_pe6gAoKRaTmG%?u0- z3};zW!xZI%j{nv+B3&~B0|Uc;Mt>_CuCQHFHhKSW1tP&RY~|yJ#ZTFP7k^;+Be`Ah z6vNw>ry1Dq-(t9Kxs#ER*pOZQ@L`qoTSi|o0WNhBVJFdh=fK@?{q1#7%54Kf7|}2CkPyTZlspumzwe;`jmr%a@bh`d!rSC!V`R6 zEc`Y9VZO=6z}B?S{_HvH6tCS(TcRRla<<-7K0JheBj zoRz!o?X8vH-GAEbJeOv1xN4=#`{`HmH<{dywcgx6JwCtrmcQa9Q)2@ln75WwcFVdQ&MBb@0I+4JTL1t6 literal 0 HcmV?d00001 diff --git a/resources/style/mobile/images/radio-button-selected.png b/resources/style/mobile/images/radio-button-selected.png new file mode 100644 index 0000000000000000000000000000000000000000..96411bcd1c1c5314362a0adea1526813a4e50026 GIT binary patch literal 3825 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 literal 0 HcmV?d00001 diff --git a/resources/style/mobile/images/radio-button-unselected.png b/resources/style/mobile/images/radio-button-unselected.png new file mode 100644 index 0000000000000000000000000000000000000000..bdf4abd8e854b94060961a79e1a17428414099af GIT binary patch literal 3148 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 literal 0 HcmV?d00001 diff --git a/resources/style/mobile/images/slider-skin-progress-green.9.png b/resources/style/mobile/images/slider-skin-progress-green.9.png new file mode 100644 index 0000000000000000000000000000000000000000..6738075da5cf112d75cc796991796709ceaca2de GIT binary patch literal 425 zcmV;a0apHrP)I%J~0pG_g^Iq8S<;Ok`<>#3S(lP4gcO3N$l_Q=<7L1)5oIP-62b zvNbdQXF0&Y#6q6tD|TCU{!-I9Pp-2W*sh%@`L3+|n=H*&?T_pe6gAoKRaTmG%?u0- z3};zW!xZI%j{nv+B3&~B0|Uc;Mt>_CuCQHFHhKSW1tP&RY~|yJ#ZTFP7k^;+Be`Ah z6vNw>ry1Dq-(t9Kxs#ER*pOZQ@L`qoTSi|o0WNhBVJFdh=fK@?{q1#7%54Kf7|}2CkPyTZlspumzwe;`jmr%a@bh`d!rSC!V`R6 zEc`Y9VZO=6z}B?S{_HvH6tCS(TcRRla<<-7K0JheBj zoRz!o?X8vH-GAEbJeOv1xN4=#`{`HmH<{dywcgx6JwCtrmcQa9Q)2@ln75WwcFVdQ&MBb@0I+4JTL1t6 literal 0 HcmV?d00001 diff --git a/resources/style/mobile/style-example-theme-one.json.in b/resources/style/mobile/style-example-theme-one.json.in new file mode 100644 index 0000000..e84d423 --- /dev/null +++ b/resources/style/mobile/style-example-theme-one.json.in @@ -0,0 +1,67 @@ +{ + "styles": + { + "title":{ + "textColor":"#0000ff", + "background": + { + "visualType":"COLOR", + "mixColor": [ 1.0, 1.0, 1.0, 1.0 ] + } + }, + "tableview":{ + "background": + { + "visualType":"COLOR", + "mixColor": [ 1.0, 1.0, 1.0, 0.03 ] + } + }, + "flexcontainer":{ + "background": + { + "visualType":"COLOR", + "mixColor": [ 1.0, 1.0, 1.0, 0.1 ] + } + }, + "radiobutton":{ + "label":{ + "textColor": [1,1,1,1] + } + }, + "checkboxbutton":{ + "label":{ + "textColor": [1,1,1,1] + } + }, + "colorLabel1":{ + "textColor": [1,0,0,1] + }, + "colorLabel2":{ + "textColor": [0,1,0,1] + }, + "colorLabel3":{ + "textColor": [0.3,0.3,1,1] + }, + "themelabel":{ + "textColor":[0,1,1,1] + }, + "popupTitle":{ + "textColor":[1,1,1,1] + }, + "popupBody":{ + "textColor":[1,1,0,1] + }, + "textlabel":{ + "textColor":[0,0,0,1] + }, + "colorSlider1":{ + "styles":["slider"] + }, + "colorSlider2":{ + "styles":["slider"] + }, + "colorSlider3":{ + "styles":["slider"] + } + } +} diff --git a/resources/style/mobile/style-example-theme-three.json.in b/resources/style/mobile/style-example-theme-three.json.in new file mode 100644 index 0000000..0326e3d --- /dev/null +++ b/resources/style/mobile/style-example-theme-three.json.in @@ -0,0 +1,51 @@ +{ + "styles": + { + "title":{ + "textColor":"#0000ff", + "background": + { + "rendererType":"color", + "mixColor": [ 1.0, 1.0, 1.0, 1.0 ] + } + }, + "tableview":{ + "background": + { + "rendererType":"color", + "mixColor": [ 1.0, 1.0, 1.0, 0.03 ] + } + }, + "radiobutton":{ + "label":{ + "textColor": [1,1,1,1] + } + }, + "checkboxbutton":{ + "label":{ + "textColor": [1,1,1,1] + } + }, + "colorLabel1":{ + "textColor": [1,0,0,1] + }, + "colorLabel2":{ + "textColor": [0,1,0,1] + }, + "colorLabel3":{ + "textColor": [0.3,0.3,1,1] + }, + "themelabel":{ + "textColor":[0,1,1,1] + }, + "popupTitle":{ + "textColor":[1,1,1,1] + }, + "popupBody":{ + "textColor":[1,1,0,1] + }, + "textlabel":{ + "textColor":[0,0,0,1] + } + } +} diff --git a/resources/style/mobile/style-example-theme-two.json.in b/resources/style/mobile/style-example-theme-two.json.in new file mode 100644 index 0000000..884d1ca --- /dev/null +++ b/resources/style/mobile/style-example-theme-two.json.in @@ -0,0 +1,97 @@ +{ + "constants": + { + "DEMO_IMAGE_DIR":"@DEMO_STYLE_IMAGE_DIR@" + }, + "styles": + { + "title":{ + "textColor":"#0000ff", + "background": + { + "visualType":"COLOR", + "mixColor": [ 1.0, 1.0, 1.0, 1.0 ] + } + }, + "tableview":{ + "background": + { + "visualType":"GRADIENT", + "startPosition": [0,-1], + "endPosition": [0,1], + "stopColor": [ [ 1.0, 0.0, 1.0, 0.03 ], [1.0,0.0,1.0,0.15] ] + } + }, + + // Change an icon size, see if it gets properly re-sized + "radiobutton":{ + "unselectedStateImage":"{DEMO_IMAGE_DIR}/radio-button-unselected.png", + "selectedStateImage":"{DEMO_IMAGE_DIR}/radio-button-selected.png", + "disabledStateImage":"{DEMO_IMAGE_DIR}/radio-button-unselected-disabled.png", + "imageLabelGap":10, + "label":{ + "textColor": [0.1,1,1,1] + } + }, + "checkboxbutton":{ + "label":{ + "textColor": [1,1,1,1] + } + }, + "colorLabel1":{ + "textColor": [1,0,0,1] + }, + "colorLabel2":{ + "textColor": [0,1,0,1] + }, + "colorLabel3":{ + "textColor": [0.3,0.3,1,1] + }, + "themelabel":{ + "textColor":[0,1,1,1] + }, + "popupTitle":{ + "textColor":[1,1,1,1] + }, + "popupBody":{ + "textColor":[1,1,0,1] + }, + + // Note, this overrides any non-renamed label styles, e.g. those in a button. + "textlabel":{ + //"textColor":[0,0,0,1] + }, + + "thinslider":{ + "styles": ["slider"], + "showPopup":true, + "showValue":false, + "valuePrecision":0, + "handleVisual":{ + "size":[48,48] + }, + "trackVisual":{ + "size":[10, 10] + }, + "enabled":true + }, + "colorSlider1":{ + "styles":["thinslider"], + "progressVisual":{ + "url":"{DEMO_IMAGE_DIR}/slider-skin-progress-red.9.png" + } + }, + "colorSlider2":{ + "styles":["thinslider"], + "progressVisual":{ + "url":"{DEMO_IMAGE_DIR}/slider-skin-progress-green.9.png" + } + }, + "colorSlider3":{ + "styles":["thinslider"], + "progressVisual":{ + "url":"{DEMO_IMAGE_DIR}/slider-skin-progress-blue.9.png" + } + } + } +} diff --git a/resources/style/style-example-theme-one.json.in b/resources/style/style-example-theme-one.json.in new file mode 100644 index 0000000..e84d423 --- /dev/null +++ b/resources/style/style-example-theme-one.json.in @@ -0,0 +1,67 @@ +{ + "styles": + { + "title":{ + "textColor":"#0000ff", + "background": + { + "visualType":"COLOR", + "mixColor": [ 1.0, 1.0, 1.0, 1.0 ] + } + }, + "tableview":{ + "background": + { + "visualType":"COLOR", + "mixColor": [ 1.0, 1.0, 1.0, 0.03 ] + } + }, + "flexcontainer":{ + "background": + { + "visualType":"COLOR", + "mixColor": [ 1.0, 1.0, 1.0, 0.1 ] + } + }, + "radiobutton":{ + "label":{ + "textColor": [1,1,1,1] + } + }, + "checkboxbutton":{ + "label":{ + "textColor": [1,1,1,1] + } + }, + "colorLabel1":{ + "textColor": [1,0,0,1] + }, + "colorLabel2":{ + "textColor": [0,1,0,1] + }, + "colorLabel3":{ + "textColor": [0.3,0.3,1,1] + }, + "themelabel":{ + "textColor":[0,1,1,1] + }, + "popupTitle":{ + "textColor":[1,1,1,1] + }, + "popupBody":{ + "textColor":[1,1,0,1] + }, + "textlabel":{ + "textColor":[0,0,0,1] + }, + "colorSlider1":{ + "styles":["slider"] + }, + "colorSlider2":{ + "styles":["slider"] + }, + "colorSlider3":{ + "styles":["slider"] + } + } +} diff --git a/resources/style/style-example-theme-three.json.in b/resources/style/style-example-theme-three.json.in new file mode 100644 index 0000000..c50ca22 --- /dev/null +++ b/resources/style/style-example-theme-three.json.in @@ -0,0 +1,51 @@ +{ + "styles": + { + "title":{ + "textColor":"#0000ff", + "background": + { + "visualType":"COLOR", + "mixColor": [ 1.0, 1.0, 1.0, 1.0 ] + } + }, + "tableview":{ + "background": + { + "visualType":"COLOR", + "mixColor": [ 1.0, 1.0, 1.0, 0.03 ] + } + }, + "radiobutton":{ + "label":{ + "textColor": [1,1,1,1] + } + }, + "checkboxbutton":{ + "label":{ + "textColor": [1,1,1,1] + } + }, + "colorLabel1":{ + "textColor": [1,0,0,1] + }, + "colorLabel2":{ + "textColor": [0,1,0,1] + }, + "colorLabel3":{ + "textColor": [0.3,0.3,1,1] + }, + "themelabel":{ + "textColor":[0,1,1,1] + }, + "popupTitle":{ + "textColor":[1,1,1,1] + }, + "popupBody":{ + "textColor":[1,1,0,1] + }, + "textlabel":{ + "textColor":[0,0,0,1] + } + } +} diff --git a/resources/style/style-example-theme-two.json.in b/resources/style/style-example-theme-two.json.in new file mode 100644 index 0000000..884d1ca --- /dev/null +++ b/resources/style/style-example-theme-two.json.in @@ -0,0 +1,97 @@ +{ + "constants": + { + "DEMO_IMAGE_DIR":"@DEMO_STYLE_IMAGE_DIR@" + }, + "styles": + { + "title":{ + "textColor":"#0000ff", + "background": + { + "visualType":"COLOR", + "mixColor": [ 1.0, 1.0, 1.0, 1.0 ] + } + }, + "tableview":{ + "background": + { + "visualType":"GRADIENT", + "startPosition": [0,-1], + "endPosition": [0,1], + "stopColor": [ [ 1.0, 0.0, 1.0, 0.03 ], [1.0,0.0,1.0,0.15] ] + } + }, + + // Change an icon size, see if it gets properly re-sized + "radiobutton":{ + "unselectedStateImage":"{DEMO_IMAGE_DIR}/radio-button-unselected.png", + "selectedStateImage":"{DEMO_IMAGE_DIR}/radio-button-selected.png", + "disabledStateImage":"{DEMO_IMAGE_DIR}/radio-button-unselected-disabled.png", + "imageLabelGap":10, + "label":{ + "textColor": [0.1,1,1,1] + } + }, + "checkboxbutton":{ + "label":{ + "textColor": [1,1,1,1] + } + }, + "colorLabel1":{ + "textColor": [1,0,0,1] + }, + "colorLabel2":{ + "textColor": [0,1,0,1] + }, + "colorLabel3":{ + "textColor": [0.3,0.3,1,1] + }, + "themelabel":{ + "textColor":[0,1,1,1] + }, + "popupTitle":{ + "textColor":[1,1,1,1] + }, + "popupBody":{ + "textColor":[1,1,0,1] + }, + + // Note, this overrides any non-renamed label styles, e.g. those in a button. + "textlabel":{ + //"textColor":[0,0,0,1] + }, + + "thinslider":{ + "styles": ["slider"], + "showPopup":true, + "showValue":false, + "valuePrecision":0, + "handleVisual":{ + "size":[48,48] + }, + "trackVisual":{ + "size":[10, 10] + }, + "enabled":true + }, + "colorSlider1":{ + "styles":["thinslider"], + "progressVisual":{ + "url":"{DEMO_IMAGE_DIR}/slider-skin-progress-red.9.png" + } + }, + "colorSlider2":{ + "styles":["thinslider"], + "progressVisual":{ + "url":"{DEMO_IMAGE_DIR}/slider-skin-progress-green.9.png" + } + }, + "colorSlider3":{ + "styles":["thinslider"], + "progressVisual":{ + "url":"{DEMO_IMAGE_DIR}/slider-skin-progress-blue.9.png" + } + } + } +} diff --git a/shared/dali-demo-strings.h b/shared/dali-demo-strings.h index b1320c2..f191dcb 100644 --- a/shared/dali-demo-strings.h +++ b/shared/dali-demo-strings.h @@ -68,6 +68,7 @@ extern "C" #define DALI_DEMO_STR_TITLE_RENDERER_STENCIL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_RENDERER_STENCIL") #define DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI") #define DALI_DEMO_STR_TITLE_SCROLL_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCROLL_VIEW") +#define DALI_DEMO_STR_TITLE_STYLING dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_STYLING") #define DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM") #define DALI_DEMO_STR_TITLE_TEXTURED_MESH dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXTURED_MESH") #define DALI_DEMO_STR_TITLE_TEXT_EDITOR dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXT_EDITOR") @@ -115,6 +116,7 @@ extern "C" #define DALI_DEMO_STR_TITLE_RENDERER_STENCIL "Renderer Stencils" #define DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI "Script Based UI" #define DALI_DEMO_STR_TITLE_SCROLL_VIEW "Scroll View" +#define DALI_DEMO_STR_TITLE_STYLING "Styling" #define DALI_DEMO_STR_TITLE_SUPER_BLUR_BLOOM "Super Blur and Bloom" #define DALI_DEMO_STR_TITLE_TEXTURED_MESH "Mesh Texture" #define DALI_DEMO_STR_TITLE_TEXT_EDITOR "Text Editor" -- 2.7.4