microSD カードのビットマップ・ファイルのビュアー.画像の最大値 縦:272ピクセル,横:480ピクセル. Bitmap file viewer for microSD card. Maximum size Vertical: 272 pixels, Horizontal: 480.

Dependencies:   SDFileSystem_Warning_Fixed F746_GUI

Revision:
1:bb146d5fe9aa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MyFiles/FileSelectorBmp.cpp	Tue Oct 23 11:51:47 2018 +0000
@@ -0,0 +1,159 @@
+//--------------------------------------------------------------
+//  FileSelector class
+//      SD カード内の *.bmp ファイル名の一覧を表示し,ファイルを選択する
+//      だだし,日本語のファイル名は除く
+//
+//  2018/10/23, Copyright (c) 2018 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#include "FileSelectorBmp.hpp"
+
+namespace Mikami
+{
+    FileSelector::FileSelector(uint8_t x0, uint8_t y0, int maxFiles,
+                               int maxNameLength, SD_BitmapReader &reader)
+        : X_(x0), Y_(y0),
+          MAX_FILES_(maxFiles), MAX_NAME_LENGTH_(maxNameLength),
+          fileNames_(maxFiles), fileNameLabels_(MAX_LIST_PAGE_),
+          next_(50, 235, 64, 36, 2, (string[]){"<", ">"}, 10, 0, 2, -1, Font24),
+          pageLabel_(210, 250, Label::LEFT, Font16),
+          lcd_(GuiBase::GetLcd()), sdReader_(reader), page_(1),
+          nOld_(-1), kOld_(-1)
+    {
+        Array<string> nonString(MAX_LIST_PAGE_, "");
+        rect_ = new ButtonGroup(X_, Y_, W_H_, W_H_, MAX_LIST_PAGE_,
+                                nonString, 0, V_L_-W_H_, 1,
+                                -1, Font12, 0, GuiBase::ENUM_BACK,
+                                BASE_COLOR_, TOUCHED_COLOR_);
+        rect_->EraseAll();
+        next_.EraseAll();
+
+        // Label を生成
+        for (int n=0; n<MAX_LIST_PAGE_; n++)
+            fileNameLabels_[n] = new Label(X_+30, Y_+5+V_L_*n, "",
+                                           Label::LEFT, Font16, BASE_COLOR_);
+    }
+
+    FileSelector::~FileSelector()
+    {   
+        delete rect_;
+        for (int n=0; n<MAX_LIST_PAGE_; n++) delete fileNameLabels_[n];
+    }
+
+    // ファイルの一覧表を作る.BMP ファイルが存在しない場合は false を返す
+    bool FileSelector::CreateTable()
+    {
+        DIR* dp = opendir("/sd");
+        fileCount_ = 0; 
+        if (dp != NULL)
+        {
+            dirent* entry;
+            for (int n=0; n<256; n++)
+            {
+                entry = readdir(dp);
+                if (entry == NULL) break;
+
+                string strName = entry->d_name;
+                if ( (strName.find(".bmp") != string::npos) ||
+                     (strName.find(".BMP") != string::npos) )
+                {
+                    if (sdReader_.Open(strName))        // ファイルのオープン
+                    {
+                        // 不適切なファイルは除外
+                        if (sdReader_.IsAllowed())
+                            fileNames_[fileCount_++] = strName;
+                        sdReader_.Close();
+                    }
+                }
+                if (fileCount_ >= MAX_FILES_) break;
+            }
+            closedir(dp);
+        }
+        else
+            return false;                   // SD カードが装着されていない場合
+        if (fileCount_ == 0) return false;  // 該当する BMP ファイルが存在しない場合
+
+        div_t m = div(fileCount_, MAX_LIST_PAGE_);
+        maxPage_ = (m.rem == 0) ? m.quot : m.quot+1;
+        return true;                        // 該当する BMP ファイルが存在する場合
+    }
+
+    // ファイルを選択する
+    bool FileSelector::Select(string &fileName)
+    {
+        int m;
+        if (next_.GetTouchedNumber(m))
+        {
+            if (m==0) page_--;
+            else      page_++;
+            DisplayFileList(false);
+            nOld_ = -1;
+            wait_ms(300);
+        }
+        
+        int n;
+        if (rect_->GetTouchedNumber(n))
+        {
+            int k = (page_ - 1)*MAX_LIST_PAGE_ + n;
+            fileNameLabels_[n]->Draw(GetFileNameNoExt(k),
+                                     TOUCHED_COLOR_);
+            fileName = fileNames_[k];
+            // 同じページで以前に選択されているファイル名の色を戻す
+            if (nOld_ != -1)
+                fileNameLabels_[nOld_]->Draw(GetFileNameNoExt(kOld_),
+                                             BASE_COLOR_);
+            if (page_ == maxPage_)      // 最後のページで余分な四角形を消去
+                for (int j=fileCount_ % MAX_LIST_PAGE_ + 1;
+                     j < MAX_LIST_PAGE_; j++) rect_->Erase(j);
+            nOld_ = n;
+            kOld_ = k;
+            return true;
+        }
+        else
+            return false;
+    }
+
+    // ファイルの一覧の表示
+    void FileSelector::DisplayFileList(bool sortEnable)
+    {
+        if (sortEnable)
+            std::sort((string *)fileNames_,
+                      (string *)fileNames_+fileCount_); 
+        
+        Erase(0, 0, 480, 272);
+
+        div_t m = div(fileCount_, MAX_LIST_PAGE_);
+        int count = (m.quot >= page_) ? MAX_LIST_PAGE_ : m.rem;
+        for (int n=0; n<count; n++) rect_->Draw(n);
+        for (int n=0; n<count; n++)
+            fileNameLabels_[n]->Draw(GetFileNameNoExt(n+(page_-1)*MAX_LIST_PAGE_));
+
+        // 前のページ,次のページの選択ボタンなどを表示する
+        next_.InactivateAll();
+        if (page_ > 1) next_.Activate(0);           // "<" 有効
+        if (page_ < maxPage_) next_.Activate(1);    // ">" 有効
+        char page[6];
+        sprintf(page, "%d/%d", page_, maxPage_);
+        pageLabel_.Draw(page);
+    }
+
+    // ファイルの一覧の消去
+    void FileSelector::Erase(uint16_t x, uint16_t y, uint16_t width,
+                             uint16_t height, uint32_t color)
+    {
+        lcd_.SetTextColor(color);
+        lcd_.FillRect(x, y, width, height);
+    }
+
+    // 拡張子を削除したファイル名を取得
+    string FileSelector::GetFileNameNoExt(int n)
+    {
+        string name = fileNames_[n];
+        int k = name.rfind(".");
+        if (k != string::npos)
+            return name.erase(k);
+        else
+            return name;
+    }
+}
+