Commit 1193cd7ad766d2b54e018b5f2d11209e92c045b9

Authored by Andrew Cox
1 parent f44aff0b

Image Load-time Fitting and Sampling Modes Example

Change-Id: I8558b0e432cbbf2470fc9b80b4178d20663b3758
Signed-off-by: Andrew Cox <andrew.cox@partner.samsung.com>
com.samsung.dali-demo.xml
@@ -53,8 +53,8 @@ @@ -53,8 +53,8 @@
53 <label>Refraction effect</label> 53 <label>Refraction effect</label>
54 </ui-application> 54 </ui-application>
55 <ui-application appid="scripting.example" exec="/usr/apps/com.samsung.dali-demo/bin/scripting.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> 55 <ui-application appid="scripting.example" exec="/usr/apps/com.samsung.dali-demo/bin/scripting.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
56 - <label>Scroll View</label>  
57 - </ui-application> 56 + <label>Scroll View</label>
  57 + </ui-application>
58 <ui-application appid="scroll-view.example" exec="/usr/apps/com.samsung.dali-demo/bin/scroll-view.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> 58 <ui-application appid="scroll-view.example" exec="/usr/apps/com.samsung.dali-demo/bin/scroll-view.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
59 <label>Scroll View</label> 59 <label>Scroll View</label>
60 </ui-application> 60 </ui-application>
@@ -67,8 +67,11 @@ @@ -67,8 +67,11 @@
67 <ui-application appid="builder.example" exec="/usr/apps/com.samsung.dali-demo/bin/builder.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> 67 <ui-application appid="builder.example" exec="/usr/apps/com.samsung.dali-demo/bin/builder.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
68 <label>Script Based UI</label> 68 <label>Script Based UI</label>
69 </ui-application> 69 </ui-application>
  70 + <ui-application appid="image-scaling-and-filtering.example" exec="/usr/apps/com.samsung.dali-demo/bin/image-scaling-and-filtering.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
  71 + <label>Image Fitting and Sampling</label>
  72 + </ui-application>
70 <ui-application appid="image-scaling-irregular-grid.example" exec="/usr/apps/com.samsung.dali-demo/bin/image-scaling-irregular-grid.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> 73 <ui-application appid="image-scaling-irregular-grid.example" exec="/usr/apps/com.samsung.dali-demo/bin/image-scaling-irregular-grid.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
71 - <label>Image Scaling Modes</label> 74 + <label>Image Scaling Grid</label>
72 </ui-application> 75 </ui-application>
73 <ui-application appid="buttons.example" exec="/usr/apps/com.samsung.dali-demo/bin/buttons.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true"> 76 <ui-application appid="buttons.example" exec="/usr/apps/com.samsung.dali-demo/bin/buttons.example" nodisplay="true" multiple="false" type="c++app" taskmanage="true">
74 <label>Buttons</label> 77 <label>Buttons</label>
demo/dali-demo.cpp
@@ -51,6 +51,7 @@ int main(int argc, char **argv) @@ -51,6 +51,7 @@ int main(int argc, char **argv)
51 demo.AddExample(Example("scroll-view.example", DALI_DEMO_STR_TITLE_SCROLL_VIEW)); 51 demo.AddExample(Example("scroll-view.example", DALI_DEMO_STR_TITLE_SCROLL_VIEW));
52 demo.AddExample(Example("shadow-bone-lighting.example", DALI_DEMO_STR_TITLE_LIGHTS_AND_SHADOWS)); 52 demo.AddExample(Example("shadow-bone-lighting.example", DALI_DEMO_STR_TITLE_LIGHTS_AND_SHADOWS));
53 demo.AddExample(Example("builder.example", DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI)); 53 demo.AddExample(Example("builder.example", DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI));
  54 + demo.AddExample(Example("image-scaling-and-filtering.example", DALI_DEMO_STR_TITLE_IMAGE_FITTING_SAMPLING));
54 demo.AddExample(Example("image-scaling-irregular-grid.example", DALI_DEMO_STR_TITLE_IMAGE_SCALING)); 55 demo.AddExample(Example("image-scaling-irregular-grid.example", DALI_DEMO_STR_TITLE_IMAGE_SCALING));
55 demo.AddExample(Example("text-label.example", DALI_DEMO_STR_TITLE_TEXT_LABEL)); 56 demo.AddExample(Example("text-label.example", DALI_DEMO_STR_TITLE_TEXT_LABEL));
56 demo.AddExample(Example("text-label-multi-language.example", DALI_DEMO_STR_TITLE_TEXT_LABEL_MULTI_LANGUAGE)); 57 demo.AddExample(Example("text-label-multi-language.example", DALI_DEMO_STR_TITLE_TEXT_LABEL_MULTI_LANGUAGE));
examples/image-scaling-and-filtering/image-scaling-and-filtering-example.cpp 0 → 100644
  1 +/*
  2 + * Copyright (c) 2014 Samsung Electronics Co., Ltd.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + *
  16 + */
  17 +
  18 +#include <dali/dali.h>
  19 +#include <dali-toolkit/dali-toolkit.h>
  20 +#include "shared/view.h"
  21 +#include <iostream>
  22 +
  23 +using namespace Dali;
  24 +using Toolkit::TextLabel;
  25 +
  26 +namespace
  27 +{
  28 +
  29 +const char* BACKGROUND_IMAGE( DALI_IMAGE_DIR "background-gradient.jpg" );
  30 +const Vector4 BACKGROUND_COLOUR( 1.0f, 1.0f, 1.0f, 0.15f );
  31 +
  32 +const int MARGIN_SIZE = 10;
  33 +
  34 +const char* const NEXT_BUTTON_ID = "NEXT_BUTTON";
  35 +const char* const PREVIOUS_BUTTON_ID = "PREVIOUS_BUTTON";
  36 +const char * const DALI_ICON_PLAY = DALI_IMAGE_DIR "icon-play.png";
  37 +
  38 +const char* const PUSHBUTTON_PRESS_IMAGE = DALI_IMAGE_DIR "button-down.9.png";
  39 +const char* const PUSHBUTTON_BUTTON_IMAGE = DALI_IMAGE_DIR "button-up.9.png";
  40 +const char* const PUSHBUTTON_DISABLED_IMAGE = DALI_IMAGE_DIR "button-disabled.9.png";
  41 +
  42 +const char* const FITTING_BUTTON_ID = "FITTING_BUTTON";
  43 +const char* const SAMPLING_BUTTON_ID = "SAMPLING_BUTTON";
  44 +const char* const FITTING_BUTTON_TEXT = "Fitting";
  45 +const char* const SAMPLING_BUTTON_TEXT = "Sampling";
  46 +
  47 +const char* const STYLE_LABEL_TEXT = "grouplabel";
  48 +const char* const STYLE_BUTTON_TEXT = "buttonlabel";
  49 +
  50 +
  51 +
  52 +const char* IMAGE_PATHS[] =
  53 +{
  54 + // Worst case for aliasing in downscaling, 2k x 2k 1 bit per pixel dithered
  55 + // black and white image:
  56 + DALI_IMAGE_DIR "gallery-large-14.wbmp",
  57 + // Variety of sizes, shapes and formats:
  58 + DALI_IMAGE_DIR "animation-list.png",
  59 + DALI_IMAGE_DIR "layer1.png",
  60 + DALI_IMAGE_DIR "layer2.png",
  61 + DALI_IMAGE_DIR "music-libray-main-screen.png",
  62 + DALI_IMAGE_DIR "music-libray-record-cover.png",
  63 + DALI_IMAGE_DIR "contacts-background.png",
  64 + DALI_IMAGE_DIR "portrait_screen_primitive_shapes.gif",
  65 + DALI_IMAGE_DIR "landscape_screen_primitive_shapes.gif",
  66 + DALI_IMAGE_DIR "square_primitive_shapes.bmp",
  67 + DALI_IMAGE_DIR "dali-logo.png",
  68 + DALI_IMAGE_DIR "com.samsung.dali-demo.ico",
  69 + DALI_IMAGE_DIR "gallery-large-14.jpg",
  70 + DALI_IMAGE_DIR "book-landscape-cover.jpg",
  71 + DALI_IMAGE_DIR "book-portrait-p1.jpg",
  72 + DALI_IMAGE_DIR "book-landscape-cover-back.jpg",
  73 + DALI_IMAGE_DIR "background-1.jpg",
  74 + DALI_IMAGE_DIR "background-blocks.jpg",
  75 + DALI_IMAGE_DIR "background-magnifier.jpg",
  76 + DALI_IMAGE_DIR "gallery-large-14.jpg",
  77 + NULL
  78 +};
  79 +const int NUM_IMAGE_PATHS = sizeof(IMAGE_PATHS) / sizeof(IMAGE_PATHS[0]) - 1u;
  80 +
  81 +/** Cycle the scaling mode options. */
  82 +FittingMode::Type NextScalingMode( FittingMode::Type oldMode )
  83 +{
  84 + FittingMode::Type newMode = FittingMode::SHRINK_TO_FIT;
  85 + switch ( oldMode )
  86 + {
  87 + case FittingMode::SHRINK_TO_FIT:
  88 + newMode = FittingMode::SCALE_TO_FILL;
  89 + break;
  90 + case FittingMode::SCALE_TO_FILL:
  91 + newMode = FittingMode::FIT_WIDTH;
  92 + break;
  93 + case FittingMode::FIT_WIDTH:
  94 + newMode = FittingMode::FIT_HEIGHT;
  95 + break;
  96 + case FittingMode::FIT_HEIGHT:
  97 + newMode = FittingMode::SHRINK_TO_FIT;
  98 + break;
  99 + }
  100 + return newMode;
  101 +}
  102 +
  103 +/** Cycle through filter mode options. */
  104 +SamplingMode::Type NextFilterMode( SamplingMode::Type oldMode )
  105 +{
  106 + SamplingMode::Type newMode = SamplingMode::BOX;
  107 +
  108 + switch ( oldMode )
  109 + {
  110 + case SamplingMode::BOX:
  111 + newMode = SamplingMode::NEAREST;
  112 + break;
  113 + case SamplingMode::NEAREST:
  114 + newMode = SamplingMode::LINEAR;
  115 + break;
  116 + case SamplingMode::LINEAR:
  117 + newMode = SamplingMode::BOX_THEN_NEAREST;
  118 + break;
  119 + case SamplingMode::BOX_THEN_NEAREST:
  120 + newMode = SamplingMode::BOX_THEN_LINEAR;
  121 + break;
  122 + case SamplingMode::BOX_THEN_LINEAR:
  123 + newMode = SamplingMode::NO_FILTER;
  124 + break;
  125 + case SamplingMode::NO_FILTER:
  126 + newMode = SamplingMode::BOX;
  127 + break;
  128 + case SamplingMode::DONT_CARE:
  129 + newMode = SamplingMode::BOX;
  130 + break;
  131 + }
  132 + return newMode;
  133 +}
  134 +
  135 +const char* StringFromScalingMode( FittingMode::Type scalingMode )
  136 +{
  137 + return scalingMode == FittingMode::SCALE_TO_FILL ? "SCALE_TO_FILL" : scalingMode == FittingMode::SHRINK_TO_FIT ? "SHRINK_TO_FIT" : scalingMode == FittingMode::FIT_WIDTH ? "FIT_WIDTH" : scalingMode == FittingMode::FIT_HEIGHT ? "FIT_HEIGHT" : "UnknownScalingMode";
  138 +}
  139 +
  140 +const char* StringFromFilterMode( SamplingMode::Type filterMode )
  141 +{
  142 + return filterMode == SamplingMode::BOX ? "BOX" : filterMode == SamplingMode::BOX_THEN_NEAREST ? "BOX_THEN_NEAREST" : filterMode == SamplingMode::BOX_THEN_LINEAR ? "BOX_THEN_LINEAR" : filterMode == SamplingMode::NEAREST ? "NEAREST" : filterMode == SamplingMode::LINEAR ? "LINEAR" : filterMode == SamplingMode::NO_FILTER ? "NO_FILTER" : filterMode == SamplingMode::DONT_CARE ? "DONT_CARE" : "UnknownFilterMode";
  143 +}
  144 +
  145 +}
  146 +
  147 +// This example shows the load-time image scaling and filtering features.
  148 +//
  149 +class ImageScalingAndFilteringController : public ConnectionTracker
  150 +{
  151 +public:
  152 +
  153 + ImageScalingAndFilteringController( Application& application )
  154 + : mApplication( application ),
  155 + mImageStageScale( 0.5f, 0.5f ),
  156 + mCurrentPath( 0 ),
  157 + mFittingMode( FittingMode::SCALE_TO_FILL ),
  158 + mSamplingMode( SamplingMode::BOX_THEN_LINEAR)
  159 + {
  160 + // Connect to the Application's Init signal
  161 + mApplication.InitSignal().Connect( this, &ImageScalingAndFilteringController::Create );
  162 + }
  163 +
  164 + ~ImageScalingAndFilteringController()
  165 + {
  166 + // Nothing to do here;
  167 + }
  168 +
  169 + // The Init signal is received once (only) during the Application lifetime
  170 + void Create( Application& application )
  171 + {
  172 + // Apply the default theme:
  173 + DemoHelper::RequestThemeChange();
  174 +
  175 + // Get a handle to the stage
  176 + Stage stage = Stage::GetCurrent();
  177 +
  178 + // Background image:
  179 + ResourceImage backgroundImage = ResourceImage::New( BACKGROUND_IMAGE, ImageDimensions( stage.GetSize().width, stage.GetSize().height ), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR );
  180 + ImageActor background = ImageActor::New( backgroundImage );
  181 + background.SetZ( -2.0f );
  182 + background.SetAnchorPoint( AnchorPoint::TOP_LEFT );
  183 + background.SetSize( stage.GetSize() );
  184 + stage.Add( background );
  185 +
  186 + // Make grey pixels for the desired box, the desired height the desired width:
  187 + BufferImage desiredBackground = BufferImage::WHITE();
  188 +
  189 + BufferImage heightBackground = BufferImage::WHITE();
  190 + PixelBuffer* const heightPixel = heightBackground.GetBuffer();
  191 + heightPixel[0] = 0x8f;
  192 + heightPixel[1] = 0x8f;
  193 + heightPixel[2] = 0x8f;
  194 +
  195 + BufferImage widthBackground = BufferImage::WHITE();
  196 + PixelBuffer* const widthPixel = widthBackground.GetBuffer();
  197 + widthPixel[0] = 0x4f;
  198 + widthPixel[1] = 0x4f;
  199 + widthPixel[2] = 0x4f;
  200 +
  201 + mHeightBox = ImageActor::New( heightBackground );
  202 + mHeightBox.SetOpacity( 0.2f );
  203 + stage.Add( mHeightBox );
  204 +
  205 + mWidthBox = ImageActor::New( widthBackground );
  206 + mWidthBox.SetOpacity( 0.2f );
  207 + stage.Add( mWidthBox );
  208 +
  209 + mDesiredBox = ImageActor::New( desiredBackground );
  210 + stage.Add( mDesiredBox );
  211 +
  212 + mDesiredBox.SetSize( stage.GetSize() * mImageStageScale );
  213 + mDesiredBox.SetParentOrigin( ParentOrigin::CENTER );
  214 + mDesiredBox.SetAnchorPoint( AnchorPoint::CENTER );
  215 + mDesiredBox.SetPosition( 0, 0, -1 );
  216 +
  217 + mHeightBox.SetSize( stage.GetSize().width, (stage.GetSize() * mImageStageScale).height );
  218 + mHeightBox.SetParentOrigin( ParentOrigin::CENTER );
  219 + mHeightBox.SetAnchorPoint( AnchorPoint::CENTER );
  220 + mHeightBox.SetPosition( 0, 0, -1 );
  221 +
  222 + mWidthBox.SetSize( (stage.GetSize() * mImageStageScale).width, stage.GetSize().height );
  223 + mWidthBox.SetParentOrigin( ParentOrigin::CENTER );
  224 + mWidthBox.SetAnchorPoint( AnchorPoint::CENTER );
  225 + mWidthBox.SetPosition( 0, 0, -1 );
  226 +
  227 + // Make a grab-handle for resizing the image:
  228 + mGrabCorner = Toolkit::PushButton::New();
  229 + mGrabCorner.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::WIDTH );
  230 + mGrabCorner.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
  231 + mGrabCorner.SetSelectedImage( Dali::ResourceImage::New( PUSHBUTTON_PRESS_IMAGE ) );
  232 + mGrabCorner.SetButtonImage( Dali::ResourceImage::New( PUSHBUTTON_BUTTON_IMAGE ) );
  233 + mGrabCorner.SetDisabledImage( Dali::ResourceImage::New( PUSHBUTTON_DISABLED_IMAGE ) );
  234 + mGrabCorner.SetName( "GrabCorner" );
  235 + mGrabCorner.SetAnchorPoint( AnchorPoint::BOTTOM_RIGHT );
  236 + mGrabCorner.SetParentOrigin( ParentOrigin::BOTTOM_RIGHT );
  237 + mGrabCorner.SetSize( Vector2( stage.GetSize().width*0.08f, stage.GetSize().width*0.08f ) );
  238 + mGrabCorner.SetZ( 1.0f );
  239 + mGrabCorner.SetOpacity( 0.6f );
  240 + mDesiredBox.Add( mGrabCorner );
  241 + mPanGestureDetector = PanGestureDetector::New();
  242 + mPanGestureDetector.Attach( mGrabCorner );
  243 + mPanGestureDetector.DetectedSignal().Connect( this, &ImageScalingAndFilteringController::OnPan );
  244 +
  245 + // Initialize the actor
  246 + mImageActor = ImageActor::New();
  247 +
  248 + // Reposition the actor
  249 + mImageActor.SetParentOrigin( ParentOrigin::CENTER );
  250 + mImageActor.SetAnchorPoint( AnchorPoint::CENTER );
  251 +
  252 + // Display the actor on the stage
  253 + stage.Add( mImageActor );
  254 +
  255 + mImageActor.SetSize( stage.GetSize() * mImageStageScale );
  256 +
  257 + // Setup the pinch detector for scaling the desired image load dimensions:
  258 + mPinchDetector = PinchGestureDetector::New();
  259 + mPinchDetector.Attach( mImageActor );
  260 + mPinchDetector.DetectedSignal().Connect( this, &ImageScalingAndFilteringController::OnPinch );
  261 +
  262 + // Tie-in input event handlers:
  263 + stage.KeyEventSignal().Connect( this, &ImageScalingAndFilteringController::OnKeyEvent );
  264 +
  265 + CreateControls();
  266 +
  267 + ResizeImage();
  268 + }
  269 +
  270 + /**
  271 + * Create the GUI controls which float above the scene
  272 + */
  273 + void CreateControls()
  274 + {
  275 + Stage stage = Stage::GetCurrent();
  276 +
  277 + Dali::Layer controlsLayer = Dali::Layer::New();
  278 + controlsLayer.SetResizePolicy( ResizePolicy::SIZE_RELATIVE_TO_PARENT, Dimension::ALL_DIMENSIONS );
  279 + controlsLayer.SetSizeModeFactor( Vector3( 1.0f, 1.0f, 1.0f ) );
  280 + controlsLayer.SetAnchorPoint( AnchorPoint::TOP_LEFT);
  281 + controlsLayer.SetParentOrigin( ParentOrigin::TOP_LEFT);
  282 + stage.Add( controlsLayer );
  283 +
  284 + // Back and next image buttons in corners of stage:
  285 + unsigned int playWidth = std::min( stage.GetSize().x * (1 / 5.0f), 58.0f );
  286 + Image playImage = ResourceImage::New( DALI_ICON_PLAY, ImageDimensions( playWidth, playWidth ), FittingMode::SHRINK_TO_FIT, SamplingMode::BOX_THEN_LINEAR );
  287 + Actor imagePrevious = ImageActor::New( playImage );
  288 +
  289 + // Last image button:
  290 + imagePrevious.SetAnchorPoint( AnchorPoint::TOP_LEFT );
  291 + imagePrevious.RotateBy( Radian(3.14159265358979323846f), Vector3( 0, 1.0f, 0 ) );
  292 + imagePrevious.SetY( playWidth * 0.5f );
  293 + imagePrevious.SetX( playWidth + playWidth * 0.5f );
  294 + imagePrevious.SetOpacity( 0.6f );
  295 + controlsLayer.Add( imagePrevious );
  296 + imagePrevious.SetName( PREVIOUS_BUTTON_ID );
  297 + imagePrevious.TouchedSignal().Connect( this, &ImageScalingAndFilteringController::OnControlTouched );
  298 +
  299 + // Next image button:
  300 + Actor imageNext = ImageActor::New( playImage );
  301 + imageNext.SetAnchorPoint( AnchorPoint::TOP_RIGHT );
  302 + imageNext.SetY( playWidth * 0.5f );
  303 + imageNext.SetX( stage.GetSize().x - playWidth * 0.5f );
  304 + imageNext.SetOpacity( 0.6f );
  305 + controlsLayer.Add( imageNext );
  306 + imageNext.SetName( NEXT_BUTTON_ID );
  307 + imageNext.TouchedSignal().Connect( this, &ImageScalingAndFilteringController::OnControlTouched );
  308 +
  309 + // Buttons to popup selectors for fitting and sampling modes:
  310 +
  311 + // Wrapper table to hold two buttons side by side:
  312 + Toolkit::TableView modesGroupBackground = Toolkit::TableView::New( 1, 2 );
  313 + modesGroupBackground.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
  314 + modesGroupBackground.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
  315 + modesGroupBackground.SetBackgroundColor( BACKGROUND_COLOUR );
  316 + modesGroupBackground.SetCellPadding( Size( MARGIN_SIZE * 0.5f, MARGIN_SIZE ) );
  317 + modesGroupBackground.SetFitHeight( 0 );
  318 +
  319 + modesGroupBackground.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
  320 + modesGroupBackground.SetParentOrigin( ParentOrigin::BOTTOM_LEFT );
  321 + modesGroupBackground.SetPosition( 0.0f, 0.0f );
  322 +
  323 + controlsLayer.Add( modesGroupBackground );
  324 +
  325 + {
  326 + // Vertical table to hold label and button:
  327 + Toolkit::TableView fittingModeGroup = Toolkit::TableView::New( 2, 1 );
  328 + fittingModeGroup.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
  329 + fittingModeGroup.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
  330 + fittingModeGroup.SetBackgroundColor( BACKGROUND_COLOUR );
  331 + fittingModeGroup.SetCellPadding( Size( MARGIN_SIZE * 0.5f, MARGIN_SIZE * 0.5f ) );
  332 + fittingModeGroup.SetFitHeight( 0 );
  333 + fittingModeGroup.SetFitHeight( 1 );
  334 +
  335 + TextLabel label = TextLabel::New( "Image fitting mode:" );
  336 + label.SetProperty( Toolkit::Control::Property::STYLE_NAME, STYLE_LABEL_TEXT );
  337 + fittingModeGroup.Add( label );
  338 +
  339 + Toolkit::PushButton button = CreateButton( FITTING_BUTTON_ID, StringFromScalingMode( mFittingMode ) );
  340 + button.GetLabel().SetProperty( Toolkit::Control::Property::STYLE_NAME, STYLE_BUTTON_TEXT );
  341 + fittingModeGroup.Add( button );
  342 + mFittingModeButton = button;
  343 +
  344 + modesGroupBackground.Add( fittingModeGroup );
  345 + }
  346 +
  347 + {
  348 + // Vertical table to hold label and button:
  349 + Toolkit::TableView samplingModeGroup = Toolkit::TableView::New( 2, 1 );
  350 + samplingModeGroup.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
  351 + samplingModeGroup.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
  352 + samplingModeGroup.SetBackgroundColor( BACKGROUND_COLOUR );
  353 + samplingModeGroup.SetCellPadding( Size( MARGIN_SIZE * 0.5f, MARGIN_SIZE * 0.5f ) );
  354 + samplingModeGroup.SetFitHeight( 0 );
  355 + samplingModeGroup.SetFitHeight( 1 );
  356 +
  357 + TextLabel label = TextLabel::New( "Image sampling mode:" );
  358 + label.SetProperty( Toolkit::Control::Property::STYLE_NAME, STYLE_LABEL_TEXT );
  359 + samplingModeGroup.Add( label );
  360 +
  361 + Toolkit::PushButton button = CreateButton( SAMPLING_BUTTON_ID, StringFromFilterMode( mSamplingMode ) );
  362 + button.GetLabel().SetProperty( Toolkit::Control::Property::STYLE_NAME, STYLE_BUTTON_TEXT );
  363 + samplingModeGroup.Add( button );
  364 + mSamplingModeButton = button;
  365 +
  366 + modesGroupBackground.Add( samplingModeGroup );
  367 + }
  368 + }
  369 +
  370 + Toolkit::PushButton CreateButton( const char * id, const char * label )
  371 + {
  372 + Toolkit::PushButton button = Toolkit::PushButton::New();
  373 + button.SetProperty( Toolkit::Control::Property::STYLE_NAME, STYLE_BUTTON_TEXT );
  374 + button.SetName( id );
  375 + button.SetLabel( label );
  376 + button.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
  377 + button.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
  378 + button.SetSelectedImage( Dali::ResourceImage::New( PUSHBUTTON_PRESS_IMAGE ) );
  379 + button.SetButtonImage( Dali::ResourceImage::New( PUSHBUTTON_BUTTON_IMAGE ) );
  380 + button.SetDisabledImage( Dali::ResourceImage::New( PUSHBUTTON_DISABLED_IMAGE ) );
  381 + button.ClickedSignal().Connect( this, &ImageScalingAndFilteringController::OnButtonClicked );
  382 + return button;
  383 + }
  384 +
  385 + Toolkit::Popup CreatePopup()
  386 + {
  387 + Stage stage = Stage::GetCurrent();
  388 + const float POPUP_WIDTH_DP = stage.GetSize().width * 0.75f;
  389 +
  390 + Toolkit::Popup popup = Toolkit::Popup::New();
  391 + popup.SetName( "POPUP" );
  392 + popup.SetParentOrigin( ParentOrigin::CENTER );
  393 + popup.SetAnchorPoint( AnchorPoint::CENTER );
  394 + popup.SetSize( POPUP_WIDTH_DP, 0.0f );
  395 + popup.HideTail();
  396 +
  397 + popup.OutsideTouchedSignal().Connect( this, &ImageScalingAndFilteringController::OnPopupOutsideTouched );
  398 +
  399 + return popup;
  400 + }
  401 +
  402 + //void CreatePopupButton( Toolkit::Popup popup, const char* id )
  403 + Toolkit::PushButton CreatePopupButton( Actor parent, const char* id )
  404 + {
  405 + Toolkit::PushButton button = Toolkit::PushButton::New();
  406 + button.SetName( id );
  407 + button.SetLabel( id );
  408 + button.SetSelectedImage( Dali::ResourceImage::New( PUSHBUTTON_PRESS_IMAGE ) );
  409 + button.SetButtonImage( Dali::ResourceImage::New( PUSHBUTTON_BUTTON_IMAGE ) );
  410 + Toolkit::TextLabel textLabel = Toolkit::TextLabel::DownCast( button.GetLabel() );
  411 + textLabel.SetProperty( TextLabel::Property::POINT_SIZE, 12.0f );
  412 +
  413 + button.SetAnchorPoint( AnchorPoint::TOP_LEFT );
  414 + button.SetParentOrigin( ParentOrigin::BOTTOM_LEFT );
  415 + button.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
  416 + button.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
  417 +
  418 + button.ClickedSignal().Connect( this, &ImageScalingAndFilteringController::OnButtonClicked );
  419 +
  420 + parent.Add( button );
  421 + return button;
  422 + }
  423 +
  424 + bool OnButtonClicked( Toolkit::Button button )
  425 + {
  426 + if( button.GetName() == FITTING_BUTTON_ID )
  427 + {
  428 + mPopup = CreatePopup();
  429 +
  430 + // Four-row table to hold buttons:
  431 + Toolkit::TableView fittingModes = Toolkit::TableView::New( 4, 1 );
  432 + fittingModes.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
  433 + fittingModes.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
  434 + fittingModes.SetBackgroundColor( BACKGROUND_COLOUR );
  435 + fittingModes.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE * 0.5 ) );
  436 + fittingModes.SetFitHeight( 0 );
  437 + fittingModes.SetFitHeight( 1 );
  438 + fittingModes.SetFitHeight( 2 );
  439 + fittingModes.SetFitHeight( 3 );
  440 +
  441 + CreatePopupButton( fittingModes, StringFromScalingMode( FittingMode::SCALE_TO_FILL ) );
  442 + CreatePopupButton( fittingModes, StringFromScalingMode( FittingMode::SHRINK_TO_FIT ) );
  443 + CreatePopupButton( fittingModes, StringFromScalingMode( FittingMode::FIT_WIDTH ) );
  444 + CreatePopupButton( fittingModes, StringFromScalingMode( FittingMode::FIT_HEIGHT ) );
  445 +
  446 + mPopup.Add( fittingModes );
  447 + mPopup.Show();
  448 + }
  449 + else if( button.GetName() == SAMPLING_BUTTON_ID )
  450 + {
  451 + mPopup = CreatePopup();
  452 +
  453 + // Table to hold buttons for each sampling mode:
  454 + Toolkit::TableView samplingModes = Toolkit::TableView::New( 6, 1 );
  455 + samplingModes.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
  456 + samplingModes.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::HEIGHT );
  457 + samplingModes.SetBackgroundColor( BACKGROUND_COLOUR );
  458 + samplingModes.SetCellPadding( Size( MARGIN_SIZE, MARGIN_SIZE * 0.5 ) );
  459 + samplingModes.SetFitHeight( 0 );
  460 + samplingModes.SetFitHeight( 1 );
  461 + samplingModes.SetFitHeight( 2 );
  462 + samplingModes.SetFitHeight( 3 );
  463 + samplingModes.SetFitHeight( 4 );
  464 + samplingModes.SetFitHeight( 5 );
  465 +
  466 + CreatePopupButton( samplingModes, StringFromFilterMode( SamplingMode::NEAREST ) );
  467 + CreatePopupButton( samplingModes, StringFromFilterMode( SamplingMode::LINEAR ) );
  468 + CreatePopupButton( samplingModes, StringFromFilterMode( SamplingMode::BOX ) );
  469 + CreatePopupButton( samplingModes, StringFromFilterMode( SamplingMode::BOX_THEN_NEAREST ) );
  470 + CreatePopupButton( samplingModes, StringFromFilterMode( SamplingMode::BOX_THEN_LINEAR ) );
  471 + CreatePopupButton( samplingModes, StringFromFilterMode( SamplingMode::NO_FILTER ) );
  472 +
  473 + mPopup.Add( samplingModes );
  474 + mPopup.Show();
  475 + }
  476 + else if( CheckFittingModeButton( button, FittingMode::SCALE_TO_FILL) ||
  477 + CheckFittingModeButton( button, FittingMode::SHRINK_TO_FIT) ||
  478 + CheckFittingModeButton( button, FittingMode::FIT_WIDTH) ||
  479 + CheckFittingModeButton( button, FittingMode::FIT_HEIGHT) )
  480 + {
  481 + }
  482 + else if( CheckSamplingModeButton( button, SamplingMode::NEAREST ) ||
  483 + CheckSamplingModeButton( button, SamplingMode::LINEAR ) ||
  484 + CheckSamplingModeButton( button, SamplingMode::BOX ) ||
  485 + CheckSamplingModeButton( button, SamplingMode::LINEAR ) ||
  486 + CheckSamplingModeButton( button, SamplingMode::BOX_THEN_NEAREST ) ||
  487 + CheckSamplingModeButton( button, SamplingMode::BOX_THEN_LINEAR ) ||
  488 + CheckSamplingModeButton( button, SamplingMode::NO_FILTER ) )
  489 + {
  490 + }
  491 + return true;
  492 + }
  493 +
  494 + bool CheckFittingModeButton( Actor &button, FittingMode::Type mode )
  495 + {
  496 + const char * const modeName = StringFromScalingMode( mode );
  497 + if( button.GetName() == modeName )
  498 + {
  499 + mFittingMode = mode;
  500 + mFittingModeButton.SetLabel( modeName );
  501 + mFittingModeButton.GetLabel().SetProperty( Toolkit::Control::Property::STYLE_NAME, STYLE_BUTTON_TEXT );
  502 + ResizeImage();
  503 + mPopup.Hide();
  504 + mPopup.Reset();
  505 + return true;
  506 + }
  507 + return false;
  508 + }
  509 +
  510 + bool CheckSamplingModeButton( Actor &button, SamplingMode::Type mode )
  511 + {
  512 + const char * const modeName = StringFromFilterMode( mode );
  513 + if( button.GetName() == modeName )
  514 + {
  515 + mSamplingMode = mode;
  516 + mSamplingModeButton.SetLabel( modeName );
  517 + mSamplingModeButton.GetLabel().SetProperty( Toolkit::Control::Property::STYLE_NAME, STYLE_BUTTON_TEXT );
  518 + ResizeImage();
  519 + mPopup.Hide();
  520 + mPopup.Reset();
  521 + return true;
  522 + }
  523 + return false;
  524 + }
  525 +
  526 + void OnPopupOutsideTouched()
  527 + {
  528 + if( mPopup )
  529 + {
  530 + mPopup.Hide();
  531 + mPopup.Reset();
  532 + }
  533 + }
  534 +
  535 + void OnImageLoaded( ResourceImage image )
  536 + {
  537 + DALI_ASSERT_DEBUG( image == mNextImage );
  538 + mImageActor.SetImage( image );
  539 + mImageActor.SetSize( Size( image.GetWidth(), image.GetHeight() ) );
  540 + }
  541 +
  542 + bool OnControlTouched( Actor actor, const TouchEvent& event )
  543 + {
  544 + if(event.GetPointCount() > 0)
  545 + {
  546 + const TouchPoint& point = event.GetPoint(0);
  547 + switch(point.state)
  548 + {
  549 + case TouchPoint::Up:
  550 + {
  551 + const std::string & name = actor.GetName();
  552 + if( name == NEXT_BUTTON_ID )
  553 + {
  554 + mCurrentPath = mCurrentPath + 1;
  555 + mCurrentPath = mCurrentPath < NUM_IMAGE_PATHS ? mCurrentPath : 0;
  556 + ResizeImage();
  557 + }
  558 + else if( name == PREVIOUS_BUTTON_ID )
  559 + {
  560 + mCurrentPath = mCurrentPath - 1;
  561 + mCurrentPath = mCurrentPath >= 0 ? mCurrentPath : NUM_IMAGE_PATHS - 1;
  562 + ResizeImage();
  563 + }
  564 + break;
  565 + }
  566 + default:
  567 + {
  568 + break;
  569 + }
  570 + } // end switch
  571 + }
  572 +
  573 + return false;
  574 + }
  575 +
  576 + void OnPinch( Actor actor, const PinchGesture& pinch )
  577 + {
  578 + if( pinch.state == Gesture::Started )
  579 + {
  580 + mLastPinchScale = pinch.scale;
  581 + }
  582 + const float scale = pinch.scale;
  583 +
  584 + if( scale != mLastPinchScale )
  585 + {
  586 + if ( scale < mLastPinchScale )
  587 + {
  588 + mImageStageScale.x = std::max( 0.05f, mImageStageScale.x * 0.9f );
  589 + mImageStageScale.y = std::max( 0.05f, mImageStageScale.y * 0.9f );
  590 + }
  591 + else
  592 + {
  593 + mImageStageScale.x = std::max( 0.05f, std::min( 1.0f, mImageStageScale.x * 1.1f ) );
  594 + mImageStageScale.y = std::max( 0.05f, std::min( 1.0f, mImageStageScale.y * 1.1f ) );
  595 + }
  596 + ResizeImage();
  597 + }
  598 + mLastPinchScale = scale;
  599 + }
  600 +
  601 + void OnPan( Actor actor, const PanGesture& gesture )
  602 + {
  603 + Stage stage = Stage::GetCurrent();
  604 + mImageStageScale.x = std::max( 0.05f, std::min( 1.0f, mImageStageScale.x + (gesture.displacement.x * 2.0f / stage.GetSize().width ) ) );
  605 + mImageStageScale.y = std::max( 0.05f, std::min( 1.0f, mImageStageScale.y + (gesture.displacement.y * 2.0f / stage.GetSize().height ) ) );
  606 + ResizeImage();
  607 + }
  608 +
  609 + void OnKeyEvent(const KeyEvent& event)
  610 + {
  611 + if( event.state == KeyEvent::Down )
  612 + {
  613 + if( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
  614 + {
  615 + if( mPopup && mPopup.IsVisible() )
  616 + {
  617 + mPopup.Hide();
  618 + mPopup.Reset();
  619 + }
  620 + else
  621 + {
  622 + mApplication.Quit();
  623 + }
  624 + }
  625 + else if ( event.keyPressedName == "Right" )
  626 + {
  627 + mImageStageScale.x = std::max( 0.05f, std::min( 1.0f, mImageStageScale.x * 1.1f ) );
  628 + }
  629 + else if ( event.keyPressedName == "Left" )
  630 + {
  631 + mImageStageScale.x = std::max( 0.05f, mImageStageScale.x * 0.9f );
  632 + }
  633 + else if ( event.keyPressedName == "Up" )
  634 + {
  635 + mImageStageScale.y = std::max( 0.05f, std::min( 1.0f, mImageStageScale.y * 1.1f ) );
  636 + }
  637 + else if ( event.keyPressedName == "Down" )
  638 + {
  639 + mImageStageScale.y = std::max( 0.05f, mImageStageScale.y * 0.9f );
  640 + }
  641 + else if ( event.keyPressedName == "o" )
  642 + {
  643 + mImageStageScale.x = std::max( 0.05f, mImageStageScale.x * 0.9f );
  644 + mImageStageScale.y = std::max( 0.05f, mImageStageScale.y * 0.9f );
  645 + }
  646 + else if ( event.keyPressedName == "p" )
  647 + {
  648 + mImageStageScale.x = std::max( 0.05f, std::min( 1.0f, mImageStageScale.x * 1.1f ) );
  649 + mImageStageScale.y = std::max( 0.05f, std::min( 1.0f, mImageStageScale.y * 1.1f ) );
  650 + }
  651 + else if ( event.keyPressedName == "n" )
  652 + {
  653 + mCurrentPath = mCurrentPath + 1;
  654 + mCurrentPath = mCurrentPath < NUM_IMAGE_PATHS ? mCurrentPath : 0;
  655 + }
  656 + else if ( event.keyPressedName == "b" )
  657 + {
  658 + mCurrentPath = mCurrentPath - 1;
  659 + mCurrentPath = mCurrentPath >= 0 ? mCurrentPath : NUM_IMAGE_PATHS - 1;
  660 + }
  661 + // Cycle filter and scaling modes:
  662 + else if ( event.keyPressedName == "f" )
  663 + {
  664 + mSamplingMode = NextFilterMode( mSamplingMode );
  665 + mSamplingModeButton.SetLabel( StringFromFilterMode( mSamplingMode ) );
  666 + mSamplingModeButton.GetLabel().SetProperty( Toolkit::Control::Property::STYLE_NAME, STYLE_BUTTON_TEXT );
  667 + }
  668 + // Cycle filter and scaling modes:
  669 + else if ( event.keyPressedName == "s" )
  670 + {
  671 + mFittingMode = NextScalingMode( mFittingMode );
  672 + mFittingModeButton.SetLabel( StringFromScalingMode( mFittingMode ) );
  673 + mFittingModeButton.GetLabel().SetProperty( Toolkit::Control::Property::STYLE_NAME, STYLE_BUTTON_TEXT );
  674 + }
  675 + else
  676 + {
  677 + return;
  678 + }
  679 +
  680 + ResizeImage();
  681 + }
  682 + }
  683 +
  684 +private:
  685 + void ResizeImage()
  686 + {
  687 + const char * const path = IMAGE_PATHS[mCurrentPath];
  688 +
  689 + Stage stage = Stage::GetCurrent();
  690 + Size imageSize = stage.GetSize() * mImageStageScale;
  691 + const ImageDimensions imageSizeInt = ImageDimensions::FromFloatArray( &imageSize.x );
  692 +
  693 + ResourceImage image = ResourceImage::New( path, imageSizeInt, mFittingMode, mSamplingMode );
  694 + image.LoadingFinishedSignal().Connect( this, &ImageScalingAndFilteringController::OnImageLoaded );
  695 +
  696 + mNextImage = image;
  697 +
  698 + mDesiredBox.SetSize( stage.GetSize() * mImageStageScale );
  699 + mHeightBox.SetSize( stage.GetSize().width, (stage.GetSize() * mImageStageScale).height );
  700 + mWidthBox.SetSize( (stage.GetSize() * mImageStageScale).width, stage.GetSize().height );
  701 + }
  702 +
  703 +private:
  704 + Application& mApplication;
  705 + Actor mDesiredBox; //< Background rectangle to show requested image size.
  706 + Actor mHeightBox; //< Background horizontal stripe to show requested image height.
  707 + Actor mWidthBox; //< Background vertical stripe to show requested image width.
  708 + Toolkit::PushButton mFittingModeButton;
  709 + Toolkit::PushButton mSamplingModeButton;
  710 + Toolkit::Popup mPopup;
  711 + PinchGestureDetector mPinchDetector;
  712 + float mLastPinchScale;
  713 + Toolkit::PushButton mGrabCorner;
  714 + PanGestureDetector mPanGestureDetector;
  715 + ImageActor mImageActor;
  716 + ResourceImage mNextImage; //< Currently-loading image
  717 + Vector2 mImageStageScale;
  718 + int mCurrentPath;
  719 + FittingMode::Type mFittingMode;
  720 + SamplingMode::Type mSamplingMode;
  721 +};
  722 +
  723 +void RunTest( Application& application )
  724 +{
  725 + ImageScalingAndFilteringController test( application );
  726 +
  727 + application.MainLoop();
  728 +}
  729 +
  730 +// Entry point for Linux & Tizen applications
  731 +int main( int argc, char **argv )
  732 +{
  733 + Application application = Application::New( &argc, &argv );
  734 +
  735 + RunTest( application );
  736 +
  737 + return 0;
  738 +}
resources/style/demo-theme.json
@@ -54,6 +54,16 @@ distributing this software or its derivatives. @@ -54,6 +54,16 @@ distributing this software or its derivatives.
54 "scrollview": 54 "scrollview":
55 { 55 {
56 "overshoot-effect-color":"B018" 56 "overshoot-effect-color":"B018"
  57 + },
  58 +
  59 + "grouplabel":
  60 + {
  61 + "point-size":9
  62 + },
  63 +
  64 + "buttonlabel":
  65 + {
  66 + "point-size":11
57 } 67 }
58 } 68 }
59 } 69 }
resources/style/mobile/demo-theme.json
@@ -94,6 +94,16 @@ distributing this software or its derivatives. @@ -94,6 +94,16 @@ distributing this software or its derivatives.
94 "scrollview": 94 "scrollview":
95 { 95 {
96 "overshoot-effect-color":"B018" 96 "overshoot-effect-color":"B018"
  97 + },
  98 +
  99 + "grouplabel":
  100 + {
  101 + "point-size":6
  102 + },
  103 +
  104 + "buttonlabel":
  105 + {
  106 + "point-size":8
97 } 107 }
98 } 108 }
99 } 109 }
shared/dali-demo-strings.h
@@ -47,6 +47,7 @@ extern &quot;C&quot; @@ -47,6 +47,7 @@ extern &quot;C&quot;
47 #define DALI_DEMO_STR_TITLE_SCROLL_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCROLL_VIEW") 47 #define DALI_DEMO_STR_TITLE_SCROLL_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCROLL_VIEW")
48 #define DALI_DEMO_STR_TITLE_LIGHTS_AND_SHADOWS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_LIGHTS_AND_SHADOWS") 48 #define DALI_DEMO_STR_TITLE_LIGHTS_AND_SHADOWS dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_LIGHTS_AND_SHADOWS")
49 #define DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI") 49 #define DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI")
  50 +#define DALI_DEMO_STR_TITLE_IMAGE_FITTING_SAMPLING dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_IMAGE_FITTING_SAMPLING")
50 #define DALI_DEMO_STR_TITLE_IMAGE_SCALING dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_IMAGE_SCALING") 51 #define DALI_DEMO_STR_TITLE_IMAGE_SCALING dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_IMAGE_SCALING")
51 #define DALI_DEMO_STR_TITLE_TEXT_LABEL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXT_LABEL") 52 #define DALI_DEMO_STR_TITLE_TEXT_LABEL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXT_LABEL")
52 #define DALI_DEMO_STR_TITLE_TEXT_LABEL_MULTI_LANGUAGE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXT_LABEL_MULTI_LANGUAGE") 53 #define DALI_DEMO_STR_TITLE_TEXT_LABEL_MULTI_LANGUAGE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_TEXT_LABEL_MULTI_LANGUAGE")
@@ -74,7 +75,8 @@ extern &quot;C&quot; @@ -74,7 +75,8 @@ extern &quot;C&quot;
74 #define DALI_DEMO_STR_TITLE_SCROLL_VIEW "Scroll View" 75 #define DALI_DEMO_STR_TITLE_SCROLL_VIEW "Scroll View"
75 #define DALI_DEMO_STR_TITLE_LIGHTS_AND_SHADOWS "Lights and shadows" 76 #define DALI_DEMO_STR_TITLE_LIGHTS_AND_SHADOWS "Lights and shadows"
76 #define DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI "Script Based UI" 77 #define DALI_DEMO_STR_TITLE_SCRIPT_BASED_UI "Script Based UI"
77 -#define DALI_DEMO_STR_TITLE_IMAGE_SCALING "Image Scaling Modes" 78 +#define DALI_DEMO_STR_TITLE_IMAGE_FITTING_SAMPLING "Image Fitting and Sampling"
  79 +#define DALI_DEMO_STR_TITLE_IMAGE_SCALING "Image Scaling Grid"
78 #define DALI_DEMO_STR_TITLE_TEXT_LABEL "Text Label" 80 #define DALI_DEMO_STR_TITLE_TEXT_LABEL "Text Label"
79 #define DALI_DEMO_STR_TITLE_TEXT_LABEL_MULTI_LANGUAGE "Text Scripts" 81 #define DALI_DEMO_STR_TITLE_TEXT_LABEL_MULTI_LANGUAGE "Text Scripts"
80 #define DALI_DEMO_STR_TITLE_EMOJI_TEXT "Emoji Text" 82 #define DALI_DEMO_STR_TITLE_EMOJI_TEXT "Emoji Text"