#pragma once #include #include #include #include "image_file.h" #include "key_event.h" #include "key_help.h" #include "services/storage_service.h" #include "ui/canvas.h" namespace roro { // A picture from the card, for the Storage App's viewer (issue #45, F1 Q233-Q242): PNG, JPEG, BMP // and the first picture of a GIF (only JPEG needs a decoder that isn't ours). It is decoded once, straight into the screen's own buffer, and // left there (App::retainsContent): there is no copy of it in memory. It is decoded again only // when something else was drawn over it, or when it is zoomed or moved. // // The decoding runs on the storage task while the main loop goes on: a photograph takes seconds, // and the picture appears as it comes. Anything that needs the screen back stops it first. class ImagePane { public: explicit ImagePane(StorageService& storage) : storage_(storage) {} std::string open(const std::string& path, uint32_t size); // "" or why it can't be shown void close(); bool onKey(const KeyEvent& e); // true: the key was the picture's void help(std::vector& out) const; bool update(uint32_t nowMs); // true: draw again void draw(Canvas& c); void lost(); // the screen no longer holds it void say(const std::string& text); struct Job; // one decoding: shared with the storage task, which may outlive the view of it private: enum class Phase { Wanted, Decoding, Shown }; std::string describe() const; void start(Canvas& c); void cancel(); // returns once the storage task has let go of the screen void hideNote(Canvas* c); StorageService& storage_; std::string path_, problem_, note_; uint32_t size_ = 0, noteMs_ = 0, shotAt_ = 0, pushedMs_ = 0; files::ImageInfo info_; files::ImageFrame frame_; Phase phase_ = Phase::Wanted; std::shared_ptr job_; Canvas* canvas_ = nullptr; bool told_ = false, noteDrawn_ = false; std::vector under_; // what the note was written over }; } // namespace roro