Commit 07391315 authored by Cyril Deguet's avatar Cyril Deguet

* 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.
parent eba35637
......@@ -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 \
......
......@@ -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<AnimBitmap> &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 );
}
......@@ -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<AnimBitmap>
{
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<AnimBitmap> &rBitmap );
};
......
......@@ -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 )
{
......
......@@ -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<VarBool>
/// 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;
......
......@@ -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 )
......
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
......
......@@ -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<Bitmap> 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<SubBitmap> m_listSubBitmap;
......
......@@ -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 );
}
......
......@@ -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;
......
......@@ -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();
......
......@@ -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 );
......
......@@ -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
......
......@@ -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 ) {}
};
......
......@@ -21,6 +21,8 @@
id CDATA #REQUIRED
file CDATA #REQUIRED
alphacolor CDATA #REQUIRED
nbFrames CDATA "1"
fps CDATA "0"
>
<!ELEMENT SubBitmap EMPTY>
<!ATTLIST SubBitmap
......@@ -29,6 +31,8 @@
y CDATA #REQUIRED
width CDATA #REQUIRED
height CDATA #REQUIRED
nbFrames CDATA "1"
fps CDATA "0"
>
<!ELEMENT Font EMPTY>
<!ATTLIST Font
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment