diff --git a/Sources/libetk/etk/os/FSNode.cpp b/Sources/libetk/etk/os/FSNode.cpp new file mode 100644 index 00000000..b94864a1 --- /dev/null +++ b/Sources/libetk/etk/os/FSNode.cpp @@ -0,0 +1,942 @@ +/** + ******************************************************************************* + * @file etk/os/FSNode.cpp + * @brief Ewol Tool Kit : File System node access abstraction (Sources) + * @author Edouard DUPIN + * @date 31/10/2012 + * @par Project + * Ewol TK + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + + +#include +#include +#include +#include +#include +#include + +#ifdef __TARGET_OS__Android +# include +# include +#endif + +// zip file of the apk file for Android ==> set to zip file apk access +static etk::UString s_fileAPK = ""; +staticetk::UString baseApplName = "ewolNoName"; +#if defined(__TARGET_OS__Android) + static etk::UString baseFolderHome = "/sdcard/"; // home folder + static etk::UString baseFolderData = "assets/"; // program Data + static etk::UString baseFolderDataUser = "/sdcard/.tmp/userData/"; // Data specific user (local modification) + static etk::UString baseFolderCache = "/sdcard/.tmp/cache/"; // Temporary data (can be removed the next time) +#elif defined(__TARGET_OS__Windows) + static etk::UString baseFolderHome = "c:/test"; // home folder + static etk::UString baseFolderData = "c:/test/share/"; // program Data + static etk::UString baseFolderDataUser = "c:/test/userData/"; // Data specific user (local modification) + static etk::UString baseFolderCache = "c:/Windows/Temp/ewol/"; // Temporary data (can be removed the next time) +#else + static etk::UString baseFolderHome = "~"; // home folder + static etk::UString baseFolderData = "share/"; // program Data + static etk::UString baseFolderDataUser = "~/.tmp/userData/"; // Data specific user (local modification) + static etk::UString baseFolderCache = "~/.tmp/cache/"; // Temporary data (can be removed the next time) +#endif + + +#ifdef __TARGET_OS__Android + static struct zip * s_APKArchive = NULL; + static int32_t s_APKnbFiles = 0; + static void loadAPK(etk::UString& apkPath) + { + TK_DEBUG("Loading APK \"" << apkPath << "\""); + s_APKArchive = zip_open(apkPath.c_str(), 0, NULL); + TK_ASSERT(s_APKArchive != NULL, "Error loading APK ... \"" << apkPath << "\""); + //Just for debug, print APK contents + s_APKnbFiles = zip_get_num_files(s_APKArchive); + TK_INFO("List all files in the APK : " << s_APKnbFiles << " files"); + for (int iii=0; iii go to the root Folder + destFilename = "ROOT:"; + } else { + destFilename = newName; + } + // ici ... + + #ifdef __TARGET_OS__Windows + TK_DBG_MODE("2 : Get file Name : " << destFilename << "start with 'c:/'=" << destFilename.StartWith("c:/")); + if (true == destFilename.StartWith("c:/")) { + #else + TK_DBG_MODE("2 : Get file Name : " << destFilename << "start with '/'=" << destFilename.StartWith('/')); + if (true == destFilename.StartWith('/')) { + #endif + m_type = etk::FILE_TYPE_DIRECT; + if (type != etk::FILE_TYPE_DIRECT) { + TK_WARNING("Incompatible type with a file=\"" << newFilename << "\" ==> force it in direct mode ..."); + } + } else { + if (type == etk::FILE_TYPE_DIRECT) { + //TK_WARNING("Incompatible type with a file=\"" << newFilename << "\" ==> force it in FILE_TYPE_DATA mode ..."); + //m_type = etk::FILE_TYPE_DATA; + m_type = etk::FILE_TYPE_DIRECT; + // add current path : + // Get the command came from the running of the program : + char cCurrentPath[FILENAME_MAX]; + if (!getcwd(cCurrentPath, FILENAME_MAX)) { + return; + } + cCurrentPath[FILENAME_MAX - 1] = '\0'; + etk::UString tmpFilename = destFilename; + destFilename = cCurrentPath; + destFilename += "/"; + destFilename += tmpFilename; + } else { + m_type = type; + } + } + bool needUnpack = false; + #if ETK_DEBUG_LEVEL > 3 + char *mode = NULL; + #endif + switch (m_type) + { + case etk::FILE_TYPE_DATA: + { + #if DEBUG_LEVEL > 3 + mode = "FILE_TYPE_DATA"; + #endif + #ifdef __TARGET_OS__Android + etk::UString tmpFilename = baseFolderData + destFilename; + for (int iii=0; iii id=" << m_idZipFile); + } + #else + //etk::UString tmpFilename = destFilename; + //destFilename = baseFolderData; + //destFilename += tmpFilename; + #endif + } + break; + case etk::FILE_TYPE_USER_DATA: + { + #if DEBUG_LEVEL > 3 + mode = "FILE_TYPE_USER_DATA"; + #endif + etk::UString tmpFilename = destFilename; + destFilename = baseFolderDataUser; + destFilename += tmpFilename; + } + needUnpack = true; + break; + case etk::FILE_TYPE_CACHE: + { + #if DEBUG_LEVEL > 3 + mode = "FILE_TYPE_CACHE"; + #endif + etk::UString tmpFilename = destFilename; + destFilename = baseFolderCache; + destFilename += tmpFilename; + } + needUnpack = true; + break; + default: + // nothing to do ... + #if DEBUG_LEVEL > 3 + mode = "FILE_TYPE_DIRECT"; + #endif + needUnpack = true; + break; + } + TK_DBG_MODE("3 : Get file Name : " << destFilename ); + if (true == needUnpack) { + + int32_t lastPos = destFilename.FindBack('/'); + if (-1 != lastPos) { + m_shortFilename = destFilename.Extract(lastPos+1); + m_folder = destFilename.Extract(0, lastPos); + } else { + // Basic ERROR ... + TK_DBG_MODE("file : \"" << destFilename << "\" ==> No data???"); + m_shortFilename = destFilename; + m_folder = ""; + } + // Get the real Path of the current File + m_folder = etk::tool::SimplifyPath(m_folder); + } else { + int32_t lastPos = destFilename.FindBack('/'); + if (-1 != lastPos) { + m_shortFilename = destFilename.Extract(lastPos+1); + m_folder = destFilename.Extract(0, lastPos); + } else { + // Basic ERROR ... + TK_DBG_MODE("file : \"" << destFilename << "\" ==> No data???"); + m_shortFilename = destFilename; + } + } + TK_DBG_MODE("Set FileName :\"" << m_folder << "\" / \"" << m_shortFilename << "\""); + TK_VERBOSE(" ==> mode=" << mode); +} + + +etk::UString etk::FSNode::GetFileSystemName(void) +{ + return ""; +} +/* + All Right of the file +*/ +bool etk::FSNode::Exist(void) +{ + #ifdef __TARGET_OS__Android + if (etk::FILE_TYPE_DATA == m_type) { + if (m_idZipFile >= -1 && m_idZipFile < s_APKnbFiles) { + return true; + } + return false; + } + #endif + FILE *myFile=NULL; + etk::UString myCompleateName; + switch (m_type) + { + case etk::FILE_TYPE_DATA: + myCompleateName = baseFolderData; + break; + case etk::FILE_TYPE_USER_DATA: + myCompleateName = baseFolderDataUser; + break; + case etk::FILE_TYPE_CACHE: + myCompleateName = baseFolderCache; + break; + default: + myCompleateName = ""; + break; + } + myCompleateName += GetCompleateName(); + myFile=fopen(myCompleateName.c_str(),"rb"); + if(NULL == myFile) { + TK_DEBUG("try to open : " << myCompleateName.c_str()); + return false; + } + fclose(myFile); + return true; +} +bool etk::FSNode::IsFile(void) +{ + return ((m_rights&etk::RIGHT_FILE)!=0)?true:false; +} +bool etk::FSNode::IsFolder(void) +{ + return ((m_rights&etk::RIGHT_FOLDER)!=0)?true:false; +} +bool etk::FSNode::IsLink(void) +{ + return ((m_rights&etk::RIGHT_LINK)!=0)?true:false; +} +// User +bool etk::FSNode::IsUserReadable(void) +{ + return ((m_rights&etk::RIGHT_USER_READ)!=0)?true:false; +} +bool etk::FSNode::IsUserWritable(void) +{ + return ((m_rights&etk::RIGHT_USER_WRITE)!=0)?true:false; +} +bool etk::FSNode::IsUserRunable(void) +{ + return ((m_rights&etk::RIGHT_USER_EXECUTE)!=0)?true:false; +} +void etk::FSNode::SetUserReadable(bool newStatus) +{ + +} +void etk::FSNode::SetUserWritable(bool newStatus) +{ + +} +void etk::FSNode::SetUserRunable(bool newStatus) +{ + +} +// group +bool etk::FSNode::IsGroupReadable(void) +{ + return ((m_rights&etk::RIGHT_GROUP_READ)!=0)?true:false; +} +bool etk::FSNode::IsGroupWritable(void) +{ + return ((m_rights&etk::RIGHT_GROUP_WRITE)!=0)?true:false; +} +bool etk::FSNode::IsGroupRunable(void) +{ + return ((m_rights&etk::RIGHT_GROUP_EXECUTE)!=0)?true:false; +} +void etk::FSNode::SetGroupReadable(bool newStatus) +{ + +} +void etk::FSNode::SetGroupWritable(bool newStatus) +{ + +} +void etk::FSNode::SetGroupRunable(bool newStatus) +{ + +} +// other +bool etk::FSNode::IsOtherReadable(void) +{ + return ((m_rights&etk::RIGHT_OTHER_READ)!=0)?true:false; +} +bool etk::FSNode::IsOtherWritable(void) +{ + return ((m_rights&etk::RIGHT_OTHER_WRITE)!=0)?true:false; +} +bool etk::FSNode::IsOtherRunable(void) +{ + return ((m_rights&etk::RIGHT_OTHER_EXECUTE)!=0)?true:false; +} +void etk::FSNode::SetOtherReadable(bool newStatus) +{ + +} +void etk::FSNode::SetOtherWritable(bool newStatus) +{ + +} +void etk::FSNode::SetOtherRunable(bool newStatus) +{ + +} + + +/* + Common API : +*/ +void etk::FSNode::SetName(etk::UString newName) +{ + privateSetName(newName); +} +etk::UString etk::FSNode::GetNameFolder(void) const +{ + return ""; +} +etk::UString etk::FSNode::GetName(void) const +{ + return ""; +} +etk::UString etk::FSNode::GetNameFile(void) const +{ + return ""; +} +bool etk::FSNode::Touch(void) +{ + return false; +} +bool etk::FSNode::Remove(void) +{ + return false; +} +uint64_t etk::FSNode::TimeCreated(void) +{ + return 0; +} +uint64_t etk::FSNode::TimeModified(void) +{ + return 0; +} + +/* + Operator : +*/ +const etk::FSNode& etk::FSNode::operator= (const etk::FSNode &obj ) +{ + if( this != &etkF ) // avoid copy to itself + { + m_folder = etkF.m_folder; + m_shortFilename = etkF.m_shortFilename; + m_lineNumberOpen = etkF.m_lineNumberOpen; + m_type = etkF.m_type; + if (NULL != m_PointerFile) { + TK_ERROR("Missing close the file : \"" << GetCompleateName() << "\""); + fClose(); + } + #ifdef __TARGET_OS__Android + m_idZipFile = etkF.m_idZipFile; + m_zipData = NULL; + m_zipDataSize = 0; + m_zipReadingOffset = 0; + //m_zipPointerFile = NULL; + #endif + } + return *this; +} +bool etk::FSNode::operator== (const etk::FSNode &obj ) const +{ + if( this != &etkF ) { + if (etkF.GetCompleateName() == GetCompleateName() ) { + return true; + } else { + return false; + } + return true; + } + return true; +} +bool etk::FSNode::operator!= (const etk::FSNode &obj ) const +{ + return !(*this == etkF); +} + +friend etk::CCout& etk::FSNode::operator <<( etk::CCout &os,const etk::FSNode &obj) +{ + os << obj.m_userFileName; + return os; +} + +/* + Folder specific : +*/ +int32_t etk::FSNode::FolderCount(void) +{ + +} +etk::Vector etk::FSNode::FolderGetSubList(void) +{ + etk::Vector tmpp; + return tmpp; +} +ewol::FSNode etk::FSNode::FolderGetParent(void) +{ + ewol::FSNode tmpp; + return tmpp; +} + +/* + File Specific : +*/ +bool etk::FSNode::FileHasExtention(void) +{ + int32_t lastPos = m_shortFilename.FindBack('.'); + if( -1 != lastPos // not find the . + && 0 != lastPos // Find a . at the fist position .jdlskjdfklj ==> hiden file + && m_shortFilename.Size() != lastPos ) // Remove file ended with . + { + return true; + } else { + return false; + } +} + +etk::UString etk::FSNode::FileGetExtention(void) +{ + etk::UString tmpExt = ""; + int32_t lastPos = m_shortFilename.FindBack('.'); + if( -1 != lastPos // not find the . + && 0 != lastPos // Find a . at the fist position .jdlskjdfklj ==> hiden file + && m_shortFilename.Size() != lastPos ) // Remove file ended with . + { + // Get the FileName + tmpExt = m_shortFilename.Extract(lastPos+1); + } + return tmpExt; +} +int32_t etk::FSNode::FileSize(void) +{ + #ifdef __TARGET_OS__Android + if (etk::FILE_TYPE_DATA == m_type) { + if (true == LoadDataZip()) { + return m_zipDataSize; + } + return 0; + } + #endif + FILE *myFile=NULL; + etk::UString myCompleateName; + switch (m_type) + { + case etk::FILE_TYPE_DATA: + myCompleateName = baseFolderData; + break; + case etk::FILE_TYPE_USER_DATA: + myCompleateName = baseFolderDataUser; + break; + case etk::FILE_TYPE_CACHE: + myCompleateName = baseFolderCache; + break; + default: + myCompleateName = ""; + break; + } + myCompleateName += GetCompleateName(); + myFile=fopen(myCompleateName.c_str(),"rb"); + if(NULL == myFile) { + //EWOL_ERROR("Can not find the file name=\"" << m_folder << "\" / \"" << m_shortFilename << "\""); + return -1; + } + int32_t size = 0; + fseek(myFile, 0, SEEK_END); + size = ftell(myFile); + fseek(myFile, 0, SEEK_SET); + fclose(myFile); + return size; +} +bool etk::FSNode::FileOpenRead(void) +{ + #ifdef __TARGET_OS__Android + if (etk::FILE_TYPE_DATA == m_type) { + return LoadDataZip(); + } + #endif + if (NULL != m_PointerFile) { + TK_CRITICAL("File Already open : \"" << GetCompleateName() << "\""); + return true; + } + etk::UString myCompleateName; + switch (m_type) + { + case etk::FILE_TYPE_DATA: + myCompleateName = baseFolderData; + break; + case etk::FILE_TYPE_USER_DATA: + myCompleateName = baseFolderDataUser; + break; + case etk::FILE_TYPE_CACHE: + myCompleateName = baseFolderCache; + break; + default: + myCompleateName = ""; + break; + } + myCompleateName += GetCompleateName(); + m_PointerFile=fopen(myCompleateName.c_str(),"rb"); + if(NULL == m_PointerFile) { + TK_ERROR("Can not find the file name=\"" << GetCompleateName() << "\""); + return false; + } + return true; +} +bool etk::FSNode::FileOpenWrite(void) +{ + #ifdef __TARGET_OS__Android + if (etk::FILE_TYPE_DATA == m_type) { + return false; + } + #endif + if (NULL != m_PointerFile) { + TK_CRITICAL("File Already open : \"" << GetCompleateName() << "\""); + return true; + } + etk::UString myCompleateName; + switch (m_type) + { + case etk::FILE_TYPE_DATA: + myCompleateName = baseFolderData; + break; + case etk::FILE_TYPE_USER_DATA: + myCompleateName = baseFolderDataUser; + break; + case etk::FILE_TYPE_CACHE: + myCompleateName = baseFolderCache; + break; + default: + myCompleateName = ""; + break; + } + myCompleateName += GetCompleateName(); + m_PointerFile=fopen(myCompleateName.c_str(),"wb"); + if(NULL == m_PointerFile) { + TK_ERROR("Can not find the file name=\"" << GetCompleateName() << "\""); + return false; + } + return true; +} +bool etk::FSNode::FileClose(void) +{ + #ifdef __TARGET_OS__Android + if (etk::FILE_TYPE_DATA == m_type) { + if (NULL == m_zipData) { + TK_CRITICAL("File Already closed : \"" << GetCompleateName() << "\""); + return false; + } + delete[] m_zipData; + m_zipData = NULL; + m_zipDataSize = 0; + m_zipReadingOffset = 0; + return true; + } + #endif + if (NULL == m_PointerFile) { + TK_CRITICAL("File Already closed : \"" << GetCompleateName() << "\""); + return false; + } + fclose(m_PointerFile); + m_PointerFile = NULL; + return true; +} +char* etk::FSNode::FileGets(char * elementLine, int32_t maxData) +{ + memset(elementLine, 0, maxData); + #ifdef __TARGET_OS__Android + char * element = elementLine; + int32_t outSize = 0; + if (etk::FILE_TYPE_DATA == m_type) {//char * tmpData = internalDataFiles[iii].data + m_readingOffset; + if (NULL == m_zipData) { + element[0] = '\0'; + return NULL; + } + if (m_zipReadingOffset>m_zipDataSize) { + element[0] = '\0'; + return NULL; + } + while (m_zipData[m_zipReadingOffset] != '\0') { + if( m_zipData[m_zipReadingOffset] == '\n' + || m_zipData[m_zipReadingOffset] == '\r') + { + *element = m_zipData[m_zipReadingOffset]; + element++; + m_zipReadingOffset++; + *element = '\0'; + return elementLine; + } + *element = m_zipData[m_zipReadingOffset]; + element++; + m_zipReadingOffset++; + if (m_zipReadingOffset>m_zipDataSize) { + *element = '\0'; + return elementLine; + } + // check maxData Size ... + if (outSize>=maxData-1) { + *element = '\0'; + return elementLine; + } + outSize++; + } + if (outSize==0) { + return NULL; + } else { + // send last line + return elementLine; + } + } + #endif + return fgets(elementLine, maxData, m_PointerFile); +} +int32_t etk::FSNode::FileRead(void * data, int32_t blockSize, int32_t nbBlock) +{ + #ifdef __TARGET_OS__Android + if (etk::FILE_TYPE_DATA == m_type) { + if (NULL == m_zipData) { + ((char*)data)[0] = '\0'; + return 0; + } + int32_t dataToRead = blockSize * nbBlock; + if (dataToRead + m_zipReadingOffset > m_zipDataSize) { + nbBlock = ((m_zipDataSize - m_zipReadingOffset) / blockSize); + dataToRead = blockSize * nbBlock; + } + memcpy(data, &m_zipData[m_zipReadingOffset], dataToRead); + m_zipReadingOffset += dataToRead; + return nbBlock; + } + #endif + return fread(data, blockSize, nbBlock, m_PointerFile); +} +int32_t etk::FSNode::FileWrite(void * data, int32_t blockSize, int32_t nbBlock) +{ + #ifdef __TARGET_OS__Android + if (etk::FILE_TYPE_DATA == m_type) { + TK_CRITICAL("Can not write on data inside APK : \"" << GetCompleateName() << "\""); + return 0; + } + #endif + return fwrite(data, blockSize, nbBlock, m_PointerFile); +} +bool etk::FSNode::FileSeek(long int offset, int origin) +{ + #ifdef __TARGET_OS__Android + if (etk::FILE_TYPE_DATA == m_type) { + if (NULL == m_zipData) { + return false; + } + int32_t positionEnd = 0; + switch(origin) { + case SEEK_END: + positionEnd = m_zipDataSize; + break; + case SEEK_CUR: + positionEnd = m_zipReadingOffset; + break; + default: + positionEnd = 0; + break; + } + positionEnd += offset; + if (positionEnd < 0) { + positionEnd = 0; + } else if (positionEnd > m_zipDataSize) { + positionEnd = m_zipDataSize; + } + m_zipReadingOffset = positionEnd; + return true; + } + #endif + fseek(m_PointerFile, offset, origin); + if(ferror(m_PointerFile)) { + return false; + } else { + return true; + } +} diff --git a/Sources/libetk/etk/os/FSNode.h b/Sources/libetk/etk/os/FSNode.h new file mode 100644 index 00000000..ccb52000 --- /dev/null +++ b/Sources/libetk/etk/os/FSNode.h @@ -0,0 +1,225 @@ +/** + ******************************************************************************* + * @file etk/os/FSNode.h + * @brief Ewol Tool Kit : File System node access abstraction (header) + * @author Edouard DUPIN + * @date 31/10/2012 + * @par Project + * Ewol TK + * + * @par Copyright + * Copyright 2011 Edouard DUPIN, all right reserved + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY. + * + * Licence summary : + * You can modify and redistribute the sources code and binaries. + * You can send me the bug-fix + * + * Term of the licence in in the file licence.txt. + * + ******************************************************************************* + */ + +#ifndef __ETK_FILE_SYSTEM_NODE_H__ +#define __ETK_FILE_SYSTEM_NODE_H__ + +#include + +#define MAX_FILE_NAME (10240) + +//http://developer.android.com/guide/topics/data/data-storage.html + +namespace etk +{ + // Right Flags : + typedef enum { + RIGHT_OTHER_EXECUTE = 1 << 0; + RIGHT_OTHER_WRITE = 1 << 1; + RIGHT_OTHER_READ = 1 << 2; + RIGHT_GROUP_EXECUTE = 1 << 3; + RIGHT_GROUP_WRITE = 1 << 4; + RIGHT_GROUP_READ = 1 << 5; + RIGHT_USER_EXECUTE = 1 << 6; + RIGHT_USER_WRITE = 1 << 7; + RIGHT_USER_READ = 1 << 8; + RIGHT_FILE = 1 << 9; + RIGHT_FOLDER = 1 << 10; + RIGHT_LINK = 1 << 12; + }; + + typedef enum { + FSN_TYPE_UNKNOW, + // user might done abstraction ==> acces of the sdcard when possible ... + FSN_TYPE_DIRECT, + FSN_TYPE_RELATIF, + + // depend of the case + // - PC : /usr/shared/programName/ + // - Android : Internal at the executable file (pointer on static area) + // - Apple : Internal at the executable file + FSN_TYPE_DATA, + + // depend on case + // - PC : ~/.programName/ + // - Android : /data/data/programName/files/ + // - Apple : ???? + FSN_TYPE_USER_DATA, + + // depend on case + // - PC : ~/.programName/cache/ + // - Android : /data/data/programName/cache/ + // - Apple : ???? + FSN_TYPE_CACHE, + + // depend on case + // - try on FSN_TYPE_USER_DATA/theme/themeName/xxx + // - try on FSN_TYPE_DATA/theme/themeName/xxx + // - try on FSN_TYPE_EWOL_DATA/theme/themeName/xxx + // and jump to the default theme file + // - try on FSN_TYPE_USER_DATA/theme/default/xxx + // - try on FSN_TYPE_DATA/theme/default/xxx + // - try on FSN_TYPE_EWOL_DATA/theme/default/xxx + FSN_TYPE_THEME, + } FSNType_te; + + /* + note : The filename can be + Direct mode : + DIRECT:/sdfsdfsdf/ + /XX ==> for Linux / Mac / Android + c:/xxx ==> for Windows + + Data mode : + DATA:folder/File.ccc + + User data mode : + USERDATA:folder/File.ccc + + Cache Data : + CACHE:folder/File.ccc + + Theme data : + THEME:folder/file.xxx + + Get the root folder : + ROOT: + / + C: ==> create more risk ... + + Get the Home folder : + HOME: + ~ + */ + class FSNode + { + private: + etk::UString m_userFileName; //!< the name requested by the User + FSNType_te m_type; //!< the Type of data requested by the User + //etk::UString m_realFileSystemName; //!< the real FS name + uint32_t m_rights; //!< IO right of the current file + // specific when file Access : + FILE * m_PointerFile; + private: + etk::UString GetFileSystemName(void); + void privateSetName(etk::UString& newName); + private: + #ifdef __TARGET_OS__Android + bool LoadDataZip(void); + int32_t m_idZipFile; + char * m_zipData; + int32_t m_zipDataSize; + int32_t m_zipReadingOffset; + #endif + + public: + FSNode(void); + FSNode(etk::UString nodeName); + ~FSNode(void); + /* + All Right of the file + */ + bool Exist(void); + bool IsFile(void); + bool IsFolder(void); + bool IsLink(void); + // User + bool IsUserReadable(void); + bool IsUserWritable(void); + bool IsUserRunable(void); + void SetUserReadable(bool newStatus); + void SetUserWritable(bool newStatus); + void SetUserRunable(bool newStatus); + // group + bool IsGroupReadable(void); + bool IsGroupWritable(void); + bool IsGroupRunable(void); + void SetGroupReadable(bool newStatus); + void SetGroupWritable(bool newStatus); + void SetGroupRunable(bool newStatus); + // other + bool IsOtherReadable(void); + bool IsOtherWritable(void); + bool IsOtherRunable(void); + void SetOtherReadable(bool newStatus); + void SetOtherWritable(bool newStatus); + void SetOtherRunable(bool newStatus); + + + /* + Common API : + */ + void SetName(etk::UString newName); + etk::UString GetNameFolder(void) const; + etk::UString GetName(void) const; + etk::UString GetNameFile(void) const; + bool Touch(void); + FSNType_te GetTypeAccess(void) { return m_type; }; + bool Remove(void); + uint64_t TimeCreated(void); + uint64_t TimeModified(void); + + /* + Operator : + */ + const etk::FSNode& operator= (const etk::FSNode &obj ); + bool operator== (const etk::FSNode &obj ) const; + bool operator!= (const etk::FSNode &obj ) const; + friend etk::CCout& operator <<( etk::CCout &os,const etk::FSNode &obj); + + /* + Folder specific : + */ + int32_t FolderCount(void); + etk::Vector FolderGetSubList(void); + ewol::FSNode FolderGetParent(void); // ordered by name ... + + /* + File Specific : + */ + bool FileHasExtention(void); + etk::UString FileGetExtention(void); + int32_t FileSize(void); + bool FileOpenRead(void); + bool FileOpenWrite(void); + bool FileClose(void); + char* FileGets(char * elementLine, int32_t maxData); + int32_t FileRead(void * data, int32_t blockSize, int32_t nbBlock); + int32_t FileWrite(void * data, int32_t blockSize, int32_t nbBlock); + bool FileSeek(long int offset, int origin); + }; + + etk::CCout& operator <<(etk::CCout &os, const etk::FSNode &obj); + /* + void SetBaseFolderData(const char * folder); + void SetBaseFolderDataUser(const char * folder); + void SetBaseFolderCache(const char * folder); + void InitDefaultFolder(const char * applName); + etk::UString GetUserHomeFolder(void); + */ + +} + +#endif + diff --git a/Sources/libewol/ewol/Mesh/Mesh.cpp b/Sources/libewol/ewol/Mesh/Mesh.cpp index 034ae228..3da896e4 100644 --- a/Sources/libewol/ewol/Mesh/Mesh.cpp +++ b/Sources/libewol/ewol/Mesh/Mesh.cpp @@ -84,9 +84,9 @@ void ewol::Mesh::Draw(void) etk::Matrix4 tmpMatrix = ewol::openGL::GetMatrix(); tmpMatrix = etk::matrix::Scale(100,100,100) * etk::matrix::rotate(1,0,0,rotx) - * etk::matrix::rotate(0,1,0,roty) + * etk::matrix::rotate(0,1,0,roty)/* * etk::matrix::Translate(0.01,0,0) - * etk::matrix::rotate(0,0,1,rotz) + * etk::matrix::rotate(0,0,1,rotz)*/ * tmpMatrix; m_GLprogram->UniformMatrix4fv(m_GLMatrix, 1, tmpMatrix.m_mat); // TextureID diff --git a/share/widgetEntry.frag b/share/theme/default/widgetEntry.frag similarity index 72% rename from share/widgetEntry.frag rename to share/theme/default/widgetEntry.frag index 42ab8a77..29e067e0 100644 --- a/share/widgetEntry.frag +++ b/share/theme/default/widgetEntry.frag @@ -10,7 +10,12 @@ uniform vec4 EW_posText; uniform int EW_state; // transmit from the vertex shader -varying vec2 v_position; // intermolated position ... +varying vec2 v_position; // interpolated position ... + +// internal static define +vec4 S_colorBg = vec4(0.0); +vec4 S_colorFg = vec4(1.0,1.0,1.0,0.8); +vec4 S_colorBorder = vec4(0.0,0.0,0.0,1.0); void main(void) { float specialBorder = EW_sizeBorder+EW_sizePadding; @@ -26,12 +31,12 @@ void main(void) { || v_position.x> endStart.x || v_position.y> endStart.y ) { - gl_FragColor = vec4(0.0,0.0,0.0,1.0); + gl_FragColor = S_colorBorder; } else { - gl_FragColor = vec4(1.0,1.0,1.0,0.8); + gl_FragColor = S_colorFg; } } else { - gl_FragColor = vec4(0.0); + gl_FragColor = S_colorBg; } - } + diff --git a/share/widgetEntry.prog b/share/theme/default/widgetEntry.prog similarity index 100% rename from share/widgetEntry.prog rename to share/theme/default/widgetEntry.prog diff --git a/share/widgetEntry.vert b/share/theme/default/widgetEntry.vert similarity index 100% rename from share/widgetEntry.vert rename to share/theme/default/widgetEntry.vert diff --git a/share/theme/rounded/widgetEntry.frag b/share/theme/rounded/widgetEntry.frag new file mode 100644 index 00000000..71d352bc --- /dev/null +++ b/share/theme/rounded/widgetEntry.frag @@ -0,0 +1,52 @@ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +uniform float EW_sizeBorder; +uniform float EW_sizePadding; +uniform vec2 EW_size; +uniform vec4 EW_posText; +uniform int EW_state; + +// transmit from the vertex shader +varying vec2 v_position; // interpolated position ... + +// internal static define +float S_roundedRatio = 10.0; +vec4 S_colorBg = vec4(0.0); +vec4 S_colorFg = vec4(1.0,1.0,1.0,0.8); +vec4 S_colorBorder = vec4(0.0,0.0,0.0,1.0); + + +void main(void) { + // position form center : + vec2 ratio = EW_size / 2.0; + vec2 positionCenter = v_position-ratio; + if(positionCenter.x<0.0) { + positionCenter.x = -1.0*positionCenter.x; + } + if(positionCenter.y<0.0) { + positionCenter.y = -1.0*positionCenter.y; + } + vec2 ratioHight = ratio - EW_sizePadding; + vec2 ratioLow = ratioHight - (EW_sizeBorder+S_roundedRatio); + vec2 circleMode = smoothstep(ratioLow, ratioHight, positionCenter); + float tmpDist = sqrt(circleMode.x*circleMode.x + circleMode.y*circleMode.y); + + //float distanceInternal = (S_roundedRatio-EW_sizeBorder/2.0)/(S_roundedRatio-EW_sizeBorder); + //float distanceExternal = (S_roundedRatio+EW_sizeBorder/2.0)/(S_roundedRatio-EW_sizeBorder);; + if(tmpDist <= 0.7 ) { + gl_FragColor = S_colorFg; + } else if(tmpDist <= 0.9) { + float tmpVal = smoothstep(0.7, 0.9, tmpDist); + if (tmpVal<=0.5) { + gl_FragColor = S_colorBorder*(tmpVal*2.0) + S_colorFg*(1.0-tmpVal*2.0); + } else { + gl_FragColor = S_colorBorder*(1.0-(tmpVal-0.5)*2.0) + S_colorBg*((tmpVal-0.5)*2.0); + } + } else { + gl_FragColor = S_colorBg; + } +} + diff --git a/share/theme/rounded/widgetEntry.prog b/share/theme/rounded/widgetEntry.prog new file mode 100644 index 00000000..464185b4 --- /dev/null +++ b/share/theme/rounded/widgetEntry.prog @@ -0,0 +1,2 @@ +widgetEntry.vert +widgetEntry.frag \ No newline at end of file diff --git a/share/theme/rounded/widgetEntry.vert b/share/theme/rounded/widgetEntry.vert new file mode 100644 index 00000000..1b0652d7 --- /dev/null +++ b/share/theme/rounded/widgetEntry.vert @@ -0,0 +1,17 @@ +#ifdef GL_ES +precision mediump float; +precision mediump int; +#endif + +// Input : +attribute vec2 EW_coord2d; +uniform mat4 EW_MatrixTransformation; + +// output : +varying vec2 v_position; // This will be passed into the fragment shader. + +void main(void) { + gl_Position = EW_MatrixTransformation * vec4(EW_coord2d, 0.0, 1.0); + // transmit position of the curent element (intermolated ...) + v_position = EW_coord2d; +}