- fix tooltips in GameCarousel

- change gui_keyboard stuff
- change filebrowser stuff
This commit is contained in:
ardi@ist-einmalig.de 2009-10-05 10:53:19 +00:00
parent 608dd91a21
commit 505e4cd09c
8 changed files with 622 additions and 503 deletions

View File

@ -193,6 +193,7 @@ GuiFileBrowser::~GuiFileBrowser()
void GuiFileBrowser::SetFocus(int f)
{
LOCK(this);
focus = f;
for(int i=0; i<FILEBROWSERSIZE; i++)
@ -204,11 +205,13 @@ void GuiFileBrowser::SetFocus(int f)
void GuiFileBrowser::DisableTriggerUpdate(bool set)
{
LOCK(this);
triggerdisabled = set;
}
void GuiFileBrowser::ResetState()
{
LOCK(this);
state = STATE_DEFAULT;
stateChan = -1;
selectedItem = 0;
@ -221,6 +224,7 @@ void GuiFileBrowser::ResetState()
void GuiFileBrowser::TriggerUpdate()
{
LOCK(this);
listChanged = true;
}
@ -229,6 +233,7 @@ void GuiFileBrowser::TriggerUpdate()
*/
void GuiFileBrowser::Draw()
{
LOCK(this);
if(!this->IsVisible())
return;
@ -249,6 +254,7 @@ void GuiFileBrowser::Draw()
void GuiFileBrowser::Update(GuiTrigger * t)
{
LOCK(this);
if(state == STATE_DISABLED || !t || triggerdisabled)
return;
@ -263,7 +269,7 @@ void GuiFileBrowser::Update(GuiTrigger * t)
if(scrollbarBoxBtn->GetState() == STATE_HELD &&
scrollbarBoxBtn->GetStateChan() == t->chan &&
t->wpad.ir.valid &&
browser.numEntries > FILEBROWSERSIZE
browser->browserList.size() > FILEBROWSERSIZE
)
{
scrollbarBoxBtn->SetPosition(20,-10);
@ -274,15 +280,15 @@ void GuiFileBrowser::Update(GuiTrigger * t)
else if(positionWiimote > scrollbarBoxBtn->GetMaxY())
positionWiimote = scrollbarBoxBtn->GetMaxY();
browser.pageIndex = (positionWiimote * browser.numEntries)/136.0 - selectedItem;
browser->pageIndex = (positionWiimote * browser->browserList.size())/136.0 - selectedItem;
if(browser.pageIndex <= 0)
if(browser->pageIndex <= 0)
{
browser.pageIndex = 0;
browser->pageIndex = 0;
}
else if(browser.pageIndex+FILEBROWSERSIZE >= browser.numEntries)
else if(browser->pageIndex+FILEBROWSERSIZE >= (int)browser->browserList.size())
{
browser.pageIndex = browser.numEntries-FILEBROWSERSIZE;
browser->pageIndex = browser->browserList.size()-FILEBROWSERSIZE;
}
listChanged = true;
focus = false;
@ -314,32 +320,32 @@ void GuiFileBrowser::Update(GuiTrigger * t)
*/
if(t->Right())
{
if(browser.pageIndex < browser.numEntries && browser.numEntries > FILEBROWSERSIZE)
if(browser->pageIndex < (int)browser->browserList.size() && browser->browserList.size() > FILEBROWSERSIZE)
{
browser.pageIndex += FILEBROWSERSIZE;
if(browser.pageIndex+FILEBROWSERSIZE >= browser.numEntries)
browser.pageIndex = browser.numEntries-FILEBROWSERSIZE;
browser->pageIndex += FILEBROWSERSIZE;
if(browser->pageIndex+FILEBROWSERSIZE >= (int)browser->browserList.size())
browser->pageIndex = browser->browserList.size()-FILEBROWSERSIZE;
listChanged = true;
}
}
else if(t->Left())
{
if(browser.pageIndex > 0)
if(browser->pageIndex > 0)
{
browser.pageIndex -= FILEBROWSERSIZE;
if(browser.pageIndex < 0)
browser.pageIndex = 0;
browser->pageIndex -= FILEBROWSERSIZE;
if(browser->pageIndex < 0)
browser->pageIndex = 0;
listChanged = true;
}
}
else if(t->Down())
{
if(browser.pageIndex + selectedItem + 1 < browser.numEntries)
if(browser->pageIndex + selectedItem + 1 < (int)browser->browserList.size())
{
if(selectedItem == FILEBROWSERSIZE-1)
{
// move list down by 1
browser.pageIndex++;
browser->pageIndex++;
listChanged = true;
}
else if(fileList[selectedItem+1]->IsVisible())
@ -351,10 +357,10 @@ void GuiFileBrowser::Update(GuiTrigger * t)
}
else if(t->Up())
{
if(selectedItem == 0 && browser.pageIndex + selectedItem > 0)
if(selectedItem == 0 && browser->pageIndex + selectedItem > 0)
{
// move list up by 1
browser.pageIndex--;
browser->pageIndex--;
listChanged = true;
}
else if(selectedItem > 0)
@ -370,17 +376,21 @@ void GuiFileBrowser::Update(GuiTrigger * t)
{
if(listChanged)
{
if(browser.pageIndex+i < browser.numEntries)
bool haveselected = false;
if(browser->pageIndex+i < (int)browser->browserList.size())
{
if(fileList[i]->GetState() == STATE_DISABLED)
fileList[i]->SetState(STATE_DEFAULT);
if(fileList[i]->GetState() == STATE_SELECTED)
haveselected = true;
fileList[i]->SetVisible(true);
fileListText[i]->SetText(browserList[browser.pageIndex+i].displayname);
fileListTextOver[i]->SetText(browserList[browser.pageIndex+i].displayname);
fileListText[i]->SetText(browser->browserList[browser->pageIndex+i].displayname);
fileListTextOver[i]->SetText(browser->browserList[browser->pageIndex+i].displayname);
if(browserList[browser.pageIndex+i].isdir) // directory
if(browser->browserList[browser->pageIndex+i].isdir) // directory
{
fileList[i]->SetIcon(fileListFolder[i]);
fileListText[i]->SetPosition(30,0);
@ -427,6 +437,9 @@ void GuiFileBrowser::Update(GuiTrigger * t)
fileList[i]->SetVisible(false);
fileList[i]->SetState(STATE_DISABLED);
}
if(!haveselected && browser->pageIndex < (int)browser->browserList.size())
fileList[i]->SetState(STATE_SELECTED, t->chan);
}
if(i != selectedItem && fileList[i]->GetState() == STATE_SELECTED)
@ -445,7 +458,6 @@ void GuiFileBrowser::Update(GuiTrigger * t)
if(fileList[i]->GetState() == STATE_SELECTED)
{
selectedItem = i;
browser.selIndex = browser.pageIndex + i;
}
}
@ -456,11 +468,11 @@ void GuiFileBrowser::Update(GuiTrigger * t)
}
else
{
position = 136*(browser.pageIndex + FILEBROWSERSIZE/2.0) / (browser.numEntries*1.0);
position = 136*(browser->pageIndex + FILEBROWSERSIZE/2.0) / (browser->browserList.size()*1.0);
if(browser.pageIndex/(FILEBROWSERSIZE/2.0) < 1)
if(browser->pageIndex/(FILEBROWSERSIZE/2.0) < 1)
position = -10;
else if((browser.pageIndex+FILEBROWSERSIZE)/(FILEBROWSERSIZE*1.0) >= (browser.numEntries)/(FILEBROWSERSIZE*1.0))
else if((browser->pageIndex+FILEBROWSERSIZE)/(FILEBROWSERSIZE*1.0) >= (browser->browserList.size())/(FILEBROWSERSIZE*1.0))
position = 156;
}

View File

@ -344,10 +344,7 @@ void GuiGameCarousel::Update(GuiTrigger * t)
else
gamename->SetText((char*)NULL);
if(selectedItem_old>=0)
{
game[selectedItem_old]->SetEffect(EFFECT_SCALE, -1, 100);
game[selectedItem_old]->RemoveToolTip();
}
}
// navigation
if(focus && gameCnt>6)

View File

@ -32,10 +32,10 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max, int min, int lang)
focus = 0; // allow focus
alignmentHor = ALIGN_CENTRE;
alignmentVert = ALIGN_MIDDLE;
strncpy(kbtextstr, t, max); // do not change from strncpy to strlcpy, it needs to be padded with 0
kbtextstr[max] = 0;
kbtextmaxlen = max;
kbtextmaxlen = max>sizeof(kbtextstr) ? sizeof(kbtextstr) : max; // limit max up to sizeof(kbtextstr)
// strlcpy(kbtextstr, t, kbtextmaxlen);
strncpy(kbtextstr, t, kbtextmaxlen); // strncpy is needed to fill the rest with \0
kbtextstr[sizeof(kbtextstr)-1] = 0; // terminate with \0
//QWERTY//
if (mode == 0){
Key thekeys[4][11] = {
@ -471,6 +471,7 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max, int min, int lang)
//keySpace->SetEffectGrow();
this->Append(keySpace);
char txt[2] = { 0, 0 };
for(int i=0; i<4; i++)
{
for(int j=0; j<11; j++)
@ -479,7 +480,8 @@ GuiKeyboard::GuiKeyboard(char * t, u32 max, int min, int lang)
{
keyImg[i][j] = new GuiImage(key);
keyImgOver[i][j] = new GuiImage(keyOver);
keyTxt[i][j] = new GuiText(NULL, 20, (GXColor){0, 0, 0, 0xff});
txt[0] = keys[i][j].ch;
keyTxt[i][j] = new GuiText(txt, 20, (GXColor){0, 0, 0, 0xff});
keyTxt[i][j]->SetAlignment(ALIGN_CENTRE, ALIGN_BOTTOM);
keyTxt[i][j]->SetPosition(0, -10);
keyBtn[i][j] = new GuiButton(keyImg[i][j], keyImgOver[i][j], 0, 3, (j*42+21*i+40)+eurocheck, i*42+120, trigA, keySoundOver, keySoundClick,1);
@ -563,11 +565,11 @@ void GuiKeyboard::Update(GuiTrigger * t)
catch (const std::exception& e) { }
}
bool update = false;
bool changedShiftKey = false;
if(keySpace->GetState() == STATE_CLICKED)
{
if(strlen(kbtextstr) < kbtextmaxlen)
if(strlen(kbtextstr) < kbtextmaxlen-1) // -1 --> kbtextmaxlen means with terminating '\0'
{
kbtextstr[strlen(kbtextstr)] = ' ';
kbText->SetText(kbtextstr);
@ -578,19 +580,21 @@ void GuiKeyboard::Update(GuiTrigger * t)
{
if (strlen(kbtextstr) >(m)){
kbtextstr[strlen(kbtextstr)-1] = 0;
kbText->SetText(kbtextstr);}
kbText->SetText(kbtextstr);
}
keyBack->SetState(STATE_SELECTED, t->chan);
}
else if(keyClear->GetState() == STATE_CLICKED)
{ clearMore:
if (strlen(kbtextstr) >(m)){
{
while (strlen(kbtextstr) >(m)){
kbtextstr[strlen(kbtextstr)-1] = 0;
kbText->SetText(kbtextstr);
goto clearMore;}
}
keyClear->SetState(STATE_SELECTED, t->chan);
}
else if(keyShift->GetState() == STATE_CLICKED)
{
changedShiftKey =true;
shift ^= 1;
if(alt) alt ^= 1;
if(alt2) alt2 ^= 1;
@ -598,6 +602,7 @@ void GuiKeyboard::Update(GuiTrigger * t)
}
else if(keyAlt->GetState() == STATE_CLICKED)
{
changedShiftKey =true;
alt ^= 1;
if(shift) shift ^= 1;
if(alt2) alt2 ^= 1;
@ -605,6 +610,7 @@ void GuiKeyboard::Update(GuiTrigger * t)
}
else if(keyAlt2->GetState() == STATE_CLICKED)
{
changedShiftKey =true;
alt2 ^= 1;
if(shift) shift ^= 1;
if(alt) alt ^= 1;
@ -612,14 +618,19 @@ void GuiKeyboard::Update(GuiTrigger * t)
}
else if(keyCaps->GetState() == STATE_CLICKED)
{
changedShiftKey =true;
caps ^= 1;
keyCaps->SetState(STATE_SELECTED, t->chan);
}
bool update = false;
char txt[2] = { 0, 0 };
startloop:
do
{
update = false;
for(int i=0; i<4; i++)
{
for(int j=0; j<11; j++)
@ -635,45 +646,31 @@ void GuiKeyboard::Update(GuiTrigger * t)
else
txt[0] = keys[i][j].ch;
if(changedShiftKey) // change text only if needed
keyTxt[i][j]->SetText(txt);
if(keyBtn[i][j]->GetState() == STATE_CLICKED)
{
if(strlen(kbtextstr) < kbtextmaxlen)
if(strlen(kbtextstr) < kbtextmaxlen-1) // -1 --> kbtextmaxlen means with term. '\0'
{
if(shift || caps)
{
kbtextstr[strlen(kbtextstr)] = keys[i][j].chShift;
}
else if(alt)
{
kbtextstr[strlen(kbtextstr)] = keys[i][j].chalt;
}
else if(alt2)
{
kbtextstr[strlen(kbtextstr)] = keys[i][j].chalt2;
}
else
{
kbtextstr[strlen(kbtextstr)] = keys[i][j].ch;
}
}
kbtextstr[strlen(kbtextstr)] = txt[0];
kbText->SetText(kbtextstr);
}
keyBtn[i][j]->SetState(STATE_SELECTED, t->chan);
if(shift || alt || alt2)
{
if(shift) shift ^= 1;
if(alt) alt ^= 1;
if(alt2) alt2 ^= 1;
update = true;
goto startloop;
changedShiftKey = true;
}
}
}
}
}
} while(update);
kbText->SetPosition(0, 53);

View File

@ -31,27 +31,36 @@ bool findfile(const char * filename, const char * path) {
return false;
}
bool subfoldercreate(char * fullpath) {
bool subfoldercreate(const char * fullpath) {
//check forsubfolders
char dircheck[300];
char dirnoslash[300];
char dir[300];
char * pch = NULL;
u32 cnt = 0;
u32 len;
struct stat st;
snprintf(dirnoslash, strlen(fullpath), "%s", fullpath);
if (stat(fullpath, &st) != 0) {
pch = strrchr(dirnoslash, '/');
cnt = pch-dirnoslash;
snprintf(dircheck, cnt+2, "%s", dirnoslash);
subfoldercreate(dircheck);
};
if (mkdir(dirnoslash, 0777) == -1) {
strlcpy(dir, fullpath, sizeof(dir));
len = strlen(dir);
if(len && len< sizeof(dir)-2 && dir[len-1] != '/');
{
dir[len++] = '/';
dir[len] = '\0';
}
if (stat(dir, &st) != 0) // fullpath not exist?
{
while(len && dir[len-1] == '/')
dir[--len] = '\0'; // remove all trailing /
pch = strrchr(dir, '/');
if(pch == NULL) return false;
*pch = '\0';
if(subfoldercreate(dir))
{
*pch = '/';
if (mkdir(dir, 0777) == -1)
return false;
}
else
return false;
}
return true;
}

View File

@ -8,7 +8,7 @@ extern "C" {
bool findfile(const char * filename, const char * path);
char * GetFileName(int i);
int GetAllDirFiles(char * filespath);
bool subfoldercreate(char * fullpath);
bool subfoldercreate(const char * fullpath);
bool checkfile(char * path);
#ifdef __cplusplus

View File

@ -15,9 +15,10 @@
#include <string.h>
#include <wiiuse/wpad.h>
#include <sys/dir.h>
#include <sys/iosupport.h>
#include <malloc.h>
#include <algorithm>
#include "filebrowser.h"
#include "menu.h"
#include "listfiles.h"
@ -25,6 +26,7 @@
#include "PromptWindows.h"
#include "libwiigui/gui.h"
#include "sys.h"
#include "filebrowser.h"
/*** Extern variables ***/
extern GuiWindow * mainWindow;
@ -35,157 +37,222 @@ extern u8 reset;
extern void ResumeGui();
extern void HaltGui();
BROWSERINFO browser;
BROWSERENTRY * browserList = NULL; // list of files/folders in browser
static int curDevice = -1;
static std::vector<BROWSERINFO> browsers;
BROWSERINFO *browser = NULL;
/****************************************************************************
* FileFilterCallbacks
* return: 1-visible 0-hidden
***************************************************************************/
int noDIRS(BROWSERENTRY *Entry, void* Args)
{
return !Entry->isdir;
}
int noFILES(BROWSERENTRY *Entry, void* Args)
{
return Entry->isdir;
}
int noEXT(BROWSERENTRY *Entry, void* Args)
{
if(!Entry->isdir)
{
char *cptr = strrchr(Entry->displayname, '.');
if(cptr && cptr!= Entry->displayname) *cptr = 0;
}
return 1;
}
void ResetBrowser(BROWSERINFO *browser);
/****************************************************************************
* InitBrowsers()
* Clears the file browser memory, and allocates one initial entry
***************************************************************************/
int InitBrowsers() {
curDevice = -1;
browsers.clear();
browser = NULL;
char rootdir[ROOTDIRLEN];
for(int i=3; i<STD_MAX; i++)
{
if(strcmp(devoptab_list[i]->name, "stdnull"))
{
snprintf(rootdir, sizeof(rootdir) , "%s:/", devoptab_list[i]->name);
if(DIR_ITER *dir = diropen(rootdir))
{
dirclose(dir);
BROWSERINFO browser;
browser.dir[0] = '\0';
strcpy(browser.rootdir, rootdir);
ResetBrowser(&browser);
browsers.push_back(browser);
}
}
}
if(!browsers.size()) return -1;
curDevice = 0;
browser = &browsers[curDevice];
return 0;
}
/****************************************************************************
* ResetBrowser()
* Clears the file browser memory, and allocates one initial entry
***************************************************************************/
void ResetBrowser() {
browser.numEntries = 0;
browser.selIndex = 0;
browser.pageIndex = 0;
void ResetBrowser(BROWSERINFO *browser) {
browser->pageIndex = 0;
browser->browserList.clear();
/*
// Clear any existing values
if (browserList != NULL) {
free(browserList);
browserList = NULL;
if (browser->browserList != NULL) {
free(browser->browserList);
browser->browserList = NULL;
}
// set aside space for 1 entry
browserList = (BROWSERENTRY *)malloc(sizeof(BROWSERENTRY));
memset(browserList, 0, sizeof(BROWSERENTRY));
}
/****************************************************************************
* UpdateDirName()
* Update curent directory name for file browser
***************************************************************************/
int UpdateDirName() {
int size=0;
char * test;
char temp[1024];
/* current directory doesn't change */
if (strcmp(browserList[browser.selIndex].filename,".") == 0) {
return 0;
}
/* go up to parent directory */
else if (strcmp(browserList[browser.selIndex].filename,"..") == 0) {
/* determine last subdirectory namelength */
sprintf(temp,"%s",browser.dir);
test = strtok(temp,"/");
while (test != NULL) {
size = strlen(test);
test = strtok(NULL,"/");
}
/* remove last subdirectory name */
size = strlen(browser.dir) - size - 1;
browser.dir[size] = 0;
return 1;
}
/* Open a directory */
else {
/* test new directory namelength */
if ((strlen(browser.dir)+1+strlen(browserList[browser.selIndex].filename)) < MAXPATHLEN) {
/* update current directory name */
sprintf(browser.dir, "%s/%s",browser.dir, browserList[browser.selIndex].filename);
return 1;
} else {
return -1;
}
}
browser->browserList = (BROWSERENTRY *)malloc(sizeof(BROWSERENTRY));
if(browser->browserList)
memset(browser->browserList, 0, sizeof(BROWSERENTRY));
*/
}
/****************************************************************************
* FileSortCallback
*
* Quick sort callback to sort file entries with the following order:
* sort callback to sort file entries with the following order:
* .
* ..
* <dirs>
* <files>
***************************************************************************/
int FileSortCallback(const void *f1, const void *f2) {
//int FileSortCallback(const void *f1, const void *f2) {
bool operator< (const BROWSERENTRY &f1, const BROWSERENTRY &f2) {
/* Special case for implicit directories */
if (((BROWSERENTRY *)f1)->filename[0] == '.' || ((BROWSERENTRY *)f2)->filename[0] == '.') {
if (strcmp(((BROWSERENTRY *)f1)->filename, ".") == 0) {
return -1;
if (f1.filename[0] == '.' || f2.filename[0] == '.') {
if (strcmp(f1.filename, ".") == 0) {
return true;
}
if (strcmp(((BROWSERENTRY *)f2)->filename, ".") == 0) {
return 1;
if (strcmp(f2.filename, ".") == 0) {
return false;
}
if (strcmp(((BROWSERENTRY *)f1)->filename, "..") == 0) {
return -1;
if (strcmp(f1.filename, "..") == 0) {
return true;
}
if (strcmp(((BROWSERENTRY *)f2)->filename, "..") == 0) {
return 1;
if (strcmp(f2.filename, "..") == 0) {
return false;
}
}
/* If one is a file and one is a directory the directory is first. */
if (((BROWSERENTRY *)f1)->isdir && !(((BROWSERENTRY *)f2)->isdir)) return -1;
if (!(((BROWSERENTRY *)f1)->isdir) && ((BROWSERENTRY *)f2)->isdir) return 1;
if (f1.isdir && !(f2.isdir)) return true;
if (!(f1.isdir) && f2.isdir) return false;
return stricmp(((BROWSERENTRY *)f1)->filename, ((BROWSERENTRY *)f2)->filename);
return stricmp(f1.filename, f2.filename)<0;
}
int ParseFilter(FILTERCASCADE *Filter, BROWSERENTRY* Entry)
{
while(Filter)
{
if(Filter->filter && Filter->filter(Entry, Filter->filter_args) == 0)
return 0;
Filter = Filter->next;
}
return 1;
}
/***************************************************************************
* Browse subdirectories
**************************************************************************/
int
ParseDirectory() {
int ParseDirectory(const char* Path, int Flags, FILTERCASCADE *Filter) {
DIR_ITER *dir = NULL;
char fulldir[MAXPATHLEN];
char filename[MAXPATHLEN];
struct stat filestat;
unsigned int i;
// reset browser
ResetBrowser();
if(curDevice == -1)
if(InitBrowsers()) return -1; // InitBrowser fails
// open the directory
sprintf(fulldir, "%s%s", browser.rootdir, browser.dir); // add currentDevice to path
dir = diropen(fulldir);
// if we can't open the dir, try opening the root dir
if (dir == NULL) {
sprintf(browser.dir,"/");
dir = diropen(browser.rootdir);
if (dir == NULL) {
if(Path) // note in this codeblock use filename temporary
{
strlcpy(fulldir, Path, sizeof(fulldir));
if(*fulldir && fulldir[strlen(fulldir)-1] != '/') // a file
{
char * chrp = strrchr(fulldir, '/');
if(chrp) chrp[1] = 0;
}
if(strchr(fulldir, ':') == NULL) // Path has no device device
{
getcwd(filename, sizeof(filename)); // save the current working dir
if(*fulldir==0) // if path is empty
strlcpy(fulldir, filename, sizeof(fulldir)); // we use the current working dir
else
{ // path is not empty
if(chdir(fulldir)); // sets the path to concatenate and validate
{
if(Flags & (FB_TRYROOTDIR | FB_TRYSTDDEV))
if(chdir("/") && !(Flags & FB_TRYSTDDEV))// try to set root if is needed
return -1;
}
if(getcwd(fulldir, sizeof(fulldir))) return -1; // gets the concatenated current working dir
chdir(filename); // restore the saved cwd
}
// index files/folders
int entryNum = 0;
while (dirnext(dir,filename,&filestat) == 0) {
if (strcmp(filename,".") != 0) {
BROWSERENTRY * newBrowserList = (BROWSERENTRY *)realloc(browserList, (entryNum+1) * sizeof(BROWSERENTRY));
if (!newBrowserList) { // failed to allocate required memory
ResetBrowser();
entryNum = -1;
}
for(i=0; i<browsers.size(); i++) // searchs the browser who match the path
{
if(strnicmp(fulldir, browsers[i].rootdir, strlen(browsers[i].rootdir)-1 /*means without trailing '/'*/) == 0)
{
browser = &browsers[curDevice];
break;
} else {
browserList = newBrowserList;
}
memset(&(browserList[entryNum]), 0, sizeof(BROWSERENTRY)); // clear the new entry
}
if(i != browsers.size()) // found browser
{
curDevice = i;
browser = &browsers[curDevice];
strcpy(browser->dir, &fulldir[strlen(browser->rootdir)]);
}
else if(Flags & FB_TRYSTDDEV)
{
curDevice = 0;
browser = &browsers[curDevice]; // when no browser was found and
browser->dir[0] = 0; // we alowed try StdDevice and try RootDir
strlcpy(fulldir, browser->rootdir, sizeof(fulldir)); // set the first browser with root-dir
}
else
return -1;
}
else
snprintf(fulldir, sizeof(fulldir), "%s%s", browser->rootdir, browser->dir);
strncpy(browserList[entryNum].filename, filename, MAXJOLIET);
// reset browser
ResetBrowser(browser);
if (strcmp(filename,"..") == 0) {
sprintf(browserList[entryNum].displayname, "..");
} else {
strcpy(browserList[entryNum].displayname, filename); // crop name for display
// open the directory
if((dir = diropen(fulldir)) == NULL)
{
if(Flags & FB_TRYROOTDIR)
{
browser->dir[0] = 0;
if((dir = diropen(browser->rootdir)) == NULL)
return -1;
}
else
return -1;
}
browserList[entryNum].length = filestat.st_size;
browserList[entryNum].isdir = (filestat.st_mode & _IFDIR) == 0 ? 0 : 1; // flag this as a dir
entryNum++;
while (dirnext(dir,filename,&filestat) == 0)
{
if (strcmp(filename,".") != 0)
{
BROWSERENTRY newEntry;
memset(&newEntry, 0, sizeof(BROWSERENTRY)); // clear the new entry
strlcpy(newEntry.filename, filename, sizeof(newEntry.filename));
strlcpy(newEntry.displayname, filename, sizeof(newEntry.displayname));
newEntry.length = filestat.st_size;
newEntry.isdir = (filestat.st_mode & S_IFDIR) == 0 ? 0 : 1; // flag this as a dir
if(ParseFilter(Filter, &newEntry))
browser->browserList.push_back(newEntry);
}
}
@ -193,76 +260,38 @@ ParseDirectory() {
dirclose(dir);
// Sort the file list
qsort(browserList, entryNum, sizeof(BROWSERENTRY), FileSortCallback);
browser.numEntries = entryNum;
return entryNum;
std::sort(browser->browserList.begin(), browser->browserList.end());
return 0;
}
int ParseDirectory(int Device, int Flags, FILTERCASCADE *Filter)
{
if(Device >=0 && Device < (int)browsers.size())
{
int old_curDevice = curDevice;
curDevice = Device;
browser = &browsers[curDevice];
if(ParseDirectory((char*)NULL, Flags, Filter) == 0) return 0;
curDevice = old_curDevice;
browser = &browsers[old_curDevice];
}
/****************************************************************************
* BrowserChangeFolder
*
* Update current directory and set new entry list if directory has changed
***************************************************************************/
int BrowserChangeFolder() {
if (!UpdateDirName())
return -1;
ParseDirectory();
return browser.numEntries;
}
/****************************************************************************
* BrowseDevice
* Displays a list of files on the selected device
***************************************************************************/
int BrowseDevice(int device) {
sprintf(browser.dir, "/");
switch (device) {
case SD:
sprintf(browser.rootdir, "SD:");
break;
case USB:
sprintf(browser.rootdir, "USB:");
break;
}
ParseDirectory(); // Parse root directory
return browser.numEntries;
}
/****************************************************************************
* MenuBrowseDevice
* Displays a list of files on the selected path
***************************************************************************/
int BrowseDevice(char * var, int force) {
int BrowseDevice(char * Path, int Path_size, int Flags, FILTERCASCADE *Filter/*=NULL*/)
{
int result=-1;
int i;
char currentdir[90];
int curDivice = -1;
int forced =force;
if (forced>-1) {
if (BrowseDevice(forced) > 0) {
curDivice = forced;
goto main;
}
}
else if ((!strcasecmp(bootDevice, "USB:"))&&(BrowseDevice(USB) > 0)) {
curDivice = USB;
goto main;
} else if ((!strcasecmp(bootDevice, "SD:"))&&(BrowseDevice(SD) > 0)) {
curDivice = SD;
goto main;
} else {
WindowPrompt(tr("Error"),0,tr("OK"));
if(InitBrowsers() || ParseDirectory(Path, Flags, Filter))
{
WindowPrompt(tr("Error"),0,tr("Ok"));
return -1;
}
main:
int menu = MENU_NONE;
/*
@ -305,7 +334,7 @@ main:
ExitBtn.SetTrigger(&trigB);
ExitBtn.SetEffectGrow();
GuiText usbBtnTxt((curDivice==SD?"USB":"SD"), 24, (GXColor) {0, 0, 0, 255});
GuiText usbBtnTxt(browsers[(curDevice+1)%browsers.size()].rootdir, 24, (GXColor) {0, 0, 0, 255});
GuiImage usbBtnImg(&btnOutline);
if (Settings.wsprompt == yes) {
usbBtnTxt.SetWidescreen(CFG.widescreen);
@ -319,7 +348,7 @@ main:
usbBtn.SetTrigger(&trigA);
usbBtn.SetEffectGrow();
GuiText okBtnTxt(tr("OK"), 22, THEME.prompttext);
GuiText okBtnTxt(tr("Ok"), 22, THEME.prompttext);
GuiImage okBtnImg(&btnOutline);
if (Settings.wsprompt == yes) {
okBtnTxt.SetWidescreen(CFG.widescreen);
@ -333,8 +362,8 @@ main:
fileBrowser.SetPosition(0, 120);
GuiImageData Address(addressbar_textbox_png);
snprintf(currentdir, sizeof(currentdir), "%s%s", browser.rootdir, browser.dir);
GuiText AdressText(currentdir, 20, (GXColor) { 0, 0, 0, 255});
GuiText AdressText(NULL, 20, (GXColor) { 0, 0, 0, 255});
AdressText.SetTextf("%s%s", browser->rootdir, browser->dir);
AdressText.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
AdressText.SetPosition(20, 0);
AdressText.SetMaxWidth(Address.GetWidth()-40, GuiText::SCROLL);
@ -345,10 +374,6 @@ main:
Adressbar.SetImage(&AdressbarImg);
Adressbar.SetLabel(&AdressText);
//save var in case they cancel and return it to them
snprintf(currentdir, sizeof(currentdir), "%s", var);
sprintf(var,"%s", browser.rootdir);
HaltGui();
GuiWindow w(screenwidth, screenheight);
w.Append(&ExitBtn);
@ -356,11 +381,13 @@ main:
w.Append(&fileBrowser);
w.Append(&Adressbar);
w.Append(&okBtn);
if(!(Flags & FB_NOFOLDER_BTN))
w.Append(&folderBtn);
if(browsers.size()>1 && !(Flags & FB_NODEVICE_BTN))
w.Append(&usbBtn);
mainWindow->Append(&w);
ResumeGui();
int clickedIndex = -1;
while (menu == MENU_NONE) {
VIDEO_WaitVSync();
@ -370,77 +397,120 @@ main:
if (reset == 1)
Sys_Reboot();
for (i=0; i<PAGESIZE; i++) {
for (i=0; i<FILEBROWSERSIZE; i++) {
if (fileBrowser.fileList[i]->GetState() == STATE_CLICKED) {
fileBrowser.fileList[i]->ResetState();
clickedIndex = browser->pageIndex + i;
bool pathCanged = false;
// check corresponding browser entry
if (browserList[browser.selIndex].isdir) {
if (BrowserChangeFolder()) {
if (browser->browserList[clickedIndex].isdir)
{
/* go up to parent directory */
if (strcmp(browser->browserList[clickedIndex].filename,"..") == 0)
{
/* remove last subdirectory name */
int len = strlen(browser->dir);
while(browser->dir[0] && browser->dir[len-1] == '/')
browser->dir[--len] = '\0'; // remove all trailing '/'
char *cptr = strrchr(browser->dir, '/');
if(cptr) *++cptr = 0; else browser->dir[0] = '\0'; // remove trailing dir
pathCanged = true;
}
/* Open a directory */
/* current directory doesn't change */
else if (strcmp(browser->browserList[clickedIndex].filename,"."))
{
/* test new directory namelength */
if ((strlen(browser->dir) + strlen(browser->browserList[clickedIndex].filename)
+ 1/*'/'*/) < MAXPATHLEN)
{
/* update current directory name */
sprintf(browser->dir, "%s%s/",browser->dir,
browser->browserList[clickedIndex].filename);
pathCanged = true;
}
}
if (pathCanged)
{
LOCK(&fileBrowser);
ParseDirectory((char*)NULL, Flags, Filter);
fileBrowser.ResetState();
fileBrowser.fileList[0]->SetState(STATE_SELECTED);
fileBrowser.TriggerUpdate();
sprintf(var,"%s", browser.rootdir);
int len=strlen(browser.rootdir);
for (unsigned int i=len;i<strlen(browser.rootdir)+strlen(browser.dir);i++) {
var[i]=browser.dir[i-(len-1)];
AdressText.SetTextf("%s%s", browser->rootdir, browser->dir);
}
AdressText.SetTextf("%s", var);
} else {
menu = MENU_DISCLIST;
break;
clickedIndex = -1;
}
} else {
mainWindow->SetState(STATE_DISABLED);
mainWindow->SetState(STATE_DEFAULT);
else /* isFile */
{
AdressText.SetTextf("%s%s%s", browser->rootdir, browser->dir, browser->browserList[clickedIndex].filename);
}
}
}
if (ExitBtn.GetState() == STATE_CLICKED) {
snprintf(var,sizeof(currentdir),"%s", currentdir);
break;
}
if (okBtn.GetState() == STATE_CLICKED) {
else if (okBtn.GetState() == STATE_CLICKED) {
if(clickedIndex>=0)
snprintf(Path, Path_size, "%s%s%s", browser->rootdir, browser->dir,browser->browserList[clickedIndex].filename);
else
snprintf(Path, Path_size, "%s%s", browser->rootdir, browser->dir);
result = 1;
break;
} else if (usbBtn.GetState() == STATE_CLICKED) {
HaltGui();
mainWindow->Remove(&w);
ResumeGui();
result = BrowseDevice(var, (curDivice==SD?USB:SD));
}
else if (usbBtn.GetState() == STATE_CLICKED) {
usbBtn.ResetState();
for(u32 i=1; i<browsers.size(); i++)
{
LOCK(&fileBrowser);
if(ParseDirectory((curDevice+i) % browsers.size(), Flags, Filter)==0)
{
fileBrowser.ResetState();
fileBrowser.TriggerUpdate();
AdressText.SetTextf("%s%s", browser->rootdir, browser->dir);
usbBtnTxt.SetText(browsers[(curDevice+1)%browsers.size()].rootdir);
break;
} else if (folderBtn.GetState() == STATE_CLICKED) {
}
}
}
else if (folderBtn.GetState() == STATE_CLICKED) {
folderBtn.ResetState();
HaltGui();
mainWindow->Remove(&w);
ResumeGui();
char newfolder[100];
char oldfolder[100];
sprintf(newfolder,"%s/",var);
snprintf(newfolder, sizeof(newfolder), "%s%s", browser->rootdir, browser->dir);
strcpy(oldfolder,newfolder);
int result = OnScreenKeyboard(newfolder,100,0);
int result = OnScreenKeyboard(newfolder, sizeof(newfolder), strlen(browser->rootdir));
if ( result == 1 ) {
int len = (strlen(newfolder)-1);
if (newfolder[len] !='/')
strncat (newfolder, "/", 1);
char* pos = newfolder;
char root[6];
sprintf(root,"%s/",browser.rootdir);
if (len > 0 && strcmp(oldfolder,newfolder)!=0 && strstr(newfolder,root) == pos && strstr(newfolder,"//") == NULL) {
unsigned int len = strlen(newfolder);
if (len>0 && len+1 < sizeof(newfolder) && newfolder[len-1] !='/')
{
newfolder[len] = '/';
newfolder[len+1] = '\0';
}
struct stat st;
if (stat(newfolder, &st) != 0) {
if (subfoldercreate(newfolder) != 1) {
if(WindowPrompt(tr("Directory does not exist!"),tr("The entered directory does not exist. Would you like to create it?") ,tr("OK"), tr("Cancel")) == 1)
if (subfoldercreate(newfolder) == false)
WindowPrompt(tr("Error !"),tr("Can't create directory"),tr("OK"));
break;
}
} else {
break;
if(ParseDirectory(newfolder, Flags, Filter)==0)
{
fileBrowser.ResetState();
fileBrowser.TriggerUpdate();
AdressText.SetTextf("%s%s", browser->rootdir, browser->dir);
usbBtnTxt.SetText(browsers[(curDevice+1)%browsers.size()].rootdir);
}
}
}
result = BrowseDevice(var, (curDivice==SD?SD:USB));
break;
HaltGui();
mainWindow->Append(&w);
ResumeGui();
}
}
@ -453,3 +523,12 @@ main:
return result;
}
int BrowseDevice(char * Path, int Path_size, int Flags, FILEFILTERCALLBACK Filter, void *FilterArgs)
{
if(Filter)
{
FILTERCASCADE filter = {Filter, FilterArgs, NULL};
return BrowseDevice(Path, Path_size, Flags, &filter);
}
return BrowseDevice(Path, Path_size, Flags);
}

View File

@ -2,7 +2,7 @@
* libwiigui Template
* Tantric 2009
*
* modified by dimok
* modified by dimok and ardi
*
* filebrowser.h
*
@ -17,21 +17,9 @@
#define MAXJOLIET 255
#define MAXDISPLAY MAXPATHLEN
#define ROOTDIRLEN 10
enum {
SD,
USB
};
typedef struct {
char dir[MAXPATHLEN]; // directory path of browserList
char rootdir[10]; // directory path of browserList
int numEntries; // # of entries in browserList
int selIndex; // currently selected index of browserList
int pageIndex; // starting index of browserList page display
} BROWSERINFO;
typedef struct {
u64 offset; // DVD offset
u64 length; // file length in 64 bytes for sizes higher than 4GB
@ -40,15 +28,52 @@ typedef struct {
char displayname[MAXDISPLAY + 1]; // name for browser display
} BROWSERENTRY;
extern BROWSERINFO browser;
extern BROWSERENTRY * browserList;
typedef struct {
char dir[MAXPATHLEN]; // directory path of browserList
char rootdir[ROOTDIRLEN];// directory path of browserList
int pageIndex; // starting index of browserList page display
std::vector<BROWSERENTRY> browserList;
} BROWSERINFO;
extern BROWSERINFO *browser;
int UpdateDirName();
int FileSortCallback(const void *f1, const void *f2);
void ResetBrowser();
int ParseDirectory();
int BrowserChangeFolder();
int BrowseDevice(int device);
int BrowseDevice(char * var, int force =-1);
#define FB_NOFOLDER_BTN 0x0001
#define FB_NODEVICE_BTN 0x0002
#define FB_TRYROOTDIR 0x0004
#define FB_TRYSTDDEV 0x0008
#define FB_DEFAULT (FB_TRYROOTDIR | FB_TRYSTDDEV)
typedef int (*FILEFILTERCALLBACK)(BROWSERENTRY *Entry, void* Args);
int noDIRS(BROWSERENTRY *Entry, void* Args);
int noFILES(BROWSERENTRY *Entry, void* Args);
int noEXT(BROWSERENTRY *Entry, void* Args);
typedef struct _FILTERCASCADE{
FILEFILTERCALLBACK filter;
void *filter_args;
_FILTERCASCADE *next;
} FILTERCASCADE;
/****************************************************************************
* BrowseDevice
* Displays a list of files on the selected path
* Path returns the selectet Path/File
* Path_size is the space of the Path-array
* Ret: 0 ok / -1 Error
***************************************************************************/
/***************************************************************************
* Example:
* FILTERKASKADE filter2 = {noEXT, NULL, NULL};
* FILTERKASKADE filter1 = {noDirs, NULL, &filter2};
* char Path[MAXPATHLEN] = "SD:/";
* BrowseDevice(Path, MAXPATHLEN, FB_DEFAULT, &filter1);
*
*
***************************************************************************/
int BrowseDevice(char * Path, int Path_size, int Flags/*=FB_DEFAULT*/, FILTERCASCADE *Filter=NULL) ;
int BrowseDevice(char * Path, int Path_size, int Flags, FILEFILTERCALLBACK Filter, void *FilterArgs=NULL);
#endif

View File

@ -1259,7 +1259,7 @@ int MenuSettings() {
char entered[43] = "";
strlcpy(entered, Settings.covers_path, sizeof(entered));
titleTxt.SetText(tr("3D Cover Path"));
int result = BrowseDevice(entered);
int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES);
titleTxt.SetText(tr("Custom Paths"));
w.Append(&optionBrowser2);
w.Append(&backBtn);
@ -1285,7 +1285,7 @@ int MenuSettings() {
char entered[43] = "";
strlcpy(entered, Settings.covers2d_path, sizeof(entered));
titleTxt.SetText(tr("2D Cover Path"));
int result = BrowseDevice(entered);
int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES);
titleTxt.SetText(tr("Custom Paths"));
w.Append(&optionBrowser2);
w.Append(&backBtn);
@ -1311,7 +1311,7 @@ int MenuSettings() {
char entered[43] = "";
strlcpy(entered, Settings.disc_path, sizeof(entered));
titleTxt.SetText(tr("Disc Artwork Path"));
int result = BrowseDevice(entered);
int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES);
titleTxt.SetText(tr("Custom Paths"));
w.Append(&optionBrowser2);
w.Append(&backBtn);
@ -1337,7 +1337,7 @@ int MenuSettings() {
char entered[43] = "";
titleTxt.SetText(tr("Theme Path"));
strlcpy(entered, CFG.theme_path, sizeof(entered));
int result = BrowseDevice(entered);
int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES);
HaltGui();
w.RemoveAll();
if ( result == 1 ) {
@ -1394,7 +1394,7 @@ int MenuSettings() {
char entered[43] = "";
titleTxt.SetText(tr("WiiTDB Path"));
strlcpy(entered, Settings.titlestxt_path, sizeof(entered));
int result = BrowseDevice(entered);
int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES);
w.Append(&optionBrowser2);
titleTxt.SetText(tr("Custom Paths"));
w.Append(&backBtn);
@ -1425,7 +1425,7 @@ int MenuSettings() {
char entered[43] = "";
strlcpy(entered, Settings.update_path, sizeof(entered));
titleTxt.SetText(tr("Update Path"));
int result = BrowseDevice(entered);
int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES);
titleTxt.SetText(tr("Custom Paths"));
w.Append(&optionBrowser2);
w.Append(&backBtn);
@ -1446,7 +1446,7 @@ int MenuSettings() {
char entered[43] = "";
strlcpy(entered, Settings.Cheatcodespath, sizeof(entered));
titleTxt.SetText(tr("GCT Cheatcodes Path"));
int result = BrowseDevice(entered);
int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES);
titleTxt.SetText(tr("Custom Paths"));
w.Append(&optionBrowser2);
w.Append(&backBtn);
@ -1467,7 +1467,7 @@ int MenuSettings() {
char entered[43] = "";
strlcpy(entered, Settings.TxtCheatcodespath, sizeof(entered));
titleTxt.SetText(tr("TXT Cheatcodes Path"));
int result = BrowseDevice(entered);
int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES);
titleTxt.SetText(tr("Custom Paths"));
w.Append(&optionBrowser2);
w.Append(&backBtn);
@ -1488,7 +1488,7 @@ int MenuSettings() {
char entered[43] = "";
strlcpy(entered, Settings.dolpath, sizeof(entered));
titleTxt.SetText(tr("DOL Path"));
int result = BrowseDevice(entered);
int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES);
titleTxt.SetText(tr("Custom Paths"));
w.Append(&optionBrowser2);
w.Append(&backBtn);
@ -1514,7 +1514,7 @@ int MenuSettings() {
char entered[43] = "";
strlcpy(entered, Settings.homebrewapps_path, sizeof(entered));
titleTxt.SetText(tr("Homebrew Apps Path"));
int result = BrowseDevice(entered);
int result = BrowseDevice(entered, sizeof(entered), FB_DEFAULT, noFILES);
titleTxt.SetText(tr("Custom Paths"));
w.Append(&optionBrowser2);
w.Append(&backBtn);