00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
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
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
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
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
00275
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
00284
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
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
00339 Interpreter *pInterpreter = Interpreter::instance( getIntf() );
00340 VarBool *pVar = pInterpreter->getVarBool( rData.m_state, m_pTheme );
00341 if( pVar == NULL )
00342 {
00343
00344 return;
00345 }
00346
00347
00348
00349 VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
00350
00351
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
00359
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
00391
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
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
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
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
00452
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
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
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
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
00496
00497 VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
00498
00499
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
00507
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
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
00548
00549 Interpreter *pInterpreter = Interpreter::instance( getIntf() );
00550 VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
00551
00552
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
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
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
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
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
00614
00615 VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
00616
00617
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
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
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
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
00670
00671 VarBool *pVisible = pInterpreter->getVarBool( rData.m_visible, m_pTheme );
00672
00673
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
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
00701
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
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
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
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
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
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
00857 return new Bezier( getIntf(), xBez, yBez );
00858 }
00859