Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

builder.cpp

00001 /*****************************************************************************
00002  * builder.cpp
00003  *****************************************************************************
00004  * Copyright (C) 2003 the VideoLAN team
00005  * $Id: builder.cpp 12912 2005-10-22 11:57:29Z asmax $
00006  *
00007  * Authors: Cyril Deguet     <[email protected]>
00008  *          Olivier Teulière <[email protected]>
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00023  *****************************************************************************/
00024 
00025 #include <string.h>
00026 #include "builder.hpp"
00027 #include "builder_data.hpp"
00028 #include "interpreter.hpp"
00029 #include "../src/png_bitmap.hpp"
00030 #include "../src/os_factory.hpp"
00031 #include "../src/generic_bitmap.hpp"
00032 #include "../src/top_window.hpp"
00033 #include "../src/anchor.hpp"
00034 #include "../src/bitmap_font.hpp"
00035 #include "../src/ft2_font.hpp"
00036 #include "../src/theme.hpp"
00037 #include "../controls/ctrl_button.hpp"
00038 #include "../controls/ctrl_checkbox.hpp"
00039 #include "../controls/ctrl_image.hpp"
00040 #include "../controls/ctrl_list.hpp"
00041 #include "../controls/ctrl_move.hpp"
00042 #include "../controls/ctrl_resize.hpp"
00043 #include "../controls/ctrl_slider.hpp"
00044 #include "../controls/ctrl_radialslider.hpp"
00045 #include "../controls/ctrl_text.hpp"
00046 #include "../controls/ctrl_tree.hpp"
00047 #include "../controls/ctrl_video.hpp"
00048 #include "../utils/position.hpp"
00049 #include "../utils/var_bool.hpp"
00050 #include "../utils/var_text.hpp"
00051 
00052 #include "vlc_image.h"
00053 
00054 
00055 Builder::Builder( intf_thread_t *pIntf, const BuilderData &rData ):
00056     SkinObject( pIntf ), m_rData( rData ), m_pTheme( NULL )
00057 {
00058     m_pImageHandler = image_HandlerCreate( pIntf );
00059 }
00060 
00061 Builder::~Builder()
00062 {
00063     if( m_pImageHandler ) image_HandlerDelete( m_pImageHandler );
00064 }
00065 
00066 CmdGeneric *Builder::parseAction( const string &rAction )
00067 {
00068     return Interpreter::instance( getIntf() )->parseAction( rAction, m_pTheme );
00069 }
00070 
00071 
00072 // Useful macro
00073 #define ADD_OBJECTS( type ) \
00074     list<BuilderData::type>::const_iterator it##type; \
00075     for( it##type = m_rData.m_list##type.begin(); \
00076          it##type != m_rData.m_list##type.end(); it##type++ ) \
00077     { \
00078         add##type( *it##type ); \
00079     }
00080 
00081 
00082 Theme *Builder::build()
00083 {
00084     m_pTheme = new Theme( getIntf() );
00085     if( m_pTheme == NULL )
00086     {
00087         return NULL;
00088     }
00089 
00090     // Create everything from the data in the XML
00091     ADD_OBJECTS( Theme );
00092     ADD_OBJECTS( Bitmap );
00093     ADD_OBJECTS( BitmapFont );
00094     ADD_OBJECTS( Font );
00095     ADD_OBJECTS( Window );
00096     ADD_OBJECTS( Layout );
00097     ADD_OBJECTS( Anchor );
00098     ADD_OBJECTS( Button );
00099     ADD_OBJECTS( Checkbox );
00100     ADD_OBJECTS( Image );
00101     ADD_OBJECTS( Text );
00102     ADD_OBJECTS( RadialSlider );
00103     ADD_OBJECTS( Slider );
00104     ADD_OBJECTS( List );
00105     ADD_OBJECTS( Tree );
00106     ADD_OBJECTS( Video );
00107 
00108     return m_pTheme;
00109 }
00110 
00111 
00112 // Macro to get a bitmap by its ID in the builder
00113 #define GET_BMP( pBmp, id ) \
00114     if( id != "none" ) \
00115     { \
00116         pBmp = m_pTheme->getBitmapById(id); \
00117         if( pBmp == NULL ) \
00118         { \
00119             msg_Err( getIntf(), "unknown bitmap id: %s", id.c_str() ); \
00120             return; \
00121         } \
00122     }
00123 
00124 void Builder::addTheme( const BuilderData::Theme &rData )
00125 {
00126     WindowManager &rManager = m_pTheme->getWindowManager();
00127     rManager.setMagnetValue( rData.m_magnet );
00128     rManager.setAlphaValue( rData.m_alpha );
00129     rManager.setMoveAlphaValue( rData.m_moveAlpha );
00130     GenericFont *pFont = getFont( rData.m_tooltipfont );
00131     if( pFont )
00132     {
00133         rManager.createTooltip( *pFont );
00134     }
00135     else
00136     {
00137         msg_Warn( getIntf(), "Invalid tooltip font: %s",
00138                   rData.m_tooltipfont.c_str() );
00139     }
00140 }
00141 
00142 
00143 void Builder::addBitmap( const BuilderData::Bitmap &rData )
00144 {
00145     GenericBitmap *pBmp =
00146         new PngBitmap( getIntf(), m_pImageHandler,
00147                        rData.m_fileName, rData.m_alphaColor );
00148     m_pTheme->m_bitmaps[rData.m_id] = GenericBitmapPtr( pBmp );
00149 }
00150 
00151 
00152 void Builder::addBitmapFont( const BuilderData::BitmapFont &rData )
00153 {
00154     GenericBitmap *pBmp =
00155         new PngBitmap( getIntf(), m_pImageHandler, rData.m_file, 0 );
00156     m_pTheme->m_bitmaps[rData.m_id] = GenericBitmapPtr( pBmp );
00157 
00158     GenericFont *pFont = new BitmapFont( getIntf(), *pBmp, rData.m_type );
00159     if( pFont->init() )
00160     {
00161         m_pTheme->m_fonts[rData.m_id] = GenericFontPtr( pFont );
00162     }
00163     else
00164     {
00165         delete pFont;
00166     }
00167 }
00168 
00169 
00170 void Builder::addFont( const BuilderData::Font &rData )
00171 {
00172     GenericFont *pFont = new FT2Font( getIntf(), rData.m_fontFile,
00173                                       rData.m_size );
00174     if( pFont->init() )
00175     {
00176         m_pTheme->m_fonts[rData.m_id] = GenericFontPtr( pFont );
00177     }
00178     else
00179     {
00180         delete pFont;
00181     }
00182 }
00183 
00184 
00185 void Builder::addWindow( const BuilderData::Window &rData )
00186 {
00187     TopWindow *pWin =
00188         new TopWindow( getIntf(), rData.m_xPos, rData.m_yPos,
00189                        m_pTheme->getWindowManager(),
00190                        rData.m_dragDrop, rData.m_playOnDrop,
00191                        rData.m_visible );
00192 
00193     m_pTheme->m_windows[rData.m_id] = TopWindowPtr( pWin );
00194 }
00195 
00196 
00197 void Builder::addLayout( const BuilderData::Layout &rData )
00198 {
00199     TopWindow *pWin = m_pTheme->getWindowById(rData.m_windowId);
00200     if( pWin == NULL )
00201     {
00202         msg_Err( getIntf(), "unknown window id: %s", rData.m_windowId.c_str() );
00203         return;
00204     }
00205 
00206     int minWidth = rData.m_minWidth != -1 ? rData.m_minWidth : rData.m_width;
00207     int maxWidth = rData.m_maxWidth != -1 ? rData.m_maxWidth : rData.m_width;
00208     int minHeight = rData.m_minHeight != -1 ? rData.m_minHeight :
00209                     rData.m_height;
00210     int maxHeight = rData.m_maxHeight != -1 ? rData.m_maxHeight :
00211                     rData.m_height;
00212     GenericLayout *pLayout = new GenericLayout( getIntf(), rData.m_width,
00213                                                 rData.m_height,
00214                                                 minWidth, maxWidth, minHeight,
00215                                                 maxHeight );
00216     m_pTheme->m_layouts[rData.m_id] = GenericLayoutPtr( pLayout );
00217 
00218     // Attach the layout to its window
00219     m_pTheme->getWindowManager().addLayout( *pWin, *pLayout );
00220 }
00221 
00222 
00223 void Builder::addAnchor( const BuilderData::Anchor &rData )
00224 {
00225     GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId);
00226     if( pLayout == NULL )
00227     {
00228         msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
00229         return;
00230     }
00231 
00232     Bezier *pCurve = getPoints( rData.m_points.c_str() );
00233     if( pCurve == NULL )
00234     {
00235         msg_Err( getIntf(), "Invalid format in tag points=\"%s\"",
00236                  rData.m_points.c_str() );
00237         return;
00238     }
00239     m_pTheme->m_curves.push_back( BezierPtr( pCurve ) );
00240 
00241     Anchor *pAnc = new Anchor( getIntf(), rData.m_xPos, rData.m_yPos,
00242                                rData.m_range, rData.m_priority,
00243                                *pCurve, *pLayout );
00244     pLayout->addAnchor( pAnc );
00245 }
00246 
00247 
00248 void Builder::addButton( const BuilderData::Button &rData )
00249 {
00250     // Get the bitmaps of the button
00251     GenericBitmap *pBmpUp = NULL;
00252     GET_BMP( pBmpUp, rData.m_upId );
00253 
00254     GenericBitmap *pBmpDown = pBmpUp;
00255     GET_BMP( pBmpDown, rData.m_downId );
00256 
00257     GenericBitmap *pBmpOver = pBmpUp;
00258     GET_BMP( pBmpOver, rData.m_overId );
00259 
00260     GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId);
00261     if( pLayout == NULL )
00262     {
00263         msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
00264         return;
00265     }
00266 
00267     CmdGeneric *pCommand = parseAction( rData.m_actionId );
00268     if( pCommand == NULL )
00269     {
00270         msg_Err( getIntf(), "Invalid action: %s", rData.m_actionId.c_str() );
00271         return;
00272     }
00273 
00274     // Get the visibility variable
00275     // XXX check when it is null
00276     Interpreter *pInterpreter = Interpreter::instance( getIntf() );
00277     VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
00278 
00279     CtrlButton *pButton = new CtrlButton( getIntf(), *pBmpUp, *pBmpOver,
00280         *pBmpDown, *pCommand, UString( getIntf(), rData.m_tooltip.c_str() ),
00281         UString( getIntf(), rData.m_help.c_str() ), pVisible );
00282 
00283     // Compute the position of the control
00284     // XXX (we suppose all the images have the same size...)
00285     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
00286                                        rData.m_xPos, rData.m_yPos,
00287                                        pBmpUp->getWidth(),
00288                                        pBmpUp->getHeight(), *pLayout );
00289 
00290     pLayout->addControl( pButton, pos, rData.m_layer );
00291 
00292     m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pButton );
00293 }
00294 
00295 
00296 void Builder::addCheckbox( const BuilderData::Checkbox &rData )
00297 {
00298     // Get the bitmaps of the checkbox
00299     GenericBitmap *pBmpUp1 = NULL;
00300     GET_BMP( pBmpUp1, rData.m_up1Id );
00301 
00302     GenericBitmap *pBmpDown1 = pBmpUp1;
00303     GET_BMP( pBmpDown1, rData.m_down1Id );
00304 
00305     GenericBitmap *pBmpOver1 = pBmpUp1;
00306     GET_BMP( pBmpOver1, rData.m_over1Id );
00307 
00308     GenericBitmap *pBmpUp2 = NULL;
00309     GET_BMP( pBmpUp2, rData.m_up2Id );
00310 
00311     GenericBitmap *pBmpDown2 = pBmpUp2;
00312     GET_BMP( pBmpDown2, rData.m_down2Id );
00313 
00314     GenericBitmap *pBmpOver2 = pBmpUp2;
00315     GET_BMP( pBmpOver2, rData.m_over2Id );
00316 
00317     GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId);
00318     if( pLayout == NULL )
00319     {
00320         msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
00321         return;
00322     }
00323 
00324     CmdGeneric *pCommand1 = parseAction( rData.m_action1 );
00325     if( pCommand1 == NULL )
00326     {
00327         msg_Err( getIntf(), "Invalid action: %s", rData.m_action1.c_str() );
00328         return;
00329     }
00330 
00331     CmdGeneric *pCommand2 = parseAction( rData.m_action2 );
00332     if( pCommand2 == NULL )
00333     {
00334         msg_Err( getIntf(), "Invalid action: %s", rData.m_action2.c_str() );
00335         return;
00336     }
00337 
00338     // Get the state variable
00339     Interpreter *pInterpreter = Interpreter::instance( getIntf() );
00340     VarBool *pVar = pInterpreter->getVarBool( rData.m_state, m_pTheme );
00341     if( pVar == NULL )
00342     {
00343         // TODO: default state
00344         return;
00345     }
00346 
00347     // Get the visibility variable
00348     // XXX check when it is null
00349     VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
00350 
00351     // Create the control
00352     CtrlCheckbox *pCheckbox = new CtrlCheckbox( getIntf(), *pBmpUp1,
00353         *pBmpOver1, *pBmpDown1, *pBmpUp2, *pBmpOver2, *pBmpDown2, *pCommand1,
00354         *pCommand2, UString( getIntf(), rData.m_tooltip1.c_str() ),
00355         UString( getIntf(), rData.m_tooltip2.c_str() ), *pVar,
00356         UString( getIntf(), rData.m_help.c_str() ), pVisible );
00357 
00358     // Compute the position of the control
00359     // XXX (we suppose all the images have the same size...)
00360     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
00361                                        rData.m_xPos, rData.m_yPos,
00362                                        pBmpUp1->getWidth(),
00363                                        pBmpUp1->getHeight(), *pLayout );
00364 
00365     pLayout->addControl( pCheckbox, pos, rData.m_layer );
00366 
00367     m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pCheckbox );
00368 }
00369 
00370 
00371 void Builder::addImage( const BuilderData::Image &rData )
00372 {
00373     GenericBitmap *pBmp = NULL;
00374     GET_BMP( pBmp, rData.m_bmpId );
00375 
00376     GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId);
00377     if( pLayout == NULL )
00378     {
00379         msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
00380         return;
00381     }
00382 
00383     TopWindow *pWindow = m_pTheme->getWindowById(rData.m_windowId);
00384     if( pWindow == NULL )
00385     {
00386         msg_Err( getIntf(), "unknown window id: %s", rData.m_windowId.c_str() );
00387         return;
00388     }
00389 
00390     // Get the visibility variable
00391     // XXX check when it is null
00392     Interpreter *pInterpreter = Interpreter::instance( getIntf() );
00393     VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
00394 
00395     CtrlImage::resize_t resizeMethod =
00396         (rData.m_resize == "scale" ? CtrlImage::kScale : CtrlImage::kMosaic);
00397     CtrlImage *pImage = new CtrlImage( getIntf(), *pBmp, resizeMethod,
00398         UString( getIntf(), rData.m_help.c_str() ), pVisible );
00399 
00400     // Compute the position of the control
00401     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
00402                                        rData.m_xPos,
00403                                        rData.m_yPos, pBmp->getWidth(),
00404                                        pBmp->getHeight(), *pLayout );
00405 
00406     // XXX: test to be changed! XXX
00407     if( rData.m_actionId == "move" )
00408     {
00409         CtrlMove *pMove = new CtrlMove( getIntf(), m_pTheme->getWindowManager(),
00410              *pImage, *pWindow, UString( getIntf(), rData.m_help.c_str() ),
00411              NULL);
00412         pLayout->addControl( pMove, pos, rData.m_layer );
00413     }
00414     else if( rData.m_actionId == "resizeSE" )
00415     {
00416         CtrlResize *pResize = new CtrlResize( getIntf(), *pImage, *pLayout,
00417                 UString( getIntf(), rData.m_help.c_str() ), NULL );
00418         pLayout->addControl( pResize, pos, rData.m_layer );
00419     }
00420     else
00421     {
00422         pLayout->addControl( pImage, pos, rData.m_layer );
00423     }
00424 
00425     m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pImage );
00426 }
00427 
00428 
00429 void Builder::addText( const BuilderData::Text &rData )
00430 {
00431     GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId);
00432     if( pLayout == NULL )
00433     {
00434         msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
00435         return;
00436     }
00437 
00438     GenericFont *pFont = getFont( rData.m_fontId );
00439     if( pFont == NULL )
00440     {
00441         msg_Err( getIntf(), "Unknown font id: %s", rData.m_fontId.c_str() );
00442         return;
00443     }
00444 
00445     // Create a text variable
00446     VarText *pVar = new VarText( getIntf() );
00447     UString msg( getIntf(), rData.m_text.c_str() );
00448     pVar->set( msg );
00449     m_pTheme->m_vars.push_back( VariablePtr( pVar ) );
00450 
00451     // Get the visibility variable
00452     // XXX check when it is null
00453     Interpreter *pInterpreter = Interpreter::instance( getIntf() );
00454     VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
00455 
00456     CtrlText *pText = new CtrlText( getIntf(), *pVar, *pFont,
00457         UString( getIntf(), rData.m_help.c_str() ), rData.m_color, pVisible );
00458 
00459     int height = pFont->getSize();
00460 
00461     // Compute the position of the control
00462     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
00463                                        rData.m_xPos, rData.m_yPos,
00464                                        rData.m_width, height,
00465                                        *pLayout );
00466 
00467     pLayout->addControl( pText, pos, rData.m_layer );
00468 
00469     m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pText );
00470 }
00471 
00472 
00473 void Builder::addRadialSlider( const BuilderData::RadialSlider &rData )
00474 {
00475     // Get the bitmaps of the slider
00476     GenericBitmap *pSeq = NULL;
00477     GET_BMP( pSeq, rData.m_sequence );
00478 
00479     GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId);
00480     if( pLayout == NULL )
00481     {
00482         msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
00483         return;
00484     }
00485 
00486     // Get the variable associated to the slider
00487     Interpreter *pInterpreter = Interpreter::instance( getIntf() );
00488     VarPercent *pVar = pInterpreter->getVarPercent( rData.m_value, m_pTheme );
00489     if( pVar == NULL )
00490     {
00491         msg_Err( getIntf(), "Unknown slider value: %s", rData.m_value.c_str() );
00492         return;
00493     }
00494 
00495     // Get the visibility variable
00496     // XXX check when it is null
00497     VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
00498 
00499     // Create the control
00500     CtrlRadialSlider *pRadial =
00501         new CtrlRadialSlider( getIntf(), *pSeq, rData.m_nbImages, *pVar,
00502                               rData.m_minAngle, rData.m_maxAngle,
00503                               UString( getIntf(), rData.m_help.c_str() ),
00504                               pVisible );
00505 
00506     // XXX: resizing is not supported
00507     // Compute the position of the control
00508     const Position pos =
00509         makePosition( rData.m_leftTop, rData.m_rightBottom, rData.m_xPos,
00510                       rData.m_yPos, pSeq->getWidth(),
00511                       pSeq->getHeight() / rData.m_nbImages, *pLayout );
00512 
00513     pLayout->addControl( pRadial, pos, rData.m_layer );
00514 
00515     m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pRadial );
00516 }
00517 
00518 
00519 void Builder::addSlider( const BuilderData::Slider &rData )
00520 {
00521     // Get the bitmaps of the slider
00522     GenericBitmap *pBmpUp = NULL;
00523     GET_BMP( pBmpUp, rData.m_upId );
00524 
00525     GenericBitmap *pBmpDown = pBmpUp;
00526     GET_BMP( pBmpDown, rData.m_downId );
00527 
00528     GenericBitmap *pBmpOver = pBmpUp;
00529     GET_BMP( pBmpOver, rData.m_overId );
00530 
00531     GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId);
00532     if( pLayout == NULL )
00533     {
00534         msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
00535         return;
00536     }
00537 
00538     Bezier *pCurve = getPoints( rData.m_points.c_str() );
00539     if( pCurve == NULL )
00540     {
00541         msg_Err( getIntf(), "Invalid format in tag points=\"%s\"",
00542                  rData.m_points.c_str() );
00543         return;
00544     }
00545     m_pTheme->m_curves.push_back( BezierPtr( pCurve ) );
00546 
00547     // Get the visibility variable
00548     // XXX check when it is null
00549     Interpreter *pInterpreter = Interpreter::instance( getIntf() );
00550     VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
00551 
00552     // Get the variable associated to the slider
00553     VarPercent *pVar = pInterpreter->getVarPercent( rData.m_value, m_pTheme );
00554     if( pVar == NULL )
00555     {
00556         msg_Err( getIntf(), "Unknown slider value: %s", rData.m_value.c_str() );
00557         return;
00558     }
00559 
00560     // Create the cursor and background controls
00561     CtrlSliderCursor *pCursor = new CtrlSliderCursor( getIntf(), *pBmpUp,
00562         *pBmpOver, *pBmpDown, *pCurve, *pVar, pVisible,
00563         UString( getIntf(), rData.m_tooltip.c_str() ),
00564         UString( getIntf(), rData.m_help.c_str() ) );
00565 
00566     CtrlSliderBg *pBackground = new CtrlSliderBg( getIntf(), *pCursor,
00567         *pCurve, *pVar, rData.m_thickness, pVisible,
00568         UString( getIntf(), rData.m_help.c_str() ) );
00569 
00570     // Compute the position of the control
00571     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
00572                                        rData.m_xPos, rData.m_yPos,
00573                                        pCurve->getWidth(), pCurve->getHeight(),
00574                                        *pLayout );
00575 
00576     pLayout->addControl( pBackground, pos, rData.m_layer );
00577     pLayout->addControl( pCursor, pos, rData.m_layer );
00578 
00579     m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pCursor );
00580     m_pTheme->m_controls[rData.m_id + "_bg"] = CtrlGenericPtr( pBackground );
00581 }
00582 
00583 
00584 void Builder::addList( const BuilderData::List &rData )
00585 {
00586     // Get the background bitmap, if any
00587     GenericBitmap *pBgBmp = NULL;
00588     GET_BMP( pBgBmp, rData.m_bgImageId );
00589 
00590     GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId);
00591     if( pLayout == NULL )
00592     {
00593         msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
00594         return;
00595     }
00596 
00597     GenericFont *pFont = getFont( rData.m_fontId );
00598     if( pFont == NULL )
00599     {
00600         msg_Err( getIntf(), "Unknown font id: %s", rData.m_fontId.c_str() );
00601         return;
00602     }
00603 
00604     // Get the list variable
00605     Interpreter *pInterpreter = Interpreter::instance( getIntf() );
00606     VarList *pVar = pInterpreter->getVarList( rData.m_var, m_pTheme );
00607     if( pVar == NULL )
00608     {
00609         msg_Err( getIntf(), "No such list variable: %s", rData.m_var.c_str() );
00610         return;
00611     }
00612 
00613     // Get the visibility variable
00614     // XXX check when it is null
00615     VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
00616 
00617     // Create the list control
00618     CtrlList *pList = new CtrlList( getIntf(), *pVar, *pFont, pBgBmp,
00619        rData.m_fgColor, rData.m_playColor, rData.m_bgColor1,
00620        rData.m_bgColor2, rData.m_selColor,
00621        UString( getIntf(), rData.m_help.c_str() ), pVisible );
00622 
00623     // Compute the position of the control
00624     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
00625                                        rData.m_xPos, rData.m_yPos,
00626                                        rData.m_width, rData.m_height,
00627                                        *pLayout );
00628 
00629     pLayout->addControl( pList, pos, rData.m_layer );
00630 
00631     m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pList );
00632 }
00633 
00634 void Builder::addTree( const BuilderData::Tree &rData )
00635 {
00636     // Get the bitmaps, if any
00637     GenericBitmap *pBgBmp = NULL;
00638     GenericBitmap *pItemBmp = NULL;
00639     GenericBitmap *pOpenBmp = NULL;
00640     GenericBitmap *pClosedBmp = NULL;
00641     GET_BMP( pBgBmp, rData.m_bgImageId );
00642     GET_BMP( pItemBmp, rData.m_itemImageId );
00643     GET_BMP( pOpenBmp, rData.m_openImageId );
00644     GET_BMP( pClosedBmp, rData.m_closedImageId );
00645 
00646     GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId);
00647     if( pLayout == NULL )
00648     {
00649         msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
00650         return;
00651     }
00652 
00653     GenericFont *pFont = getFont( rData.m_fontId );
00654     if( pFont == NULL )
00655     {
00656         msg_Err( getIntf(), "Unknown font id: %s", rData.m_fontId.c_str() );
00657         return;
00658     }
00659 
00660     // Get the list variable
00661     Interpreter *pInterpreter = Interpreter::instance( getIntf() );
00662     VarTree *pVar = pInterpreter->getVarTree( rData.m_var, m_pTheme );
00663     if( pVar == NULL )
00664     {
00665         msg_Err( getIntf(), "No such list variable: %s", rData.m_var.c_str() );
00666         return;
00667     }
00668 
00669     // Get the visibility variable
00670     // XXX check when it is null
00671     VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
00672 
00673     // Create the list control
00674     CtrlTree *pTree = new CtrlTree( getIntf(), *pVar, *pFont, pBgBmp,
00675        pItemBmp, pOpenBmp, pClosedBmp,
00676        rData.m_fgColor, rData.m_playColor, rData.m_bgColor1,
00677        rData.m_bgColor2, rData.m_selColor,
00678        UString( getIntf(), rData.m_help.c_str() ), pVisible );
00679 
00680     // Compute the position of the control
00681     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
00682                                        rData.m_xPos, rData.m_yPos,
00683                                        rData.m_width, rData.m_height,
00684                                        *pLayout );
00685 
00686     pLayout->addControl( pTree, pos, rData.m_layer );
00687 
00688     m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pTree );
00689 }
00690 
00691 void Builder::addVideo( const BuilderData::Video &rData )
00692 {
00693     GenericLayout *pLayout = m_pTheme->getLayoutById(rData.m_layoutId);
00694     if( pLayout == NULL )
00695     {
00696         msg_Err( getIntf(), "unknown layout id: %s", rData.m_layoutId.c_str() );
00697         return;
00698     }
00699 
00700     // Get the visibility variable
00701     // XXX check when it is null
00702     Interpreter *pInterpreter = Interpreter::instance( getIntf() );
00703     VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
00704 
00705     CtrlVideo *pVideo = new CtrlVideo( getIntf(),
00706         UString( getIntf(), rData.m_help.c_str() ), pVisible );
00707 
00708     // Compute the position of the control
00709     const Position pos = makePosition( rData.m_leftTop, rData.m_rightBottom,
00710                                        rData.m_xPos, rData.m_yPos,
00711                                        rData.m_width, rData.m_height,
00712                                        *pLayout );
00713 
00714     pLayout->addControl( pVideo, pos, rData.m_layer );
00715 
00716     m_pTheme->m_controls[rData.m_id] = CtrlGenericPtr( pVideo );
00717 }
00718 
00719 
00720 const Position Builder::makePosition( const string &rLeftTop,
00721                                       const string &rRightBottom,
00722                                       int xPos, int yPos, int width,
00723                                       int height, const Box &rBox ) const
00724 {
00725     int left = 0, top = 0, right = 0, bottom = 0;
00726     Position::Ref_t refLeftTop = Position::kLeftTop;
00727     Position::Ref_t refRightBottom = Position::kLeftTop;
00728 
00729     int boxWidth = rBox.getWidth();
00730     int boxHeight = rBox.getHeight();
00731 
00732     // Position of the left top corner
00733     if( rLeftTop == "lefttop" )
00734     {
00735         left = xPos;
00736         top = yPos;
00737         refLeftTop = Position::kLeftTop;
00738     }
00739     else if( rLeftTop == "righttop" )
00740     {
00741         left = xPos - boxWidth + 1;
00742         top = yPos;
00743         refLeftTop = Position::kRightTop;
00744     }
00745     else if( rLeftTop == "leftbottom" )
00746     {
00747         left = xPos;
00748         top = yPos - boxHeight + 1;
00749         refLeftTop = Position::kLeftBottom;
00750     }
00751     else if( rLeftTop == "rightbottom" )
00752     {
00753         left = xPos - boxWidth + 1;
00754         top = yPos - boxHeight + 1;
00755         refLeftTop = Position::kRightBottom;
00756     }
00757 
00758     // Position of the right bottom corner
00759     if( rRightBottom == "lefttop" )
00760     {
00761         right = xPos + width - 1;
00762         bottom = yPos + height - 1;
00763         refRightBottom = Position::kLeftTop;
00764     }
00765     else if( rRightBottom == "righttop" )
00766     {
00767         right = xPos + width - boxWidth;
00768         bottom = yPos + height - 1;
00769         refRightBottom = Position::kRightTop;
00770     }
00771     else if( rRightBottom == "leftbottom" )
00772     {
00773         right = xPos + width - 1;
00774         bottom = yPos + height - boxHeight;
00775         refRightBottom = Position::kLeftBottom;
00776     }
00777     else if( rRightBottom == "rightbottom" )
00778     {
00779         right = xPos + width - boxWidth;
00780         bottom = yPos + height - boxHeight;
00781         refRightBottom = Position::kRightBottom;
00782     }
00783 
00784     return Position( left, top, right, bottom, rBox, refLeftTop,
00785                      refRightBottom );
00786 }
00787 
00788 
00789 GenericFont *Builder::getFont( const string &fontId )
00790 {
00791     GenericFont *pFont = m_pTheme->getFontById(fontId);
00792     if( !pFont && fontId == "defaultfont" )
00793     {
00794         // Get the resource path and try to load the default font
00795         OSFactory *pOSFactory = OSFactory::instance( getIntf() );
00796         const list<string> &resPath = pOSFactory->getResourcePath();
00797         const string &sep = pOSFactory->getDirSeparator();
00798 
00799         list<string>::const_iterator it;
00800         for( it = resPath.begin(); it != resPath.end(); it++ )
00801         {
00802             string path = (*it) + sep + "fonts" + sep + "FreeSans.ttf";
00803             pFont = new FT2Font( getIntf(), path, 12 );
00804             if( pFont->init() )
00805             {
00806                 // Font loaded successfully
00807                 m_pTheme->m_fonts["defaultfont"] = GenericFontPtr( pFont );
00808                 break;
00809             }
00810             else
00811             {
00812                 delete pFont;
00813                 pFont = NULL;
00814             }
00815         }
00816         if( !pFont )
00817         {
00818             msg_Err( getIntf(), "Failed to open the default font" );
00819         }
00820     }
00821     return pFont;
00822 }
00823 
00824 
00825 Bezier *Builder::getPoints( const char *pTag ) const
00826 {
00827     vector<float> xBez, yBez;
00828     int x, y, n;
00829     while( 1 )
00830     {
00831         if( sscanf( pTag, "(%d,%d)%n", &x, &y, &n ) < 1 )
00832         {
00833             return NULL;
00834         }
00835 #if 0
00836         if( x < 0 || y < 0 )
00837         {
00838             msg_Err( getIntf(),
00839                      "Slider points cannot have negative coordinates!" );
00840             return NULL;
00841         }
00842 #endif
00843         xBez.push_back( x );
00844         yBez.push_back( y );
00845         pTag += n;
00846         if( *pTag == '\0' )
00847         {
00848             break;
00849         }
00850         if( *(pTag++) != ',' )
00851         {
00852             return NULL;
00853         }
00854     }
00855 
00856     // Create the Bezier curve
00857     return new Bezier( getIntf(), xBez, yBez );
00858 }
00859 

Generated on Tue Dec 20 10:14:42 2005 for vlc-0.8.4a by  doxygen 1.4.2