From 07391315eb5d77e02a3b0569f52c2d45fb22973d Mon Sep 17 00:00:00 2001 From: Cyril Deguet Date: Sat, 3 Dec 2005 11:43:35 +0000 Subject: [PATCH] * all: support of animated bitmaps in skins: there are new attributes "nbFrames" and "fps" in the (Sub)Bitmap elements to set the number of frames and the frame rate in a bitmap. As in the radialslider, the different frames are just laid vertically in the bitamp (and all the frames must have the same size) At the moment animated bitmaps are only supported in Button controls. --- modules/gui/skins2/Modules.am | 2 + modules/gui/skins2/controls/ctrl_button.cpp | 90 ++++++++++---------- modules/gui/skins2/controls/ctrl_button.hpp | 14 ++- modules/gui/skins2/controls/ctrl_generic.cpp | 3 +- modules/gui/skins2/controls/ctrl_generic.hpp | 5 +- modules/gui/skins2/parser/builder.cpp | 6 +- modules/gui/skins2/parser/builder_data.def | 4 +- modules/gui/skins2/parser/builder_data.hpp | 12 ++- modules/gui/skins2/parser/skin_parser.cpp | 10 ++- modules/gui/skins2/src/file_bitmap.cpp | 6 +- modules/gui/skins2/src/file_bitmap.hpp | 3 +- modules/gui/skins2/src/generic_bitmap.cpp | 13 ++- modules/gui/skins2/src/generic_bitmap.hpp | 26 ++++-- modules/gui/skins2/src/os_graphics.hpp | 7 +- share/skins2/skin.dtd | 4 + 15 files changed, 120 insertions(+), 85 deletions(-) diff --git a/modules/gui/skins2/Modules.am b/modules/gui/skins2/Modules.am index ea4076e40f..343764ef84 100644 --- a/modules/gui/skins2/Modules.am +++ b/modules/gui/skins2/Modules.am @@ -91,6 +91,8 @@ SOURCES_skins2 = \ \ src/anchor.cpp \ src/anchor.hpp \ + src/anim_bitmap.cpp \ + src/anim_bitmap.hpp \ src/bitmap_font.cpp \ src/bitmap_font.hpp \ src/dialogs.cpp \ diff --git a/modules/gui/skins2/controls/ctrl_button.cpp b/modules/gui/skins2/controls/ctrl_button.cpp index 0cfe884cbc..eec39d7edd 100644 --- a/modules/gui/skins2/controls/ctrl_button.cpp +++ b/modules/gui/skins2/controls/ctrl_button.cpp @@ -37,24 +37,12 @@ CtrlButton::CtrlButton( intf_thread_t *pIntf, const GenericBitmap &rBmpUp, VarBool *pVisible ): CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ), m_rCommand( rCommand ), m_tooltip( rTooltip ), - m_cmdUpOverDownOver( this ), m_cmdDownOverUpOver( this ), - m_cmdDownOverDown( this ), m_cmdDownDownOver( this ), - m_cmdUpOverUp( this ), m_cmdUpUpOver( this ), - m_cmdDownUp( this ), m_cmdUpHidden( this ), - m_cmdHiddenUp( this ) -{ - // Build the images of the button - OSFactory *pOsFactory = OSFactory::instance( pIntf ); - m_pImgUp = pOsFactory->createOSGraphics( rBmpUp.getWidth(), - rBmpUp.getHeight() ); - m_pImgUp->drawBitmap( rBmpUp, 0, 0 ); - m_pImgDown = pOsFactory->createOSGraphics( rBmpDown.getWidth(), - rBmpDown.getHeight() ); - m_pImgDown->drawBitmap( rBmpDown, 0, 0 ); - m_pImgOver = pOsFactory->createOSGraphics( rBmpOver.getWidth(), - rBmpOver.getHeight() ); - m_pImgOver->drawBitmap( rBmpOver, 0, 0 ); - + m_imgUp( pIntf, rBmpUp ), m_imgOver( pIntf, rBmpOver ), + m_imgDown( pIntf, rBmpDown ), m_pImg( NULL ), m_cmdUpOverDownOver( this ), + m_cmdDownOverUpOver( this ), m_cmdDownOverDown( this ), + m_cmdDownDownOver( this ), m_cmdUpOverUp( this ), m_cmdUpUpOver( this ), + m_cmdDownUp( this ), m_cmdUpHidden( this ), m_cmdHiddenUp( this ) +{ // States m_fsm.addState( "up" ); m_fsm.addState( "down" ); @@ -84,15 +72,12 @@ CtrlButton::CtrlButton( intf_thread_t *pIntf, const GenericBitmap &rBmpUp, // Initial state m_fsm.setState( "up" ); - m_pImg = m_pImgUp; + setImage( &m_imgUp ); } CtrlButton::~CtrlButton() { - SKINS_DELETE( m_pImgUp ); - SKINS_DELETE( m_pImgDown ); - SKINS_DELETE( m_pImgOver ); } @@ -120,26 +105,49 @@ void CtrlButton::draw( OSGraphics &rImage, int xDest, int yDest ) if( m_pImg ) { // Draw the current image - rImage.drawGraphics( *m_pImg, 0, 0, xDest, yDest ); + m_pImg->draw( rImage, xDest, yDest ); + } +} + + +void CtrlButton::setImage( AnimBitmap *pImg ) +{ + AnimBitmap *pOldImg = m_pImg; + m_pImg = pImg; + + if( pOldImg ) + { + pOldImg->stopAnim(); + pOldImg->delObserver( this ); } + + if( pImg ) + { + pImg->startAnim(); + pImg->addObserver( this ); + } + + notifyLayoutMaxSize( pOldImg, pImg ); +} + + +void CtrlButton::onUpdate( Subject &rBitmap ) +{ + notifyLayout(); } void CtrlButton::CmdUpOverDownOver::execute() { m_pParent->captureMouse(); - const OSGraphics *pOldImg = m_pParent->m_pImg; - m_pParent->m_pImg = m_pParent->m_pImgDown; - m_pParent->notifyLayoutMaxSize( pOldImg, m_pParent->m_pImg ); + m_pParent->setImage( &m_pParent->m_imgDown ); } void CtrlButton::CmdDownOverUpOver::execute() { m_pParent->releaseMouse(); - const OSGraphics *pOldImg = m_pParent->m_pImg; - m_pParent->m_pImg = m_pParent->m_pImgUp; - m_pParent->notifyLayoutMaxSize( pOldImg, m_pParent->m_pImg ); + m_pParent->setImage( &m_pParent->m_imgUp ); // Execute the command associated to this button m_pParent->m_rCommand.execute(); } @@ -147,33 +155,25 @@ void CtrlButton::CmdDownOverUpOver::execute() void CtrlButton::CmdDownOverDown::execute() { - const OSGraphics *pOldImg = m_pParent->m_pImg; - m_pParent->m_pImg = m_pParent->m_pImgUp; - m_pParent->notifyLayoutMaxSize( pOldImg, m_pParent->m_pImg ); + m_pParent->setImage( &m_pParent->m_imgUp ); } void CtrlButton::CmdDownDownOver::execute() { - const OSGraphics *pOldImg = m_pParent->m_pImg; - m_pParent->m_pImg = m_pParent->m_pImgDown; - m_pParent->notifyLayoutMaxSize( pOldImg, m_pParent->m_pImg ); + m_pParent->setImage( &m_pParent->m_imgDown ); } void CtrlButton::CmdUpUpOver::execute() { - const OSGraphics *pOldImg = m_pParent->m_pImg; - m_pParent->m_pImg = m_pParent->m_pImgOver; - m_pParent->notifyLayoutMaxSize( pOldImg, m_pParent->m_pImg ); + m_pParent->setImage( &m_pParent->m_imgOver ); } void CtrlButton::CmdUpOverUp::execute() { - const OSGraphics *pOldImg = m_pParent->m_pImg; - m_pParent->m_pImg = m_pParent->m_pImgUp; - m_pParent->notifyLayoutMaxSize( pOldImg, m_pParent->m_pImg ); + m_pParent->setImage( &m_pParent->m_imgUp ); } @@ -185,16 +185,12 @@ void CtrlButton::CmdDownUp::execute() void CtrlButton::CmdUpHidden::execute() { - const OSGraphics *pOldImg = m_pParent->m_pImg; - m_pParent->m_pImg = NULL; - m_pParent->notifyLayoutMaxSize( pOldImg, m_pParent->m_pImg ); + m_pParent->setImage( NULL ); } void CtrlButton::CmdHiddenUp::execute() { - const OSGraphics *pOldImg = m_pParent->m_pImg; - m_pParent->m_pImg = m_pParent->m_pImgUp; - m_pParent->notifyLayoutMaxSize( pOldImg, m_pParent->m_pImg ); + m_pParent->setImage( &m_pParent->m_imgUp ); } diff --git a/modules/gui/skins2/controls/ctrl_button.hpp b/modules/gui/skins2/controls/ctrl_button.hpp index 5b86f14a4d..eb88a06b5a 100644 --- a/modules/gui/skins2/controls/ctrl_button.hpp +++ b/modules/gui/skins2/controls/ctrl_button.hpp @@ -27,14 +27,14 @@ #include "ctrl_generic.hpp" #include "../utils/fsm.hpp" +#include "../src/anim_bitmap.hpp" class GenericBitmap; -class OSGraphics; class CmdGeneric; /// Base class for button controls -class CtrlButton: public CtrlGeneric +class CtrlButton: public CtrlGeneric, public Observer { public: /// Create a button with 3 images @@ -69,9 +69,9 @@ class CtrlButton: public CtrlGeneric /// Tooltip text const UString m_tooltip; /// Images of the button in the different states - OSGraphics *m_pImgUp, *m_pImgOver, *m_pImgDown; + AnimBitmap m_imgUp, m_imgOver, m_imgDown; /// Current image - OSGraphics *m_pImg; + AnimBitmap *m_pImg; /// Callback objects DEFINE_CALLBACK( CtrlButton, UpOverDownOver ) @@ -83,6 +83,12 @@ class CtrlButton: public CtrlGeneric DEFINE_CALLBACK( CtrlButton, DownUp ) DEFINE_CALLBACK( CtrlButton, UpHidden ) DEFINE_CALLBACK( CtrlButton, HiddenUp ) + + /// Change the current image + void setImage( AnimBitmap *pImg ); + + /// Method called when an animated bitmap changes + virtual void onUpdate( Subject &rBitmap ); }; diff --git a/modules/gui/skins2/controls/ctrl_generic.cpp b/modules/gui/skins2/controls/ctrl_generic.cpp index 49d3ac7d22..e19fb28ed6 100644 --- a/modules/gui/skins2/controls/ctrl_generic.cpp +++ b/modules/gui/skins2/controls/ctrl_generic.cpp @@ -80,8 +80,7 @@ void CtrlGeneric::notifyLayout( int width, int height, } -void CtrlGeneric::notifyLayoutMaxSize( const OSGraphics *pImg1, - const OSGraphics *pImg2 ) +void CtrlGeneric::notifyLayoutMaxSize( const Box *pImg1, const Box *pImg2 ) { if( pImg1 == NULL ) { diff --git a/modules/gui/skins2/controls/ctrl_generic.hpp b/modules/gui/skins2/controls/ctrl_generic.hpp index 551fd2eb0a..861c45976f 100644 --- a/modules/gui/skins2/controls/ctrl_generic.hpp +++ b/modules/gui/skins2/controls/ctrl_generic.hpp @@ -31,6 +31,7 @@ #include "../utils/observer.hpp" #include "../commands/cmd_generic.hpp" +class Box; class EvtGeneric; class OSGraphics; class GenericLayout; @@ -94,8 +95,8 @@ class CtrlGeneric: public SkinObject, public Observer /// Same as notifyLayout(), but takes optional images as parameters. /// The maximum size(s) of the images will be used for repainting. - void notifyLayoutMaxSize( const OSGraphics *pImg1 = NULL, - const OSGraphics *pImg2 = NULL ); + void notifyLayoutMaxSize( const Box *pImg1 = NULL, + const Box *pImg2 = NULL ); /// Ask the layout to capture the mouse virtual void captureMouse() const; diff --git a/modules/gui/skins2/parser/builder.cpp b/modules/gui/skins2/parser/builder.cpp index 555b97a90a..5f9b4fa3d7 100644 --- a/modules/gui/skins2/parser/builder.cpp +++ b/modules/gui/skins2/parser/builder.cpp @@ -146,7 +146,8 @@ void Builder::addBitmap( const BuilderData::Bitmap &rData ) { GenericBitmap *pBmp = new FileBitmap( getIntf(), m_pImageHandler, - getFilePath( rData.m_fileName ), rData.m_alphaColor ); + getFilePath( rData.m_fileName ), rData.m_alphaColor, + rData.m_nbFrames, rData.m_fps ); if( !pBmp->getData() ) { // Invalid bitmap @@ -171,7 +172,8 @@ void Builder::addSubBitmap( const BuilderData::SubBitmap &rData ) // Copy a region of the parent bitmap to the new one BitmapImpl *pBmp = - new BitmapImpl( getIntf(), rData.m_width, rData.m_height ); + new BitmapImpl( getIntf(), rData.m_width, rData.m_height, + rData.m_nbFrames, rData.m_fps ); bool res = pBmp->drawBitmap( *pParentBmp, rData.m_x, rData.m_y, 0, 0, rData.m_width, rData.m_height ); if( !res ) diff --git a/modules/gui/skins2/parser/builder_data.def b/modules/gui/skins2/parser/builder_data.def index 2fc2f6e67e..a534166f3b 100644 --- a/modules/gui/skins2/parser/builder_data.def +++ b/modules/gui/skins2/parser/builder_data.def @@ -1,6 +1,6 @@ Theme tooltipfont:string magnet:int alpha:uint32_t moveAlpha:uint32_t -Bitmap id:string fileName:string alphaColor:uint32_t -SubBitmap id:string parent:string x:int y:int width:int height:int +Bitmap id:string fileName:string alphaColor:uint32_t nbFrames:int fps:int +SubBitmap id:string parent:string x:int y:int width:int height:int nbFrames:int fps:int BitmapFont id:string file:string type:string Font id:string fontFile:string size:int Window id:string xPos:int yPos:int visible:bool dragDrop:bool playOnDrop:bool diff --git a/modules/gui/skins2/parser/builder_data.hpp b/modules/gui/skins2/parser/builder_data.hpp index d75d8afb6f..eb02df37af 100644 --- a/modules/gui/skins2/parser/builder_data.hpp +++ b/modules/gui/skins2/parser/builder_data.hpp @@ -56,12 +56,14 @@ m_tooltipfont( tooltipfont ), m_magnet( magnet ), m_alpha( alpha ), m_moveAlpha( /// Type definition struct Bitmap { - Bitmap( const string & id, const string & fileName, uint32_t alphaColor ): -m_id( id ), m_fileName( fileName ), m_alphaColor( alphaColor ) {} + Bitmap( const string & id, const string & fileName, uint32_t alphaColor, int nbFrames, int fps ): +m_id( id ), m_fileName( fileName ), m_alphaColor( alphaColor ), m_nbFrames( nbFrames ), m_fps( fps ) {} string m_id; string m_fileName; uint32_t m_alphaColor; + int m_nbFrames; + int m_fps; }; /// List list m_listBitmap; @@ -69,8 +71,8 @@ m_id( id ), m_fileName( fileName ), m_alphaColor( alphaColor ) {} /// Type definition struct SubBitmap { - SubBitmap( const string & id, const string & parent, int x, int y, int width, int height ): -m_id( id ), m_parent( parent ), m_x( x ), m_y( y ), m_width( width ), m_height( height ) {} + SubBitmap( const string & id, const string & parent, int x, int y, int width, int height, int nbFrames, int fps ): +m_id( id ), m_parent( parent ), m_x( x ), m_y( y ), m_width( width ), m_height( height ), m_nbFrames( nbFrames ), m_fps( fps ) {} string m_id; string m_parent; @@ -78,6 +80,8 @@ m_id( id ), m_parent( parent ), m_x( x ), m_y( y ), m_width( width ), m_height( int m_y; int m_width; int m_height; + int m_nbFrames; + int m_fps; }; /// List list m_listSubBitmap; diff --git a/modules/gui/skins2/parser/skin_parser.cpp b/modules/gui/skins2/parser/skin_parser.cpp index 575735f4ef..3adff6a4d1 100644 --- a/modules/gui/skins2/parser/skin_parser.cpp +++ b/modules/gui/skins2/parser/skin_parser.cpp @@ -91,10 +91,13 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) RequireDefault( "id" ); RequireDefault( "file" ); RequireDefault( "alphacolor" ); + CheckDefault( "nbFrames", "1" ); + CheckDefault( "fps", "4" ); m_curBitmapId = uniqueId( attr["id"] ); const BuilderData::Bitmap bitmap( m_curBitmapId, - attr["file"], convertColor( attr["alphacolor"] ) ); + attr["file"], convertColor( attr["alphacolor"] ), + atoi( attr["nbFrames"] ), atoi( attr["fps"] ) ); m_pData->m_listBitmap.push_back( bitmap ); } @@ -105,10 +108,13 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr ) RequireDefault( "y" ); RequireDefault( "width" ); RequireDefault( "height" ); + CheckDefault( "nbFrames", "1" ); + CheckDefault( "fps", "4" ); const BuilderData::SubBitmap bitmap( attr["id"], m_curBitmapId, atoi( attr["x"] ), atoi( attr["y"] ), - atoi( attr["width"] ), atoi( attr["height"] ) ); + atoi( attr["width"] ), atoi( attr["height"] ), + atoi( attr["nbFrames"] ), atoi( attr["fps"] ) ); m_pData->m_listSubBitmap.push_back( bitmap ); } diff --git a/modules/gui/skins2/src/file_bitmap.cpp b/modules/gui/skins2/src/file_bitmap.cpp index 99fcc5d862..a3e500d4fa 100644 --- a/modules/gui/skins2/src/file_bitmap.cpp +++ b/modules/gui/skins2/src/file_bitmap.cpp @@ -27,8 +27,10 @@ #include "file_bitmap.hpp" FileBitmap::FileBitmap( intf_thread_t *pIntf, image_handler_t *pImageHandler, - string fileName, uint32_t aColor ): - GenericBitmap( pIntf ), m_width( 0 ), m_height( 0 ), m_pData( NULL ) + string fileName, uint32_t aColor, int nbFrames, + int fps ): + GenericBitmap( pIntf, nbFrames, fps ), m_width( 0 ), m_height( 0 ), + m_pData( NULL ) { video_format_t fmt_in = {0}, fmt_out = {0}; picture_t *pPic; diff --git a/modules/gui/skins2/src/file_bitmap.hpp b/modules/gui/skins2/src/file_bitmap.hpp index a26721c579..426b981e1a 100644 --- a/modules/gui/skins2/src/file_bitmap.hpp +++ b/modules/gui/skins2/src/file_bitmap.hpp @@ -36,7 +36,8 @@ class FileBitmap: public GenericBitmap /// Load a bitmap from a file. aColor is the transparency /// color, in the format 0xRRGGBB FileBitmap( intf_thread_t *pIntf, image_handler_t *pImageHandler, - string fileName, uint32_t aColor ); + string fileName, uint32_t aColor, int nbFrames = 1, + int fps = 0 ); virtual ~FileBitmap(); diff --git a/modules/gui/skins2/src/generic_bitmap.cpp b/modules/gui/skins2/src/generic_bitmap.cpp index 5a9b96417a..146210aa3f 100644 --- a/modules/gui/skins2/src/generic_bitmap.cpp +++ b/modules/gui/skins2/src/generic_bitmap.cpp @@ -24,9 +24,16 @@ #include "generic_bitmap.hpp" -BitmapImpl::BitmapImpl( intf_thread_t *pIntf, int width, int height ): - GenericBitmap( pIntf ), m_width( width ), m_height( height ), - m_pData( NULL ) +GenericBitmap::GenericBitmap( intf_thread_t *pIntf, int nbFrames, int fps ): + SkinObject( pIntf ), m_nbFrames( nbFrames ), m_frameRate( fps ) +{ +} + + +BitmapImpl::BitmapImpl( intf_thread_t *pIntf, int width, int height, + int nbFrames, int fps ): + GenericBitmap( pIntf, nbFrames, fps ), m_width( width ), + m_height( height ), m_pData( NULL ) { m_pData = new uint8_t[width * height * 4]; memset( m_pData, 0, width * height * 4 ); diff --git a/modules/gui/skins2/src/generic_bitmap.hpp b/modules/gui/skins2/src/generic_bitmap.hpp index e33514be2a..75f5c4eeb1 100644 --- a/modules/gui/skins2/src/generic_bitmap.hpp +++ b/modules/gui/skins2/src/generic_bitmap.hpp @@ -27,26 +27,33 @@ #include "skin_common.hpp" #include "../utils/pointer.hpp" +#include "../utils/position.hpp" /// Generic interface for bitmaps -class GenericBitmap: public SkinObject +class GenericBitmap: public SkinObject, public Box { public: virtual ~GenericBitmap() {} - /// Get the width of the bitmap - virtual int getWidth() const = 0; - - /// Get the heighth of the bitmap - virtual int getHeight() const = 0; - /// Get a linear buffer containing the image data. /// Each pixel is stored in 4 bytes in the order B,G,R,A virtual uint8_t *getData() const = 0; + /// Get the number of frames in the bitmap + int getNbFrames() const { return m_nbFrames; } + + /// Get the number of frames per second (for animated bitmaps) + int getFrameRate() const { return m_frameRate; } + protected: - GenericBitmap( intf_thread_t *pIntf ): SkinObject( pIntf ) {} + GenericBitmap( intf_thread_t *pIntf, int nbFrames = 1, int fps = 0); + + private: + /// Number of frames + int m_nbFrames; + /// Frame rate + int m_frameRate; }; @@ -55,7 +62,8 @@ class BitmapImpl: public GenericBitmap { public: /// Create an empty bitmap of the given size - BitmapImpl( intf_thread_t *pIntf, int width, int height ); + BitmapImpl( intf_thread_t *pIntf, int width, int height, + int nbFrames = 1, int fps = 0 ); ~BitmapImpl(); /// Get the width of the bitmap diff --git a/modules/gui/skins2/src/os_graphics.hpp b/modules/gui/skins2/src/os_graphics.hpp index e74bd60a90..c71de4e307 100644 --- a/modules/gui/skins2/src/os_graphics.hpp +++ b/modules/gui/skins2/src/os_graphics.hpp @@ -26,6 +26,7 @@ #define OS_GRAPHICS_HPP #include "skin_common.hpp" +#include "../utils/position.hpp" #include "../utils/pointer.hpp" class GenericBitmap; @@ -33,7 +34,7 @@ class OSWindow; /// OS specific graphics class -class OSGraphics: public SkinObject +class OSGraphics: public SkinObject, public Box { public: virtual ~OSGraphics() {} @@ -72,10 +73,6 @@ class OSGraphics: public SkinObject /// Tell whether the pixel at the given position is visible virtual bool hit( int x, int y ) const = 0; - /// Getters - virtual int getWidth() const = 0; - virtual int getHeight() const = 0; - protected: OSGraphics( intf_thread_t *pIntf ): SkinObject( pIntf ) {} }; diff --git a/share/skins2/skin.dtd b/share/skins2/skin.dtd index b939d718ca..635e23918a 100644 --- a/share/skins2/skin.dtd +++ b/share/skins2/skin.dtd @@ -21,6 +21,8 @@ id CDATA #REQUIRED file CDATA #REQUIRED alphacolor CDATA #REQUIRED + nbFrames CDATA "1" + fps CDATA "0" >