2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
3 Smoothie 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 3 of the License, or (at your option) any later version.
4 Smoothie 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.
5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
8 #include "libs/Kernel.h"
10 #include "PanelScreen.h"
11 #include "MainMenuScreen.h"
12 #include "FileScreen.h"
13 #include "libs/nuts_bolts.h"
14 #include "libs/utils.h"
16 #include "libs/SerialMessage.h"
17 #include "StreamOutput.h"
18 #include "DirHandle.h"
23 FileScreen::FileScreen()
25 this->current_folder
= "";
26 this->start_play
= false;
29 // When entering this screen
30 void FileScreen::on_enter()
32 THEPANEL
->lcd
->clear();
34 // Default folder to enter
35 if ( this->current_folder
.compare("") == 0 ) {
36 this->enter_folder("/");
38 this->enter_folder(this->current_folder
);
42 // For every ( potential ) refresh of the screen
43 void FileScreen::on_refresh()
45 if ( THEPANEL
->menu_change() ) {
48 if ( THEPANEL
->click() ) {
49 this->clicked_line(THEPANEL
->get_menu_current_line());
54 void FileScreen::enter_folder(std::string folder
)
57 // Rembember where we are
58 this->current_folder
= folder
;
60 // We need the number of lines to setup the menu
61 uint16_t number_of_files_in_folder
= this->count_folder_content(this->current_folder
);
64 THEPANEL
->setup_menu(number_of_files_in_folder
+ 1); // same number of files as menu items
65 THEPANEL
->enter_menu_mode();
71 // Called by the panel when refreshing the menu, display .. then all files in the current dir
72 void FileScreen::display_menu_line(uint16_t line
)
75 THEPANEL
->lcd
->printf("..");
77 THEPANEL
->lcd
->printf("%s", (this->file_at(line
- 1).substr(0, 18)).c_str());
81 // When a line is clicked in the menu, act
82 void FileScreen::clicked_line(uint16_t line
)
85 if ( this->current_folder
.compare("/") == 0 ) {
86 // Exit file navigation
87 THEPANEL
->enter_screen(this->parent
);
90 this->current_folder
= this->current_folder
.substr(0, this->current_folder
.find_last_of('/') + 1);
91 if ( this->current_folder
[this->current_folder
.length() - 1] == '/' && this->current_folder
.length() != 1 ) {
92 this->current_folder
.erase(this->current_folder
.length() - 1, 1);
94 this->enter_folder(this->current_folder
);
97 //printf("enter file\r\n");
99 string path
= this->current_folder
;
100 if ( path
.compare("/") == 0 ) {
103 path
= path
+ "/" + this->file_at( line
- 1 );
104 if ( this->is_a_folder( path
) ) {
105 this->enter_folder(path
);
109 // start printing that file...
110 this->play_path
= path
;
111 this->start_play
= true;
116 // Check wether a line is a folder or a file
117 bool FileScreen::is_a_folder( string path
)
119 // In the special case of /local/ ( the mbed flash chip ) we don't have sub-folders, everything is a file
120 if ( path
.substr(0, 7).compare("/local/") == 0 ) {
123 // Else, check if it's a folder or not
125 d
= opendir(path
.c_str());
134 // Find the "line"th file in the current folder
135 string
FileScreen::file_at(uint16_t line
)
140 d
= opendir(this->current_folder
.c_str());
142 while ((p
= readdir(d
)) != NULL
) {
143 if ( count
== line
) {
144 string to_return
= lc(string(p
->d_name
));
145 //printf("line: %u string:%s\r\n", line, to_return.c_str());
146 //if( to_return[to_return.length()-1] == '.' ){ to_return[to_return.length()-1] = 0x00; }
154 if (d
!= NULL
) closedir(d
);
158 // Count how many files there are in the current folder
159 uint16_t FileScreen::count_folder_content(std::string folder
)
164 d
= opendir(folder
.c_str());
166 while ((p
= readdir(d
)) != NULL
) {
175 void FileScreen::on_main_loop()
177 if (this->start_play
) {
178 this->start_play
= false;
179 THEPANEL
->set_playing_file(this->play_path
);
180 this->play(this->play_path
);
181 THEPANEL
->enter_screen(this->parent
);
186 void FileScreen::play(string path
)
188 struct SerialMessage message
;
189 message
.message
= string("play ") + path
+ " -q";
190 message
.stream
= &(StreamOutput::NullStream
);
191 THEKERNEL
->call_event(ON_CONSOLE_LINE_RECEIVED
, &message
);