2010-02-04 13:33:47 +02:00
/***************************************************************************
2011-10-23 17:43:56 +03:00
* Copyright ( C ) 2006 by Massimiliano Torromeo *
* massimiliano . torromeo @ gmail . com *
2010-02-04 13:33:47 +02:00
* *
* This program is free software ; you can redistribute it and / or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation ; either version 2 of the License , or *
* ( at your option ) any later version . *
* *
* This program is distributed in the hope that it will be useful , *
* but WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the *
* GNU General Public License for more details . *
* *
* You should have received a copy of the GNU General Public License *
* along with this program ; if not , write to the *
* Free Software Foundation , Inc . , *
* 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA . *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-10-23 18:32:46 +03:00
# include "gp2x.h"
# include "asfont.h"
# include "cpu.h"
# include "debug.h"
# include "filedialog.h"
# include "filelister.h"
# include "gmenu2x.h"
# include "iconbutton.h"
# include "inputdialog.h"
# include "linkapp.h"
# include "menu.h"
# include "menusettingbool.h"
# include "menusettingdir.h"
# include "menusettingfile.h"
# include "menusettingimage.h"
# include "menusettingint.h"
# include "menusettingmultistring.h"
# include "menusettingrgba.h"
# include "menusettingstring.h"
# include "messagebox.h"
# include "powersaver.h"
# include "settingsdialog.h"
# include "textdialog.h"
# include "wallpaperdialog.h"
# include "utilities.h"
2010-02-04 13:33:47 +02:00
# include <iostream>
# include <sstream>
# include <fstream>
2010-07-28 04:31:41 +03:00
# include <algorithm>
2010-02-04 13:33:47 +02:00
# include <stdlib.h>
# include <unistd.h>
# include <math.h>
# include <SDL.h>
# include <SDL_gfxPrimitives.h>
# include <signal.h>
# include <sys/statvfs.h>
# include <errno.h>
# include <sys/fcntl.h> //for battery
2011-07-11 12:27:38 +03:00
# ifdef PLATFORM_DINGUX
# define UNLOCK_VT
# include <sys / ioctl.h>
# include <linux / vt.h>
# include <linux / kd.h>
# endif
2011-10-23 18:32:46 +03:00
# ifdef PLATFORM_PANDORA
//#include <pnd_container.h>
//#include <pnd_conf.h>
//#include <pnd_discovery.h>
# endif
2010-02-04 13:33:47 +02:00
//for browsing the filesystem
# include <sys/stat.h>
# include <sys/types.h>
# include <dirent.h>
//for soundcard
# include <sys/ioctl.h>
# include <linux/soundcard.h>
# include <sys/mman.h>
2011-10-23 18:27:29 +03:00
typedef fastdelegate : : FastDelegate0 < > MenuAction ;
struct MenuOption {
std : : string text ;
MenuAction action ;
} ;
2011-10-23 17:43:56 +03:00
using namespace std ;
using namespace fastdelegate ;
2011-10-23 18:27:29 +03:00
# ifndef DEFAULT_WALLPAPER_PATH
# define DEFAULT_WALLPAPER_PATH \
GMENU2X_SYSTEM_DIR " /skins/Default/wallpapers/default.png "
# endif
2010-09-01 18:37:27 +03:00
# ifdef _CARD_ROOT
const char * CARD_ROOT = _CARD_ROOT ;
2011-08-11 04:42:18 +03:00
# elif defined(PLATFORM_DINGUX)
const char * CARD_ROOT = " /media/ " ;
2010-09-01 18:37:27 +03:00
# else
2010-08-03 18:46:34 +03:00
const char * CARD_ROOT = " /card/ " ; //Note: Add a trailing /!
2010-09-01 18:37:27 +03:00
# endif
2011-08-11 04:42:18 +03:00
const int CARD_ROOT_LEN = strlen ( CARD_ROOT ) - 1 ;
2010-07-04 04:19:52 +03:00
2010-09-17 23:32:41 +03:00
static GMenu2X * app ;
2011-03-29 13:15:16 +03:00
static string gmenu2x_home ;
2010-09-17 23:32:41 +03:00
2010-07-28 17:15:52 +03:00
// Note: Keep this in sync with the enum!
static const char * colorNames [ NUM_COLORS ] = {
" topBarBg " ,
" bottomBarBg " ,
" selectionBg " ,
" messageBoxBg " ,
" messageBoxBorder " ,
" messageBoxSelection " ,
} ;
static enum color stringToColor ( const string & name )
{
for ( unsigned int i = 0 ; i < NUM_COLORS ; i + + ) {
if ( strcmp ( colorNames [ i ] , name . c_str ( ) ) = = 0 ) {
return ( enum color ) i ;
}
}
return ( enum color ) - 1 ;
}
static const char * colorToString ( enum color c )
{
return colorNames [ c ] ;
}
2010-09-17 23:32:41 +03:00
static void quit_all ( int err ) {
delete app ;
exit ( err ) ;
}
2011-07-11 12:27:38 +03:00
# ifdef UNLOCK_VT
# define FB_TTY " / dev / tty%i"
static void unlockVT ( )
{
int i ;
int fd ;
char tty [ 10 ] ;
for ( i = 0 ; i < 10 ; i + + ) {
int mode ;
sprintf ( tty , FB_TTY , i ) ;
fd = open ( tty , O_RDWR ) ;
if ( fd < 0 )
continue ;
if ( ioctl ( fd , KDGETMODE , & mode ) < 0 ) {
WARNING ( " Unable to get mode for tty %i. \n " , i ) ;
close ( fd ) ;
return ;
}
if ( mode ! = KD_TEXT )
break ;
close ( fd ) ;
}
if ( i = = 10 ) {
DEBUG ( " No graphic tty found. \n " ) ;
return ;
}
DEBUG ( " Graphic tty found on %s. \n " , tty ) ;
if ( ioctl ( fd , KDSETMODE , KD_TEXT ) < 0 )
WARNING ( " unable to set keyboard mode. \n " ) ;
if ( ioctl ( fd , VT_UNLOCKSWITCH , 1 ) < 0 )
WARNING ( " unable to unlock terminal. \n " ) ;
close ( fd ) ;
}
# endif
2011-03-29 13:15:16 +03:00
const string GMenu2X : : getHome ( void )
{
return gmenu2x_home ;
}
2010-09-17 23:31:09 +03:00
int main ( int /*argc*/ , char * /*argv*/ [ ] ) {
INFO ( " ---- \n GMenu2X starting: If you read this message in the logs, check http://gmenu2x.sourceforge.net/page/Troubleshooting for a solution \n ---- \n " ) ;
2010-02-04 13:33:47 +02:00
2010-09-17 23:32:41 +03:00
signal ( SIGINT , & quit_all ) ;
signal ( SIGSEGV , & quit_all ) ;
signal ( SIGTERM , & quit_all ) ;
2010-09-17 23:31:09 +03:00
2011-03-29 13:15:16 +03:00
char * home = getenv ( " HOME " ) ;
if ( home = = NULL ) {
ERROR ( " Unable to find gmenu2x home directory. The $HOME variable is not defined. \n " ) ;
return 1 ;
}
gmenu2x_home = ( string ) home + ( string ) " /.gmenu2x " ;
if ( ! fileExists ( gmenu2x_home ) & & mkdir ( gmenu2x_home . c_str ( ) , 0770 ) < 0 ) {
ERROR ( " Unable to create gmenu2x home directory. \n " ) ;
return 1 ;
}
DEBUG ( " Home path: %s. \n " , gmenu2x_home . c_str ( ) ) ;
2010-09-17 23:32:41 +03:00
app = new GMenu2X ( ) ;
2010-09-17 23:31:09 +03:00
DEBUG ( " Starting main() \n " ) ;
2010-09-17 23:32:41 +03:00
app - > main ( ) ;
2010-09-17 23:31:09 +03:00
2010-02-04 13:33:47 +02:00
return 0 ;
}
2011-09-18 19:27:03 +03:00
void GMenu2X : : initCPULimits ( ) {
// Note: These values are for the Dingoo.
// The NanoNote does not have cpufreq enabled in its kernel and
// other devices are not actively maintained.
// TODO: Read min and max from sysfs.
cpuFreqMin = 30 ;
cpuFreqMax = 500 ;
cpuFreqSafeMax = 420 ;
cpuFreqMenuDefault = 200 ;
cpuFreqAppDefault = 384 ;
cpuFreqMultiple = 24 ;
// Round min and max values to the specified multiple.
cpuFreqMin = ( ( cpuFreqMin + cpuFreqMultiple - 1 ) / cpuFreqMultiple )
* cpuFreqMultiple ;
cpuFreqMax = ( cpuFreqMax / cpuFreqMultiple ) * cpuFreqMultiple ;
cpuFreqSafeMax = ( cpuFreqSafeMax / cpuFreqMultiple ) * cpuFreqMultiple ;
cpuFreqMenuDefault = ( cpuFreqMenuDefault / cpuFreqMultiple ) * cpuFreqMultiple ;
cpuFreqAppDefault = ( cpuFreqAppDefault / cpuFreqMultiple ) * cpuFreqMultiple ;
}
2011-07-29 02:13:35 +03:00
void GMenu2X : : init ( ) {
2011-09-23 02:01:57 +03:00
batteryHandle = 0 ;
usbHandle = 0 ;
acHandle = 0 ;
2010-02-04 13:33:47 +02:00
batteryHandle = fopen ( " /sys/class/power_supply/battery/capacity " , " r " ) ;
2011-09-23 01:57:27 +03:00
usbHandle = fopen ( " /sys/class/power_supply/usb/online " , " r " ) ;
2010-02-04 13:33:47 +02:00
acHandle = fopen ( " /sys/class/power_supply/ac/online " , " r " ) ;
}
2011-07-29 02:13:35 +03:00
void GMenu2X : : deinit ( ) {
2010-02-04 13:33:47 +02:00
if ( batteryHandle ) fclose ( batteryHandle ) ;
if ( usbHandle ) fclose ( usbHandle ) ;
if ( acHandle ) fclose ( acHandle ) ;
}
2011-07-29 02:13:35 +03:00
GMenu2X : : GMenu2X ( )
{
2010-02-04 13:33:47 +02:00
usbnet = samba = inet = web = false ;
useSelectionPng = false ;
2011-09-18 19:27:03 +03:00
initCPULimits ( ) ;
2010-02-04 13:33:47 +02:00
//load config data
readConfig ( ) ;
2011-07-29 02:13:35 +03:00
2010-02-04 13:33:47 +02:00
halfX = resX / 2 ;
halfY = resY / 2 ;
bottomBarIconY = resY - 18 ;
bottomBarTextY = resY - 10 ;
path = " " ;
getExePath ( ) ;
2011-07-29 02:13:35 +03:00
init ( ) ;
2010-05-02 20:53:06 +03:00
2011-07-11 12:27:38 +03:00
# ifdef UNLOCK_VT
unlockVT ( ) ;
# endif
2011-07-28 02:48:12 +03:00
/* Do not clear the screen on exit.
* This may require an SDL patch available at
* https : //github.com/mthuurne/opendingux-buildroot/blob
* / opendingux - 2010.11 / package / sdl / sdl - fbcon - clear - onexit . patch
*/
setenv ( " SDL_FBCON_DONT_CLEAR " , " 1 " , 0 ) ;
2010-02-04 13:33:47 +02:00
//Screen
2011-08-16 03:18:09 +03:00
if ( SDL_Init ( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) < 0 ) {
2010-09-17 23:31:09 +03:00
ERROR ( " Could not initialize SDL: %s \n " , SDL_GetError ( ) ) ;
2010-02-04 13:33:47 +02:00
quit ( ) ;
}
2011-06-02 18:59:26 +03:00
s = Surface : : openOutputSurface ( resX , resY , confInt [ " videoBpp " ] ) ;
2010-02-04 13:33:47 +02:00
bg = NULL ;
font = NULL ;
menu = NULL ;
setSkin ( confStr [ " skin " ] , false ) ;
initMenu ( ) ;
if ( ! fileExists ( confStr [ " wallpaper " ] ) ) {
2011-04-03 12:49:00 +03:00
DEBUG ( " No wallpaper defined; we will take the default one. \n " ) ;
confStr [ " wallpaper " ] = DEFAULT_WALLPAPER_PATH ;
2010-02-04 13:33:47 +02:00
}
initBG ( ) ;
2011-03-29 13:31:43 +03:00
/* If a user-specified input.conf file exists, we load it;
* otherwise , we load the default one . */
2012-01-23 13:29:58 +02:00
string input_file = getHome ( ) + " /input.conf " ;
if ( fileExists ( input_file . c_str ( ) ) ) {
DEBUG ( " Loading user-specific input.conf file: %s. \n " , input_file . c_str ( ) ) ;
2011-03-29 13:31:43 +03:00
} else {
input_file = GMENU2X_SYSTEM_DIR " /input.conf " ;
2012-01-23 13:29:58 +02:00
DEBUG ( " Loading system input.conf file: %s. \n " , input_file . c_str ( ) ) ;
2011-03-29 13:31:43 +03:00
}
input . init ( input_file ) ;
2011-08-17 01:46:11 +03:00
if ( confInt [ " backlightTimeout " ] > 0 )
PowerSaver : : getInstance ( ) - > setScreenTimeout ( confInt [ " backlightTimeout " ] ) ;
2010-02-04 13:33:47 +02:00
setInputSpeed ( ) ;
setClock ( confInt [ " menuClock " ] ) ;
//recover last session
readTmp ( ) ;
if ( lastSelectorElement > - 1 & & menu - > selLinkApp ( ) ! = NULL & & ( ! menu - > selLinkApp ( ) - > getSelectorDir ( ) . empty ( ) | | ! lastSelectorDir . empty ( ) ) )
menu - > selLinkApp ( ) - > selector ( lastSelectorElement , lastSelectorDir ) ;
2011-06-02 06:04:35 +03:00
2010-06-19 04:50:23 +03:00
}
2010-02-04 13:33:47 +02:00
2010-06-19 04:50:23 +03:00
GMenu2X : : ~ GMenu2X ( ) {
2011-08-17 01:46:11 +03:00
if ( PowerSaver : : isRunning ( ) )
delete PowerSaver : : getInstance ( ) ;
2010-02-04 13:33:47 +02:00
quit ( ) ;
2011-07-20 14:43:25 +03:00
delete menu ;
delete font ;
2010-02-04 13:33:47 +02:00
}
void GMenu2X : : quit ( ) {
fflush ( NULL ) ;
sc . clear ( ) ;
2011-07-20 14:43:25 +03:00
delete s ;
2011-07-11 12:27:38 +03:00
2010-02-04 13:33:47 +02:00
SDL_Quit ( ) ;
2011-07-28 02:48:12 +03:00
unsetenv ( " SDL_FBCON_DONT_CLEAR " ) ;
2011-07-11 12:27:38 +03:00
2011-09-23 01:48:13 +03:00
deinit ( ) ;
2010-02-04 13:33:47 +02:00
}
void GMenu2X : : initBG ( ) {
sc . del ( " bgmain " ) ;
2011-06-03 12:46:36 +03:00
// Load wallpaper.
2011-07-20 14:43:25 +03:00
delete bg ;
2011-06-03 12:46:36 +03:00
bg = Surface : : loadImage ( confStr [ " wallpaper " ] ) ;
if ( ! bg ) {
bg = Surface : : emptySurface ( resX , resY ) ;
2010-02-04 13:33:47 +02:00
}
drawTopBar ( bg ) ;
drawBottomBar ( bg ) ;
Surface * bgmain = new Surface ( bg ) ;
sc . add ( bgmain , " bgmain " ) ;
2011-06-02 23:09:03 +03:00
Surface * sd = Surface : : loadImage ( " imgs/sd.png " , confStr [ " skin " ] ) ;
2011-06-03 12:46:36 +03:00
if ( sd ) sd - > blit ( bgmain , 3 , bottomBarIconY ) ;
2011-09-18 13:42:08 +03:00
# ifdef PLATFORM_DINGUX
string df = getDiskFree ( " /boot " ) ;
# else
string df = getDiskFree ( CARD_ROOT ) ;
# endif
2011-06-03 12:46:36 +03:00
bgmain - > write ( font , df , 22 , bottomBarTextY , ASFont : : HAlignLeft , ASFont : : VAlignMiddle ) ;
2011-07-20 14:43:25 +03:00
delete sd ;
2010-05-03 15:21:00 +03:00
2011-06-02 23:09:03 +03:00
Surface * cpu = Surface : : loadImage ( " imgs/cpu.png " , confStr [ " skin " ] ) ;
2011-11-19 15:47:55 +02:00
cpuX = font - > getTextWidth ( df ) + 32 ;
2011-06-03 12:46:36 +03:00
if ( cpu ) cpu - > blit ( bgmain , cpuX , bottomBarIconY ) ;
2010-02-04 13:33:47 +02:00
cpuX + = 19 ;
2011-09-19 17:33:19 +03:00
manualX = cpuX + font - > getTextWidth ( " 300MHz " ) + 5 ;
2011-07-20 14:43:25 +03:00
delete cpu ;
2010-02-04 13:33:47 +02:00
int serviceX = resX - 38 ;
if ( usbnet ) {
if ( web ) {
2011-06-02 23:09:03 +03:00
Surface * webserver = Surface : : loadImage (
" imgs/webserver.png " , confStr [ " skin " ] ) ;
2011-06-03 12:46:36 +03:00
if ( webserver ) webserver - > blit ( bgmain , serviceX , bottomBarIconY ) ;
2010-02-04 13:33:47 +02:00
serviceX - = 19 ;
2011-07-20 14:43:25 +03:00
delete webserver ;
2010-02-04 13:33:47 +02:00
}
if ( samba ) {
2011-06-02 23:09:03 +03:00
Surface * sambaS = Surface : : loadImage (
" imgs/samba.png " , confStr [ " skin " ] ) ;
2011-06-03 12:46:36 +03:00
if ( sambaS ) sambaS - > blit ( bgmain , serviceX , bottomBarIconY ) ;
2010-02-04 13:33:47 +02:00
serviceX - = 19 ;
2011-07-20 14:43:25 +03:00
delete sambaS ;
2010-02-04 13:33:47 +02:00
}
if ( inet ) {
2011-06-02 23:09:03 +03:00
Surface * inetS = Surface : : loadImage ( " imgs/inet.png " , confStr [ " skin " ] ) ;
2011-06-03 12:46:36 +03:00
if ( inetS ) inetS - > blit ( bgmain , serviceX , bottomBarIconY ) ;
2010-02-04 13:33:47 +02:00
serviceX - = 19 ;
2011-07-20 14:43:25 +03:00
delete inetS ;
2010-02-04 13:33:47 +02:00
}
}
2011-06-03 12:46:36 +03:00
bgmain - > convertToDisplayFormat ( ) ;
2010-02-04 13:33:47 +02:00
}
void GMenu2X : : initFont ( ) {
if ( font ! = NULL ) {
2011-07-20 14:43:25 +03:00
delete font ;
2010-02-04 13:33:47 +02:00
font = NULL ;
}
string fontFile = sc . getSkinFilePath ( " imgs/font.png " ) ;
if ( fontFile . empty ( ) ) {
2010-09-17 23:31:09 +03:00
ERROR ( " Font png not found! \n " ) ;
2010-02-04 13:33:47 +02:00
quit ( ) ;
exit ( - 1 ) ;
}
font = new ASFont ( fontFile ) ;
}
void GMenu2X : : initMenu ( ) {
//Menu structure handler
2011-12-23 15:03:05 +02:00
menu = new Menu ( this , ts ) ;
2010-07-27 22:12:15 +03:00
for ( uint i = 0 ; i < menu - > getSections ( ) . size ( ) ; i + + ) {
2010-02-04 13:33:47 +02:00
//Add virtual links in the applications section
2010-07-27 22:12:15 +03:00
if ( menu - > getSections ( ) [ i ] = = " applications " ) {
2010-02-04 13:33:47 +02:00
menu - > addActionLink ( i , " Explorer " , MakeDelegate ( this , & GMenu2X : : explorer ) , tr [ " Launch an application " ] , " skin:icons/explorer.png " ) ;
}
//Add virtual links in the setting section
2010-07-27 22:12:15 +03:00
else if ( menu - > getSections ( ) [ i ] = = " settings " ) {
2010-02-04 13:33:47 +02:00
menu - > addActionLink ( i , " GMenu2X " , MakeDelegate ( this , & GMenu2X : : options ) , tr [ " Configure GMenu2X's options " ] , " skin:icons/configure.png " ) ;
menu - > addActionLink ( i , tr [ " Skin " ] , MakeDelegate ( this , & GMenu2X : : skinMenu ) , tr [ " Configure skin " ] , " skin:icons/skin.png " ) ;
menu - > addActionLink ( i , tr [ " Wallpaper " ] , MakeDelegate ( this , & GMenu2X : : changeWallpaper ) , tr [ " Change GMenu2X wallpaper " ] , " skin:icons/wallpaper.png " ) ;
2011-05-09 20:21:14 +03:00
if ( fileExists ( getHome ( ) + " /log.txt " ) )
2010-02-04 13:33:47 +02:00
menu - > addActionLink ( i , tr [ " Log Viewer " ] , MakeDelegate ( this , & GMenu2X : : viewLog ) , tr [ " Displays last launched program's output " ] , " skin:icons/ebook.png " ) ;
menu - > addActionLink ( i , tr [ " About " ] , MakeDelegate ( this , & GMenu2X : : about ) , tr [ " Info about GMenu2X " ] , " skin:icons/about.png " ) ;
}
}
menu - > setSectionIndex ( confInt [ " section " ] ) ;
menu - > setLinkIndex ( confInt [ " link " ] ) ;
menu - > loadIcons ( ) ;
//DEBUG
2010-07-04 04:19:52 +03:00
//menu->addLink( CARD_ROOT, "sample.pxml", "applications" );
2010-02-04 13:33:47 +02:00
}
void GMenu2X : : about ( ) {
vector < string > text ;
2012-04-27 18:42:09 +03:00
string line ;
string fn ( GMENU2X_SYSTEM_DIR ) ;
string build_date ( " Build date: " ) ;
fn . append ( " /about.txt " ) ;
build_date . append ( __DATE__ ) ;
ifstream inf ( fn . c_str ( ) , ios_base : : in ) ;
while ( getline ( inf , line , ' \n ' ) )
text . push_back ( line ) ;
inf . close ( ) ;
TextDialog td ( this , " GMenu2X " , build_date , " icons/about.png " , & text ) ;
2010-02-04 13:33:47 +02:00
td . exec ( ) ;
}
void GMenu2X : : viewLog ( ) {
2011-05-09 20:21:14 +03:00
string logfile = getHome ( ) + " /log.txt " ;
2010-02-04 13:33:47 +02:00
if ( fileExists ( logfile ) ) {
ifstream inf ( logfile . c_str ( ) , ios_base : : in ) ;
if ( inf . is_open ( ) ) {
vector < string > log ;
string line ;
while ( getline ( inf , line , ' \n ' ) )
log . push_back ( line ) ;
inf . close ( ) ;
TextDialog td ( this , tr [ " Log Viewer " ] , tr [ " Displays last launched program's output " ] , " icons/ebook.png " , & log ) ;
td . exec ( ) ;
MessageBox mb ( this , tr [ " Do you want to delete the log file? " ] , " icons/ebook.png " ) ;
2011-10-23 09:57:52 +03:00
mb . setButton ( InputManager : : ACCEPT , tr [ " Yes " ] ) ;
mb . setButton ( InputManager : : CANCEL , tr [ " No " ] ) ;
if ( mb . exec ( ) = = InputManager : : ACCEPT ) {
2010-02-04 13:33:47 +02:00
unlink ( logfile . c_str ( ) ) ;
sync ( ) ;
menu - > deleteSelectedLink ( ) ;
}
}
}
}
void GMenu2X : : readConfig ( ) {
2011-08-11 04:40:36 +03:00
string conffile = GMENU2X_SYSTEM_DIR " /gmenu2x.conf " ;
readConfig ( conffile ) ;
conffile = getHome ( ) + " /gmenu2x.conf " ;
readConfig ( conffile ) ;
}
void GMenu2X : : readConfig ( string conffile ) {
2010-02-04 13:33:47 +02:00
if ( fileExists ( conffile ) ) {
ifstream inf ( conffile . c_str ( ) , ios_base : : in ) ;
if ( inf . is_open ( ) ) {
string line ;
while ( getline ( inf , line , ' \n ' ) ) {
string : : size_type pos = line . find ( " = " ) ;
string name = trim ( line . substr ( 0 , pos ) ) ;
string value = trim ( line . substr ( pos + 1 , line . length ( ) ) ) ;
if ( value . length ( ) > 1 & & value . at ( 0 ) = = ' " ' & & value . at ( value . length ( ) - 1 ) = = ' " ' )
confStr [ name ] = value . substr ( 1 , value . length ( ) - 2 ) ;
else
confInt [ name ] = atoi ( value . c_str ( ) ) ;
}
inf . close ( ) ;
}
}
2011-07-11 13:39:31 +03:00
if ( ! confStr [ " lang " ] . empty ( ) )
tr . setLang ( confStr [ " lang " ] ) ;
if ( ! confStr [ " wallpaper " ] . empty ( ) & & ! fileExists ( confStr [ " wallpaper " ] ) )
confStr [ " wallpaper " ] = " " ;
if ( confStr [ " skin " ] . empty ( ) | | SurfaceCollection : : getSkinPath ( confStr [ " skin " ] ) . empty ( ) )
confStr [ " skin " ] = " Default " ;
2010-02-04 13:33:47 +02:00
evalIntConf ( & confInt [ " outputLogs " ] , 0 , 0 , 1 ) ;
2011-09-18 19:27:03 +03:00
evalIntConf ( & confInt [ " maxClock " ] ,
cpuFreqSafeMax , cpuFreqMin , cpuFreqMax ) ;
evalIntConf ( & confInt [ " menuClock " ] ,
cpuFreqMenuDefault , cpuFreqMin , cpuFreqSafeMax ) ;
2011-06-02 06:04:35 +03:00
evalIntConf ( & confInt [ " backlightTimeout " ] , 15 , 0 , 120 ) ;
2011-09-19 02:12:34 +03:00
evalIntConf ( & confInt [ " videoBpp " ] , 32 , 16 , 32 ) ;
2010-02-04 13:33:47 +02:00
if ( confStr [ " tvoutEncoding " ] ! = " PAL " ) confStr [ " tvoutEncoding " ] = " NTSC " ;
resX = constrain ( confInt [ " resolutionX " ] , 320 , 1920 ) ;
resY = constrain ( confInt [ " resolutionY " ] , 240 , 1200 ) ;
}
void GMenu2X : : writeConfig ( ) {
2011-03-29 13:33:56 +03:00
string conffile = getHome ( ) + " /gmenu2x.conf " ;
2010-02-04 13:33:47 +02:00
ofstream inf ( conffile . c_str ( ) ) ;
if ( inf . is_open ( ) ) {
ConfStrHash : : iterator endS = confStr . end ( ) ;
for ( ConfStrHash : : iterator curr = confStr . begin ( ) ; curr ! = endS ; curr + + )
inf < < curr - > first < < " = \" " < < curr - > second < < " \" " < < endl ;
ConfIntHash : : iterator endI = confInt . end ( ) ;
for ( ConfIntHash : : iterator curr = confInt . begin ( ) ; curr ! = endI ; curr + + )
inf < < curr - > first < < " = " < < curr - > second < < endl ;
inf . close ( ) ;
sync ( ) ;
}
}
void GMenu2X : : writeSkinConfig ( ) {
2011-04-12 11:19:00 +03:00
string conffile = getHome ( ) + " /skins/ " ;
if ( ! fileExists ( conffile ) )
mkdir ( conffile . c_str ( ) , 0770 ) ;
conffile = conffile + confStr [ " skin " ] ;
if ( ! fileExists ( conffile ) )
mkdir ( conffile . c_str ( ) , 0770 ) ;
conffile = conffile + " /skin.conf " ;
2010-02-04 13:33:47 +02:00
ofstream inf ( conffile . c_str ( ) ) ;
if ( inf . is_open ( ) ) {
ConfStrHash : : iterator endS = skinConfStr . end ( ) ;
for ( ConfStrHash : : iterator curr = skinConfStr . begin ( ) ; curr ! = endS ; curr + + )
inf < < curr - > first < < " = \" " < < curr - > second < < " \" " < < endl ;
ConfIntHash : : iterator endI = skinConfInt . end ( ) ;
for ( ConfIntHash : : iterator curr = skinConfInt . begin ( ) ; curr ! = endI ; curr + + )
inf < < curr - > first < < " = " < < curr - > second < < endl ;
2010-05-02 20:53:06 +03:00
int i ;
for ( i = 0 ; i < NUM_COLORS ; + + i ) {
2011-06-06 10:38:26 +03:00
inf < < colorToString ( ( enum color ) i ) < < " =# " ;
inf . width ( 2 ) ; inf . fill ( ' 0 ' ) ;
inf < < right < < hex < < skinConfColors [ i ] . r ;
inf . width ( 2 ) ; inf . fill ( ' 0 ' ) ;
inf < < right < < hex < < skinConfColors [ i ] . g ;
inf . width ( 2 ) ; inf . fill ( ' 0 ' ) ;
inf < < right < < hex < < skinConfColors [ i ] . b ;
inf . width ( 2 ) ; inf . fill ( ' 0 ' ) ;
inf < < right < < hex < < skinConfColors [ i ] . a < < endl ;
2010-05-02 20:53:06 +03:00
}
2010-02-04 13:33:47 +02:00
inf . close ( ) ;
sync ( ) ;
}
}
void GMenu2X : : readTmp ( ) {
lastSelectorElement = - 1 ;
if ( fileExists ( " /tmp/gmenu2x.tmp " ) ) {
ifstream inf ( " /tmp/gmenu2x.tmp " , ios_base : : in ) ;
if ( inf . is_open ( ) ) {
string line ;
string section = " " ;
while ( getline ( inf , line , ' \n ' ) ) {
string : : size_type pos = line . find ( " = " ) ;
string name = trim ( line . substr ( 0 , pos ) ) ;
string value = trim ( line . substr ( pos + 1 , line . length ( ) ) ) ;
if ( name = = " section " )
menu - > setSectionIndex ( atoi ( value . c_str ( ) ) ) ;
else if ( name = = " link " )
menu - > setLinkIndex ( atoi ( value . c_str ( ) ) ) ;
else if ( name = = " selectorelem " )
lastSelectorElement = atoi ( value . c_str ( ) ) ;
else if ( name = = " selectordir " )
lastSelectorDir = value ;
}
inf . close ( ) ;
}
}
}
2010-05-02 15:29:09 +03:00
void GMenu2X : : writeTmp ( int selelem , const string & selectordir ) {
2010-02-04 13:33:47 +02:00
string conffile = " /tmp/gmenu2x.tmp " ;
ofstream inf ( conffile . c_str ( ) ) ;
if ( inf . is_open ( ) ) {
inf < < " section= " < < menu - > selSectionIndex ( ) < < endl ;
inf < < " link= " < < menu - > selLinkIndex ( ) < < endl ;
if ( selelem > - 1 )
inf < < " selectorelem= " < < selelem < < endl ;
if ( selectordir ! = " " )
inf < < " selectordir= " < < selectordir < < endl ;
inf . close ( ) ;
sync ( ) ;
}
}
2010-06-19 04:50:23 +03:00
void GMenu2X : : main ( ) {
2010-02-04 13:33:47 +02:00
uint linksPerPage = linkColumns * linkRows ;
int linkSpacingX = ( resX - 10 - linkColumns * skinConfInt [ " linkWidth " ] ) / linkColumns ;
int linkSpacingY = ( resY - 35 - skinConfInt [ " topBarHeight " ] - linkRows * skinConfInt [ " linkHeight " ] ) / linkRows ;
uint sectionLinkPadding = ( skinConfInt [ " topBarHeight " ] - 32 - font - > getLineHeight ( ) ) / 3 ;
bool quit = false ;
2011-07-29 02:13:35 +03:00
int x , y , offset = menu - > sectionLinks ( ) - > size ( ) > linksPerPage ? 2 : 6 ;
int helpBoxHeight = 154 ;
2010-02-04 13:33:47 +02:00
uint i ;
long tickBattery = - 60000 , tickNow ;
string batteryIcon = " imgs/battery/0.png " ;
stringstream ss ;
uint sectionsCoordX = 24 ;
SDL_Rect re = { 0 , 0 , 0 , 0 } ;
bool helpDisplayed = false ;
2010-09-17 23:31:09 +03:00
# ifdef WITH_DEBUG
2010-02-04 13:33:47 +02:00
//framerate
long tickFPS = SDL_GetTicks ( ) ;
int drawn_frames = 0 ;
string fps = " " ;
# endif
2010-06-18 04:12:58 +03:00
2011-12-23 15:03:05 +02:00
IconButton btnContextMenu ( this , ts , " skin:imgs/menu.png " ) ;
2010-02-04 13:33:47 +02:00
btnContextMenu . setPosition ( resX - 38 , bottomBarIconY ) ;
btnContextMenu . setAction ( MakeDelegate ( this , & GMenu2X : : contextMenu ) ) ;
2010-09-01 23:50:43 +03:00
if ( ! fileExists ( CARD_ROOT ) )
CARD_ROOT = " / " ;
2010-02-04 13:33:47 +02:00
while ( ! quit ) {
tickNow = SDL_GetTicks ( ) ;
//Background
sc [ " bgmain " ] - > blit ( s , 0 , 0 ) ;
//Sections
2010-07-27 22:12:15 +03:00
sectionsCoordX = halfX - ( constrain ( ( uint ) menu - > getSections ( ) . size ( ) , 0 , linkColumns ) * skinConfInt [ " linkWidth " ] ) / 2 ;
2010-02-04 13:33:47 +02:00
if ( menu - > firstDispSection ( ) > 0 )
sc . skinRes ( " imgs/l_enabled.png " ) - > blit ( s , 0 , 0 ) ;
else
sc . skinRes ( " imgs/l_disabled.png " ) - > blit ( s , 0 , 0 ) ;
2010-07-27 22:12:15 +03:00
if ( menu - > firstDispSection ( ) + linkColumns < menu - > getSections ( ) . size ( ) )
2010-02-04 13:33:47 +02:00
sc . skinRes ( " imgs/r_enabled.png " ) - > blit ( s , resX - 10 , 0 ) ;
else
sc . skinRes ( " imgs/r_disabled.png " ) - > blit ( s , resX - 10 , 0 ) ;
2010-07-27 22:12:15 +03:00
for ( i = menu - > firstDispSection ( ) ; i < menu - > getSections ( ) . size ( ) & & i < menu - > firstDispSection ( ) + linkColumns ; i + + ) {
string sectionIcon = " skin:sections/ " + menu - > getSections ( ) [ i ] + " .png " ;
2010-02-04 13:33:47 +02:00
x = ( i - menu - > firstDispSection ( ) ) * skinConfInt [ " linkWidth " ] + sectionsCoordX ;
if ( menu - > selSectionIndex ( ) = = ( int ) i )
2010-05-02 20:53:06 +03:00
s - > box ( x , 0 , skinConfInt [ " linkWidth " ] ,
skinConfInt [ " topBarHeight " ] , skinConfColors [ COLOR_SELECTION_BG ] ) ;
2010-02-04 13:33:47 +02:00
x + = skinConfInt [ " linkWidth " ] / 2 ;
if ( sc . exists ( sectionIcon ) )
sc [ sectionIcon ] - > blit ( s , x - 16 , sectionLinkPadding , 32 , 32 ) ;
else
sc . skinRes ( " icons/section.png " ) - > blit ( s , x - 16 , sectionLinkPadding ) ;
2011-05-09 06:17:25 +03:00
s - > write ( font , menu - > getSections ( ) [ i ] , x , skinConfInt [ " topBarHeight " ] - sectionLinkPadding , ASFont : : HAlignCenter , ASFont : : VAlignBottom ) ;
2010-02-04 13:33:47 +02:00
}
//Links
s - > setClipRect ( offset , skinConfInt [ " topBarHeight " ] , resX - 9 , resY - 74 ) ; //32*2+10
for ( i = menu - > firstDispRow ( ) * linkColumns ; i < ( menu - > firstDispRow ( ) * linkColumns ) + linksPerPage & & i < menu - > sectionLinks ( ) - > size ( ) ; i + + ) {
int ir = i - menu - > firstDispRow ( ) * linkColumns ;
x = ( ir % linkColumns ) * ( skinConfInt [ " linkWidth " ] + linkSpacingX ) + offset ;
y = ir / linkColumns * ( skinConfInt [ " linkHeight " ] + linkSpacingY ) + skinConfInt [ " topBarHeight " ] + 2 ;
menu - > sectionLinks ( ) - > at ( i ) - > setPosition ( x , y ) ;
if ( i = = ( uint ) menu - > selLinkIndex ( ) )
menu - > sectionLinks ( ) - > at ( i ) - > paintHover ( ) ;
menu - > sectionLinks ( ) - > at ( i ) - > paint ( ) ;
}
s - > clearClipRect ( ) ;
drawScrollBar ( linkRows , menu - > sectionLinks ( ) - > size ( ) / linkColumns + ( ( menu - > sectionLinks ( ) - > size ( ) % linkColumns = = 0 ) ? 0 : 1 ) , menu - > firstDispRow ( ) , 43 , resY - 81 ) ;
if ( menu - > selLink ( ) ! = NULL ) {
2011-05-09 06:17:25 +03:00
s - > write ( font , menu - > selLink ( ) - > getDescription ( ) , halfX , resY - 19 , ASFont : : HAlignCenter , ASFont : : VAlignBottom ) ;
2010-02-04 13:33:47 +02:00
if ( menu - > selLinkApp ( ) ! = NULL ) {
2011-05-09 06:17:25 +03:00
s - > write ( font , menu - > selLinkApp ( ) - > clockStr ( confInt [ " maxClock " ] ) , cpuX , bottomBarTextY , ASFont : : HAlignLeft , ASFont : : VAlignMiddle ) ;
2010-02-04 13:33:47 +02:00
//Manual indicator
if ( ! menu - > selLinkApp ( ) - > getManual ( ) . empty ( ) )
sc . skinRes ( " imgs/manual.png " ) - > blit ( s , manualX , bottomBarIconY ) ;
}
}
2011-12-23 13:30:15 +02:00
if ( ts . available ( ) ) {
2010-02-04 13:33:47 +02:00
btnContextMenu . paint ( ) ;
}
//check battery status every 60 seconds
if ( tickNow - tickBattery > = 60000 ) {
tickBattery = tickNow ;
unsigned short battlevel = getBatteryLevel ( ) ;
if ( battlevel > 5 ) {
batteryIcon = " imgs/battery/ac.png " ;
} else {
ss . clear ( ) ;
ss < < battlevel ;
ss > > batteryIcon ;
batteryIcon = " imgs/battery/ " + batteryIcon + " .png " ;
}
}
sc . skinRes ( batteryIcon ) - > blit ( s , resX - 19 , bottomBarIconY ) ;
//s->write( font, tr[batstr.c_str()], 20, 170 );
//On Screen Help
2010-06-18 04:12:58 +03:00
2010-02-04 13:33:47 +02:00
if ( helpDisplayed ) {
2011-09-04 04:02:17 +03:00
s - > box ( 10 , 50 , 300 , helpBoxHeight + 4 , skinConfColors [ COLOR_MESSAGE_BOX_BG ] ) ;
2010-05-02 20:53:06 +03:00
s - > rectangle ( 12 , 52 , 296 , helpBoxHeight ,
skinConfColors [ COLOR_MESSAGE_BOX_BORDER ] ) ;
2010-02-04 13:33:47 +02:00
s - > write ( font , tr [ " CONTROLS " ] , 20 , 60 ) ;
2011-09-04 04:02:17 +03:00
# ifdef PLATFORM_DINGUX
s - > write ( font , tr [ " A: Launch link / Confirm action " ] , 20 , 80 ) ;
s - > write ( font , tr [ " B: Show this help menu " ] , 20 , 95 ) ;
s - > write ( font , tr [ " L, R: Change section " ] , 20 , 110 ) ;
s - > write ( font , tr [ " SELECT: Show contextual menu " ] , 20 , 155 ) ;
s - > write ( font , tr [ " START: Show options menu " ] , 20 , 170 ) ;
2011-07-29 02:13:35 +03:00
# endif
2011-09-04 04:02:17 +03:00
s - > flip ( ) ;
2011-10-23 09:57:52 +03:00
while ( input . waitForPressedButton ( ) ! = InputManager : : CANCEL ) { }
2011-09-04 04:02:17 +03:00
helpDisplayed = false ;
continue ;
2010-02-04 13:33:47 +02:00
}
2010-09-17 23:31:09 +03:00
# ifdef WITH_DEBUG
2010-02-04 13:33:47 +02:00
//framerate
drawn_frames + + ;
if ( tickNow - tickFPS > = 1000 ) {
ss . clear ( ) ;
ss < < drawn_frames * ( tickNow - tickFPS + 1 ) / 1000 ;
ss > > fps ;
tickFPS = tickNow ;
drawn_frames = 0 ;
}
2011-05-09 06:17:25 +03:00
s - > write ( font , fps + " FPS " , resX - 1 , 1 , ASFont : : HAlignRight ) ;
2010-02-04 13:33:47 +02:00
# endif
s - > flip ( ) ;
//touchscreen
2011-12-23 13:30:15 +02:00
if ( ts . available ( ) ) {
2010-02-04 13:33:47 +02:00
ts . poll ( ) ;
btnContextMenu . handleTS ( ) ;
re . x = 0 ; re . y = 0 ; re . h = skinConfInt [ " topBarHeight " ] ; re . w = resX ;
if ( ts . pressed ( ) & & ts . inRect ( re ) ) {
re . w = skinConfInt [ " linkWidth " ] ;
2010-07-27 22:12:15 +03:00
sectionsCoordX = halfX - ( constrain ( ( uint ) menu - > getSections ( ) . size ( ) , 0 , linkColumns ) * skinConfInt [ " linkWidth " ] ) / 2 ;
for ( i = menu - > firstDispSection ( ) ; ! ts . handled ( ) & & i < menu - > getSections ( ) . size ( ) & & i < menu - > firstDispSection ( ) + linkColumns ; i + + ) {
2010-02-04 13:33:47 +02:00
re . x = ( i - menu - > firstDispSection ( ) ) * re . w + sectionsCoordX ;
if ( ts . inRect ( re ) ) {
menu - > setSectionIndex ( i ) ;
ts . setHandled ( ) ;
}
}
}
i = menu - > firstDispRow ( ) * linkColumns ;
while ( i < ( menu - > firstDispRow ( ) * linkColumns ) + linksPerPage & & i < menu - > sectionLinks ( ) - > size ( ) ) {
if ( menu - > sectionLinks ( ) - > at ( i ) - > isPressed ( ) )
menu - > setLinkIndex ( i ) ;
if ( menu - > sectionLinks ( ) - > at ( i ) - > handleTS ( ) )
i = menu - > sectionLinks ( ) - > size ( ) ;
i + + ;
}
}
2010-09-17 23:34:26 +03:00
switch ( input . waitForPressedButton ( ) ) {
2011-10-23 09:57:52 +03:00
case InputManager : : ACCEPT :
2010-09-17 23:34:26 +03:00
if ( menu - > selLink ( ) ! = NULL ) menu - > selLink ( ) - > run ( ) ;
break ;
2011-10-23 09:57:52 +03:00
case InputManager : : CANCEL :
2011-09-04 04:02:17 +03:00
helpDisplayed = true ;
2010-09-17 23:34:26 +03:00
break ;
2011-10-23 09:57:52 +03:00
case InputManager : : SETTINGS :
2010-09-17 23:34:26 +03:00
options ( ) ;
break ;
2011-10-23 09:57:52 +03:00
case InputManager : : MENU :
2010-09-17 23:34:26 +03:00
contextMenu ( ) ;
break ;
2011-10-23 09:57:52 +03:00
case InputManager : : UP :
2010-09-17 23:34:26 +03:00
menu - > linkUp ( ) ;
break ;
2011-10-23 09:57:52 +03:00
case InputManager : : DOWN :
2010-09-17 23:34:26 +03:00
menu - > linkDown ( ) ;
break ;
2011-10-23 09:57:52 +03:00
case InputManager : : LEFT :
2010-09-17 23:34:26 +03:00
menu - > linkLeft ( ) ;
break ;
2011-10-23 09:57:52 +03:00
case InputManager : : RIGHT :
2010-09-17 23:34:26 +03:00
menu - > linkRight ( ) ;
break ;
2011-10-23 09:57:52 +03:00
case InputManager : : ALTLEFT :
2010-09-17 23:34:26 +03:00
menu - > decSectionIndex ( ) ;
offset = menu - > sectionLinks ( ) - > size ( ) > linksPerPage ? 2 : 6 ;
break ;
2011-10-23 09:57:52 +03:00
case InputManager : : ALTRIGHT :
2010-09-17 23:34:26 +03:00
menu - > incSectionIndex ( ) ;
offset = menu - > sectionLinks ( ) - > size ( ) > linksPerPage ? 2 : 6 ;
break ;
default :
break ;
}
2010-02-04 13:33:47 +02:00
}
}
void GMenu2X : : explorer ( ) {
2011-12-23 15:03:05 +02:00
FileDialog fd ( this , ts , tr [ " Select an application " ] , " .gpu,.dge,.sh, " ) ;
2010-02-04 13:33:47 +02:00
if ( fd . exec ( ) ) {
if ( confInt [ " saveSelection " ] & & ( confInt [ " section " ] ! = menu - > selSectionIndex ( ) | | confInt [ " link " ] ! = menu - > selLinkIndex ( ) ) )
writeConfig ( ) ;
//string command = cmdclean(fd.path()+"/"+fd.file) + "; sync & cd "+cmdclean(getExePath())+"; exec ./gmenu2x";
2010-05-03 20:58:28 +03:00
string command = cmdclean ( fd . getPath ( ) + " / " + fd . getFile ( ) ) ;
chdir ( fd . getPath ( ) . c_str ( ) ) ;
2010-02-04 13:33:47 +02:00
quit ( ) ;
2011-09-18 19:27:03 +03:00
setClock ( cpuFreqAppDefault ) ;
2010-02-04 13:33:47 +02:00
execlp ( " /bin/sh " , " /bin/sh " , " -c " , command . c_str ( ) , NULL ) ;
//if execution continues then something went wrong and as we already called SDL_Quit we cannot continue
//try relaunching gmenu2x
2010-09-17 23:31:09 +03:00
ERROR ( " Error executing selected application, re-launching gmenu2x \n " ) ;
2010-02-04 13:33:47 +02:00
chdir ( getExePath ( ) . c_str ( ) ) ;
execlp ( " ./gmenu2x " , " ./gmenu2x " , NULL ) ;
}
}
void GMenu2X : : options ( ) {
int curMenuClock = confInt [ " menuClock " ] ;
2010-07-04 04:19:52 +03:00
bool showRootFolder = fileExists ( CARD_ROOT ) ;
2010-02-04 13:33:47 +02:00
2011-04-14 12:16:16 +03:00
FileLister fl_tr ( getHome ( ) + " /translations " ) ;
2010-02-04 13:33:47 +02:00
fl_tr . browse ( ) ;
2011-04-14 12:16:16 +03:00
fl_tr . setPath ( GMENU2X_SYSTEM_DIR " /translations " , false ) ;
2011-04-12 10:59:32 +03:00
fl_tr . browse ( false ) ;
2010-07-27 22:41:35 +03:00
fl_tr . insertFile ( " English " ) ;
2010-02-04 13:33:47 +02:00
string lang = tr . lang ( ) ;
vector < string > encodings ;
encodings . push_back ( " NTSC " ) ;
encodings . push_back ( " PAL " ) ;
2010-07-28 00:09:16 +03:00
SettingsDialog sd ( this , input , ts , tr [ " Settings " ] ) ;
2011-12-23 15:03:05 +02:00
sd . addSetting ( new MenuSettingMultiString ( this , ts , tr [ " Language " ] , tr [ " Set the language used by GMenu2X " ] , & lang , & fl_tr . getFiles ( ) ) ) ;
sd . addSetting ( new MenuSettingBool ( this , ts , tr [ " Save last selection " ] , tr [ " Save the last selected link and section on exit " ] , & confInt [ " saveSelection " ] ) ) ;
sd . addSetting ( new MenuSettingInt ( this , ts , tr [ " Clock for GMenu2X " ] , tr [ " Set the cpu working frequency when running GMenu2X " ] , & confInt [ " menuClock " ] , cpuFreqMin , cpuFreqSafeMax , cpuFreqMultiple ) ) ;
sd . addSetting ( new MenuSettingInt ( this , ts , tr [ " Maximum overclock " ] , tr [ " Set the maximum overclock for launching links " ] , & confInt [ " maxClock " ] , cpuFreqMin , cpuFreqMax , cpuFreqMultiple ) ) ;
sd . addSetting ( new MenuSettingBool ( this , ts , tr [ " Output logs " ] , tr [ " Logs the output of the links. Use the Log Viewer to read them. " ] , & confInt [ " outputLogs " ] ) ) ;
sd . addSetting ( new MenuSettingInt ( this , ts , tr [ " Screen Timeout " ] , tr [ " Set screen's backlight timeout in seconds " ] , & confInt [ " backlightTimeout " ] , 0 , 120 ) ) ;
// sd.addSetting(new MenuSettingMultiString(this, ts, tr["Tv-Out encoding"], tr["Encoding of the tv-out signal"], &confStr["tvoutEncoding"], &encodings));
sd . addSetting ( new MenuSettingBool ( this , ts , tr [ " Show root " ] , tr [ " Show root folder in the file selection dialogs " ] , & showRootFolder ) ) ;
2010-02-04 13:33:47 +02:00
if ( sd . exec ( ) & & sd . edited ( ) ) {
2011-12-23 15:03:05 +02:00
if ( curMenuClock ! = confInt [ " menuClock " ] ) setClock ( confInt [ " menuClock " ] ) ;
2011-08-17 01:46:11 +03:00
if ( confInt [ " backlightTimeout " ] = = 0 ) {
if ( PowerSaver : : isRunning ( ) )
delete PowerSaver : : getInstance ( ) ;
} else {
PowerSaver : : getInstance ( ) - > setScreenTimeout ( confInt [ " backlightTimeout " ] ) ;
}
2010-02-04 13:33:47 +02:00
if ( lang = = " English " ) lang = " " ;
2011-04-12 14:24:35 +03:00
if ( lang ! = tr . lang ( ) ) {
tr . setLang ( lang ) ;
confStr [ " lang " ] = lang ;
}
2010-09-01 23:50:43 +03:00
/*if (fileExists(CARD_ROOT) && !showRootFolder)
2010-07-04 04:19:52 +03:00
unlink ( CARD_ROOT ) ;
2010-09-01 23:50:43 +03:00
else if ( ! fileExists ( CARD_ROOT ) & & showRootFolder )
symlink ( " / " , CARD_ROOT ) ; */
2010-09-01 18:37:27 +03:00
//WARNING: the above might be dangerous with CARD_ROOT set to /
2010-02-04 13:33:47 +02:00
writeConfig ( ) ;
}
}
void GMenu2X : : skinMenu ( ) {
2011-04-14 12:16:16 +03:00
FileLister fl_sk ( getHome ( ) + " /skins " , true , false ) ;
2010-07-27 22:41:35 +03:00
fl_sk . addExclude ( " .. " ) ;
2010-02-04 13:33:47 +02:00
fl_sk . browse ( ) ;
2011-04-14 12:16:16 +03:00
fl_sk . setPath ( GMENU2X_SYSTEM_DIR " /skins " , false ) ;
2011-04-12 11:16:28 +03:00
fl_sk . browse ( false ) ;
2010-02-04 13:33:47 +02:00
string curSkin = confStr [ " skin " ] ;
2010-07-28 00:09:16 +03:00
SettingsDialog sd ( this , input , ts , tr [ " Skin " ] ) ;
2011-12-23 15:03:05 +02:00
sd . addSetting ( new MenuSettingMultiString ( this , ts , tr [ " Skin " ] , tr [ " Set the skin used by GMenu2X " ] , & confStr [ " skin " ] , & fl_sk . getDirectories ( ) ) ) ;
sd . addSetting ( new MenuSettingRGBA ( this , ts , tr [ " Top Bar Color " ] , tr [ " Color of the top bar " ] , & skinConfColors [ COLOR_TOP_BAR_BG ] ) ) ;
sd . addSetting ( new MenuSettingRGBA ( this , ts , tr [ " Bottom Bar Color " ] , tr [ " Color of the bottom bar " ] , & skinConfColors [ COLOR_BOTTOM_BAR_BG ] ) ) ;
sd . addSetting ( new MenuSettingRGBA ( this , ts , tr [ " Selection Color " ] , tr [ " Color of the selection and other interface details " ] , & skinConfColors [ COLOR_SELECTION_BG ] ) ) ;
sd . addSetting ( new MenuSettingRGBA ( this , ts , tr [ " Message Box Color " ] , tr [ " Background color of the message box " ] , & skinConfColors [ COLOR_MESSAGE_BOX_BG ] ) ) ;
sd . addSetting ( new MenuSettingRGBA ( this , ts , tr [ " Message Box Border Color " ] , tr [ " Border color of the message box " ] , & skinConfColors [ COLOR_MESSAGE_BOX_BORDER ] ) ) ;
sd . addSetting ( new MenuSettingRGBA ( this , ts , tr [ " Message Box Selection Color " ] , tr [ " Color of the selection of the message box " ] , & skinConfColors [ COLOR_MESSAGE_BOX_SELECTION ] ) ) ;
2010-02-04 13:33:47 +02:00
if ( sd . exec ( ) & & sd . edited ( ) ) {
if ( curSkin ! = confStr [ " skin " ] ) {
setSkin ( confStr [ " skin " ] ) ;
writeConfig ( ) ;
}
writeSkinConfig ( ) ;
initBG ( ) ;
}
}
2010-05-02 15:29:09 +03:00
void GMenu2X : : setSkin ( const string & skin , bool setWallpaper ) {
2010-02-04 13:33:47 +02:00
confStr [ " skin " ] = skin ;
//Clear previous skin settings
skinConfStr . clear ( ) ;
skinConfInt . clear ( ) ;
2011-07-11 13:39:31 +03:00
DEBUG ( " GMenu2X: setting new skin %s. \n " , skin . c_str ( ) ) ;
2010-02-04 13:33:47 +02:00
//clear collection and change the skin path
sc . clear ( ) ;
sc . setSkin ( skin ) ;
//reset colors to the default values
2010-05-02 20:53:06 +03:00
skinConfColors [ COLOR_TOP_BAR_BG ] = ( RGBAColor ) { 255 , 255 , 255 , 130 } ;
skinConfColors [ COLOR_BOTTOM_BAR_BG ] = ( RGBAColor ) { 255 , 255 , 255 , 130 } ;
skinConfColors [ COLOR_SELECTION_BG ] = ( RGBAColor ) { 255 , 255 , 255 , 130 } ;
skinConfColors [ COLOR_MESSAGE_BOX_BG ] = ( RGBAColor ) { 255 , 255 , 255 , 255 } ;
skinConfColors [ COLOR_MESSAGE_BOX_BORDER ] = ( RGBAColor ) { 80 , 80 , 80 , 255 } ;
skinConfColors [ COLOR_MESSAGE_BOX_SELECTION ] = ( RGBAColor ) { 160 , 160 , 160 , 255 } ;
2010-02-04 13:33:47 +02:00
2011-03-29 13:37:53 +03:00
/* Load skin settings from user directory if present,
* or from the system directory . */
string skinconfname = getHome ( ) + " /skins/ " + skin + " /skin.conf " ;
if ( ! fileExists ( skinconfname ) )
skinconfname = GMENU2X_SYSTEM_DIR " /skins/ " + skin + " /skin.conf " ;
2010-02-04 13:33:47 +02:00
if ( fileExists ( skinconfname ) ) {
ifstream skinconf ( skinconfname . c_str ( ) , ios_base : : in ) ;
if ( skinconf . is_open ( ) ) {
string line ;
while ( getline ( skinconf , line , ' \n ' ) ) {
line = trim ( line ) ;
2010-09-17 23:31:09 +03:00
DEBUG ( " skinconf: '%s' \n " , line . c_str ( ) ) ;
2010-02-04 13:33:47 +02:00
string : : size_type pos = line . find ( " = " ) ;
string name = trim ( line . substr ( 0 , pos ) ) ;
string value = trim ( line . substr ( pos + 1 , line . length ( ) ) ) ;
if ( value . length ( ) > 0 ) {
if ( value . length ( ) > 1 & & value . at ( 0 ) = = ' " ' & & value . at ( value . length ( ) - 1 ) = = ' " ' )
skinConfStr [ name ] = value . substr ( 1 , value . length ( ) - 2 ) ;
else if ( value . at ( 0 ) = = ' # ' )
2010-05-02 20:53:06 +03:00
skinConfColors [ stringToColor ( name ) ] = strtorgba ( value . substr ( 1 , value . length ( ) ) ) ;
2010-02-04 13:33:47 +02:00
else
skinConfInt [ name ] = atoi ( value . c_str ( ) ) ;
}
}
skinconf . close ( ) ;
if ( setWallpaper & & ! skinConfStr [ " wallpaper " ] . empty ( ) & & fileExists ( " skins/ " + skin + " /wallpapers/ " + skinConfStr [ " wallpaper " ] ) )
confStr [ " wallpaper " ] = " skins/ " + skin + " /wallpapers/ " + skinConfStr [ " wallpaper " ] ;
}
}
evalIntConf ( & skinConfInt [ " topBarHeight " ] , 40 , 32 , 120 ) ;
evalIntConf ( & skinConfInt [ " linkHeight " ] , 40 , 32 , 120 ) ;
evalIntConf ( & skinConfInt [ " linkWidth " ] , 60 , 32 , 120 ) ;
//recalculate some coordinates based on the new element sizes
linkColumns = ( resX - 10 ) / skinConfInt [ " linkWidth " ] ;
linkRows = ( resY - 35 - skinConfInt [ " topBarHeight " ] ) / skinConfInt [ " linkHeight " ] ;
if ( menu ! = NULL ) menu - > loadIcons ( ) ;
//Selection png
2011-07-11 14:34:52 +03:00
useSelectionPng = sc . addSkinRes ( " imgs/selection.png " , false ) ! = NULL ;
2010-02-04 13:33:47 +02:00
//font
initFont ( ) ;
}
2011-09-15 12:18:07 +03:00
void GMenu2X : : showManual ( ) {
menu - > selLinkApp ( ) - > showManual ( ) ;
}
2010-02-04 13:33:47 +02:00
void GMenu2X : : contextMenu ( ) {
vector < MenuOption > voices ;
{
MenuOption opt = { tr . translate ( " Add link in $1 " , menu - > selSection ( ) . c_str ( ) , NULL ) , MakeDelegate ( this , & GMenu2X : : addLink ) } ;
voices . push_back ( opt ) ;
}
2011-09-15 12:18:07 +03:00
{
LinkApp * app = menu - > selLinkApp ( ) ;
if ( app & & fileExists ( app - > getManual ( ) ) ) {
MenuOption opt = { tr . translate ( " Show manual of $1 " , menu - > selLink ( ) - > getTitle ( ) . c_str ( ) , NULL ) ,
MakeDelegate ( this , & GMenu2X : : showManual ) ,
} ;
voices . push_back ( opt ) ;
}
}
2010-02-04 13:33:47 +02:00
if ( menu - > selLinkApp ( ) ! = NULL ) {
{
MenuOption opt = { tr . translate ( " Edit $1 " , menu - > selLink ( ) - > getTitle ( ) . c_str ( ) , NULL ) , MakeDelegate ( this , & GMenu2X : : editLink ) } ;
voices . push_back ( opt ) ;
} {
MenuOption opt = { tr . translate ( " Delete $1 link " , menu - > selLink ( ) - > getTitle ( ) . c_str ( ) , NULL ) , MakeDelegate ( this , & GMenu2X : : deleteLink ) } ;
voices . push_back ( opt ) ;
}
}
{
MenuOption opt = { tr [ " Add section " ] , MakeDelegate ( this , & GMenu2X : : addSection ) } ;
voices . push_back ( opt ) ;
} {
MenuOption opt = { tr [ " Rename section " ] , MakeDelegate ( this , & GMenu2X : : renameSection ) } ;
voices . push_back ( opt ) ;
} {
MenuOption opt = { tr [ " Delete section " ] , MakeDelegate ( this , & GMenu2X : : deleteSection ) } ;
voices . push_back ( opt ) ;
} {
MenuOption opt = { tr [ " Scan for applications and games " ] , MakeDelegate ( this , & GMenu2X : : scanner ) } ;
voices . push_back ( opt ) ;
}
bool close = false ;
2011-10-23 18:00:23 +03:00
uint i , fadeAlpha = 0 ;
int sel = 0 ;
2010-02-04 13:33:47 +02:00
int h = font - > getHeight ( ) ;
SDL_Rect box ;
box . h = ( h + 2 ) * voices . size ( ) + 8 ;
box . w = 0 ;
for ( i = 0 ; i < voices . size ( ) ; i + + ) {
int w = font - > getTextWidth ( voices [ i ] . text ) ;
if ( w > box . w ) box . w = w ;
}
box . w + = 23 ;
box . x = halfX - box . w / 2 ;
box . y = halfY - box . h / 2 ;
2012-04-11 00:01:16 +03:00
SDL_Rect selbox = {
static_cast < Sint16 > ( box . x + 4 ) ,
0 ,
static_cast < Uint16 > ( box . w - 8 ) ,
static_cast < Uint16 > ( h + 2 )
} ;
2010-02-04 13:33:47 +02:00
long tickNow , tickStart = SDL_GetTicks ( ) ;
Surface bg ( s ) ;
/*//Darken background
bg . box ( 0 , 0 , resX , resY , 0 , 0 , 0 , 150 ) ;
bg . box ( box . x , box . y , box . w , box . h , skinConfColors [ " messageBoxBg " ] ) ;
bg . rectangle ( box . x + 2 , box . y + 2 , box . w - 4 , box . h - 4 , skinConfColors [ " messageBoxBorder " ] ) ; */
2010-09-17 23:34:26 +03:00
2011-10-23 09:57:52 +03:00
InputManager : : ButtonEvent event ;
2010-02-04 13:33:47 +02:00
while ( ! close ) {
tickNow = SDL_GetTicks ( ) ;
selbox . y = box . y + 4 + ( h + 2 ) * sel ;
bg . blit ( s , 0 , 0 ) ;
if ( fadeAlpha < 200 ) fadeAlpha = intTransition ( 0 , 200 , tickStart , 500 , tickNow ) ;
s - > box ( 0 , 0 , resX , resY , 0 , 0 , 0 , fadeAlpha ) ;
2010-05-02 20:53:06 +03:00
s - > box ( box . x , box . y , box . w , box . h , skinConfColors [ COLOR_MESSAGE_BOX_BG ] ) ;
s - > rectangle ( box . x + 2 , box . y + 2 , box . w - 4 , box . h - 4 , skinConfColors [ COLOR_MESSAGE_BOX_BORDER ] ) ;
2010-02-04 13:33:47 +02:00
//draw selection rect
2010-05-02 20:53:06 +03:00
s - > box ( selbox . x , selbox . y , selbox . w , selbox . h , skinConfColors [ COLOR_MESSAGE_BOX_SELECTION ] ) ;
2010-02-04 13:33:47 +02:00
for ( i = 0 ; i < voices . size ( ) ; i + + )
2011-05-10 01:31:45 +03:00
s - > write ( font , voices [ i ] . text , box . x + 12 , box . y + 5 + ( h + 2 ) * i , ASFont : : HAlignLeft , ASFont : : VAlignTop ) ;
2010-02-04 13:33:47 +02:00
s - > flip ( ) ;
//touchscreen
2011-12-23 13:30:15 +02:00
if ( ts . available ( ) ) {
2010-02-04 13:33:47 +02:00
ts . poll ( ) ;
if ( ts . released ( ) ) {
if ( ! ts . inRect ( box ) )
close = true ;
2010-07-26 06:24:55 +03:00
else if ( ts . getX ( ) > = selbox . x
& & ts . getX ( ) < = selbox . x + selbox . w )
2010-02-04 13:33:47 +02:00
for ( i = 0 ; i < voices . size ( ) ; i + + ) {
selbox . y = box . y + 4 + ( h + 2 ) * i ;
2010-07-26 06:24:55 +03:00
if ( ts . getY ( ) > = selbox . y
& & ts . getY ( ) < = selbox . y + selbox . h ) {
2010-02-04 13:33:47 +02:00
voices [ i ] . action ( ) ;
close = true ;
i = voices . size ( ) ;
}
}
} else if ( ts . pressed ( ) & & ts . inRect ( box ) ) {
for ( i = 0 ; i < voices . size ( ) ; i + + ) {
selbox . y = box . y + 4 + ( h + 2 ) * i ;
2010-07-26 06:24:55 +03:00
if ( ts . getY ( ) > = selbox . y
& & ts . getY ( ) < = selbox . y + selbox . h ) {
2010-02-04 13:33:47 +02:00
sel = i ;
i = voices . size ( ) ;
}
}
}
}
2011-09-18 19:27:03 +03:00
2010-09-17 23:34:26 +03:00
if ( fadeAlpha < 200 ) {
2011-10-23 09:57:52 +03:00
if ( ! input . pollEvent ( & event ) | | event . state ! = InputManager : : PRESSED ) continue ;
2010-09-17 23:34:26 +03:00
} else {
event . button = input . waitForPressedButton ( ) ;
}
switch ( event . button ) {
2011-10-23 09:57:52 +03:00
case InputManager : : MENU :
2010-09-17 23:34:26 +03:00
close = true ;
break ;
2011-10-23 09:57:52 +03:00
case InputManager : : UP :
2011-10-23 18:00:23 +03:00
sel = std : : max ( 0 , sel - 1 ) ;
2010-09-17 23:34:26 +03:00
break ;
2011-10-23 09:57:52 +03:00
case InputManager : : DOWN :
2011-10-23 18:00:23 +03:00
sel = std : : min ( ( int ) voices . size ( ) - 1 , sel + 1 ) ;
2010-09-17 23:34:26 +03:00
break ;
2011-10-23 09:57:52 +03:00
case InputManager : : ACCEPT :
2010-09-17 23:34:26 +03:00
voices [ sel ] . action ( ) ;
close = true ;
break ;
default :
break ;
}
2010-02-04 13:33:47 +02:00
}
}
void GMenu2X : : changeWallpaper ( ) {
2011-12-23 15:03:05 +02:00
WallpaperDialog wp ( this , ts ) ;
2010-02-04 13:33:47 +02:00
if ( wp . exec ( ) & & confStr [ " wallpaper " ] ! = wp . wallpaper ) {
confStr [ " wallpaper " ] = wp . wallpaper ;
initBG ( ) ;
writeConfig ( ) ;
}
}
void GMenu2X : : addLink ( ) {
2011-12-23 15:03:05 +02:00
FileDialog fd ( this , ts , tr [ " Select an application " ] ) ;
2010-02-04 13:33:47 +02:00
if ( fd . exec ( ) ) {
2010-05-03 20:58:28 +03:00
menu - > addLink ( fd . getPath ( ) , fd . getFile ( ) ) ;
2010-02-04 13:33:47 +02:00
sync ( ) ;
}
}
void GMenu2X : : editLink ( ) {
if ( menu - > selLinkApp ( ) = = NULL ) return ;
vector < string > pathV ;
2010-07-27 22:26:02 +03:00
split ( pathV , menu - > selLinkApp ( ) - > getFile ( ) , " / " ) ;
2010-02-04 13:33:47 +02:00
string oldSection = " " ;
if ( pathV . size ( ) > 1 )
oldSection = pathV [ pathV . size ( ) - 2 ] ;
string newSection = oldSection ;
string linkTitle = menu - > selLinkApp ( ) - > getTitle ( ) ;
string linkDescription = menu - > selLinkApp ( ) - > getDescription ( ) ;
string linkIcon = menu - > selLinkApp ( ) - > getIcon ( ) ;
string linkManual = menu - > selLinkApp ( ) - > getManual ( ) ;
string linkParams = menu - > selLinkApp ( ) - > getParams ( ) ;
string linkSelFilter = menu - > selLinkApp ( ) - > getSelectorFilter ( ) ;
string linkSelDir = menu - > selLinkApp ( ) - > getSelectorDir ( ) ;
bool linkSelBrowser = menu - > selLinkApp ( ) - > getSelectorBrowser ( ) ;
string linkSelScreens = menu - > selLinkApp ( ) - > getSelectorScreens ( ) ;
string linkSelAliases = menu - > selLinkApp ( ) - > getAliasFile ( ) ;
int linkClock = menu - > selLinkApp ( ) - > clock ( ) ;
string diagTitle = tr . translate ( " Edit link: $1 " , linkTitle . c_str ( ) , NULL ) ;
string diagIcon = menu - > selLinkApp ( ) - > getIconPath ( ) ;
2010-07-28 00:09:16 +03:00
SettingsDialog sd ( this , input , ts , diagTitle , diagIcon ) ;
2011-12-23 15:03:05 +02:00
sd . addSetting ( new MenuSettingString ( this , ts , tr [ " Title " ] , tr [ " Link title " ] , & linkTitle , diagTitle , diagIcon ) ) ;
sd . addSetting ( new MenuSettingString ( this , ts , tr [ " Description " ] , tr [ " Link description " ] , & linkDescription , diagTitle , diagIcon ) ) ;
sd . addSetting ( new MenuSettingMultiString ( this , ts , tr [ " Section " ] , tr [ " The section this link belongs to " ] , & newSection , & menu - > getSections ( ) ) ) ;
sd . addSetting ( new MenuSettingImage ( this , ts , tr [ " Icon " ] , tr . translate ( " Select an icon for the link: $1 " , linkTitle . c_str ( ) , NULL ) , & linkIcon , " .png,.bmp,.jpg,.jpeg " ) ) ;
sd . addSetting ( new MenuSettingFile ( this , ts , tr [ " Manual " ] , tr [ " Select a graphic/textual manual or a readme " ] , & linkManual , " .man.png,.txt " ) ) ;
sd . addSetting ( new MenuSettingInt ( this , ts , tr [ " Clock (default: 336) " ] , tr [ " Cpu clock frequency to set when launching this link " ] , & linkClock , cpuFreqMin , confInt [ " maxClock " ] , cpuFreqMultiple ) ) ;
sd . addSetting ( new MenuSettingString ( this , ts , tr [ " Parameters " ] , tr [ " Parameters to pass to the application " ] , & linkParams , diagTitle , diagIcon ) ) ;
sd . addSetting ( new MenuSettingDir ( this , ts , tr [ " Selector Directory " ] , tr [ " Directory to scan for the selector " ] , & linkSelDir ) ) ;
sd . addSetting ( new MenuSettingBool ( this , ts , tr [ " Selector Browser " ] , tr [ " Allow the selector to change directory " ] , & linkSelBrowser ) ) ;
sd . addSetting ( new MenuSettingString ( this , ts , tr [ " Selector Filter " ] , tr [ " Selector filter (Separate values with a comma) " ] , & linkSelFilter , diagTitle , diagIcon ) ) ;
sd . addSetting ( new MenuSettingDir ( this , ts , tr [ " Selector Screenshots " ] , tr [ " Directory of the screenshots for the selector " ] , & linkSelScreens ) ) ;
sd . addSetting ( new MenuSettingFile ( this , ts , tr [ " Selector Aliases " ] , tr [ " File containing a list of aliases for the selector " ] , & linkSelAliases ) ) ;
sd . addSetting ( new MenuSettingBool ( this , ts , tr [ " Don't Leave " ] , tr [ " Don't quit GMenu2X when launching this link " ] , & menu - > selLinkApp ( ) - > runsInBackgroundRef ( ) ) ) ;
2012-04-13 20:21:49 +03:00
# ifdef PLATFORM_DINGUX
sd . addSetting ( new MenuSettingBool ( this , ts , tr [ " Display Console " ] , tr [ " Must be enabled for console-based applications " ] , & menu - > selLinkApp ( ) - > consoleApp ) ) ;
# endif
2010-02-04 13:33:47 +02:00
if ( sd . exec ( ) & & sd . edited ( ) ) {
menu - > selLinkApp ( ) - > setTitle ( linkTitle ) ;
menu - > selLinkApp ( ) - > setDescription ( linkDescription ) ;
menu - > selLinkApp ( ) - > setIcon ( linkIcon ) ;
menu - > selLinkApp ( ) - > setManual ( linkManual ) ;
menu - > selLinkApp ( ) - > setParams ( linkParams ) ;
menu - > selLinkApp ( ) - > setSelectorFilter ( linkSelFilter ) ;
menu - > selLinkApp ( ) - > setSelectorDir ( linkSelDir ) ;
menu - > selLinkApp ( ) - > setSelectorBrowser ( linkSelBrowser ) ;
menu - > selLinkApp ( ) - > setSelectorScreens ( linkSelScreens ) ;
menu - > selLinkApp ( ) - > setAliasFile ( linkSelAliases ) ;
menu - > selLinkApp ( ) - > setClock ( linkClock ) ;
2010-09-17 23:31:09 +03:00
INFO ( " New Section: '%s' \n " , newSection . c_str ( ) ) ;
2010-02-04 13:33:47 +02:00
//if section changed move file and update link->file
if ( oldSection ! = newSection ) {
2010-07-27 22:12:15 +03:00
vector < string > : : const_iterator newSectionIndex = find ( menu - > getSections ( ) . begin ( ) , menu - > getSections ( ) . end ( ) , newSection ) ;
if ( newSectionIndex = = menu - > getSections ( ) . end ( ) ) return ;
2010-02-04 13:33:47 +02:00
string newFileName = " sections/ " + newSection + " / " + linkTitle ;
uint x = 2 ;
while ( fileExists ( newFileName ) ) {
string id = " " ;
stringstream ss ; ss < < x ; ss > > id ;
newFileName = " sections/ " + newSection + " / " + linkTitle + id ;
x + + ;
}
2010-07-27 22:26:02 +03:00
rename ( menu - > selLinkApp ( ) - > getFile ( ) . c_str ( ) , newFileName . c_str ( ) ) ;
menu - > selLinkApp ( ) - > renameFile ( newFileName ) ;
2010-09-17 23:31:09 +03:00
INFO ( " New section index: %i. \n " , newSectionIndex - menu - > getSections ( ) . begin ( ) ) ;
2010-07-27 22:12:15 +03:00
menu - > linkChangeSection ( menu - > selLinkIndex ( ) , menu - > selSectionIndex ( ) , newSectionIndex - menu - > getSections ( ) . begin ( ) ) ;
2010-02-04 13:33:47 +02:00
}
menu - > selLinkApp ( ) - > save ( ) ;
sync ( ) ;
}
}
void GMenu2X : : deleteLink ( ) {
if ( menu - > selLinkApp ( ) ! = NULL ) {
MessageBox mb ( this , tr . translate ( " Deleting $1 " , menu - > selLink ( ) - > getTitle ( ) . c_str ( ) , NULL ) + " \n " + tr [ " Are you sure? " ] , menu - > selLink ( ) - > getIconPath ( ) ) ;
2011-10-23 09:57:52 +03:00
mb . setButton ( InputManager : : ACCEPT , tr [ " Yes " ] ) ;
mb . setButton ( InputManager : : CANCEL , tr [ " No " ] ) ;
if ( mb . exec ( ) = = InputManager : : ACCEPT ) {
2010-02-04 13:33:47 +02:00
menu - > deleteSelectedLink ( ) ;
sync ( ) ;
}
}
}
void GMenu2X : : addSection ( ) {
2010-07-27 23:56:03 +03:00
InputDialog id ( this , input , ts , tr [ " Insert a name for the new section " ] ) ;
2010-02-04 13:33:47 +02:00
if ( id . exec ( ) ) {
//only if a section with the same name does not exist
2010-07-27 22:12:15 +03:00
if ( find ( menu - > getSections ( ) . begin ( ) , menu - > getSections ( ) . end ( ) , id . getInput ( ) )
= = menu - > getSections ( ) . end ( ) ) {
2010-02-04 13:33:47 +02:00
//section directory doesn't exists
2010-07-26 06:58:06 +03:00
if ( menu - > addSection ( id . getInput ( ) ) ) {
2010-07-27 22:12:15 +03:00
menu - > setSectionIndex ( menu - > getSections ( ) . size ( ) - 1 ) ; //switch to the new section
2010-02-04 13:33:47 +02:00
sync ( ) ;
}
}
}
}
void GMenu2X : : renameSection ( ) {
2010-07-27 23:56:03 +03:00
InputDialog id ( this , input , ts , tr [ " Insert a new name for this section " ] , menu - > selSection ( ) ) ;
2010-02-04 13:33:47 +02:00
if ( id . exec ( ) ) {
//only if a section with the same name does not exist & !samename
2010-07-26 06:58:06 +03:00
if ( menu - > selSection ( ) ! = id . getInput ( )
2010-07-27 22:12:15 +03:00
& & find ( menu - > getSections ( ) . begin ( ) , menu - > getSections ( ) . end ( ) , id . getInput ( ) )
= = menu - > getSections ( ) . end ( ) ) {
2010-02-04 13:33:47 +02:00
//section directory doesn't exists
2011-04-14 13:08:10 +03:00
string newsectiondir = getHome ( ) + " /sections/ " + id . getInput ( ) ;
string sectiondir = getHome ( ) + " /sections/ " + menu - > selSection ( ) ;
if ( ! rename ( sectiondir . c_str ( ) , newsectiondir . c_str ( ) ) ) {
string oldpng = menu - > selSection ( ) + " .png " ;
string newpng = id . getInput ( ) + " .png " ;
string oldicon = sc . getSkinFilePath ( oldpng ) ;
string newicon = sc . getSkinFilePath ( newpng ) ;
2010-02-04 13:33:47 +02:00
if ( ! oldicon . empty ( ) & & newicon . empty ( ) ) {
newicon = oldicon ;
2010-06-19 06:10:19 +03:00
newicon . replace ( newicon . find ( oldpng ) , oldpng . length ( ) , newpng ) ;
2010-02-04 13:33:47 +02:00
if ( ! fileExists ( newicon ) ) {
2011-04-14 13:08:10 +03:00
rename ( oldicon . c_str ( ) , newicon . c_str ( ) ) ;
2010-02-04 13:33:47 +02:00
sc . move ( " skin: " + oldpng , " skin: " + newpng ) ;
}
}
2010-07-27 22:12:15 +03:00
menu - > renameSection ( menu - > selSectionIndex ( ) , id . getInput ( ) ) ;
2010-02-04 13:33:47 +02:00
sync ( ) ;
}
}
}
}
void GMenu2X : : deleteSection ( ) {
MessageBox mb ( this , tr [ " You will lose all the links in this section. " ] + " \n " + tr [ " Are you sure? " ] ) ;
2011-10-23 09:57:52 +03:00
mb . setButton ( InputManager : : ACCEPT , tr [ " Yes " ] ) ;
mb . setButton ( InputManager : : CANCEL , tr [ " No " ] ) ;
if ( mb . exec ( ) = = InputManager : : ACCEPT ) {
2012-06-15 00:45:57 +03:00
2011-04-14 13:08:10 +03:00
if ( rmtree ( getHome ( ) + " /sections/ " + menu - > selSection ( ) ) ) {
2010-02-04 13:33:47 +02:00
menu - > deleteSelectedSection ( ) ;
sync ( ) ;
}
}
}
void GMenu2X : : scanner ( ) {
Surface scanbg ( bg ) ;
2011-09-18 04:40:33 +03:00
drawButton ( & scanbg , " cancel " , tr [ " Exit " ] ,
drawButton ( & scanbg , " accept " , " " , 5 ) - 10 ) ;
2011-05-09 06:17:25 +03:00
scanbg . write ( font , tr [ " Link Scanner " ] , halfX , 7 , ASFont : : HAlignCenter , ASFont : : VAlignMiddle ) ;
2011-06-03 12:46:36 +03:00
scanbg . convertToDisplayFormat ( ) ;
2010-02-04 13:33:47 +02:00
uint lineY = 42 ;
2011-07-29 02:13:35 +03:00
# ifdef PLATFORM_PANDORA
2010-02-04 13:33:47 +02:00
//char *configpath = pnd_conf_query_searchpath();
# else
2011-09-18 19:27:03 +03:00
if ( confInt [ " menuClock " ] < 336 ) {
2010-02-04 13:33:47 +02:00
setClock ( 336 ) ;
2011-09-19 17:33:19 +03:00
scanbg . write ( font , tr [ " Raising cpu clock to 336MHz " ] , 5 , lineY ) ;
2010-02-04 13:33:47 +02:00
scanbg . blit ( s , 0 , 0 ) ;
s - > flip ( ) ;
lineY + = 26 ;
}
2012-06-24 23:19:36 +03:00
scanbg . write ( font , tr [ " Scanning filesystem... " ] , 5 , lineY ) ;
2010-02-04 13:33:47 +02:00
scanbg . blit ( s , 0 , 0 ) ;
s - > flip ( ) ;
lineY + = 26 ;
vector < string > files ;
2010-07-04 04:19:52 +03:00
scanPath ( CARD_ROOT , & files ) ;
2010-02-04 13:33:47 +02:00
stringstream ss ;
ss < < files . size ( ) ;
string str = " " ;
ss > > str ;
scanbg . write ( font , tr . translate ( " $1 files found. " , str . c_str ( ) , NULL ) , 5 , lineY ) ;
lineY + = 26 ;
scanbg . write ( font , tr [ " Creating links... " ] , 5 , lineY ) ;
scanbg . blit ( s , 0 , 0 ) ;
s - > flip ( ) ;
lineY + = 26 ;
string path , file ;
string : : size_type pos ;
uint linkCount = 0 ;
for ( uint i = 0 ; i < files . size ( ) ; i + + ) {
pos = files [ i ] . rfind ( " / " ) ;
if ( pos ! = string : : npos & & pos > 0 ) {
path = files [ i ] . substr ( 0 , pos + 1 ) ;
file = files [ i ] . substr ( pos + 1 , files [ i ] . length ( ) ) ;
if ( menu - > addLink ( path , file , " found " + file . substr ( file . length ( ) - 3 , 3 ) ) )
linkCount + + ;
}
}
ss . clear ( ) ;
ss < < linkCount ;
ss > > str ;
scanbg . write ( font , tr . translate ( " $1 links created. " , str . c_str ( ) , NULL ) , 5 , lineY ) ;
scanbg . blit ( s , 0 , 0 ) ;
s - > flip ( ) ;
lineY + = 26 ;
2011-09-18 19:27:03 +03:00
if ( confInt [ " menuClock " ] < 336 ) {
2010-02-04 13:33:47 +02:00
setClock ( confInt [ " menuClock " ] ) ;
scanbg . write ( font , tr [ " Decreasing cpu clock " ] , 5 , lineY ) ;
scanbg . blit ( s , 0 , 0 ) ;
s - > flip ( ) ;
lineY + = 26 ;
}
sync ( ) ;
# endif
2011-10-23 09:57:52 +03:00
InputManager : : Button button ;
2010-09-17 23:34:26 +03:00
do {
button = input . waitForPressedButton ( ) ;
2011-10-23 09:57:52 +03:00
} while ( ( button ! = InputManager : : SETTINGS )
& & ( button ! = InputManager : : ACCEPT )
& & ( button ! = InputManager : : CANCEL ) ) ;
2010-02-04 13:33:47 +02:00
}
void GMenu2X : : scanPath ( string path , vector < string > * files ) {
DIR * dirp ;
struct stat st ;
struct dirent * dptr ;
string filepath , ext ;
if ( path [ path . length ( ) - 1 ] ! = ' / ' ) path + = " / " ;
if ( ( dirp = opendir ( path . c_str ( ) ) ) = = NULL ) return ;
while ( ( dptr = readdir ( dirp ) ) ) {
if ( dptr - > d_name [ 0 ] = = ' . ' )
continue ;
filepath = path + dptr - > d_name ;
int statRet = stat ( filepath . c_str ( ) , & st ) ;
if ( S_ISDIR ( st . st_mode ) )
scanPath ( filepath , files ) ;
if ( statRet ! = - 1 ) {
ext = filepath . substr ( filepath . length ( ) - 4 , 4 ) ;
2012-06-15 00:45:57 +03:00
# if defined(PLATFORM_DINGUX) || defined(PLATFORM_NANONOTE)
2011-07-29 02:13:35 +03:00
if ( ext = = " .dge " )
2010-02-04 13:33:47 +02:00
# else
if ( ext = = " .pxml " )
# endif
files - > push_back ( filepath ) ;
}
}
closedir ( dirp ) ;
}
2011-10-23 18:27:29 +03:00
typedef struct {
unsigned short batt ;
unsigned short remocon ;
} MMSP2ADC ;
2010-02-04 13:33:47 +02:00
unsigned short GMenu2X : : getBatteryLevel ( ) {
if ( ! batteryHandle ) return 0 ;
int battval = 0 ;
2011-09-23 02:23:53 +03:00
fscanf ( batteryHandle , " %d " , & battval ) ;
2010-02-04 13:33:47 +02:00
rewind ( batteryHandle ) ;
if ( battval > 90 ) return 5 ;
if ( battval > 70 ) return 4 ;
if ( battval > 50 ) return 3 ;
if ( battval > 30 ) return 2 ;
if ( battval > 10 ) return 1 ;
2010-06-19 06:10:19 +03:00
if ( ! usbHandle ) return 0 ;
int usbval = 0 ;
2011-09-23 02:23:53 +03:00
fscanf ( usbHandle , " %d " , & usbval ) ;
2010-06-19 06:10:19 +03:00
rewind ( usbHandle ) ;
if ( usbval = = 1 ) return 6 ;
2010-02-04 13:33:47 +02:00
return 0 ;
}
void GMenu2X : : setInputSpeed ( ) {
SDL_EnableKeyRepeat ( 1 , 150 ) ;
}
void GMenu2X : : setClock ( unsigned mhz ) {
2011-09-19 17:26:42 +03:00
mhz = constrain ( mhz , cpuFreqMin , confInt [ " maxClock " ] ) ;
2011-07-29 02:13:35 +03:00
# if defined(PLATFORM_DINGUX) || defined(PLATFORM_NANONOTE)
2010-07-04 04:04:42 +03:00
jz_cpuspeed ( mhz ) ;
2010-02-04 13:33:47 +02:00
# endif
}
2010-05-02 15:29:09 +03:00
const string & GMenu2X : : getExePath ( ) {
2010-02-04 13:33:47 +02:00
if ( path . empty ( ) ) {
char buf [ 255 ] ;
2010-05-04 00:56:15 +03:00
memset ( buf , 0 , 255 ) ;
int l = readlink ( " /proc/self/exe " , buf , 255 ) ;
2010-02-04 13:33:47 +02:00
path = buf ;
path = path . substr ( 0 , l ) ;
l = path . rfind ( " / " ) ;
path = path . substr ( 0 , l + 1 ) ;
}
return path ;
}
2011-09-18 13:42:08 +03:00
string GMenu2X : : getDiskFree ( const char * path ) {
2010-02-04 13:33:47 +02:00
stringstream ss ;
string df = " " ;
struct statvfs b ;
2011-09-18 13:42:08 +03:00
int ret = statvfs ( path , & b ) ;
2010-02-04 13:33:47 +02:00
if ( ret = = 0 ) {
2010-06-18 04:16:44 +03:00
// Make sure that the multiplication happens in 64 bits.
unsigned long long free =
( ( unsigned long long ) b . f_bfree * b . f_bsize ) / 1048576 ;
unsigned long long total =
( ( unsigned long long ) b . f_blocks * b . f_frsize ) / 1048576 ;
2010-05-01 14:20:47 +03:00
ss < < free < < " / " < < total < < " MB " ;
2010-02-04 13:33:47 +02:00
ss > > df ;
2010-09-17 23:31:09 +03:00
} else WARNING ( " statvfs failed with error '%s'. \n " , strerror ( errno ) ) ;
2010-02-04 13:33:47 +02:00
return df ;
}
2010-05-03 23:21:36 +03:00
int GMenu2X : : drawButton ( Button * btn , int x , int y ) {
2010-02-04 13:33:47 +02:00
if ( y < 0 ) y = resY + y ;
btn - > setPosition ( x , y - 7 ) ;
btn - > paint ( ) ;
return x + btn - > getRect ( ) . w + 6 ;
}
2010-05-02 15:29:09 +03:00
int GMenu2X : : drawButton ( Surface * s , const string & btn , const string & text , int x , int y ) {
2010-02-04 13:33:47 +02:00
if ( y < 0 ) y = resY + y ;
2012-04-11 00:01:16 +03:00
SDL_Rect re = { static_cast < Sint16 > ( x ) , static_cast < Sint16 > ( y - 7 ) , 0 , 16 } ;
2010-02-04 13:33:47 +02:00
if ( sc . skinRes ( " imgs/buttons/ " + btn + " .png " ) ! = NULL ) {
sc [ " imgs/buttons/ " + btn + " .png " ] - > blit ( s , x , y - 7 ) ;
2011-06-02 23:44:04 +03:00
re . w = sc [ " imgs/buttons/ " + btn + " .png " ] - > width ( ) + 3 ;
2011-05-09 06:17:25 +03:00
s - > write ( font , text , x + re . w , y , ASFont : : HAlignLeft , ASFont : : VAlignMiddle ) ;
2010-02-04 13:33:47 +02:00
re . w + = font - > getTextWidth ( text ) ;
}
return x + re . w + 6 ;
}
2010-05-02 15:29:09 +03:00
int GMenu2X : : drawButtonRight ( Surface * s , const string & btn , const string & text , int x , int y ) {
2010-02-04 13:33:47 +02:00
if ( y < 0 ) y = resY + y ;
if ( sc . skinRes ( " imgs/buttons/ " + btn + " .png " ) ! = NULL ) {
x - = 16 ;
sc [ " imgs/buttons/ " + btn + " .png " ] - > blit ( s , x , y - 7 ) ;
x - = 3 ;
2011-05-09 06:17:25 +03:00
s - > write ( font , text , x , y , ASFont : : HAlignRight , ASFont : : VAlignMiddle ) ;
2010-02-04 13:33:47 +02:00
return x - 6 - font - > getTextWidth ( text ) ;
}
return x - 6 ;
}
void GMenu2X : : drawScrollBar ( uint pagesize , uint totalsize , uint pagepos , uint top , uint height ) {
if ( totalsize < = pagesize ) return ;
2010-05-02 20:53:06 +03:00
s - > rectangle ( resX - 8 , top , 7 , height , skinConfColors [ COLOR_SELECTION_BG ] ) ;
2010-02-04 13:33:47 +02:00
//internal bar total height = height-2
//bar size
uint bs = ( height - 2 ) * pagesize / totalsize ;
//bar y position
uint by = ( height - 2 ) * pagepos / totalsize ;
by = top + 2 + by ;
if ( by + bs > top + height - 2 ) by = top + height - 2 - bs ;
2010-05-02 20:53:06 +03:00
s - > box ( resX - 6 , by , 3 , bs , skinConfColors [ COLOR_SELECTION_BG ] ) ;
2010-02-04 13:33:47 +02:00
}
void GMenu2X : : drawTopBar ( Surface * s ) {
if ( s = = NULL ) s = this - > s ;
2011-07-11 14:34:52 +03:00
Surface * bar = sc . skinRes ( " imgs/topbar.png " , false ) ;
2010-02-04 13:33:47 +02:00
if ( bar ! = NULL )
bar - > blit ( s , 0 , 0 ) ;
else
2010-05-02 20:53:06 +03:00
s - > box ( 0 , 0 , resX , skinConfInt [ " topBarHeight " ] ,
skinConfColors [ COLOR_TOP_BAR_BG ] ) ;
2010-02-04 13:33:47 +02:00
}
void GMenu2X : : drawBottomBar ( Surface * s ) {
if ( s = = NULL ) s = this - > s ;
2011-07-11 14:34:52 +03:00
Surface * bar = sc . skinRes ( " imgs/bottombar.png " , false ) ;
2010-02-04 13:33:47 +02:00
if ( bar ! = NULL )
2011-06-02 23:44:04 +03:00
bar - > blit ( s , 0 , resY - bar - > height ( ) ) ;
2010-02-04 13:33:47 +02:00
else
2010-05-02 20:53:06 +03:00
s - > box ( 0 , resY - 20 , resX , 20 , skinConfColors [ COLOR_BOTTOM_BAR_BG ] ) ;
2010-02-04 13:33:47 +02:00
}