// Activities get values from the expression parser, // which returns _relative_ sizes/positions. // Convert back relative to reference coordinate system
aValue *= basegfx::B2DPoint(maReferenceSize);
// deviated from the (*shared_ptr).*mpFuncPtr // notation here, since gcc does not seem to parse // that as a member function call anymore.
basegfx::B2DPoint aPoint(maDefaultValue);
aRetVal.setX( (mpAttrLayer.get()->*mpIs1stValidFunc)() ?
(mpAttrLayer.get()->*mpGet1stValueFunc)() :
aPoint.getX() );
aRetVal.setY( (mpAttrLayer.get()->*mpIs2ndValidFunc)() ?
(mpAttrLayer.get()->*mpGet2ndValueFunc)() :
aPoint.getY() );
// Activities get values from the expression // parser, which returns _relative_ // sizes/positions. Convert start value to the // same coordinate space (i.e. relative to given // reference size).
aRetVal /= basegfx::B2DPoint(maReferenceSize);
// TODO(F1): Check whether _shape_ bounds are correct here. // Theoretically, our AttrLayer is way down the stack, and // we only have to consider _that_ value, not the one from // the top of the stack as returned by Shape::getBounds() if( mnAdditive == animations::AnimationAdditiveMode::SUM )
maShapeOrig = mpShape->getBounds().getCenter(); else
maShapeOrig = mpShape->getDomBounds().getCenter();
// if there is a physics animation going on report the animation ending // and zero out the velocity of the shape if( mpBox2DWorld->isInitialized() )
mpBox2DWorld->queueLinearVelocityUpdate( mpShape->getXShape(), {0,0}, 0);
}
// if there's a physics animation going on report the change to it if ( mpBox2DWorld->isInitialized() )
{
mpBox2DWorld->queueShapePathAnimationUpdate( mpShape->getXShape(),
mpAttrLayer,
mbAnimationFirstUpdate );
}
}
return0.0; // though this should be used in concert with // ActivitiesFactory::createSimpleActivity, better // explicitly name our start value. // Permissible range for operator() above is [0,1]
}
mpBox2DWorld->alertPhysicsAnimationEnd(mpShape); // if this was the only physics animation effect going on // all box2d bodies were destroyed on alertPhysicsAnimationEnd // except the one owned by the animation. // Try to destroy the remaining body - if it is unique // (it being unique means all physics animation effects have ended // since otherwise mpBox2DWorld would own a copy of the shared_ptr )
mpBox2DBody.reset();
// if there are multiple physics animations going in parallel // Only one of them should step the box2d world if( !mpBox2DWorld->hasWorldStepper() )
{
mbIsBox2dWorldStepper = true;
mpBox2DWorld->setHasWorldStepper(true);
}
// only start animation once per repeated start() call, // and only if sprites should be used for display if( !mbAnimationStarted )
{
mbAnimationStarted = true;
void end()
{ // TODO(Q2): Factor out common code (most // prominently start() and end()) into base class
// only stop animation once per repeated end() call, // and only if sprites are used for display if( !mbAnimationStarted ) return;
mbAnimationStarted = false;
if( mpBox2DWorld && mpBox2DWorld->isInitialized() )
{ // if there's a physics animation going on report the animation ending to it
mpBox2DWorld->queueShapeAnimationEndUpdate( mpShape->getXShape(), meAttrType );
}
// Attention, this notifyShapeUpdate() is // somewhat delicate here. Calling it // unconditional (i.e. not guarded by // mbAnimationStarted) will lead to shapes // snapping back to their original state just // before the slide ends. Not calling it at // all might swallow final animation // states. The current implementation relies // on the fact that end() is either called by // the Activity (then, the last animation // state has been set, and corresponds to the // shape's hold state), or by the animation // node (then, it's a forced end, and we // _have_ to snap back).
// To reiterate: normally, we're called from // the Activity first, thus the // notifyShapeUpdate() below will update to // the last activity value.
// force shape update, activity might have changed // state in the last round. if( mpShape->isContentChanged() )
mpShapeManager->notifyShapeUpdate( mpShape );
}
/** For by-value interfaces (bool, double)
*/ booloperator()( ValueT x )
{
ENSURE_OR_RETURN_FALSE( mpAttrLayer && mpShape, "GenericAnimation::operator(): Invalid ShapeAttributeLayer" );
((*mpAttrLayer).*mpSetValueFunc)( maSetterModifier( x ) );
if( mpBox2DWorld && mpBox2DWorld->isInitialized() )
{ // if there's a physics animation going on report the change to it
mpBox2DWorld->queueShapeAnimationUpdate( mpShape->getXShape(), mpAttrLayer, meAttrType, mbAnimationFirstUpdate );
}
// deviated from the (*shared_ptr).*mpFuncPtr // notation here, since gcc does not seem to parse // that as a member function call anymore. if( (mpAttrLayer.get()->*mpIsValidFunc)() ) return maGetterModifier( ((*mpAttrLayer).*mpGetValueFunc)() ); else return maDefaultValue;
}
// convert from 0xAARRGGBB API color to 0xRRGGBB00 // canvas color return RGBColor( (nValue << 8U) & 0xFFFFFF00U );
}
}
}
AnimationFactory::AttributeClass AnimationFactory::classifyAttributeName( const OUString& rAttrName )
{ // ATTENTION: When changing this map, also the create*PropertyAnimation() methods must // be checked and possibly adapted in their switch statements
// TODO(Q2): Since this map must be coherent with the various switch statements // in the create*PropertyAnimation methods, try to unify into a single method or table switch( mapAttributeName( rAttrName ) )
{ default: case AttributeType::Invalid: return CLASS_UNKNOWN_PROPERTY;
case AttributeType::CharColor: case AttributeType::Color: case AttributeType::DimColor: case AttributeType::FillColor: case AttributeType::LineColor: return CLASS_COLOR_PROPERTY;
case AttributeType::CharFontName: return CLASS_STRING_PROPERTY;
case AttributeType::Visibility: return CLASS_BOOL_PROPERTY;
case AttributeType::CharHeight: case AttributeType::CharWeight: case AttributeType::Height: case AttributeType::Opacity: case AttributeType::Rotate: case AttributeType::SkewX: case AttributeType::SkewY: case AttributeType::Width: case AttributeType::PosX: case AttributeType::PosY: return CLASS_NUMBER_PROPERTY;
case AttributeType::CharUnderline: case AttributeType::FillStyle: case AttributeType::LineStyle: case AttributeType::CharPosture: return CLASS_ENUM_PROPERTY;
}
}
NumberAnimationSharedPtr AnimationFactory::createNumberPropertyAnimation( const OUString& rAttrName, const AnimatableShapeSharedPtr& rShape, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& rSlideSize, const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, int nFlags )
{ // ATTENTION: When changing this map, also the classifyAttributeName() method must // be checked and possibly adapted in their switch statement
AttributeType eAttrType = mapAttributeName(rAttrName); switch( eAttrType )
{ default: case AttributeType::Invalid:
ENSURE_OR_THROW( false, "AnimationFactory::createNumberPropertyAnimation(): Unknown attribute" ); break;
case AttributeType::CharColor: case AttributeType::CharFontName: case AttributeType::CharPosture: case AttributeType::CharUnderline: case AttributeType::Color: case AttributeType::DimColor: case AttributeType::FillColor: case AttributeType::FillStyle: case AttributeType::LineColor: case AttributeType::LineStyle: case AttributeType::Visibility:
ENSURE_OR_THROW( false, "AnimationFactory::createNumberPropertyAnimation(): Attribute type mismatch" ); break;
case AttributeType::CharHeight: return makeGenericAnimation<NumberAnimation>( rShapeManager,
nFlags,
&ShapeAttributeLayer::isCharScaleValid, 1.0, // CharHeight is a relative attribute, thus // default is 1.0
&ShapeAttributeLayer::getCharScale,
&ShapeAttributeLayer::setCharScale,
eAttrType,
pBox2DWorld );
case AttributeType::Height: return makeGenericAnimation( rShapeManager,
nFlags,
&ShapeAttributeLayer::isHeightValid, // TODO(F1): Check whether _shape_ bounds are correct here. // Theoretically, our AttrLayer is way down the stack, and // we only have to consider _that_ value, not the one from // the top of the stack as returned by Shape::getBounds()
rShape->getBounds().getHeight(),
&ShapeAttributeLayer::getHeight,
&ShapeAttributeLayer::setHeight, // convert expression parser value from relative page size
rSlideSize.getY(),
eAttrType,
pBox2DWorld );
case AttributeType::Opacity: return makeGenericAnimation<NumberAnimation>( rShapeManager,
nFlags,
&ShapeAttributeLayer::isAlphaValid, // TODO(F1): Provide shape default here (FillTransparency?) 1.0,
&ShapeAttributeLayer::getAlpha,
&ShapeAttributeLayer::setAlpha,
eAttrType,
pBox2DWorld );
case AttributeType::Rotate: return makeGenericAnimation<NumberAnimation>( rShapeManager,
nFlags,
&ShapeAttributeLayer::isRotationAngleValid, // NOTE: Since we paint the shape as-is from metafile, // rotation angle is always 0.0, even for rotated shapes 0.0,
&ShapeAttributeLayer::getRotationAngle,
&ShapeAttributeLayer::setRotationAngle,
eAttrType,
pBox2DWorld );
case AttributeType::SkewX: return makeGenericAnimation<NumberAnimation>( rShapeManager,
nFlags,
&ShapeAttributeLayer::isShearXAngleValid, // TODO(F1): Is there any shape property for skew? 0.0,
&ShapeAttributeLayer::getShearXAngle,
&ShapeAttributeLayer::setShearXAngle,
eAttrType,
pBox2DWorld );
case AttributeType::SkewY: return makeGenericAnimation<NumberAnimation>( rShapeManager,
nFlags,
&ShapeAttributeLayer::isShearYAngleValid, // TODO(F1): Is there any shape property for skew? 0.0,
&ShapeAttributeLayer::getShearYAngle,
&ShapeAttributeLayer::setShearYAngle,
eAttrType,
pBox2DWorld );
case AttributeType::Width: return makeGenericAnimation( rShapeManager,
nFlags,
&ShapeAttributeLayer::isWidthValid, // TODO(F1): Check whether _shape_ bounds are correct here. // Theoretically, our AttrLayer is way down the stack, and // we only have to consider _that_ value, not the one from // the top of the stack as returned by Shape::getBounds()
rShape->getBounds().getWidth(),
&ShapeAttributeLayer::getWidth,
&ShapeAttributeLayer::setWidth, // convert expression parser value from relative page size
rSlideSize.getX(),
eAttrType,
pBox2DWorld );
case AttributeType::PosX: return makeGenericAnimation( rShapeManager,
nFlags,
&ShapeAttributeLayer::isPosXValid, // TODO(F1): Check whether _shape_ bounds are correct here. // Theoretically, our AttrLayer is way down the stack, and // we only have to consider _that_ value, not the one from // the top of the stack as returned by Shape::getBounds()
rShape->getBounds().getCenterX(),
&ShapeAttributeLayer::getPosX,
&ShapeAttributeLayer::setPosX, // convert expression parser value from relative page size
rSlideSize.getX(),
eAttrType,
pBox2DWorld );
case AttributeType::PosY: return makeGenericAnimation( rShapeManager,
nFlags,
&ShapeAttributeLayer::isPosYValid, // TODO(F1): Check whether _shape_ bounds are correct here. // Theoretically, our AttrLayer is way down the stack, and // we only have to consider _that_ value, not the one from // the top of the stack as returned by Shape::getBounds()
rShape->getBounds().getCenterY(),
&ShapeAttributeLayer::getPosY,
&ShapeAttributeLayer::setPosY, // convert expression parser value from relative page size
rSlideSize.getY(),
eAttrType,
pBox2DWorld );
}
return NumberAnimationSharedPtr();
}
EnumAnimationSharedPtr AnimationFactory::createEnumPropertyAnimation( const OUString& rAttrName, const AnimatableShapeSharedPtr& rShape, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& /*rSlideSize*/, const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, int nFlags )
{ // ATTENTION: When changing this map, also the classifyAttributeName() method must // be checked and possibly adapted in their switch statement
AttributeType eAttrType = mapAttributeName( rAttrName ); switch( eAttrType )
{ default: case AttributeType::Invalid:
ENSURE_OR_THROW( false, "AnimationFactory::createEnumPropertyAnimation(): Unknown attribute" ); break;
case AttributeType::CharColor: case AttributeType::CharFontName: case AttributeType::Color: case AttributeType::DimColor: case AttributeType::FillColor: case AttributeType::LineColor: case AttributeType::Visibility: case AttributeType::CharHeight: case AttributeType::CharWeight: case AttributeType::Height: case AttributeType::Opacity: case AttributeType::Rotate: case AttributeType::SkewX: case AttributeType::SkewY: case AttributeType::Width: case AttributeType::PosX: case AttributeType::PosY:
ENSURE_OR_THROW( false, "AnimationFactory::createEnumPropertyAnimation(): Attribute type mismatch" ); break;
ColorAnimationSharedPtr AnimationFactory::createColorPropertyAnimation( const OUString& rAttrName, const AnimatableShapeSharedPtr& rShape, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& /*rSlideSize*/, const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, int nFlags )
{ // ATTENTION: When changing this map, also the classifyAttributeName() method must // be checked and possibly adapted in their switch statement
AttributeType eAttrType = mapAttributeName(rAttrName); switch( eAttrType )
{ default: case AttributeType::Invalid:
ENSURE_OR_THROW( false, "AnimationFactory::createColorPropertyAnimation(): Unknown attribute" ); break;
case AttributeType::CharFontName: case AttributeType::CharHeight: case AttributeType::CharPosture: case AttributeType::CharUnderline: case AttributeType::CharWeight: case AttributeType::FillStyle: case AttributeType::Height: case AttributeType::LineStyle: case AttributeType::Opacity: case AttributeType::Rotate: case AttributeType::SkewX: case AttributeType::SkewY: case AttributeType::Visibility: case AttributeType::Width: case AttributeType::PosX: case AttributeType::PosY:
ENSURE_OR_THROW( false, "AnimationFactory::createColorPropertyAnimation(): Attribute type mismatch" ); break;
case AttributeType::Color: // TODO(F2): This is just mapped to fill color to make it work return makeGenericAnimation<ColorAnimation>( rShapeManager,
nFlags,
&ShapeAttributeLayer::isFillColorValid,
getDefault<RGBColor>( rShape, rAttrName ),
&ShapeAttributeLayer::getFillColor,
&ShapeAttributeLayer::setFillColor,
eAttrType,
pBox2DWorld );
switch( nTransformType )
{ case animations::AnimationTransformType::SCALE: return std::make_shared<TupleAnimation< ::basegfx::B2DSize >>(
rShapeManager,
nFlags,
&ShapeAttributeLayer::isWidthValid,
&ShapeAttributeLayer::isHeightValid, // TODO(F1): Check whether _shape_ bounds are correct here. // Theoretically, our AttrLayer is way down the stack, and // we only have to consider _that_ value, not the one from // the top of the stack as returned by Shape::getBounds()
basegfx::B2DSize(aBounds.getRange().getX(), aBounds.getRange().getY()),
basegfx::B2DSize(aBounds.getRange().getX(), aBounds.getRange().getY()),
&ShapeAttributeLayer::getWidth,
&ShapeAttributeLayer::getHeight,
&ShapeAttributeLayer::setSize );
case animations::AnimationTransformType::TRANSLATE: return std::make_shared<TupleAnimation< ::basegfx::B2DPoint >>(
rShapeManager,
nFlags,
&ShapeAttributeLayer::isPosXValid,
&ShapeAttributeLayer::isPosYValid, // TODO(F1): Check whether _shape_ bounds are correct here. // Theoretically, our AttrLayer is way down the stack, and // we only have to consider _that_ value, not the one from // the top of the stack as returned by Shape::getBounds()
aBounds.getCenter(),
basegfx::B2DSize(rSlideSize.getX(), rSlideSize.getY()),
&ShapeAttributeLayer::getPosX,
&ShapeAttributeLayer::getPosY,
&ShapeAttributeLayer::setPosition );
default:
ENSURE_OR_THROW( false, "AnimationFactory::createPairPropertyAnimation(): Attribute type mismatch" ); break;
}
return PairAnimationSharedPtr();
}
StringAnimationSharedPtr AnimationFactory::createStringPropertyAnimation( const OUString& rAttrName, const AnimatableShapeSharedPtr& rShape, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& /*rSlideSize*/, const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, int nFlags )
{ // ATTENTION: When changing this map, also the classifyAttributeName() method must // be checked and possibly adapted in their switch statement
AttributeType eAttrType = mapAttributeName(rAttrName); switch( eAttrType )
{ default: case AttributeType::Invalid:
ENSURE_OR_THROW( false, "AnimationFactory::createStringPropertyAnimation(): Unknown attribute" ); break;
case AttributeType::CharColor: case AttributeType::CharHeight: case AttributeType::CharUnderline: case AttributeType::Color: case AttributeType::DimColor: case AttributeType::FillColor: case AttributeType::Height: case AttributeType::LineColor: case AttributeType::Opacity: case AttributeType::Rotate: case AttributeType::SkewX: case AttributeType::SkewY: case AttributeType::Visibility: case AttributeType::Width: case AttributeType::PosX: case AttributeType::PosY: case AttributeType::CharPosture: case AttributeType::CharWeight: case AttributeType::FillStyle: case AttributeType::LineStyle:
ENSURE_OR_THROW( false, "AnimationFactory::createStringPropertyAnimation(): Attribute type mismatch" ); break;
BoolAnimationSharedPtr AnimationFactory::createBoolPropertyAnimation( const OUString& rAttrName, const AnimatableShapeSharedPtr& /*rShape*/, const ShapeManagerSharedPtr& rShapeManager, const ::basegfx::B2DVector& /*rSlideSize*/, const box2d::utils::Box2DWorldSharedPtr& pBox2DWorld, int nFlags )
{ // ATTENTION: When changing this map, also the classifyAttributeName() method must // be checked and possibly adapted in their switch statement
AttributeType eAttrType = mapAttributeName(rAttrName); switch( eAttrType )
{ default: case AttributeType::Invalid:
ENSURE_OR_THROW( false, "AnimationFactory::createBoolPropertyAnimation(): Unknown attribute" ); break;
case AttributeType::CharColor: case AttributeType::CharFontName: case AttributeType::CharHeight: case AttributeType::CharPosture: case AttributeType::CharWeight: case AttributeType::Color: case AttributeType::DimColor: case AttributeType::FillColor: case AttributeType::FillStyle: case AttributeType::Height: case AttributeType::LineColor: case AttributeType::LineStyle: case AttributeType::Opacity: case AttributeType::Rotate: case AttributeType::SkewX: case AttributeType::SkewY: case AttributeType::Width: case AttributeType::PosX: case AttributeType::PosY: case AttributeType::CharUnderline:
ENSURE_OR_THROW( false, "AnimationFactory::createBoolPropertyAnimation(): Attribute type mismatch" ); break;
case AttributeType::Visibility: return makeGenericAnimation<BoolAnimation>( rShapeManager,
nFlags,
&ShapeAttributeLayer::isVisibilityValid, // TODO(F1): Is there a corresponding shape property? true,
&ShapeAttributeLayer::getVisibility,
&ShapeAttributeLayer::setVisibility,
eAttrType,
pBox2DWorld );
}
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.57Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-27)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.