revised version of F746_SD_GraphicEqualizer

Dependencies:   BSP_DISCO_F746NG F746_GUI F746_SAI_IO FrequencyResponseDrawer LCD_DISCO_F746NG SDFileSystem_Warning_Fixed TS_DISCO_F746NG mbed

Fork of F746_SD_GraphicEqualizer by 不韋 呂

MyClasses_Functions/FileSelectorWav.hpp

Committer:
edamame22
Date:
2016-07-07
Revision:
12:87f6955b5a80
Parent:
10:fc6367c2ffcf

File content as of revision 12:87f6955b5a80:

//--------------------------------------------------------------
//  FileSelector class
//      SD カード内のファイル名の一覧を表示し,ファイルを選択する
//
//  2016/04/18, Copyright (c) 2016 MIKAMI, Naoki
//--------------------------------------------------------------

#ifndef FILE_SELECTOR_HPP
#define FILE_SELECTOR_HPP

#include "mbed.h"
#include "Label.hpp"
#include "ButtonGroup.hpp"
#include "SD_WavReader.hpp"
#include "SDFileSystem.h"
#include <algorithm>    // sort() で使用
#include <string>


namespace Mikami
{
    class FileSelector
    {
    public:
        FileSelector(uint8_t x0, uint8_t y0, int maxFiles,
                     int maxNameLength, SD_WavReader &reader)
            : X_(x0), Y_(y0), W_H_(24), V_L_(36),
              MAX_FILES_(maxFiles), MAX_NAME_LENGTH_(maxNameLength),
              BASE_COLOR_(0xFFDBAD17), TOUCHED_COLOR_(0xFFF8F8FB),
              fileNames_(new string[maxFiles]),
              sortedFileNames_(new string[maxFiles]),
              nonString_(NULL), rect_(NULL), fileNameLabels_(NULL),
              lcd_(GuiBase::GetLcdPtr()),
              sdReader_(reader), prevFileCount_(0), prev_(-1) {}

        ~FileSelector()
        {
            for (int n=0; n<fileCount_; n++)
                delete fileNameLabels_[n];
            delete[] fileNameLabels_;
            delete rect_;
            delete[] nonString_;
            delete[] sortedFileNames_;
            delete[] fileNames_;
        }
// ren: show a string        
       void ren_Msg(int pos, char msg[])
        {  int lin, y_pos[7]= {0,70,130,160,190,220,250};
        if(pos<0) lin=0;
        else if (pos>6)  lin=6;
        else lin=pos;
        Label renLabel(240, y_pos[lin], msg, Label::CENTER,Font20);
        }  
              
        bool CreateTable()
        {
            DIR* dp = opendir("/sd");
            fileCount_ = 0; 
            if (dp != NULL)
            {
                dirent* entry;
                // ren: change n<256 to n<2560
                for (int n=0; n<2560; n++)
                {
                    entry = readdir(dp);
                    if (entry == NULL) break;

                    string strName = entry->d_name;
                    if ( (strName.find(".wav") != string::npos) ||
                         (strName.find(".WAV") != string::npos) )
                    {
                        sdReader_.Open(strName);        // ファイルオープン
/**{
char tmpmsg[500];
sprintf(tmpmsg, "1..found a file: %s", strName.c_str()); 
ren_Msg(1,tmpmsg);
sprintf(tmpmsg, "2..fileCount_: %d", fileCount_);
ren_Msg(2,tmpmsg);
}**/
                        // PCM,16 ビットステレオ,標本化周波数 44.1 kHz 以外のファイルは除外
                        if (sdReader_.IsWavFile())
                        {
                            fileNames_[fileCount_] = strName;
                            fileCount_++;
                        }
/**{
char tmpmsg[500];
sprintf(tmpmsg, "fileCount_: %d", fileCount_); 
ren_Msg(3, tmpmsg);
}**/
                        sdReader_.Close();
                    }


                    if (fileCount_ >= MAX_FILES_) break;
                }
                closedir(dp); 
            }
            else
                return false;
                
            if (fileCount_ == 0) return false;

            if (nonString_ == NULL) delete[] nonString_;
            nonString_ = new string[fileCount_];
            for (int n=0; n<fileCount_; n++) nonString_[n] = "";
            
            if (rect_ != NULL) delete rect_;
            rect_ = new ButtonGroup(X_, Y_, W_H_, W_H_, fileCount_,
                                    nonString_, 0, V_L_-W_H_, 1,
                                    -1, true,Font12, 0, GuiBase::ENUM_BACK,
                                    BASE_COLOR_, TOUCHED_COLOR_);
            for (int n=0; n<fileCount_; n++) rect_->Erase(n);
            CreateLabels();   
            prevFileCount_ = fileCount_;
 
            return true;
        }

        // ファイルを選択する
        bool Select(string fileList[],int *idx)
        {
            int n;
            if (rect_->GetTouchedNumber(n))
            {
                fileNameLabels_[n]->Draw(GetFileNameNoExt(n), TOUCHED_COLOR_);
                if ((prev_ >= 0) && (prev_ != n))
                    fileNameLabels_[prev_]->Draw(GetFileNameNoExt(prev_));
                prev_ = n;
                *idx = n;
                for (int n=0; n<fileCount_; n++) fileList[n] = sortedFileNames_[n];
//                fileName = sortedFileNames_[n];
//printf("\nSelected file : %s", fileName);
                return true;
            }
            else
                return false;
        }

        // ファイルの一覧の表示
        void DisplayFileList(int highlighted, bool sort = true)
        {
            for (int n=0; n<fileCount_; n++)
                sortedFileNames_[n] = fileNames_[n];
            if (sort)
                std::sort(sortedFileNames_, sortedFileNames_+fileCount_); 
            
            Erase(X_, 0, MAX_NAME_LENGTH_*((sFONT *)(&Font16))->Width, 288);
            rect_->DrawAll();
            for (int n=0; n<fileCount_; n++)
                fileNameLabels_[n]->Draw(GetFileNameNoExt(n));
            if((highlighted>-1) && (highlighted < fileCount_))
            {
              fileNameLabels_[highlighted]->Draw(GetFileNameNoExt(highlighted), TOUCHED_COLOR_);
              prev_ = highlighted;
            }
        }

        void Erase(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
                   uint32_t color = GuiBase::ENUM_BACK)
        {
            lcd_->SetTextColor(color);
            lcd_->FillRect(x, y, width, height);
        }

    private:
        const uint8_t X_, Y_, W_H_, V_L_;
        const int MAX_FILES_;
        const int MAX_NAME_LENGTH_;
        const uint32_t BASE_COLOR_;
        const uint32_t TOUCHED_COLOR_;
        
        string *fileNames_;
        string *sortedFileNames_;
        string *nonString_;
        ButtonGroup *rect_;
        Label **fileNameLabels_;
        LCD_DISCO_F746NG *lcd_;
        SD_WavReader &sdReader_;
        int fileCount_, prevFileCount_;
        int prev_;

        // Label を生成
        void CreateLabels()
        {
            if (fileNameLabels_ != NULL)
            {
                for (int n=0; n<prevFileCount_; n++)
                    delete fileNameLabels_[n];
                delete[] fileNameLabels_;
            }
            fileNameLabels_ = new Label *[fileCount_+1];
            for (int n=0; n<fileCount_; n++)
                fileNameLabels_[n] = new Label(X_+30, Y_+5+V_L_*n, "",
                                               Label::LEFT, Font16,
                                               BASE_COLOR_);
        }

        // 拡張子を削除した文字列を取得
        string GetFileNameNoExt(int n)
        {
            string name = sortedFileNames_[n];
            name.erase(name.find("."));
            return name.substr(0, MAX_NAME_LENGTH_);
        }

        // disallow copy constructor and assignment operator
        FileSelector(const FileSelector&);
        FileSelector& operator=(const FileSelector&);
    };
}
#endif  // FILE_SELECTOR_HPP