/**************************************************************************** ** ImageObject class ** ** Created: Tue Feb 02 22:06:51 2004 ** by: Varol Okan using Kate ** ** This class is the encapsulation of the ImageObject. ** ** AN ImageObject is a visible object in a DVD Menu. ** ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "xml_dvd.h" #include "menuobject.h" #include "frameobject.h" #include "imageobject.h" #include "dialogmovie.h" #include "messagebox.h" #include "dialogmatrix.h" #include "dialoggeometry.h" #include "dialoganimation.h" #include "structuretoolbar.h" ImageObject::ImageObject (QWidget *pParent) : MenuObject (pParent) { m_qsObjectType = QString (IMAGE_OBJECT); } ImageObject::~ImageObject () { } void ImageObject::setPixmap(QPixmap &thePixmap) { // Note: the Pixmap could be rotated, thus the bounding Rect might // be of different size than the width or height of the Pixmap. m_pixmap = thePixmap; } void ImageObject::setFile (QString fileName) { QString qsExtractionPath; QFileInfo fileInfo(fileName); m_qsFileName = fileInfo.fileName(); setName(m_qsFileName); qsExtractionPath = fileInfo.baseName ( true ); setExtractionPath(qsExtractionPath); m_qsFileName = fileName; // m_pixmap = QPixmap (fileName); } void ImageObject::setZoom (float fZoom) { // For the purpose of this class the Zoom is alreaduy incorporated into m_pixmap ... m_imageManipulator.fZoom = fZoom; } void ImageObject::setManipulator(ImageManipulator &theOther) { m_imageManipulator = theOther; } void ImageObject::setModifiers ( Modifiers &theOther ) { Modifiers *pModifier = (Modifiers *)&m_imageManipulator; *pModifier = theOther; } ImageManipulator &ImageObject::manipulator() { return m_imageManipulator; } Modifiers *ImageObject::modifiers() { // Return the base class only ... // Note: this is needed to use the same MatrixDialog for text and images. return (Modifiers *) &m_imageManipulator; } QString &ImageObject::fileName() { return m_qsFileName; } QPixmap &ImageObject::pixmap () { return m_pixmap; } float ImageObject::zoom() { return m_imageManipulator.fZoom; } void ImageObject::drawContents (QPainter *painter) { // printf ( "%s::%s::%d me<%p> shadow=<%p>\n", __FILE__, __FUNCTION__, __LINE__, this, m_pShadow ); QWMatrix theMatrix; // Here we calculate the center point of gravity (rotation) QPoint centerPos; centerPos.setX (rect().x() + (int)((float)rect().width () / 2.0)); centerPos.setY (rect().y() + (int)((float)rect().height() / 2.0)); // Here we define the cenetered rect. QRect theRect ((int)-(rect().width()/ 2.0), (int)-(rect().height()/2.0), rect().width(), rect().height()); QPen thePen (QColor (255,0,0), 2, Qt::DashDotLine); painter->setPen(thePen); // From the Qt documentation ... // This transformation engine is a three-step pipeline // The first step uses the world transformation matrix. // The second step uses the window. // The third step uses the viewport. // First we translate to the appropriate location, theMatrix.translate ( (double)centerPos.x ( ), (double)centerPos.y ( ) ); //. then we apply the other modifications ... theMatrix.scale ( modifiers ( )->fScaleX, modifiers ( )->fScaleY ); theMatrix.shear ( manipulator( ).fShearX, manipulator( ).fShearY ); theMatrix.rotate ( manipulator( ).fRotate ); // Here we get the rect that encompasses the button for this object. m_boundingRect = theMatrix.mapRect(theRect); if (m_bDrawRect) drawActiveFrame ( painter ); painter->setWorldMatrix(theMatrix); // Here we re-set the world matrix and translate the newly drawn ... thing ... if ( isActive () ) painter->drawRect(theRect); theMatrix.reset(); painter->setWorldMatrix(theMatrix); // check if we have a complete transparency, in which case we don't even need to bother... if (manipulator().fTransparency == 1.0) return; if (!m_bDrawRect) { if ( m_pShadow ) m_pShadow->drawContents ( painter ); int t, x, y; QRgb thePixel; int iSourceHeight = pixmap().height(); int iSourceWidth = pixmap().width (); int iSourceStartX = 0; int iSourceStartY = 0; int iTargetStartX = painter->viewport().x() + m_boundingRect.x(); int iTargetStartY = painter->viewport().y() + m_boundingRect.y(); // Use the fast method whenever possible if ( (manipulator().fRotate == 0.0) && (manipulator().fShearX == 0.0) && (manipulator().fShearY == 0.0) && (manipulator().fTransparency == 0.0) && (manipulator().listColorKeys.count() < 1) ) bitBlt (painter->device(), iTargetStartX, iTargetStartY, &pixmap(), iSourceStartX, iSourceStartY, iSourceWidth, iSourceHeight, Qt::CopyROP, true); // Okay if we can not use bitBlt we have to go through the exact calculations ... else { // First we need to create a Pixmap which holds the Target pixels QImage theImage = pixmap().convertToImage(); QColor sourceColor, targetColor, theColor; QRgb sourcePixel; QImage sourceImg; float fTargetTrans, fSourceTrans; fTargetTrans = 1.0 - manipulator().fTransparency; fSourceTrans = manipulator().fTransparency; if (fTargetTrans != 0.0) { QPixmap sourcePix (iSourceWidth, iSourceHeight); bitBlt (&sourcePix, 0, 0, painter->device(), iTargetStartX, iTargetStartY, iSourceWidth, iSourceHeight, Qt::CopyROP, true); // To get Pixel information we need a QImage however ... sourceImg = sourcePix.convertToImage(); // Now we can get the original Pixel information ... // Note: This ought to be done in the updatePixmap () - function // - Also there we leave all info untouched which is (0,0,0) // - Also when we move AND when fTransparency != 0.0 then we need to do updatePixmap everytime. } // Note that this function is actually using the viewport - transformation provided by Qt. The previous bitBlt's // did paint directly onto the device, thus we had to manually add the viewport coords. Now we have this info already // in the painter and thus we can substract them here. iTargetStartX -= painter->viewport().x(); iTargetStartY -= painter->viewport().y(); // Next we create the min/max Color keys, to check if we ought to filter the pixel out or not QValueListlistColorKeyMin; QValueListlistColorKeyMax; QColor *pColorMin, *pColorMax; if (manipulator().listColorKeys.count() > 0) { int iDelta, iRed, iGreen, iBlue; for (t=0;t<(int)manipulator().listColorKeys.count();t++) { iDelta = (int)(manipulator().listColorKeys[t]->fDeltaColor * 255.0); theColor = QColor (manipulator().listColorKeys[t]->theColor); iRed = theColor.red() - iDelta; iGreen = theColor.green() - iDelta; iBlue = theColor.blue() - iDelta; iRed = (iRed < 0) ? 0 : iRed; iGreen = (iGreen < 0) ? 0 : iGreen; iBlue = (iBlue < 0) ? 0 : iBlue; pColorMin = new QColor (iRed, iGreen, iBlue); iRed = theColor.red() + iDelta; iGreen = theColor.green() + iDelta; iBlue = theColor.blue() + iDelta; iRed = (iRed > 255) ? 255 : iRed; iGreen = (iGreen > 255) ? 255 : iGreen; iBlue = (iBlue > 255) ? 255 : iBlue; pColorMax = new QColor (iRed, iGreen, iBlue); listColorKeyMin.append (pColorMin); listColorKeyMax.append (pColorMax); } } for (y=0; y < iSourceHeight; y++) { for (x=0; x < iSourceWidth; x++) { thePixel = theImage.pixel(x+iSourceStartX, y+iSourceStartY); thePixel &= 0x00ffffff; // filter out the transparency part of the color (not used in Qt 3.x) if (thePixel != 0x000000) { // And check if this is a pixel we need to handle ... // If there is a transparency part, or some color we need to filter out, // then we need to go through this slow loop. if ( (fTargetTrans != 0.0) || (manipulator().listColorKeys.count ()) ) { sourcePixel = sourceImg.pixel(x, y); // calculate the mix of background and foreground. sourceColor = QColor (sourcePixel); targetColor = QColor ( thePixel ); if (filterColorKey ( &targetColor, &listColorKeyMin, &listColorKeyMax )) theColor = sourceColor; else theColor = QColor ( (int)(fSourceTrans * sourceColor.red() + (int)(fTargetTrans * targetColor.red())), (int)(fSourceTrans * sourceColor.green() + (int)(fTargetTrans * targetColor.green())), (int)(fSourceTrans * sourceColor.blue() + (int)(fTargetTrans * targetColor.blue())) ); painter->setPen ( theColor ); } else // No transparency is slightly easier ... painter->setPen ( QColor ( thePixel ) ); painter->drawPoint(x+iTargetStartX, y+iTargetStartY); } } } if (manipulator().listColorKeys.count() > 0) { for (t=0;t<(int)manipulator().listColorKeys.count();t++) { delete listColorKeyMin[t]; delete listColorKeyMax[t]; } } } } // Phew ... This funtion has grown over time ... } void ImageObject::drawContents (QPainter *pPainter, int iRenderFrameNumber, int) { // Next is to set the AnimationAttributes for (uint t=0; tsetValue (iRenderFrameNumber); // And then we ought to refresh the pixmap ... if ( m_listAnimationAttributes.count ( ) > 0 ) { updatePixmap ( ); updateShadow ( ); } // before we can go ahead and draw the contents with the newly set attributes. drawContents (pPainter); } // This function checks if pColor is within the min/max of one of the color keys. bool ImageObject::filterColorKey ( QColor *pColor, QValueList *pListColorMin, QValueList*pListColorMax ) { int iRed, iGreen, iBlue, t, iColorKeyCount; iColorKeyCount = manipulator().listColorKeys.count (); if ( ( iColorKeyCount < 1 ) || ( ! pListColorMin ) || ( ! pListColorMax ) ) return false; iRed = pColor->red(); iGreen = pColor->green(); iBlue = pColor->blue (); for (t=0;t MIN<%02x%02x%02x> MAX<%02x%02x%02x> - ", iRed, iGreen, iBlue, (*pListColorMin)[t]->red (), (*pListColorMin)[t]->green (), (*pListColorMin)[t]->blue (), (*pListColorMax)[t]->red(),(*pListColorMax)[t]->green(), (*pListColorMax)[t]->blue()); if ( (iRed >= (*pListColorMin)[t]->red () && iRed <= (*pListColorMax)[t]->red ()) && (iGreen >= (*pListColorMin)[t]->green() && iGreen <= (*pListColorMax)[t]->green()) && (iBlue >= (*pListColorMin)[t]->blue () && iBlue <= (*pListColorMax)[t]->blue ()) ) return true; } return false; } void ImageObject::updatePixmap() { // This function will take the input image and pass it through the whole modifications pipeline, // so we get a nice and clean rotated / colored image again. // In order to speed up the whole procedure, we set the matrix first to scale the image, // then we handle the color functions on the smaller image and lastly we apply the rotation,shearing... int iRed, iGreen, iBlue; int x, y; bool bLighter = true; float fAdjust = 0.0; QColor theColor; QRgb thePix; // QRgb defined as : 0xAARRGGBB; QWMatrix theMatrix; // Here we calculate the center point of gravity (rotation) QPoint centerPos; if (fileName().isEmpty()) return; QImage theImage(fileName()); if (theImage.isNull()) return; theImage = theImage.smoothScale ( rect ().width(), rect().height(), QImage::ScaleFree); centerPos.setX (rect().x() + (int)((float)rect().width () / 2.0)); centerPos.setY (rect().y() + (int)((float)rect().height() / 2.0)); // First we translate to the appropriate location, theMatrix.translate ((double)centerPos.x(), (double)centerPos.y()); // then we apply the other modifications ... theMatrix.scale (modifiers()->fScaleX, modifiers()->fScaleY); // theMatrix.scale (manipulator().fZoom, manipulator().fZoom); // Here we create the scaled image ... theImage = theImage.xForm ( theMatrix ); // create empty image. QImage imageColored = QImage (theImage.width(), theImage.height(), theImage.depth()); if (manipulator().fBrightness > 0.0) { bLighter = true; fAdjust = 100 + manipulator().fBrightness * 300; } else { bLighter = false; fAdjust = 100 + manipulator().fBrightness * -300; } for (y=0;yupdatePixmap (); return true; } bool ImageObject::writeProjectFile (QDomElement &theElement) { QDomDocument xmlDoc = theElement.ownerDocument(); QDomElement imageNode = xmlDoc.createElement( IMAGE_OBJECT ); // // Here we set the attributes of the tag if (!m_qsFileName.isNull()) imageNode.setAttribute( IMAGE_OBJECT_FILE_NAME, m_qsFileName ); manipulator().writeProjectFile (imageNode); theElement.appendChild( imageNode ); // And here we write the base class ... return MenuObject::writeProjectFile( imageNode ); } void ImageObject::createStructure (QListViewItem *pParentItem) { StructureItem *pButtonItem; QFileInfo fileInfo(m_qsFileName); QString qsName; qsName = QString ("Image Object"); pButtonItem = new StructureItem(this, pParentItem, qsName, fileInfo.fileName()); pButtonItem->setExpandable (TRUE); manipulator ().createStructure (pButtonItem); if ( m_pShadow ) m_pShadow->createStructure ( pButtonItem ); new StructureItem(this, pButtonItem, QString ("Geometry"), QString ("%1, %2, %3, %4"). arg(rect().x()).arg(rect().y()).arg(rect().width()).arg(rect().height())); } bool ImageObject::mousePressEvent (QMouseEvent *pEvent) { m_currentMousePos = pEvent->pos(); if (pEvent->button() == Qt::RightButton) { QPoint globalPos = pEvent->globalPos(); return createContextMenu ( globalPos ); } else { m_bDrawRect = true; } return false; } bool ImageObject::mouseReleaseEvent (QMouseEvent *) { m_bDrawRect = false; updatePixmap (); emit (signalUpdatePixmap()); emit (signalUpdateStructure()); return false; } bool ImageObject::mouseDoubleClickEvent (QMouseEvent *) { // Back to the MenuPreview - class, where I can handle this request ... emit (signalModifyMe(this)); return false; } bool ImageObject::createContextMenu ( QPoint globalPos ) { QString qsShadow; QPoint globalPos2 = globalPos; QPopupMenu *pStackMenu = new QPopupMenu(m_pParent); pStackMenu->insertItem ( tr ("Cut") , this, SLOT ( slotCut ( ) ) ); pStackMenu->insertItem ( tr ("Copy"), this, SLOT ( slotCopy ( ) ) ); pStackMenu->insertSeparator ( ); pStackMenu->insertItem ( tr ("To Front") , this, SLOT(slotToFront())); pStackMenu->insertItem ( tr ("To Back") , this, SLOT(slotToBack())); globalPos.setY ( globalPos.y ( ) - 25 ); globalPos.setX ( globalPos.x ( ) - pStackMenu->sizeHint().width()); // -100); pStackMenu->popup ( globalPos, 1 ); qsShadow = tr ( "Add Shadow ..." ); if ( shadow ( ) ) qsShadow = tr ( "Edit Shadow ..." ); if (m_pContextMenu) delete m_pContextMenu; m_pContextMenu = new QPopupMenu(m_pParent); m_pContextMenu->insertItem ( tr ("Edit ...") , this, SLOT(slotEdit ( ) ) ); m_pContextMenu->insertItem ( tr ("Properties ..."), this, SLOT(slotProperties( ) ) ); m_pContextMenu->insertItem ( tr ("Matrix ...") , this, SLOT(slotMatrix ( ) ) ); m_pContextMenu->insertItem ( tr ("Delete") , this, SLOT(slotDelete ( ) ) ); m_pContextMenu->insertSeparator(); m_pContextMenu->insertItem ( tr ("Rotate 90") , this, SLOT(slotRotate90 ( ) ) ); m_pContextMenu->insertItem ( tr ("Rotate 180") , this, SLOT(slotRotate180 ( ) ) ); m_pContextMenu->insertItem ( tr ("Rotate 270") , this, SLOT(slotRotate270 ( ) ) ); m_pContextMenu->insertSeparator(); m_pContextMenu->insertItem ( qsShadow , this, SLOT(slotAddShadow ( ) ) ); m_pContextMenu->insertItem ( tr ("Add Frame") , this, SLOT(slotAddFrame ( ) ) ); m_pContextMenu->insertItem ( tr ("Add Text") , this, SLOT(slotAddText ( ) ) ); m_pContextMenu->insertSeparator(); m_pContextMenu->insertItem ( tr ("Define as Button") , this, SLOT(slotDefineAsButton())); // Blocking call. m_pContextMenu->exec(globalPos2, 6); delete pStackMenu; if (m_pContextMenu) delete m_pContextMenu; m_pContextMenu = NULL; return true; } bool ImageObject::mouseMoveEvent (QMouseEvent *pEvent) { // Slightly different behaviour for images. // if we stretch X and/or Y separately we'll mess rotation up // this is why we have to prevent this. // So the stretch will be reset and ShearX will be used instead ScaleX if rotated. int iPos = 0; switch ( m_objectState ) { case MenuObject::StateScaleLeftX: case MenuObject::StateScaleRightX: { iPos = pEvent->pos().x() - m_currentMousePos.x(); double fZoom = (double)( iPos / 100.0 ); if (fZoom > 1.0) fZoom = fZoom * 2.0 - 1.0; if ( m_objectState == MenuObject::StateScaleLeftX ) fZoom *= -1; if ( modifiers()->fRotate == 0.0 ) modifiers( )->fScaleX *= ( 1.0 + fZoom ); else modifiers( )->fShearX -= fZoom; update ( ); } break; case MenuObject::StateScaleTopY: case MenuObject::StateScaleBottomY: { iPos = pEvent->pos().y() - m_currentMousePos.y(); double fZoom = (double)( iPos / 100.0 ); if (fZoom > 1.0) fZoom = fZoom * 2.0 - 1.0; if ( m_objectState == MenuObject::StateScaleTopY ) fZoom *= -1; if ( modifiers()->fRotate == 0.0 ) modifiers( )->fScaleY *= ( 1.0 + fZoom ); else modifiers( )->fShearY += fZoom; update ( ); } break; case MenuObject::StateRotate: modifiers()->fScaleX = 1.0; modifiers()->fScaleY = 1.0; default: return MenuObject::mouseMoveEvent ( pEvent ); } m_currentMousePos = pEvent->pos(); return false; } void ImageObject::slotEdit() { mouseDoubleClickEvent(NULL); } void ImageObject::slotProperties() { ImageManipulator *pMan= &manipulator(); DialogGeometry *pGeometry = new DialogGeometry (); pGeometry->initMe(rect(), pMan); connect ( pGeometry->m_pButtonAnimation, SIGNAL(clicked()), this, SLOT(slotAnimation()) ); if (pGeometry->exec() == QDialog::Accepted) { int iX, iY, iWidth, iHeight; iX = pGeometry->m_pEditX->text().toInt(); iY = pGeometry->m_pEditY->text().toInt(); iWidth = pGeometry->m_pEditWidth ->text().toInt(); iHeight = pGeometry->m_pEditHeight->text().toInt(); QRect rect (iX, iY, iWidth, iHeight); ImageManipulator::colorKeying *pColorKey; ListViewColorItem *pItem; uint t; float fDelta; QColor theColor; // First we should remove all entries in the color Key for (t=0;tlistColorKeys.count();t++) delete pMan->listColorKeys[t]; pMan->listColorKeys.clear(); // And then we add whats currently in the widget. if ( pGeometry->m_pListViewCK->childCount() ) { pItem = (ListViewColorItem *)pGeometry->m_pListViewCK->firstChild (); while (pItem) { theColor.setNamedColor (pItem->text (0)); // The Color nam is stored in the first text fDelta = pItem->text(1).toFloat(); // The delta value is stored in the second column. pColorKey = new ImageManipulator::colorKeying ( theColor.rgb(), fDelta ); pMan->listColorKeys.append ( pColorKey ); pItem = (ListViewColorItem *)pItem->itemBelow (); } } setRect (rect); updatePixmap ( ); updateShadow ( ); emit (signalUpdatePixmap()); } delete pGeometry; } void ImageObject::slotAnimation () { // This function gets the Animation Dialog // Within this dialog, you can create a script // (or hardcode) Attributes of the object. // Before rendering the menu the script will // get executed and all data sent to stdout // will be captured in the data file, wich // will provide the data for the animation. QString qsEmpty; DialogAnimation dialog; dialog.initMe ( animation(), 300, 25.0, DialogAnimation::TypeImage ); if ( dialog.exec () == QDialog::Accepted ) setAnimation ( dialog.string () ); if (animation().length () < 5) setAnimation ( qsEmpty ); } void ImageObject::slotRotate90() { rotate (90.0); } void ImageObject::slotRotate180() { rotate (180.0); } void ImageObject::slotRotate270() { rotate (270.0); } void ImageObject::rotate(float fRot) { QWMatrix theMatrix; theMatrix.rotate (fRot); float fRotate = manipulator().fRotate + fRot; if (fRotate > 180.0) fRotate -= 360.0; manipulator().fRotate = fRotate; m_pixmap = m_pixmap.xForm( theMatrix ); emit (signalUpdatePixmap()); parent()->update(); } void ImageObject::slotMatrix() { DialogMatrix *pDialog = new DialogMatrix(MenuObject::parent()); pDialog->initMe(this); connect (this, SIGNAL(signalDeleteMe(MenuObject *)), pDialog, SLOT(slotDeleteObject(MenuObject *))); pDialog->show(); } void ImageObject::slotAddFrame() { MessageBox::warning (NULL, QString ("Not Implemented yet."), QString ("Not Implemented yet."), QMessageBox::Ok , QMessageBox::Cancel); } void ImageObject::slotAddText() { MessageBox::warning (NULL, QString ("Not Implemented yet."), QString ("Not Implemented yet."), QMessageBox::Ok , QMessageBox::Cancel); } void ImageObject::slotDefineAsButton() { emit ( signalDefineAsButton ( this ) ); } MenuObject *ImageObject::clone( QWidget *pParent ) { if ( !pParent ) pParent = MenuObject::parent ( ); ImageObject *pNewObject = new ImageObject ( pParent ); pNewObject->setPixmap ( pixmap ( ) ); pNewObject->setFile ( fileName ( ) ); pNewObject->setZoom ( zoom ( ) ); // The following two are not really needed, since we get those // informations solely from the Normal State - objects ... pNewObject->setRect ( rect ( ) ); pNewObject->setManipulator ( manipulator ( ) ); pNewObject->setAnimation ( animation ( ) ); MenuObject *pShadow = shadow ( ); if ( pShadow ) pShadow = pShadow->clone ( pNewObject, pParent ); pNewObject->setShadow ( pShadow ); return pNewObject; } // Called from xyz, when creating the AnimationAttribute objects, which hold the list of values for the attribute to be set. // Note: only those AnimationAttribute objects are created which are modified during the animation (Menu - video). AnimationAttribute *ImageObject::getSpecificAttributes (long iMaxNumberOfFrames, QString qsProperty) { AnimationAttribute *pAnimAttr = NULL; if (qsProperty == "zoom") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.fZoom, &m_imageManipulator.fZoom); else if (qsProperty == "rotate") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.fRotate, &m_imageManipulator.fRotate); else if (qsProperty == "shear.x") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.fShearX, &m_imageManipulator.fShearX); else if (qsProperty == "shear.y") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.fShearY, &m_imageManipulator.fShearY); else if (qsProperty == "scale.x") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.fScaleX, &m_imageManipulator.fScaleX); else if (qsProperty == "scale.y") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.fScaleY, &m_imageManipulator.fScaleY); else if (qsProperty == "transparency") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.fTransparency, &m_imageManipulator.fTransparency); else if (qsProperty == "backgroundFileName") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.backgroundFileName, &m_imageManipulator.backgroundFileName); else if (qsProperty == "showBackground") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.bShowBackground, &m_imageManipulator.bShowBackground); else if (qsProperty == "startPos.x") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.fStartX, &m_imageManipulator.fStartX); else if (qsProperty == "startPos.y") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.fStartY, &m_imageManipulator.fStartY); else if (qsProperty == "res.x") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.iXRes, &m_imageManipulator.iXRes); else if (qsProperty == "res.y") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.iYRes, &m_imageManipulator.iYRes); else if (qsProperty == "aspectRatio") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.fAspectRatio, &m_imageManipulator.fAspectRatio); else if (qsProperty == "blendColor.red") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.fRed, &m_imageManipulator.fRed); else if (qsProperty == "blendColor.green") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.fGreen, &m_imageManipulator.fGreen); else if (qsProperty == "blendColor.blue") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.fBlue, &m_imageManipulator.fBlue); else if (qsProperty == "brightness") pAnimAttr = new AnimationAttribute (iMaxNumberOfFrames, qsProperty, m_imageManipulator.fBrightness, &m_imageManipulator.fBrightness); return pAnimAttr; }