Browse Source

Add support for reading files to file-explorer

pull/47/head
Ian Chamberlain 3 years ago
parent
commit
6b409cdcae
No known key found for this signature in database
GPG Key ID: AE5484D09405AA60
  1. 105
      ctru-rs/examples/file-explorer.rs
  2. 1
      ctru-rs/examples/romfs/garbage-data
  3. 4
      ctru-rs/examples/romfs/test-file.txt

105
ctru-rs/examples/file-explorer.rs

@ -6,7 +6,8 @@ use ctru::console::Console;
use ctru::services::hid::KeyPad; use ctru::services::hid::KeyPad;
use ctru::services::{Apt, Hid}; use ctru::services::{Apt, Hid};
use ctru::Gfx; use ctru::Gfx;
use std::fs::DirEntry; use std::fs::{DirEntry, File};
use std::io::{BufRead, BufReader};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
fn main() { fn main() {
@ -74,8 +75,36 @@ impl<'a> FileExplorer<'a> {
} }
fn print_menu(&mut self) { fn print_menu(&mut self) {
println!("Viewing {}", self.path.display()); match std::fs::metadata(&self.path) {
Ok(metadata) => {
println!(
"Viewing {} (size {} bytes)",
self.path.display(),
metadata.len()
);
if metadata.is_file() {
self.print_file_contents();
// let the user continue navigating from the parent dir
// after dumping the file
self.path.pop();
self.print_menu();
return;
} else if metadata.is_dir() {
self.print_dir_entries();
} else {
println!("unsupported file type: {:?}", metadata.file_type());
}
}
Err(e) => {
println!("Failed to read {}: {}", self.path.display(), e)
}
};
println!("Start to exit, A to select an entry by number, B to go up a directory, X to set the path.");
}
fn print_dir_entries(&mut self) {
let dir_listing = std::fs::read_dir(&self.path).expect("Failed to open path"); let dir_listing = std::fs::read_dir(&self.path).expect("Failed to open path");
self.entries = Vec::new(); self.entries = Vec::new();
@ -85,25 +114,8 @@ impl<'a> FileExplorer<'a> {
println!("{:2} - {}", i, entry.file_name().to_string_lossy()); println!("{:2} - {}", i, entry.file_name().to_string_lossy());
self.entries.push(entry); self.entries.push(entry);
// Paginate the output
if (i + 1) % 20 == 0 { if (i + 1) % 20 == 0 {
println!("Press A to go to next page, or Start to exit"); self.wait_for_page_down();
while self.apt.main_loop() {
self.hid.scan_input();
let input = self.hid.keys_down();
if input.contains(KeyPad::KEY_A) {
break;
}
if input.contains(KeyPad::KEY_START) {
self.running = false;
return;
}
self.gfx.wait_for_vblank();
}
} }
} }
Err(e) => { Err(e) => {
@ -111,8 +123,54 @@ impl<'a> FileExplorer<'a> {
} }
} }
} }
}
println!("Start to exit, A to select an entry by number, B to go up a directory, X to set the path."); fn print_file_contents(&mut self) {
match File::open(&self.path) {
Ok(f) => {
println!("File contents:\n{:->80}", "");
let reader = BufReader::new(f);
for (i, line) in reader.lines().enumerate() {
match line {
Ok(line) => {
println!("{}", line);
if (i + 1) % 20 == 0 {
self.wait_for_page_down();
}
}
Err(err) => {
println!("Error reading file: {}", err);
break;
}
}
}
println!("{:->80}", "");
}
Err(err) => {
println!("Error reading file: {}", err);
}
}
}
/// Paginate output
fn wait_for_page_down(&mut self) {
println!("Press A to go to next page, or Start to exit");
while self.apt.main_loop() {
self.hid.scan_input();
let input = self.hid.keys_down();
if input.contains(KeyPad::KEY_A) {
break;
}
if input.contains(KeyPad::KEY_START) {
self.running = false;
return;
}
self.gfx.wait_for_vblank();
}
} }
fn get_input_and_run(&mut self, action: impl FnOnce(&mut Self, String)) { fn get_input_and_run(&mut self, action: impl FnOnce(&mut Self, String)) {
@ -154,11 +212,6 @@ impl<'a> FileExplorer<'a> {
} }
}; };
if !next_entry.file_type().unwrap().is_dir() {
println!("Not a directory: {}", next_path_index);
return;
}
self.console.clear(); self.console.clear();
self.path = next_entry.path(); self.path = next_entry.path();
self.print_menu(); self.print_menu();

1
ctru-rs/examples/romfs/garbage-data

@ -0,0 +1 @@
c¯Ø:7vi•îÉz `ÁnÄ÷§<EFBFBD>Ê¢êëfb £

4
ctru-rs/examples/romfs/test-file.txt

@ -1 +1,3 @@
test test file contents
another line

Loading…
Cancel
Save