mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-24 23:09:26 -05:00
Progress bar for Notepad IO (#1322)
This commit is contained in:
parent
0a3aa706ef
commit
411f6c0a34
@ -474,7 +474,13 @@ void TextEditorView::open_file(const fs::path& path) {
|
|||||||
path_ = {};
|
path_ = {};
|
||||||
file_dirty_ = false;
|
file_dirty_ = false;
|
||||||
has_temp_file_ = false;
|
has_temp_file_ = false;
|
||||||
auto result = FileWrapper::open(path);
|
auto result = FileWrapper::open(
|
||||||
|
path, false, [](uint32_t value, uint32_t total) {
|
||||||
|
Painter p;
|
||||||
|
auto percent = (value * 100) / total;
|
||||||
|
auto width = (percent * screen_width) / 100;
|
||||||
|
p.draw_hline({0, 16}, width, Color::yellow());
|
||||||
|
});
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
nav_.display_modal("Read Error", "Cannot open file:\n" + result.error().what());
|
nav_.display_modal("Read Error", "Cannot open file:\n" + result.error().what());
|
||||||
@ -582,6 +588,10 @@ void TextEditorView::prepare_for_write() {
|
|||||||
if (has_temp_file_)
|
if (has_temp_file_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// TODO: This would be nice to have but it causes a stack overflow in an ISR?
|
||||||
|
// Painter p;
|
||||||
|
// p.draw_string({2, 48}, Styles::yellow, "Creating temporary file...");
|
||||||
|
|
||||||
// Copy to temp file on write.
|
// Copy to temp file on write.
|
||||||
has_temp_file_ = true;
|
has_temp_file_ = true;
|
||||||
delete_temp_file(path_);
|
delete_temp_file(path_);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "file.hpp"
|
#include "file.hpp"
|
||||||
#include "optional.hpp"
|
#include "optional.hpp"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
|
||||||
@ -75,6 +76,8 @@ class BufferWrapper {
|
|||||||
}
|
}
|
||||||
virtual ~BufferWrapper() {}
|
virtual ~BufferWrapper() {}
|
||||||
|
|
||||||
|
std::function<void(Size, Size)> on_read_progress{};
|
||||||
|
|
||||||
/* Prevent copies */
|
/* Prevent copies */
|
||||||
BufferWrapper(const BufferWrapper&) = delete;
|
BufferWrapper(const BufferWrapper&) = delete;
|
||||||
BufferWrapper& operator=(const BufferWrapper&) = delete;
|
BufferWrapper& operator=(const BufferWrapper&) = delete;
|
||||||
@ -234,13 +237,23 @@ class BufferWrapper {
|
|||||||
|
|
||||||
line_count_ = start_line_;
|
line_count_ = start_line_;
|
||||||
Offset offset = start_offset_;
|
Offset offset = start_offset_;
|
||||||
|
|
||||||
|
// Report progress every N lines.
|
||||||
|
constexpr auto report_interval = 100u;
|
||||||
auto result = next_newline(offset);
|
auto result = next_newline(offset);
|
||||||
|
auto next_report = report_interval;
|
||||||
|
|
||||||
while (result) {
|
while (result) {
|
||||||
++line_count_;
|
++line_count_;
|
||||||
if (newlines_.size() < max_newlines)
|
if (newlines_.size() < max_newlines)
|
||||||
newlines_.push_back(*result);
|
newlines_.push_back(*result);
|
||||||
offset = *result + 1;
|
offset = *result + 1;
|
||||||
|
|
||||||
|
if (on_read_progress && line_count_ > next_report) {
|
||||||
|
on_read_progress(offset, size());
|
||||||
|
next_report = line_count_ + report_interval;
|
||||||
|
}
|
||||||
|
|
||||||
result = next_newline(offset);
|
result = next_newline(offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,6 +410,9 @@ class BufferWrapper {
|
|||||||
// Number of bytes left to shift.
|
// Number of bytes left to shift.
|
||||||
Offset remaining = size() - src;
|
Offset remaining = size() - src;
|
||||||
Offset offset = size();
|
Offset offset = size();
|
||||||
|
Size report_total = remaining;
|
||||||
|
Size report_interval = report_total / 8;
|
||||||
|
Size next_report = remaining - report_interval;
|
||||||
|
|
||||||
while (remaining > 0) {
|
while (remaining > 0) {
|
||||||
offset -= std::min(remaining, buffer_size);
|
offset -= std::min(remaining, buffer_size);
|
||||||
@ -413,6 +429,11 @@ class BufferWrapper {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
remaining -= *result;
|
remaining -= *result;
|
||||||
|
|
||||||
|
if (on_read_progress && remaining <= next_report) {
|
||||||
|
on_read_progress(report_total - remaining, report_total);
|
||||||
|
next_report = remaining > report_interval ? remaining - report_interval : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,6 +445,9 @@ class BufferWrapper {
|
|||||||
|
|
||||||
char buffer[buffer_size];
|
char buffer[buffer_size];
|
||||||
auto offset = src;
|
auto offset = src;
|
||||||
|
Size report_total = size();
|
||||||
|
Size report_interval = report_total / 8;
|
||||||
|
Size next_report = offset + report_interval;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
wrapped_->seek(offset);
|
wrapped_->seek(offset);
|
||||||
@ -438,6 +462,11 @@ class BufferWrapper {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
offset += *result;
|
offset += *result;
|
||||||
|
|
||||||
|
if (on_read_progress && offset >= next_report) {
|
||||||
|
on_read_progress(offset, report_total);
|
||||||
|
next_report = offset + report_interval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the extra bytes at the end of the file.
|
// Delete the extra bytes at the end of the file.
|
||||||
@ -463,13 +492,19 @@ class FileWrapper : public BufferWrapper<File, 64> {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
using Result = File::Result<T>;
|
using Result = File::Result<T>;
|
||||||
using Error = File::Error;
|
using Error = File::Error;
|
||||||
static Result<std::unique_ptr<FileWrapper>> open(const std::filesystem::path& path, bool create = false) {
|
static Result<std::unique_ptr<FileWrapper>> open(
|
||||||
|
const std::filesystem::path& path,
|
||||||
|
bool create = false,
|
||||||
|
std::function<void(Size, Size)> on_read_progress = nullptr) {
|
||||||
auto fw = std::unique_ptr<FileWrapper>(new FileWrapper());
|
auto fw = std::unique_ptr<FileWrapper>(new FileWrapper());
|
||||||
auto error = fw->file_.open(path, /*read_only*/ false, create);
|
auto error = fw->file_.open(path, /*read_only*/ false, create);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
return *error;
|
return *error;
|
||||||
|
|
||||||
|
if (on_read_progress)
|
||||||
|
fw->on_read_progress = on_read_progress;
|
||||||
|
|
||||||
fw->initialize();
|
fw->initialize();
|
||||||
return fw;
|
return fw;
|
||||||
}
|
}
|
||||||
|
@ -435,4 +435,29 @@ SCENARIO("Delete line.") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SCENARIO("It calls on_read_progress while reading.") {
|
||||||
|
GIVEN("A file larger than internal buffer_size (512)") {
|
||||||
|
std::string content = std::string(599, 'a');
|
||||||
|
content.push_back('x');
|
||||||
|
MockFile f{content};
|
||||||
|
|
||||||
|
auto w = wrap_buffer(f);
|
||||||
|
auto init_line_count = w.line_count();
|
||||||
|
auto init_size = w.size();
|
||||||
|
auto called = false;
|
||||||
|
|
||||||
|
w.on_read_progress = [&called](auto, auto) {
|
||||||
|
called = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
WHEN("Replacing range with larger size") {
|
||||||
|
w.replace_range({0, 2}, "bbb");
|
||||||
|
|
||||||
|
THEN("callback should be called.") {
|
||||||
|
CHECK(called);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_SUITE_END();
|
TEST_SUITE_END();
|
Loading…
Reference in New Issue
Block a user