int desiredWidth = 15;
int desiredHeight = 20;
+ // texture size have to keep it's ratio. So, the size of texture should be 20x20.
+ const int resultWidth = 20;
+ const int resultHeight = 20;
+
Visual::Base visual = VisualFactory::Get().CreateVisual(TEST_GIF_FILE_NAME, ImageDimensions(desiredWidth, desiredHeight));
DALI_TEST_CHECK(visual);
{
std::stringstream out;
- out << GL_TEXTURE_2D << ", " << 0u << ", " << desiredWidth << ", " << desiredHeight;
+ out << GL_TEXTURE_2D << ", " << 0u << ", " << resultWidth << ", " << resultHeight;
DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str()));
}
{
std::stringstream out;
- out << GL_TEXTURE_2D << ", " << 0u << ", " << desiredWidth << ", " << desiredHeight;
- DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str())); // The size should not be changed
+ out << GL_TEXTURE_2D << ", " << 0u << ", " << resultWidth << ", " << resultHeight;
+ DALI_TEST_CHECK(textureTrace.FindMethodAndParams("TexImage2D", out.str().c_str())); // The size should be changed for keeping the aspect ratio.
}
END_TEST;
void OnResourceReadySignalSVG(Control control)
{
- // Check whether Image Visual transforms on ImageVieiw::OnRelayout()
+ // Check whether Image Visual transforms on ImageView::OnRelayout()
Toolkit::Internal::Control& controlImpl = Toolkit::Internal::GetImplementation(control);
Toolkit::Visual::Base imageVisual = DevelControl::GetVisual(controlImpl, ImageView::Property::IMAGE);
Property::Map resultMap;
Property::Map* retMap = transformValue->GetMap();
DALI_TEST_CHECK(retMap);
- // Fitting mode should not be applied at this point
- DALI_TEST_EQUALS(retMap->Find(Visual::Transform::Property::SIZE)->Get<Vector2>(), Vector2::ZERO, TEST_LOCATION);
+ // Fitting mode is applied at this point. because we do FittingMode in control
+ DALI_TEST_EQUALS(retMap->Find(Visual::Transform::Property::SIZE)->Get<Vector2>(), Vector2::ONE, TEST_LOCATION);
}
int UtcDaliImageViewCheckResourceReady(void)
OVER_FIT_KEEP_ASPECT_RATIO, ///< The visual should be scaled to fit, preserving aspect ratio. The visual will be filled without empty area, and outside is cropped away.
CENTER, ///< The visual should keep original size of image. It is not scaled and not strecthed.
FIT_HEIGHT, ///< The visual should be scaled to fit, preserving aspect ratio. Height is scaled proportionately to maintain aspect ratio. It will be deprecated.
- FIT_WIDTH ///< The visual should be scaled to fit, preserving aspect ratio. Width is scaled proportionately to maintain aspect ratio. It will be deprecated.
+ FIT_WIDTH, ///< The visual should be scaled to fit, preserving aspect ratio. Width is scaled proportionately to maintain aspect ratio. It will be deprecated.
+ DONT_CARE ///< The visual should be not use fittingMode.
};
/**
#include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
#include <dali-toolkit/public-api/visuals/image-visual-properties.h>
#include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali-toolkit/public-api/align-enumerations.h>
namespace
{
{"DISABLED", Toolkit::DevelControl::DISABLED},
};
const unsigned int ControlStateTableCount = sizeof(ControlStateTable) / sizeof(ControlStateTable[0]);
+const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
namespace
{
mStartingPinchScale(nullptr),
mMargin(0, 0, 0, 0),
mPadding(0, 0, 0, 0),
+ mSize(0, 0),
mKeyEventSignal(),
mKeyInputFocusGainedSignal(),
mKeyInputFocusLostSignal(),
mIsKeyboardFocusGroup(false),
mIsEmittingResourceReadySignal(false),
mIdleCallbackRegistered(false),
- mDispatchKeyEvents(true)
+ mDispatchKeyEvents(true),
+ mProcessorRegistered(false)
{
Dali::Accessibility::Accessible::RegisterExternalAccessibleGetter(&ExternalAccessibleGetter);
}
// All gesture detectors will be destroyed so no need to disconnect.
delete mStartingPinchScale;
+ if(mProcessorRegistered && Adaptor::IsAvailable())
+ {
+ // Unregister the processor from the adaptor
+ Adaptor::Get().UnregisterProcessorOnce(*this, true);
+ }
+
if(mIdleCallback && Adaptor::IsAvailable())
{
// Removes the callback from the callback manager in case the control is destroyed before the callback is executed.
return mAccessibleCreatable;
}
+void Control::Impl::ApplyFittingMode(const Vector2& size)
+{
+ Actor self = mControlImpl.Self();
+ for(RegisteredVisualContainer::Iterator iter = mVisuals.Begin(); iter != mVisuals.End(); iter++)
+ {
+ // Check whether the visual is empty and enabled
+ if((*iter)->visual && (*iter)->enabled)
+ {
+ Internal::Visual::Base& visualImpl = Toolkit::GetImplementation((*iter)->visual);
+
+ // If the current visual is using the transform property map, fittingMode will not be applied.
+ if(visualImpl.IsIgnoreFittingMode())
+ {
+ continue;
+ }
+
+ Visual::FittingMode fittingMode = visualImpl.GetFittingMode();
+ Property::Map transformMap = Property::Map();
+
+ // If the fittingMode is DONT_CARE, we don't need to apply fittingMode, just Set empty transformMap
+ if(fittingMode == Visual::FittingMode::DONT_CARE)
+ {
+ ((*iter)->visual).SetTransformAndSize(transformMap, size);
+ continue;
+ }
+
+ Extents padding = self.GetProperty<Extents>(Toolkit::Control::Property::PADDING);
+
+ bool zeroPadding = (padding == Extents());
+
+ Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(
+ self.GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
+ if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
+ {
+ std::swap(padding.start, padding.end);
+ }
+
+ // remove padding from the size to know how much is left for the visual
+ Vector2 finalSize = size - Vector2(padding.start + padding.end, padding.top + padding.bottom);
+ Vector2 finalOffset = Vector2(padding.start, padding.top);
+
+ // Reset PIXEL_AREA after using OVER_FIT_KEEP_ASPECT_RATIO
+ if(visualImpl.IsPixelAreaSetForFittingMode())
+ {
+ visualImpl.SetPixelAreaForFittingMode(FULL_TEXTURE_RECT);
+ }
+
+ if((!zeroPadding) || // If padding is not zero
+ (fittingMode != Visual::FittingMode::FILL))
+ {
+ visualImpl.SetTransformMapUsageForFittingMode(true);
+
+ Vector2 naturalSize;
+ // NaturalSize will not be used for FILL fitting mode, which is default.
+ // Skip GetNaturalSize
+ if(fittingMode != Visual::FittingMode::FILL)
+ {
+ ((*iter)->visual).GetNaturalSize(naturalSize);
+ }
+
+ // 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;
+ }
+
+ // Calculate size for fittingMode
+ switch(fittingMode)
+ {
+ case Visual::FittingMode::FIT_KEEP_ASPECT_RATIO:
+ {
+ auto availableVisualSize = finalSize;
+
+ // scale to fit the padded area
+ finalSize = naturalSize * std::min((!Dali::EqualsZero(naturalSize.width) ? (availableVisualSize.width / naturalSize.width) : 0),
+ (!Dali::EqualsZero(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:
+ {
+ auto availableVisualSize = finalSize;
+ finalSize = naturalSize * std::max((!Dali::EqualsZero(naturalSize.width) ? (availableVisualSize.width / naturalSize.width) : 0.0f),
+ (!Dali::EqualsZero(naturalSize.height) ? (availableVisualSize.height / naturalSize.height) : 0.0f));
+
+ 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);
+
+ if(!visualImpl.IsPixelAreaSetForFittingMode())
+ {
+ visualImpl.SetPixelAreaForFittingMode(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((!Dali::EqualsZero(naturalSize.width) ? (availableVisualSize.width / naturalSize.width) : 0.0f),
+ (!Dali::EqualsZero(naturalSize.height) ? (availableVisualSize.height / naturalSize.height) : 0.0f));
+ }
+
+ 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:
+ case Visual::FittingMode::DONT_CARE:
+ {
+ // This FittingMode already converted
+ break;
+ }
+ }
+
+ // 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(visualImpl.IsTransformMapSetForFittingMode() && zeroPadding) // Reset offset to zero only if padding applied previously
+ {
+ visualImpl.SetTransformMapUsageForFittingMode(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));
+ }
+
+ ((*iter)->visual).SetTransformAndSize(transformMap, size);
+ }
+ }
+}
+
+void Control::Impl::RegisterProcessorOnce()
+{
+ if(!mProcessorRegistered)
+ {
+ Adaptor::Get().RegisterProcessorOnce(*this, true);
+ mProcessorRegistered = true;
+ }
+}
+
+void Control::Impl::Process(bool postProcessor)
+{
+ // Call ApplyFittingMode
+ ApplyFittingMode(mSize);
+ mProcessorRegistered = false;
+}
+
} // namespace Internal
} // namespace Toolkit
#include <dali/devel-api/adaptor-framework/accessibility.h>
#include <dali/public-api/object/property-notification.h>
#include <dali/public-api/object/type-registry.h>
+#include <dali/integration-api/processor-interface.h>
#include <string>
// INTERNAL INCLUDES
/**
* @brief Holds the Implementation for the internal control class
*/
-class Control::Impl : public ConnectionTracker, public Visual::EventObserver
+class Control::Impl : public ConnectionTracker, public Visual::EventObserver, public Integration::Processor
{
friend class Toolkit::DevelControl::ControlAccessible;
*/
bool IsCreateAccessibleEnabled() const;
+ /**
+ * @brief Apply fittingMode
+ *
+ * @param[in] size The size of the control
+ */
+ void ApplyFittingMode(const Vector2& size);
+
+ /**
+ * @brief Register processor
+ */
+ void RegisterProcessorOnce();
+
+protected: // From processor-interface
+ /**
+ * @copydoc Dali::Integration::Processor::Process()
+ */
+ void Process(bool postProcessor) override;
+
+ /**
+ * @copydoc Dali::Integration::Processor::GetProcessorName()
+ */
+ std::string_view GetProcessorName() const override
+ {
+ return "ControlDataImpl";
+ }
+
private:
/**
* Used as an alternative to boolean so that it is obvious whether a visual is enabled/disabled.
Vector3* mStartingPinchScale; ///< The scale when a pinch gesture starts, TODO: consider removing this
Extents mMargin; ///< The margin values
Extents mPadding; ///< The padding values
+ Vector2 mSize; ///< The size of the control
Toolkit::Control::KeyEventSignalType mKeyEventSignal;
Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusGainedSignal;
Toolkit::Control::KeyInputFocusSignalType mKeyInputFocusLostSignal;
bool mIsEmittingResourceReadySignal : 1; ///< True during ResourceReady().
bool mIdleCallbackRegistered : 1; ///< True if need to emit the resource ready signal again.
bool mDispatchKeyEvents : 1; ///< Whether the actor emits key event signals
+ bool mProcessorRegistered : 1; ///< Whether the processor is registered.
RegisteredVisualContainer mRemoveVisuals; ///< List of visuals that are being replaced by another visual once ready
{
namespace
{
-const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
-
-constexpr float FULL_OPACITY = 1.0f;
-constexpr float LOW_OPACITY = 0.2f;
+constexpr float FULL_OPACITY = 1.0f;
+constexpr float LOW_OPACITY = 0.2f;
constexpr float TRANSITION_EFFECT_SPEED = 0.3f;
constexpr int PLACEHOLDER_DEPTH_INDEX = -2;
: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT | additionalBehaviour)),
mImageSize(),
mTransitionTargetAlpha(FULL_OPACITY),
- mImageVisualPaddingSetByTransform(false),
- mImageViewPixelAreaSetByFittingMode(false),
mTransitionEffect(false),
- mNeedLazyFittingMode(false),
mImageReplaced(false)
{
}
Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual(mPropertyMap);
if(visual)
{
+ Internal::Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
+ if(visualImpl.GetFittingMode() == Visual::FittingMode::DONT_CARE)
+ {
+ visualImpl.SetFittingMode(Visual::FittingMode::FILL);
+ }
+
// Don't set mVisual until it is ready and shown. Getters will still use current visual.
if(!mVisual)
{
if(!mShaderMap.Empty())
{
- Internal::Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
visualImpl.SetCustomShader(mShaderMap);
}
Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual(url, size);
if(visual)
{
+ Internal::Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
+ if(visualImpl.GetFittingMode() == Visual::FittingMode::DONT_CARE)
+ {
+ visualImpl.SetFittingMode(Visual::FittingMode::FILL);
+ }
+
if(!mVisual)
{
mVisual = visual;
if(!mShaderMap.Empty())
{
- Internal::Visual::Base& visualImpl = Toolkit::GetImplementation(visual);
visualImpl.SetCustomShader(mShaderMap);
}
Control::OnRelayout(size, container);
if(mVisual)
{
- // If Resource is not ready, fittingMode is not working well.
- // in this case, imageview set the flag for working applyFittingMode again when the resource is ready
- if(!IsResourceReady())
- {
- mNeedLazyFittingMode = true;
- }
-
- // Apply FittingMode using actor's size
- ApplyFittingMode(size);
-
// mVisual is not updated util the resource is ready in the case of visual replacement.
// in this case, the Property Map must be initialized so that the previous value is not reused.
// after mVisual is updated, the correct value will be reset.
// 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);
- // Applying FittingMode again if it is not working well on OnRelayout().
- if(mNeedLazyFittingMode)
- {
- const Vector2& size = Self().GetProperty(Dali::Actor::Property::SIZE).Get<Vector2>();
- ApplyFittingMode(size);
- mNeedLazyFittingMode = false;
- }
-
// 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((!Dali::EqualsZero(naturalSize.width) ? (availableVisualSize.width / naturalSize.width) : 0),
- (!Dali::EqualsZero(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((!Dali::EqualsZero(naturalSize.width) ? (availableVisualSize.width / naturalSize.width) : 0.0f),
- (!Dali::EqualsZero(naturalSize.height) ? (availableVisualSize.height / naturalSize.height) : 0.0f));
-
- 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((!Dali::EqualsZero(naturalSize.width) ? (availableVisualSize.width / naturalSize.width) : 0.0f),
- (!Dali::EqualsZero(naturalSize.height) ? (availableVisualSize.height / naturalSize.height) : 0.0f));
- }
-
- 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(const Vector2& size)
-{
- Property::Map transformMap = Property::Map();
-
- Extents padding = Self().GetProperty<Extents>(Toolkit::Control::Property::PADDING);
-
- bool zeroPadding = (padding == Extents());
-
- Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(
- Self().GetProperty(Dali::Actor::Property::LAYOUT_DIRECTION).Get<int>());
- if(Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection)
- {
- std::swap(padding.start, padding.end);
- }
-
- // remove padding from the size to know how much is left for the visual
- Vector2 finalSize = size - Vector2(padding.start + padding.end, padding.top + padding.bottom);
- Vector2 finalOffset = Vector2(padding.start, padding.top);
-
- 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;
-
- Vector2 naturalSize;
- // NaturalSize will not be used for FILL fitting mode, which is default.
- // Skip GetNaturalSize
- if(fittingMode != Visual::FittingMode::FILL)
- {
- mVisual.GetNaturalSize(naturalSize);
- }
-
- // 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));
- }
-
- mVisual.SetTransformAndSize(transformMap, size);
-}
-
void ImageView::CreatePlaceholderImage()
{
Property::Map propertyMap;
*/
void OnResourceReady(Toolkit::Control control);
- /**
- * @brief Set TransformMap for fittingMode
- * param[in] finalSize The size for fittingMode
- * param[in] textureSize The size of texture
- * param[in] offset The offset for fittingMode
- * param[in] fittingMode The mode for fitting image
- * param[in] transformMap The map for fitting image
- */
- void SetTransformMapForFittingMode(Vector2 finalSize, Vector2 textureSize, Vector2 offset, Visual::FittingMode fittingMode, Property::Map& transformMap);
-
- /**
- * @brief Apply fittingMode
- */
- void ApplyFittingMode(const Vector2& size);
-
/**
* @brief Create placeholder image if it set. placeholder image is shown when image view is waiting for the image to load.
*/
Animation mTransitionAnimation; ///< the animation for transition effect
float mTransitionTargetAlpha; ///< Keep image's alpha value
- bool mImageVisualPaddingSetByTransform : 1; ///< Flag to indicate Padding was set using a transform.
- bool mImageViewPixelAreaSetByFittingMode : 1; ///< Flag to indicate pixel area was set by fitting Mode
bool mTransitionEffect :1; ///< Flag to indicate TransitionEffect is enabled
- bool mNeedLazyFittingMode:1; ///< Flag to indicate FittingMode will be applying lazy
bool mImageReplaced:1; ///< Flag to indicate image is replaced
};
}
AnimatedGradientVisual::AnimatedGradientVisual(VisualFactoryCache& factoryCache)
-: Visual::Base(factoryCache, Visual::FittingMode::FILL, static_cast<Toolkit::Visual::Type>(Toolkit::DevelVisual::ANIMATED_GRADIENT))
+: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, static_cast<Toolkit::Visual::Type>(Toolkit::DevelVisual::ANIMATED_GRADIENT))
{
SetupDefaultValue();
}
}
AnimatedImageVisual::AnimatedImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, ImageDimensions desiredSize)
-: Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::ANIMATED_IMAGE),
+: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, Toolkit::Visual::ANIMATED_IMAGE),
mFrameDelayTimer(),
mPlacementActor(),
mImageVisualShaderFactory(shaderFactory),
mActionStatus(DevelAnimatedImageVisual::Action::PLAY),
mWrapModeU(WrapMode::DEFAULT),
mWrapModeV(WrapMode::DEFAULT),
- mFittingMode(FittingMode::SCALE_TO_FILL),
+ mFittingMode(FittingMode::VISUAL_FITTING),
mSamplingMode(SamplingMode::BOX_THEN_LINEAR),
mStopBehavior(DevelImageVisual::StopBehavior::CURRENT_FRAME),
mStartFirstFrame(false),
{
if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0)
{
+ if(mImpl->mRenderer)
+ {
+ auto textureSet = mImpl->mRenderer.GetTextures();
+ if(textureSet && textureSet.GetTextureCount())
+ {
+ auto texture = textureSet.GetTexture(0);
+ if(texture)
+ {
+ Dali::Vector2 textureSize;
+ textureSize.x = texture.GetWidth();
+ textureSize.y = texture.GetHeight();
+ if(textureSize != Vector2::ZERO)
+ {
+ naturalSize = textureSize;
+ return;
+ }
+ }
+ }
+ }
+
naturalSize.x = mDesiredSize.GetWidth();
naturalSize.y = mDesiredSize.GetHeight();
return;
}
AnimatedVectorImageVisual::AnimatedVectorImageVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size)
-: Visual::Base(factoryCache, Visual::FittingMode::FILL, static_cast<Toolkit::Visual::Type>(Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE)),
+: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, static_cast<Toolkit::Visual::Type>(Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE)),
mImageUrl(imageUrl),
mAnimationData(),
mVectorAnimationTask(new VectorAnimationTask(factoryCache)),
}
ArcVisual::ArcVisual(VisualFactoryCache& factoryCache)
-: Visual::Base(factoryCache, Visual::FittingMode::FILL, static_cast<Toolkit::Visual::Type>(Toolkit::DevelVisual::ARC)),
+: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, static_cast<Toolkit::Visual::Type>(Toolkit::DevelVisual::ARC)),
mThickness(0.0f),
mRadius(0.0f),
mStartAngle(0.0f),
}
BorderVisual::BorderVisual(VisualFactoryCache& factoryCache)
-: Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::BORDER),
+: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, Toolkit::Visual::BORDER),
mBorderColor(Color::TRANSPARENT),
mBorderSize(0.f),
mBorderColorIndex(Property::INVALID_INDEX),
}
ColorVisual::ColorVisual(VisualFactoryCache& factoryCache)
-: Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::COLOR),
+: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, Toolkit::Visual::COLOR),
mBlurRadius(0.0f),
mAlwaysUsingBlurRadius(false)
{
}
GradientVisual::GradientVisual(VisualFactoryCache& factoryCache)
-: Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::GRADIENT),
+: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, Toolkit::Visual::GRADIENT),
mGradientType(LINEAR),
mIsOpaque(true)
{
DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, SCALE_TO_FILL)
DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, FIT_WIDTH)
DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, FIT_HEIGHT)
+ DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, VISUAL_FITTING)
DALI_ENUM_TO_STRING_WITH_SCOPE(Dali::FittingMode, DEFAULT)
DALI_ENUM_TO_STRING_TABLE_END(FITTING_MODE)
ImageDimensions size,
FittingMode::Type fittingMode,
Dali::SamplingMode::Type samplingMode)
-: Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::IMAGE),
+: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, Toolkit::Visual::IMAGE),
mPixelArea(FULL_TEXTURE_RECT),
mPixelAreaIndex(Property::INVALID_INDEX),
mPlacementActor(),
{
if(mDesiredSize.GetWidth() > 0 && mDesiredSize.GetHeight() > 0)
{
+ if(mImpl->mRenderer)
+ {
+ auto textureSet = mImpl->mRenderer.GetTextures();
+ if(textureSet && textureSet.GetTextureCount())
+ {
+ auto texture = textureSet.GetTexture(0);
+ if(texture)
+ {
+ if(mTextureSize != Vector2::ZERO)
+ {
+ naturalSize = mTextureSize;
+ return;
+ }
+ }
+ }
+ }
+
naturalSize.x = mDesiredSize.GetWidth();
naturalSize.y = mDesiredSize.GetHeight();
return;
const VisualUrl& imageUrl,
const Property::Map& properties,
ImageDimensions size = ImageDimensions(),
- FittingMode::Type fittingMode = FittingMode::DEFAULT,
+ FittingMode::Type fittingMode = FittingMode::VISUAL_FITTING,
Dali::SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR);
/**
ImageVisualShaderFactory& shaderFactory,
const VisualUrl& imageUrl,
ImageDimensions size = ImageDimensions(),
- FittingMode::Type fittingMode = FittingMode::DEFAULT,
+ FittingMode::Type fittingMode = FittingMode::VISUAL_FITTING,
Dali::SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR);
public: // from Visual
}
MeshVisual::MeshVisual(VisualFactoryCache& factoryCache)
-: Visual::Base(factoryCache, Visual::FittingMode::FIT_KEEP_ASPECT_RATIO, Toolkit::Visual::MESH),
+: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, Toolkit::Visual::MESH),
mShadingMode(Toolkit::MeshVisual::ShadingMode::TEXTURED_WITH_DETAILED_SPECULAR_LIGHTING),
mUseTexture(true),
mUseMipmapping(true),
}
NPatchVisual::NPatchVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory)
-: Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::N_PATCH),
+: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, Toolkit::Visual::N_PATCH),
mPlacementActor(),
mLoader(factoryCache.GetNPatchLoader()),
mImageVisualShaderFactory(shaderFactory),
}
PrimitiveVisual::PrimitiveVisual(VisualFactoryCache& factoryCache)
-: Visual::Base(factoryCache, Visual::FittingMode::FIT_KEEP_ASPECT_RATIO, Toolkit::Visual::PRIMITIVE),
+: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, Toolkit::Visual::PRIMITIVE),
mScaleDimensions(Vector3::ONE),
mScaleTopRadius(DEFAULT_SCALE_TOP_RADIUS),
mScaleBottomRadius(DEFAULT_SCALE_BOTTOM_RADIUS),
}
SvgVisual::SvgVisual(VisualFactoryCache& factoryCache, ImageVisualShaderFactory& shaderFactory, const VisualUrl& imageUrl, ImageDimensions size)
-: Visual::Base(factoryCache, Visual::FittingMode::FILL, Toolkit::Visual::SVG),
+: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, Toolkit::Visual::SVG),
mImageVisualShaderFactory(shaderFactory),
mAtlasRect(FULL_TEXTURE_RECT),
mImageUrl(imageUrl),
}
TextVisual::TextVisual(VisualFactoryCache& factoryCache, TextVisualShaderFactory& shaderFactory)
-: Visual::Base(factoryCache, Visual::FittingMode::FIT_KEEP_ASPECT_RATIO, Toolkit::Visual::TEXT),
+: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, Toolkit::Visual::TEXT),
mController(Text::Controller::New()),
mTypesetter(Text::Typesetter::New(mController->GetTextModel())),
mTextVisualShaderFactory(shaderFactory),
mResourceStatus(Toolkit::Visual::ResourceStatus::PREPARING),
mType(type),
mAlwaysUsingBorderline(false),
- mAlwaysUsingCornerRadius(false)
+ mAlwaysUsingCornerRadius(false),
+ mIgnoreFittingMode(false),
+ mPixelAreaSetByFittingMode(false),
+ mTransformMapSetForFittingMode(false)
{
}
int mFlags;
Toolkit::Visual::ResourceStatus mResourceStatus;
const Toolkit::Visual::Type mType;
- bool mAlwaysUsingBorderline : 1; ///< Whether we need the borderline in shader always.
- bool mAlwaysUsingCornerRadius : 1; ///< Whether we need the corner radius in shader always.
+ bool mAlwaysUsingBorderline : 1; ///< Whether we need the borderline in shader always.
+ bool mAlwaysUsingCornerRadius : 1; ///< Whether we need the corner radius in shader always.
+ bool mIgnoreFittingMode : 1; ///< Whether we need to ignore fitting mode.
+ bool mPixelAreaSetByFittingMode : 1; ///< Whether the pixel area is set for fitting mode.
+ bool mTransformMapSetForFittingMode :1; ///< Whether the transformMap is set for fitting mode.
};
} // namespace Visual
{
namespace Internal
{
+
+const Vector4 FULL_TEXTURE_RECT(0.f, 0.f, 1.f, 1.f);
+
namespace
{
DALI_ENUM_TO_STRING_TABLE_BEGIN(VISUAL_FITTING_MODE)
DALI_ENUM_TO_STRING_WITH_SCOPE(Visual::FittingMode, CENTER)
DALI_ENUM_TO_STRING_WITH_SCOPE(Visual::FittingMode, FIT_HEIGHT)
DALI_ENUM_TO_STRING_WITH_SCOPE(Visual::FittingMode, FIT_WIDTH)
+ DALI_ENUM_TO_STRING_WITH_SCOPE(Visual::FittingMode, DONT_CARE)
DALI_ENUM_TO_STRING_TABLE_END(VISUAL_FITTING_MODE)
/**
return mImpl->mFittingMode;
}
+void Visual::Base::SetFittingMode(Visual::FittingMode fittingMode)
+{
+ mImpl->mFittingMode = fittingMode;
+}
+
+bool Visual::Base::IsIgnoreFittingMode() const
+{
+ return mImpl->mIgnoreFittingMode;
+}
+
+bool Visual::Base::IsPixelAreaSetForFittingMode() const
+{
+ return mImpl->mPixelAreaSetByFittingMode;
+}
+
+void Visual::Base::SetPixelAreaForFittingMode(const Vector4& pixelArea)
+{
+ if(mImpl->mRenderer)
+ {
+ mImpl->mRenderer.RegisterProperty(PIXEL_AREA_UNIFORM_NAME, pixelArea);
+ }
+
+ mImpl->mPixelAreaSetByFittingMode = (pixelArea != FULL_TEXTURE_RECT) ? true : false;
+}
+
+bool Visual::Base::IsTransformMapSetForFittingMode() const
+{
+ return mImpl->mTransformMapSetForFittingMode;
+}
+
+void Visual::Base::SetTransformMapUsageForFittingMode(bool used)
+{
+ mImpl->mTransformMapSetForFittingMode = used;
+}
+
Visual::Base& Visual::Base::GetVisualObject()
{
return *this;
map.Add(animator.propertyKey.stringKey, animator.targetValue);
}
+ // Set flag to ignore fitting mode when we set the transform property map
+ mImpl->mIgnoreFittingMode = true;
mImpl->mTransform.UpdatePropertyMap(map);
}
SetupTransition(transition, animator, index, animator.initialValue, animator.targetValue);
*/
FittingMode GetFittingMode() const;
+ /**
+ * @brief Set the fitting mode for the visual
+ *
+ * @param[in] fittingMode The fitting mode for the visual
+ */
+ void SetFittingMode(FittingMode fittingMode);
+
+ /**
+ * @brief Query whether the fittingMode is ignored.
+ *
+ * @return Returns true if the fittingMode is ignored, false otherwise.
+ */
+ bool IsIgnoreFittingMode() const;
+
+ /**
+ * @brief Query whether the pixel area is set by fitting mode.
+ */
+ bool IsPixelAreaSetForFittingMode() const;
+
+ /**
+ * @brief Set the pixel area of the visual.
+ *
+ * @param[in] pixelArea The pixel area of the visual.
+ */
+ void SetPixelAreaForFittingMode(const Vector4& pixelArea);
+
+ /**
+ * @brief Checks whether the trasformMap is being used in the FittingMode situation.
+ */
+ bool IsTransformMapSetForFittingMode() const;
+
+ /**
+ * @brief Set the flag to use transformMap in the FittingMode.
+ */
+ void SetTransformMapUsageForFittingMode(bool used);
+
/**
* @brief Get the actual Visual Object.
* @return The actual visual object
}
WireframeVisual::WireframeVisual(VisualFactoryCache& factoryCache, Visual::BasePtr actualVisual)
-: Visual::Base(factoryCache, Visual::FittingMode::FILL, actualVisual ? actualVisual->GetType() : Toolkit::Visual::WIREFRAME),
+: Visual::Base(factoryCache, Visual::FittingMode::DONT_CARE, actualVisual ? actualVisual->GetType() : Toolkit::Visual::WIREFRAME),
mActualVisual(actualVisual)
{
}
#include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
#include <dali-toolkit/devel-api/visuals/color-visual-properties-devel.h>
#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
#include <dali-toolkit/internal/styling/style-manager-impl.h>
#include <dali-toolkit/internal/visuals/color/color-visual.h>
void Control::OnSizeSet(const Vector3& targetSize)
{
+ Vector2 size(targetSize);
Toolkit::Visual::Base visual = mImpl->GetVisual(Toolkit::Control::Property::BACKGROUND);
if(visual)
{
- Vector2 size(targetSize);
visual.SetTransformAndSize(Property::Map(), size); // Send an empty map as we do not want to modify the visual's set transform
}
+
+ // Apply FittingMode here
+ mImpl->mSize = size;
+ mImpl->RegisterProcessorOnce();
}
void Control::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
container.Add(child, newChildSize);
}
- Toolkit::Visual::Base visual = mImpl->GetVisual(Toolkit::Control::Property::BACKGROUND);
- if(visual)
- {
- visual.SetTransformAndSize(Property::Map(), size); // Send an empty map as we do not want to modify the visual's set transform
- }
+ // Apply FittingMode here
+ mImpl->ApplyFittingMode(size);
}
void Control::OnSetResizePolicy(ResizePolicy::Type policy, Dimension::Type dimension)