+ Dali::Toolkit::Control handle(GetOwner());
+
+ for(auto&& data : properties)
+ {
+ if(data.first == Toolkit::ImageView::Property::IMAGE)
+ {
+ DevelControl::DoAction(handle, Toolkit::ImageView::Property::IMAGE, DevelVisual::Action::UPDATE_PROPERTY, data.second);
+ break;
+ }
+ }
+ }
+}
+
+void ImageView::OnResourceReady(Toolkit::Control control)
+{
+ // Visual ready so update visual attached to this ImageView, following call to RelayoutRequest will use this visual.
+ mVisual = DevelControl::GetVisual(*this, Toolkit::ImageView::Property::IMAGE);
+ // Signal that a Relayout may be needed
+}
+
+void ImageView::SetTransformMapForFittingMode(Vector2 finalSize, Vector2 naturalSize, Vector2 finalOffset, Visual::FittingMode fittingMode, Property::Map& transformMap)
+{
+ switch(fittingMode)
+ {
+ case Visual::FittingMode::FIT_KEEP_ASPECT_RATIO:
+ {
+ auto availableVisualSize = finalSize;
+
+ // scale to fit the padded area
+ finalSize = naturalSize * std::min((naturalSize.width ? (availableVisualSize.width / naturalSize.width) : 0),
+ (naturalSize.height ? (availableVisualSize.height / naturalSize.height) : 0));
+
+ // calculate final offset within the padded area
+ finalOffset += (availableVisualSize - finalSize) * .5f;
+
+ // populate the transform map
+ transformMap.Add(Toolkit::Visual::Transform::Property::OFFSET, finalOffset)
+ .Add(Toolkit::Visual::Transform::Property::SIZE, finalSize);
+ break;
+ }
+ case Visual::FittingMode::OVER_FIT_KEEP_ASPECT_RATIO:
+ {
+ mImageViewPixelAreaSetByFittingMode = true;
+ auto availableVisualSize = finalSize;
+ finalSize = naturalSize * std::max((naturalSize.width ? (availableVisualSize.width / naturalSize.width) : 0),
+ (naturalSize.height ? (availableVisualSize.height / naturalSize.height) : 0));
+
+ auto originalOffset = finalOffset;
+ finalOffset += (availableVisualSize - finalSize) * .5f;
+
+ float x = abs((availableVisualSize.width - finalSize.width) / finalSize.width) * .5f;
+ float y = abs((availableVisualSize.height - finalSize.height) / finalSize.height) * .5f;
+ float widthRatio = 1.f - abs((availableVisualSize.width - finalSize.width) / finalSize.width);
+ float heightRatio = 1.f - abs((availableVisualSize.height - finalSize.height) / finalSize.height);
+ Vector4 pixelArea = Vector4(x, y, widthRatio, heightRatio);
+ Self().SetProperty(Toolkit::ImageView::Property::PIXEL_AREA, pixelArea);
+
+ // populate the transform map
+ transformMap.Add(Toolkit::Visual::Transform::Property::OFFSET, originalOffset)
+ .Add(Toolkit::Visual::Transform::Property::SIZE, availableVisualSize);
+ break;
+ }
+ case Visual::FittingMode::CENTER:
+ {
+ auto availableVisualSize = finalSize;
+ if(availableVisualSize.width > naturalSize.width && availableVisualSize.height > naturalSize.height)
+ {
+ finalSize = naturalSize;
+ }
+ else
+ {
+ finalSize = naturalSize * std::min((naturalSize.width ? (availableVisualSize.width / naturalSize.width) : 0),
+ (naturalSize.height ? (availableVisualSize.height / naturalSize.height) : 0));
+ }
+
+ finalOffset += (availableVisualSize - finalSize) * .5f;
+
+ // populate the transform map
+ transformMap.Add(Toolkit::Visual::Transform::Property::OFFSET, finalOffset)
+ .Add(Toolkit::Visual::Transform::Property::SIZE, finalSize);
+ break;
+ }
+ case Visual::FittingMode::FILL:
+ {
+ transformMap.Add(Toolkit::Visual::Transform::Property::OFFSET, finalOffset)
+ .Add(Toolkit::Visual::Transform::Property::SIZE, finalSize);
+ break;
+ }
+ case Visual::FittingMode::FIT_WIDTH:
+ case Visual::FittingMode::FIT_HEIGHT:
+ {
+ // This FittingMode already converted
+ break;
+ }
+ }
+}
+
+void ImageView::ApplyFittingMode(Vector2 finalSize, Vector2 naturalSize, Vector2 finalOffset, bool zeroPadding, Property::Map& transformMap)
+{
+ Visual::FittingMode fittingMode = Toolkit::GetImplementation(mVisual).GetFittingMode();
+
+ // Reset PIXEL_AREA after using OVER_FIT_KEEP_ASPECT_RATIO
+ if(mImageViewPixelAreaSetByFittingMode)
+ {
+ Self().SetProperty(Toolkit::ImageView::Property::PIXEL_AREA, FULL_TEXTURE_RECT);
+ mImageViewPixelAreaSetByFittingMode = false;
+ }
+
+ if((!zeroPadding) || // If padding is not zero
+ (fittingMode != Visual::FittingMode::FILL))
+ {
+ mImageVisualPaddingSetByTransform = true;
+
+ // If FittingMode use FIT_WIDTH or FIT_HEIGTH, it need to change proper fittingMode
+ if(fittingMode == Visual::FittingMode::FIT_WIDTH)
+ {
+ fittingMode = (finalSize.height / naturalSize.height) < (finalSize.width / naturalSize.width) ? Visual::FittingMode::OVER_FIT_KEEP_ASPECT_RATIO : Visual::FittingMode::FIT_KEEP_ASPECT_RATIO;
+ }
+ else if(fittingMode == Visual::FittingMode::FIT_HEIGHT)
+ {
+ fittingMode = (finalSize.height / naturalSize.height) < (finalSize.width / naturalSize.width) ? Visual::FittingMode::FIT_KEEP_ASPECT_RATIO : Visual::FittingMode::OVER_FIT_KEEP_ASPECT_RATIO;
+ }
+
+ SetTransformMapForFittingMode(finalSize, naturalSize, finalOffset, fittingMode, transformMap);
+
+ // Set extra value for applying transformMap
+ transformMap.Add(Toolkit::Visual::Transform::Property::OFFSET_POLICY,
+ Vector2(Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE))
+ .Add(Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN)
+ .Add(Toolkit::Visual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN)
+ .Add(Toolkit::Visual::Transform::Property::SIZE_POLICY,
+ Vector2(Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE));
+ }
+ else if(mImageVisualPaddingSetByTransform && zeroPadding) // Reset offset to zero only if padding applied previously
+ {
+ mImageVisualPaddingSetByTransform = false;
+ // Reset the transform map
+ transformMap.Add(Toolkit::Visual::Transform::Property::OFFSET, Vector2::ZERO)
+ .Add(Toolkit::Visual::Transform::Property::OFFSET_POLICY,
+ Vector2(Toolkit::Visual::Transform::Policy::RELATIVE, Toolkit::Visual::Transform::Policy::RELATIVE))
+ .Add(Toolkit::Visual::Transform::Property::SIZE, Vector2::ONE)
+ .Add(Toolkit::Visual::Transform::Property::SIZE_POLICY,
+ Vector2(Toolkit::Visual::Transform::Policy::RELATIVE, Toolkit::Visual::Transform::Policy::RELATIVE));