#include "burn.h" #include "skins.h" #include "proctools/logger.h" #include "proctools/format.h" #include #include #include #include #include #include namespace vdr_burn { using namespace std; using namespace gdwrapper; using proctools::logger; using proctools::format; const int MAXPAGETITLES = 8; skin_list skin_list::instance; bool operator<(const skin& lhs, const skin& rhs) { if (lhs.m_default) return true; else if (rhs.m_default) return false; else return lhs.m_name < rhs.m_name; } // --- skin --------------------------------------------------------------- std::string skin::default_background; std::string skin::default_button; skin::skin(const std::string& name, const std::string& background, const std::string& button_, bool default_): m_default( default_ ), m_name( name ), m_background( background.empty() ? default_background : background ), m_button( button_.empty() ? default_button : button_ ), m_mainMenuHeader( rectangle( 90, 52, 450, 30 ), font_spec( "Vera", 16 ), color( 0xff, 0xff, 0xff ) ), m_mainMenuPrevious( m_button, point( 605, 509 ), text_spec( rectangle( 120, 513, 240, 25 ), font_spec( "Vera", 16 ), color( 0xff, 0xff, 0xff ) ) ), m_mainMenuNext( m_button, point( 80, 509 ), text_spec( rectangle( 360, 513, 240, 25 ), font_spec( "Vera", 16 ), color( 0xff, 0xff, 0xff ), 2 ) ), m_titleMenuHeader( rectangle( 90, 52, 450, 30 ), font_spec( "Vera", 16 ), color( 0xff, 0xff, 0xff ) ), m_titleMenuPlay( m_button, point( 80, 509 ), text_spec( rectangle( 120, 513, 240, 25 ), font_spec( "Vera", 16 ), color( 0xff, 0xff, 0xff ) ) ), m_titleMenuExit( m_button, point( 605, 509 ), text_spec( rectangle( 360, 513, 240, 25 ), font_spec( "Vera", 16 ), color( 0xff, 0xff, 0xff ), 2 ) ), m_titleMenuPrevious( m_button, point( 80, 469 ), text_spec( rectangle( 120, 472, 240, 25 ), font_spec( "Vera", 16 ), color( 0xff, 0xff, 0xff ) ) ), m_titleMenuNext( m_button, point( 605, 469 ), text_spec( rectangle( 360, 472, 240, 25 ), font_spec( "Vera", 16 ), color( 0xff, 0xff, 0xff ), 2 ) ), m_titleMenuText( rectangle( 90, 120, 450, 340 ), font_spec( "Vera", 16 ), color( 0xff, 0xff, 0xff ) ) { for (int i = 0; i < MAXPAGETITLES; ++i) m_mainMenuTitles.push_back( button( m_button, point( 93, 118 + i * 40 ), text_spec( rectangle( 138, 124 + i * 40, 450, 30 ), font_spec( "Vera", 16 ), color( 0xff, 0xff, 0xff ) ) ) ); replace(m_name.begin(), m_name.end(), '_', ' '); logger::debug(format("loaded skin {0} using {1} and {2}") % m_name % m_background % m_button); } void skin::set_defaults(const std::string& background, const std::string& button) { default_background = background; default_button = button; } // --- skin_list ---------------------------------------------------------- class skin_file_checker { public: skin_file_checker( const std::string& pathPrefix ): m_pathPrefix( pathPrefix ) {} void operator()( const char* extension ) { string toCheck = format( "{0}.{1}" ) % m_pathPrefix % extension; if ( access( toCheck.c_str(), R_OK ) != -1 ) path = toCheck; } std::string path; private: std::string m_pathPrefix; }; string skin_list::check_skin_files( const std::string& pathOnly, const std::string& filePrefix, bool fatal ) { static const char* extensions[] = { "jpg", "jpeg", "png" }; string pathPrefix( format( "{0}/{1}" ) % pathOnly % filePrefix ); skin_file_checker checker( for_each( extensions, extensions + sizeof(extensions)/sizeof(extensions[0]), skin_file_checker( pathPrefix ) ) ); if ( checker.path.empty() ) { if ( fatal ) logger::error( format( "couldn't find image for {0}: no suitable format found" ) % pathPrefix ); return string(); } return checker.path; } bool skin_list::load( const std::string& path ) { string background = check_skin_files( path, "menu-bg", true ); string button = check_skin_files( path, "menu-button", true ); if (background.empty() || button.empty()) return false; skin::set_defaults(background, button); get().insert(get().end(), skin(tr("Default"), string(), string(), true)); string skinPath = format("{0}/skins") % path; cReadDir dir( skinPath.c_str() ); struct dirent *ent; while ( ( ent = dir.Next() ) != NULL ) { if ( ent->d_name[0] == '.' ) // hide dotfiles, '.' and '..' continue; background = check_skin_files( format( "{0}/{1}" ) % skinPath % ent->d_name, "menu-bg" ); button = check_skin_files( format( "{0}/{1}" ) % skinPath % ent->d_name, "menu-button" ); if ( !background.empty() || !button.empty() ) get().insert( get().end(), skin( ent->d_name, background, button ) ); } sort( get().begin(), get().end() ); return true; } const string_list& skin_list::get_names() { static string_list skinNames; if ( skinNames.size() == 0 ) { skinNames.resize( get().size() ); transform( get().begin(), get().end(), skinNames.begin(), bind( &string::c_str, bind( &skin::get_name, _1 ) ) ); } return skinNames; } }