101 lines
3.6 KiB
C++
101 lines
3.6 KiB
C++
|
|
#include "BmpViewerActivity.h"
|
||
|
|
|
||
|
|
#include <Bitmap.h>
|
||
|
|
#include <GfxRenderer.h>
|
||
|
|
#include <HalStorage.h>
|
||
|
|
#include <I18n.h>
|
||
|
|
|
||
|
|
#include "components/UITheme.h"
|
||
|
|
#include "fontIds.h"
|
||
|
|
|
||
|
|
BmpViewerActivity::BmpViewerActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, std::string path,
|
||
|
|
std::function<void()> onGoBack)
|
||
|
|
: Activity("BmpViewer", renderer, mappedInput), filePath(std::move(path)), onGoBack(std::move(onGoBack)) {}
|
||
|
|
|
||
|
|
void BmpViewerActivity::onEnter() {
|
||
|
|
Activity::onEnter();
|
||
|
|
// Removed the redundant initial renderer.clearScreen()
|
||
|
|
|
||
|
|
FsFile file;
|
||
|
|
|
||
|
|
const auto pageWidth = renderer.getScreenWidth();
|
||
|
|
const auto pageHeight = renderer.getScreenHeight();
|
||
|
|
Rect popupRect = GUI.drawPopup(renderer, tr(STR_LOADING_POPUP));
|
||
|
|
GUI.fillPopupProgress(renderer, popupRect, 20); // Initial 20% progress
|
||
|
|
// 1. Open the file
|
||
|
|
if (Storage.openFileForRead("BMP", filePath, file)) {
|
||
|
|
Bitmap bitmap(file, true);
|
||
|
|
|
||
|
|
// 2. Parse headers to get dimensions
|
||
|
|
if (bitmap.parseHeaders() == BmpReaderError::Ok) {
|
||
|
|
int x, y;
|
||
|
|
|
||
|
|
if (bitmap.getWidth() > pageWidth || bitmap.getHeight() > pageHeight) {
|
||
|
|
float ratio = static_cast<float>(bitmap.getWidth()) / static_cast<float>(bitmap.getHeight());
|
||
|
|
const float screenRatio = static_cast<float>(pageWidth) / static_cast<float>(pageHeight);
|
||
|
|
|
||
|
|
if (ratio > screenRatio) {
|
||
|
|
// Wider than screen
|
||
|
|
x = 0;
|
||
|
|
y = std::round((static_cast<float>(pageHeight) - static_cast<float>(pageWidth) / ratio) / 2);
|
||
|
|
} else {
|
||
|
|
// Taller than screen
|
||
|
|
x = std::round((static_cast<float>(pageWidth) - static_cast<float>(pageHeight) * ratio) / 2);
|
||
|
|
y = 0;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
// Center small images
|
||
|
|
x = (pageWidth - bitmap.getWidth()) / 2;
|
||
|
|
y = (pageHeight - bitmap.getHeight()) / 2;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 4. Prepare Rendering
|
||
|
|
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
|
||
|
|
GUI.fillPopupProgress(renderer, popupRect, 50);
|
||
|
|
|
||
|
|
renderer.clearScreen();
|
||
|
|
// Assuming drawBitmap defaults to 0,0 crop if omitted, or pass explicitly: drawBitmap(bitmap, x, y, pageWidth,
|
||
|
|
// pageHeight, 0, 0)
|
||
|
|
renderer.drawBitmap(bitmap, x, y, pageWidth, pageHeight, 0, 0);
|
||
|
|
|
||
|
|
// Draw UI hints on the base layer
|
||
|
|
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||
|
|
// Single pass for non-grayscale images
|
||
|
|
|
||
|
|
renderer.displayBuffer(HalDisplay::FULL_REFRESH);
|
||
|
|
|
||
|
|
} else {
|
||
|
|
// Handle file parsing error
|
||
|
|
renderer.clearScreen();
|
||
|
|
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2, "Invalid BMP File");
|
||
|
|
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
|
||
|
|
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||
|
|
renderer.displayBuffer(HalDisplay::FAST_REFRESH);
|
||
|
|
}
|
||
|
|
|
||
|
|
file.close();
|
||
|
|
} else {
|
||
|
|
// Handle file open error
|
||
|
|
renderer.clearScreen();
|
||
|
|
renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2, "Could not open file");
|
||
|
|
const auto labels = mappedInput.mapLabels(tr(STR_BACK), "", "", "");
|
||
|
|
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||
|
|
renderer.displayBuffer(HalDisplay::FULL_REFRESH);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void BmpViewerActivity::onExit() {
|
||
|
|
Activity::onExit();
|
||
|
|
renderer.clearScreen();
|
||
|
|
renderer.displayBuffer(HalDisplay::FAST_REFRESH);
|
||
|
|
}
|
||
|
|
|
||
|
|
void BmpViewerActivity::loop() {
|
||
|
|
// Keep CPU awake/polling so 1st click works
|
||
|
|
Activity::loop();
|
||
|
|
|
||
|
|
if (mappedInput.wasReleased(MappedInputManager::Button::Back)) {
|
||
|
|
if (onGoBack) onGoBack();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|