mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-21 21:55:38 +00:00
Added help prompts to the media viewer and PDF viewer
Also added trigger button support to the media viewer and fixed rendering of some PDF files with unusual orientations
This commit is contained in:
parent
974ae11461
commit
610da5d771
|
@ -15,6 +15,8 @@
|
||||||
MediaViewer::MediaViewer()
|
MediaViewer::MediaViewer()
|
||||||
: mRenderer {Renderer::getInstance()}
|
: mRenderer {Renderer::getInstance()}
|
||||||
, mGame {nullptr}
|
, mGame {nullptr}
|
||||||
|
, mFrameHeight {0.0f}
|
||||||
|
, mHelpInfoPosition {HelpInfoPosition::TOP}
|
||||||
{
|
{
|
||||||
Window::getInstance()->setMediaViewer(this);
|
Window::getInstance()->setMediaViewer(this);
|
||||||
}
|
}
|
||||||
|
@ -27,14 +29,53 @@ bool MediaViewer::startMediaViewer(FileData* game)
|
||||||
mScreenshotIndex = -1;
|
mScreenshotIndex = -1;
|
||||||
mTitleScreenIndex = -1;
|
mTitleScreenIndex = -1;
|
||||||
|
|
||||||
|
if (Settings::getInstance()->getString("MediaViewerHelpPrompts") == "disabled")
|
||||||
|
mHelpInfoPosition = HelpInfoPosition::DISABLED;
|
||||||
|
else if (Settings::getInstance()->getString("MediaViewerHelpPrompts") == "bottom")
|
||||||
|
mHelpInfoPosition = HelpInfoPosition::BOTTOM;
|
||||||
|
else
|
||||||
|
mHelpInfoPosition = HelpInfoPosition::TOP;
|
||||||
|
|
||||||
|
if (mHelpInfoPosition == HelpInfoPosition::DISABLED)
|
||||||
|
mFrameHeight = 0.0f;
|
||||||
|
else
|
||||||
|
mFrameHeight = Font::get(FONT_SIZE_SMALL)->getLetterHeight() * 1.8f;
|
||||||
|
|
||||||
mGame = game;
|
mGame = game;
|
||||||
|
mHasManual = (mGame->getManualPath() != "");
|
||||||
|
|
||||||
initiateViewer();
|
initiateViewer();
|
||||||
|
|
||||||
if (mHasVideo || mHasImages)
|
if (!mHasVideo && !mHasImages)
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
HelpStyle style;
|
||||||
|
style.origin = {0.5f, 0.5f};
|
||||||
|
style.iconColor = 0xAAAAAAFF;
|
||||||
|
style.textColor = 0xAAAAAAFF;
|
||||||
|
|
||||||
|
mEntryCount = std::to_string(mImages.size() + (mVideo == nullptr ? 0 : 1));
|
||||||
|
|
||||||
|
mEntryNumText = std::make_unique<TextComponent>(
|
||||||
|
"1/" + mEntryCount, Font::get(FONT_SIZE_MINI, FONT_PATH_REGULAR), 0xAAAAAAFF);
|
||||||
|
mEntryNumText->setOrigin(0.0f, 0.5f);
|
||||||
|
|
||||||
|
if (mHelpInfoPosition == HelpInfoPosition::TOP) {
|
||||||
|
mEntryNumText->setPosition(mRenderer->getScreenWidth() * 0.01f, mFrameHeight / 2.0f);
|
||||||
|
style.position = glm::vec2 {mRenderer->getScreenWidth() / 2.0f, mFrameHeight / 2.0f};
|
||||||
|
}
|
||||||
|
else if (mHelpInfoPosition == HelpInfoPosition::BOTTOM) {
|
||||||
|
mEntryNumText->setPosition(mRenderer->getScreenWidth() * 0.01f,
|
||||||
|
mRenderer->getScreenHeight() - (mFrameHeight / 2.0f));
|
||||||
|
style.position = glm::vec2 {mRenderer->getScreenWidth() / 2.0f,
|
||||||
|
mRenderer->getScreenHeight() - (mFrameHeight / 2.0f)};
|
||||||
|
}
|
||||||
|
|
||||||
|
mHelp = std::make_unique<HelpComponent>();
|
||||||
|
mHelp->setStyle(style);
|
||||||
|
mHelp->setPrompts(getHelpPrompts());
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaViewer::stopMediaViewer()
|
void MediaViewer::stopMediaViewer()
|
||||||
|
@ -50,7 +91,7 @@ void MediaViewer::stopMediaViewer()
|
||||||
|
|
||||||
void MediaViewer::launchPDFViewer()
|
void MediaViewer::launchPDFViewer()
|
||||||
{
|
{
|
||||||
if (mGame->getManualPath() != "") {
|
if (mHasManual) {
|
||||||
Window::getInstance()->stopMediaViewer();
|
Window::getInstance()->stopMediaViewer();
|
||||||
Window::getInstance()->startPDFViewer(mGame);
|
Window::getInstance()->startPDFViewer(mGame);
|
||||||
}
|
}
|
||||||
|
@ -64,7 +105,7 @@ void MediaViewer::update(int deltaTime)
|
||||||
|
|
||||||
void MediaViewer::render(const glm::mat4& /*parentTrans*/)
|
void MediaViewer::render(const glm::mat4& /*parentTrans*/)
|
||||||
{
|
{
|
||||||
glm::mat4 trans {Renderer::getIdentity()};
|
const glm::mat4 trans {mRenderer->getIdentity()};
|
||||||
mRenderer->setMatrix(trans);
|
mRenderer->setMatrix(trans);
|
||||||
|
|
||||||
// Render a black background below the game media.
|
// Render a black background below the game media.
|
||||||
|
@ -118,6 +159,30 @@ void MediaViewer::render(const glm::mat4& /*parentTrans*/)
|
||||||
if (mVideo)
|
if (mVideo)
|
||||||
mVideo->handleLooping();
|
mVideo->handleLooping();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mHelpInfoPosition != HelpInfoPosition::DISABLED) {
|
||||||
|
// Render a dark gray frame behind the help info.
|
||||||
|
mRenderer->setMatrix(mRenderer->getIdentity());
|
||||||
|
mRenderer->drawRect(0.0f,
|
||||||
|
(mHelpInfoPosition == HelpInfoPosition::TOP ?
|
||||||
|
0.0f :
|
||||||
|
Renderer::getScreenHeight() - mFrameHeight),
|
||||||
|
Renderer::getScreenWidth(), mFrameHeight, 0x222222FF, 0x222222FF);
|
||||||
|
mHelp->render(trans);
|
||||||
|
mEntryNumText->render(trans);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<HelpPrompt> MediaViewer::getHelpPrompts()
|
||||||
|
{
|
||||||
|
std::vector<HelpPrompt> prompts;
|
||||||
|
prompts.push_back(HelpPrompt("left/right", "browse"));
|
||||||
|
if (mHasManual)
|
||||||
|
prompts.push_back(HelpPrompt("up", "pdf manual"));
|
||||||
|
prompts.push_back(HelpPrompt("lt", "first"));
|
||||||
|
prompts.push_back(HelpPrompt("rt", "last"));
|
||||||
|
|
||||||
|
return prompts;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaViewer::initiateViewer()
|
void MediaViewer::initiateViewer()
|
||||||
|
@ -180,9 +245,22 @@ void MediaViewer::loadImages()
|
||||||
for (auto& file : mImageFiles) {
|
for (auto& file : mImageFiles) {
|
||||||
mImages.emplace_back(std::make_unique<ImageComponent>(false, false));
|
mImages.emplace_back(std::make_unique<ImageComponent>(false, false));
|
||||||
mImages.back()->setOrigin(0.5f, 0.5f);
|
mImages.back()->setOrigin(0.5f, 0.5f);
|
||||||
mImages.back()->setPosition(Renderer::getScreenWidth() / 2.0f,
|
if (mHelpInfoPosition == HelpInfoPosition::TOP) {
|
||||||
Renderer::getScreenHeight() / 2.0f);
|
mImages.back()->setPosition(Renderer::getScreenWidth() / 2.0f,
|
||||||
mImages.back()->setMaxSize(Renderer::getScreenWidth(), Renderer::getScreenHeight());
|
(Renderer::getScreenHeight() / 2.0f) +
|
||||||
|
(mFrameHeight / 2.0f));
|
||||||
|
}
|
||||||
|
else if (mHelpInfoPosition == HelpInfoPosition::BOTTOM) {
|
||||||
|
mImages.back()->setPosition(Renderer::getScreenWidth() / 2.0f,
|
||||||
|
(Renderer::getScreenHeight() / 2.0f) -
|
||||||
|
(mFrameHeight / 2.0f));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mImages.back()->setPosition(Renderer::getScreenWidth() / 2.0f,
|
||||||
|
Renderer::getScreenHeight() / 2.0f);
|
||||||
|
}
|
||||||
|
mImages.back()->setMaxSize(Renderer::getScreenWidth(),
|
||||||
|
Renderer::getScreenHeight() - mFrameHeight);
|
||||||
mImages.back()->setImage(file);
|
mImages.back()->setImage(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,12 +275,23 @@ void MediaViewer::playVideo()
|
||||||
|
|
||||||
mVideo = std::make_unique<VideoFFmpegComponent>();
|
mVideo = std::make_unique<VideoFFmpegComponent>();
|
||||||
mVideo->setOrigin(0.5f, 0.5f);
|
mVideo->setOrigin(0.5f, 0.5f);
|
||||||
mVideo->setPosition(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f);
|
if (mHelpInfoPosition == HelpInfoPosition::TOP) {
|
||||||
|
mVideo->setPosition(Renderer::getScreenWidth() / 2.0f,
|
||||||
|
(Renderer::getScreenHeight() / 2.0f + (mFrameHeight / 2.0f)));
|
||||||
|
}
|
||||||
|
else if (mHelpInfoPosition == HelpInfoPosition::BOTTOM) {
|
||||||
|
mVideo->setPosition(Renderer::getScreenWidth() / 2.0f,
|
||||||
|
(Renderer::getScreenHeight() / 2.0f - (mFrameHeight / 2.0f)));
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
mVideo->setPosition(Renderer::getScreenWidth() / 2.0f, Renderer::getScreenHeight() / 2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
if (Settings::getInstance()->getBool("MediaViewerStretchVideos"))
|
if (Settings::getInstance()->getBool("MediaViewerStretchVideos"))
|
||||||
mVideo->setResize(Renderer::getScreenWidth(), Renderer::getScreenHeight());
|
mVideo->setResize(Renderer::getScreenWidth(), Renderer::getScreenHeight() - mFrameHeight);
|
||||||
else
|
else
|
||||||
mVideo->setMaxSize(Renderer::getScreenWidth(), Renderer::getScreenHeight());
|
mVideo->setMaxSize(Renderer::getScreenWidth(), Renderer::getScreenHeight() - mFrameHeight);
|
||||||
|
|
||||||
mVideo->setVideo(mVideoFile);
|
mVideo->setVideo(mVideoFile);
|
||||||
mVideo->setMediaViewerMode(true);
|
mVideo->setMediaViewerMode(true);
|
||||||
|
@ -231,6 +320,8 @@ void MediaViewer::showNext()
|
||||||
++mCurrentImageIndex;
|
++mCurrentImageIndex;
|
||||||
|
|
||||||
mDisplayingImage = true;
|
mDisplayingImage = true;
|
||||||
|
mEntryNumText->setText(std::to_string(mCurrentImageIndex + 1 + (mHasVideo ? 1 : 0)) + "/" +
|
||||||
|
mEntryCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaViewer::showPrevious()
|
void MediaViewer::showPrevious()
|
||||||
|
@ -243,9 +334,49 @@ void MediaViewer::showPrevious()
|
||||||
}
|
}
|
||||||
else if (mCurrentImageIndex == 0 && mHasVideo) {
|
else if (mCurrentImageIndex == 0 && mHasVideo) {
|
||||||
mDisplayingImage = false;
|
mDisplayingImage = false;
|
||||||
|
mEntryNumText->setText("1/" + mEntryCount);
|
||||||
playVideo();
|
playVideo();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mEntryNumText->setText(std::to_string(mCurrentImageIndex + (mHasVideo ? 1 : 0)) + "/" +
|
||||||
|
mEntryCount);
|
||||||
--mCurrentImageIndex;
|
--mCurrentImageIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaViewer::showFirst()
|
||||||
|
{
|
||||||
|
if (!mHasImages)
|
||||||
|
return;
|
||||||
|
else if (mCurrentImageIndex == 0 && !mHasVideo)
|
||||||
|
return;
|
||||||
|
else if (mCurrentImageIndex == 0 && !mDisplayingImage)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mCurrentImageIndex = 0;
|
||||||
|
mEntryNumText->setText("1/" + mEntryCount);
|
||||||
|
|
||||||
|
if (mHasVideo) {
|
||||||
|
mDisplayingImage = false;
|
||||||
|
playVideo();
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MediaViewer::showLast()
|
||||||
|
{
|
||||||
|
if (!mHasImages)
|
||||||
|
return;
|
||||||
|
else if (mCurrentImageIndex == static_cast<int>(mImages.size() - 1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
mCurrentImageIndex = static_cast<int>(mImages.size()) - 1;
|
||||||
|
mEntryNumText->setText(mEntryCount + "/" + mEntryCount);
|
||||||
|
mDisplayingImage = true;
|
||||||
|
|
||||||
|
if (mVideo && !Settings::getInstance()->getBool("MediaViewerKeepVideoRunning"))
|
||||||
|
mVideo.reset();
|
||||||
|
|
||||||
|
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
|
|
||||||
#include "FileData.h"
|
#include "FileData.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
#include "components/HelpComponent.h"
|
||||||
#include "components/ImageComponent.h"
|
#include "components/ImageComponent.h"
|
||||||
|
#include "components/TextComponent.h"
|
||||||
#include "components/VideoComponent.h"
|
#include "components/VideoComponent.h"
|
||||||
|
|
||||||
class MediaViewer : public Window::MediaViewer
|
class MediaViewer : public Window::MediaViewer
|
||||||
|
@ -25,6 +27,13 @@ public:
|
||||||
|
|
||||||
void update(int deltaTime) override;
|
void update(int deltaTime) override;
|
||||||
void render(const glm::mat4& parentTrans) override;
|
void render(const glm::mat4& parentTrans) override;
|
||||||
|
std::vector<HelpPrompt> getHelpPrompts() override;
|
||||||
|
|
||||||
|
enum class HelpInfoPosition {
|
||||||
|
TOP,
|
||||||
|
BOTTOM,
|
||||||
|
DISABLED
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initiateViewer();
|
void initiateViewer();
|
||||||
|
@ -35,6 +44,8 @@ private:
|
||||||
|
|
||||||
void showNext() override;
|
void showNext() override;
|
||||||
void showPrevious() override;
|
void showPrevious() override;
|
||||||
|
void showFirst() override;
|
||||||
|
void showLast() override;
|
||||||
|
|
||||||
Renderer* mRenderer;
|
Renderer* mRenderer;
|
||||||
FileData* mGame;
|
FileData* mGame;
|
||||||
|
@ -42,7 +53,9 @@ private:
|
||||||
bool mHasVideo;
|
bool mHasVideo;
|
||||||
bool mHasImages;
|
bool mHasImages;
|
||||||
bool mDisplayingImage;
|
bool mDisplayingImage;
|
||||||
|
bool mHasManual;
|
||||||
|
|
||||||
|
float mFrameHeight;
|
||||||
int mCurrentImageIndex;
|
int mCurrentImageIndex;
|
||||||
int mScreenshotIndex;
|
int mScreenshotIndex;
|
||||||
int mTitleScreenIndex;
|
int mTitleScreenIndex;
|
||||||
|
@ -51,6 +64,11 @@ private:
|
||||||
std::unique_ptr<VideoComponent> mVideo;
|
std::unique_ptr<VideoComponent> mVideo;
|
||||||
std::vector<std::string> mImageFiles;
|
std::vector<std::string> mImageFiles;
|
||||||
std::vector<std::unique_ptr<ImageComponent>> mImages;
|
std::vector<std::unique_ptr<ImageComponent>> mImages;
|
||||||
|
|
||||||
|
std::unique_ptr<HelpComponent> mHelp;
|
||||||
|
std::unique_ptr<TextComponent> mEntryNumText;
|
||||||
|
std::string mEntryCount;
|
||||||
|
HelpInfoPosition mHelpInfoPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ES_APP_MEDIA_VIEWER_H
|
#endif // ES_APP_MEDIA_VIEWER_H
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
PDFViewer::PDFViewer()
|
PDFViewer::PDFViewer()
|
||||||
: mRenderer {Renderer::getInstance()}
|
: mRenderer {Renderer::getInstance()}
|
||||||
, mGame {nullptr}
|
, mGame {nullptr}
|
||||||
|
, mFrameHeight {0.0f}
|
||||||
|
, mHelpInfoPosition {HelpInfoPosition::TOP}
|
||||||
{
|
{
|
||||||
Window::getInstance()->setPDFViewer(this);
|
Window::getInstance()->setPDFViewer(this);
|
||||||
mTexture = TextureResource::get("");
|
mTexture = TextureResource::get("");
|
||||||
|
@ -93,7 +95,7 @@ bool PDFViewer::startPDFViewer(FileData* game)
|
||||||
float width {mPages[i].width};
|
float width {mPages[i].width};
|
||||||
float height {mPages[i].height};
|
float height {mPages[i].height};
|
||||||
|
|
||||||
if (!mPages[i].portraitOrientation)
|
if (mPages[i].orientation != "portrait" && mPages[i].orientation != "upside_down")
|
||||||
std::swap(width, height);
|
std::swap(width, height);
|
||||||
|
|
||||||
// Maintain page aspect ratio.
|
// Maintain page aspect ratio.
|
||||||
|
@ -115,8 +117,7 @@ bool PDFViewer::startPDFViewer(FileData* game)
|
||||||
mPages[i].height = std::round(textureSize.y);
|
mPages[i].height = std::round(textureSize.y);
|
||||||
|
|
||||||
#if (DEBUG_PDF_CONVERSION)
|
#if (DEBUG_PDF_CONVERSION)
|
||||||
LOG(LogDebug) << "Page " << i << ": Orientation: "
|
LOG(LogDebug) << "Page " << i << ": Orientation: " << mPages[i].orientation << " / "
|
||||||
<< (mPages[i].portraitOrientation ? "portrait" : "landscape") << " / "
|
|
||||||
<< "crop box width: " << width << " / "
|
<< "crop box width: " << width << " / "
|
||||||
<< "crop box height: " << height << " / "
|
<< "crop box height: " << height << " / "
|
||||||
<< "size ratio: " << width / height << " / "
|
<< "size ratio: " << width / height << " / "
|
||||||
|
@ -125,6 +126,45 @@ bool PDFViewer::startPDFViewer(FileData* game)
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentPage = 1;
|
mCurrentPage = 1;
|
||||||
|
|
||||||
|
if (Settings::getInstance()->getString("MediaViewerHelpPrompts") == "disabled")
|
||||||
|
mHelpInfoPosition = HelpInfoPosition::DISABLED;
|
||||||
|
else if (Settings::getInstance()->getString("MediaViewerHelpPrompts") == "bottom")
|
||||||
|
mHelpInfoPosition = HelpInfoPosition::BOTTOM;
|
||||||
|
else
|
||||||
|
mHelpInfoPosition = HelpInfoPosition::TOP;
|
||||||
|
|
||||||
|
if (mHelpInfoPosition == HelpInfoPosition::DISABLED)
|
||||||
|
mFrameHeight = 0.0f;
|
||||||
|
else
|
||||||
|
mFrameHeight = Font::get(FONT_SIZE_SMALL)->getLetterHeight() * 1.8f;
|
||||||
|
|
||||||
|
HelpStyle style;
|
||||||
|
style.origin = {0.5f, 0.5f};
|
||||||
|
style.iconColor = 0xAAAAAAFF;
|
||||||
|
style.textColor = 0xAAAAAAFF;
|
||||||
|
|
||||||
|
mEntryCount = std::to_string(mPages.size());
|
||||||
|
|
||||||
|
mEntryNumText = std::make_unique<TextComponent>(
|
||||||
|
"1/" + mEntryCount, Font::get(FONT_SIZE_MINI, FONT_PATH_REGULAR), 0xAAAAAAFF);
|
||||||
|
mEntryNumText->setOrigin(0.0f, 0.5f);
|
||||||
|
|
||||||
|
if (mHelpInfoPosition == HelpInfoPosition::TOP) {
|
||||||
|
mEntryNumText->setPosition(mRenderer->getScreenWidth() * 0.01f, mFrameHeight / 2.0f);
|
||||||
|
style.position = glm::vec2 {mRenderer->getScreenWidth() / 2.0f, mFrameHeight / 2.0f};
|
||||||
|
}
|
||||||
|
else if (mHelpInfoPosition == HelpInfoPosition::BOTTOM) {
|
||||||
|
mEntryNumText->setPosition(mRenderer->getScreenWidth() * 0.01f,
|
||||||
|
mRenderer->getScreenHeight() - (mFrameHeight / 2.0f));
|
||||||
|
style.position = glm::vec2 {mRenderer->getScreenWidth() / 2.0f,
|
||||||
|
mRenderer->getScreenHeight() - (mFrameHeight / 2.0f)};
|
||||||
|
}
|
||||||
|
|
||||||
|
mHelp = std::make_unique<HelpComponent>();
|
||||||
|
mHelp->setStyle(style);
|
||||||
|
mHelp->setPrompts(getHelpPrompts());
|
||||||
|
|
||||||
convertPage(mCurrentPage);
|
convertPage(mCurrentPage);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -251,7 +291,7 @@ bool PDFViewer::getDocumentInfo()
|
||||||
continue;
|
continue;
|
||||||
mPages[atoi(&rowValues[0][0])] = PageEntry {static_cast<float>(atof(&rowValues[2][0])),
|
mPages[atoi(&rowValues[0][0])] = PageEntry {static_cast<float>(atof(&rowValues[2][0])),
|
||||||
static_cast<float>(atof(&rowValues[3][0])),
|
static_cast<float>(atof(&rowValues[3][0])),
|
||||||
(rowValues[1] == "portrait" ? true : false),
|
rowValues[1],
|
||||||
{}};
|
{}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,13 +434,28 @@ void PDFViewer::convertPage(int pageNum)
|
||||||
|
|
||||||
mPageImage.reset();
|
mPageImage.reset();
|
||||||
mPageImage = std::make_unique<ImageComponent>(false, false);
|
mPageImage = std::make_unique<ImageComponent>(false, false);
|
||||||
mPageImage->setOrigin(0.5f, 0.5f);
|
|
||||||
mPageImage->setPosition(mRenderer->getScreenWidth() / 2.0f,
|
|
||||||
mRenderer->getScreenHeight() / 2.0f);
|
|
||||||
|
|
||||||
mPageImage->setFlipY(true);
|
mPageImage->setFlipY(true);
|
||||||
mPageImage->setMaxSize(
|
mPageImage->setOrigin(0.5f, 0.5f);
|
||||||
glm::vec2 {mPages[pageNum].width / mScaleFactor, mPages[pageNum].height / mScaleFactor});
|
if (mHelpInfoPosition == HelpInfoPosition::TOP) {
|
||||||
|
mPageImage->setPosition(mRenderer->getScreenWidth() / 2.0f,
|
||||||
|
(mRenderer->getScreenHeight() / 2.0f) + (mFrameHeight / 2.0f));
|
||||||
|
}
|
||||||
|
else if (mHelpInfoPosition == HelpInfoPosition::BOTTOM) {
|
||||||
|
mPageImage->setPosition(Renderer::getScreenWidth() / 2.0f,
|
||||||
|
(Renderer::getScreenHeight() / 2.0f) - (mFrameHeight / 2.0f));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mPageImage->setPosition(mRenderer->getScreenWidth() / 2.0f,
|
||||||
|
mRenderer->getScreenHeight() / 2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float sizeReduction {0.0f};
|
||||||
|
if (mPages[pageNum].height > mRenderer->getScreenHeight() - mFrameHeight)
|
||||||
|
sizeReduction = mPages[pageNum].height - (mRenderer->getScreenHeight() - mFrameHeight);
|
||||||
|
|
||||||
|
mPageImage->setMaxSize(glm::vec2 {mPages[pageNum].width / mScaleFactor,
|
||||||
|
(mPages[pageNum].height / mScaleFactor) - sizeReduction});
|
||||||
|
|
||||||
mPageImage->setRawImage(reinterpret_cast<const unsigned char*>(&mPages[pageNum].imageData[0]),
|
mPageImage->setRawImage(reinterpret_cast<const unsigned char*>(&mPages[pageNum].imageData[0]),
|
||||||
static_cast<size_t>(mPages[pageNum].width),
|
static_cast<size_t>(mPages[pageNum].width),
|
||||||
static_cast<size_t>(mPages[pageNum].height));
|
static_cast<size_t>(mPages[pageNum].height));
|
||||||
|
@ -415,15 +470,37 @@ void PDFViewer::render(const glm::mat4& /*parentTrans*/)
|
||||||
glm::mat4 trans {Renderer::getIdentity()};
|
glm::mat4 trans {Renderer::getIdentity()};
|
||||||
mRenderer->setMatrix(trans);
|
mRenderer->setMatrix(trans);
|
||||||
|
|
||||||
// Render a black background below the document.
|
// Render a black background below the game media.
|
||||||
mRenderer->drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
mRenderer->drawRect(0.0f, 0.0f, Renderer::getScreenWidth(), Renderer::getScreenHeight(),
|
||||||
0x000000FF, 0x000000FF);
|
0x000000FF, 0x000000FF);
|
||||||
|
|
||||||
if (mPageImage != nullptr) {
|
if (mPageImage != nullptr)
|
||||||
mPageImage->render(trans);
|
mPageImage->render(trans);
|
||||||
|
|
||||||
|
if (mHelpInfoPosition != HelpInfoPosition::DISABLED) {
|
||||||
|
// Render a dark gray frame behind the help info.
|
||||||
|
mRenderer->setMatrix(mRenderer->getIdentity());
|
||||||
|
mRenderer->drawRect(0.0f,
|
||||||
|
(mHelpInfoPosition == HelpInfoPosition::TOP ?
|
||||||
|
0.0f :
|
||||||
|
Renderer::getScreenHeight() - mFrameHeight),
|
||||||
|
Renderer::getScreenWidth(), mFrameHeight, 0x222222FF, 0x222222FF);
|
||||||
|
mHelp->render(trans);
|
||||||
|
mEntryNumText->render(trans);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<HelpPrompt> PDFViewer::getHelpPrompts()
|
||||||
|
{
|
||||||
|
std::vector<HelpPrompt> prompts;
|
||||||
|
prompts.push_back(HelpPrompt("left/right", "browse"));
|
||||||
|
prompts.push_back(HelpPrompt("down", "game media"));
|
||||||
|
prompts.push_back(HelpPrompt("lt", "first"));
|
||||||
|
prompts.push_back(HelpPrompt("rt", "last"));
|
||||||
|
|
||||||
|
return prompts;
|
||||||
|
}
|
||||||
|
|
||||||
void PDFViewer::showNextPage()
|
void PDFViewer::showNextPage()
|
||||||
{
|
{
|
||||||
if (mCurrentPage == mPageCount)
|
if (mCurrentPage == mPageCount)
|
||||||
|
@ -431,6 +508,7 @@ void PDFViewer::showNextPage()
|
||||||
|
|
||||||
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
||||||
++mCurrentPage;
|
++mCurrentPage;
|
||||||
|
mEntryNumText->setText(std::to_string(mCurrentPage) + "/" + mEntryCount);
|
||||||
convertPage(mCurrentPage);
|
convertPage(mCurrentPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,6 +519,7 @@ void PDFViewer::showPreviousPage()
|
||||||
|
|
||||||
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
||||||
--mCurrentPage;
|
--mCurrentPage;
|
||||||
|
mEntryNumText->setText(std::to_string(mCurrentPage) + "/" + mEntryCount);
|
||||||
convertPage(mCurrentPage);
|
convertPage(mCurrentPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,6 +530,7 @@ void PDFViewer::showFirstPage()
|
||||||
|
|
||||||
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
||||||
mCurrentPage = 1;
|
mCurrentPage = 1;
|
||||||
|
mEntryNumText->setText(std::to_string(mCurrentPage) + "/" + mEntryCount);
|
||||||
convertPage(mCurrentPage);
|
convertPage(mCurrentPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,5 +541,6 @@ void PDFViewer::showLastPage()
|
||||||
|
|
||||||
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
NavigationSounds::getInstance().playThemeNavigationSound(SCROLLSOUND);
|
||||||
mCurrentPage = mPageCount;
|
mCurrentPage = mPageCount;
|
||||||
|
mEntryNumText->setText(std::to_string(mCurrentPage) + "/" + mEntryCount);
|
||||||
convertPage(mCurrentPage);
|
convertPage(mCurrentPage);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
|
|
||||||
#include "FileData.h"
|
#include "FileData.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
#include "components/HelpComponent.h"
|
||||||
#include "components/ImageComponent.h"
|
#include "components/ImageComponent.h"
|
||||||
|
#include "components/TextComponent.h"
|
||||||
|
|
||||||
class PDFViewer : public Window::PDFViewer
|
class PDFViewer : public Window::PDFViewer
|
||||||
{
|
{
|
||||||
|
@ -26,6 +28,13 @@ public:
|
||||||
void convertPage(int pageNum);
|
void convertPage(int pageNum);
|
||||||
|
|
||||||
void render(const glm::mat4& parentTrans) override;
|
void render(const glm::mat4& parentTrans) override;
|
||||||
|
std::vector<HelpPrompt> getHelpPrompts() override;
|
||||||
|
|
||||||
|
enum class HelpInfoPosition {
|
||||||
|
TOP,
|
||||||
|
BOTTOM,
|
||||||
|
DISABLED
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void showNextPage() override;
|
void showNextPage() override;
|
||||||
|
@ -36,22 +45,29 @@ private:
|
||||||
struct PageEntry {
|
struct PageEntry {
|
||||||
float width;
|
float width;
|
||||||
float height;
|
float height;
|
||||||
bool portraitOrientation;
|
std::string orientation;
|
||||||
std::vector<char> imageData;
|
std::vector<char> imageData;
|
||||||
};
|
};
|
||||||
|
|
||||||
Renderer* mRenderer;
|
Renderer* mRenderer;
|
||||||
std::shared_ptr<TextureResource> mTexture;
|
|
||||||
std::unique_ptr<ImageComponent> mPageImage;
|
|
||||||
std::map<int, PageEntry> mPages;
|
|
||||||
FileData* mGame;
|
FileData* mGame;
|
||||||
|
|
||||||
|
float mFrameHeight;
|
||||||
|
float mScaleFactor;
|
||||||
|
int mCurrentPage;
|
||||||
|
int mPageCount;
|
||||||
|
|
||||||
std::string mESConvertPath;
|
std::string mESConvertPath;
|
||||||
std::string mManualPath;
|
std::string mManualPath;
|
||||||
|
|
||||||
float mScaleFactor;
|
std::shared_ptr<TextureResource> mTexture;
|
||||||
int mCurrentPage;
|
std::unique_ptr<ImageComponent> mPageImage;
|
||||||
int mPageCount;
|
std::map<int, PageEntry> mPages;
|
||||||
|
|
||||||
|
std::unique_ptr<HelpComponent> mHelp;
|
||||||
|
std::unique_ptr<TextComponent> mEntryNumText;
|
||||||
|
std::string mEntryCount;
|
||||||
|
HelpInfoPosition mHelpInfoPosition;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ES_APP_PDF_VIEWER_H
|
#endif // ES_APP_PDF_VIEWER_H
|
||||||
|
|
|
@ -10,11 +10,34 @@
|
||||||
#include "guis/GuiMediaViewerOptions.h"
|
#include "guis/GuiMediaViewerOptions.h"
|
||||||
|
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
#include "components/OptionListComponent.h"
|
||||||
#include "components/SwitchComponent.h"
|
#include "components/SwitchComponent.h"
|
||||||
|
|
||||||
GuiMediaViewerOptions::GuiMediaViewerOptions(const std::string& title)
|
GuiMediaViewerOptions::GuiMediaViewerOptions(const std::string& title)
|
||||||
: GuiSettings {title}
|
: GuiSettings {title}
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Help prompts.
|
||||||
|
auto mediaViewerHelpPrompts =
|
||||||
|
std::make_shared<OptionListComponent<std::string>>(getHelpStyle(), "HELP PROMPTS", false);
|
||||||
|
std::string selectedHelpPrompts {Settings::getInstance()->getString("MediaViewerHelpPrompts")};
|
||||||
|
mediaViewerHelpPrompts->add("TOP", "top", selectedHelpPrompts == "top");
|
||||||
|
mediaViewerHelpPrompts->add("BOTTOM", "bottom", selectedHelpPrompts == "bottom");
|
||||||
|
mediaViewerHelpPrompts->add("DISABLED", "disabled", selectedHelpPrompts == "disabled");
|
||||||
|
// If there are no objects returned, then there must be a manually modified entry in the
|
||||||
|
// configuration file. Simply set the help prompts to "top" in this case.
|
||||||
|
if (mediaViewerHelpPrompts->getSelectedObjects().size() == 0)
|
||||||
|
mediaViewerHelpPrompts->selectEntry(0);
|
||||||
|
addWithLabel("HELP PROMPTS", mediaViewerHelpPrompts);
|
||||||
|
addSaveFunc([mediaViewerHelpPrompts, this] {
|
||||||
|
if (mediaViewerHelpPrompts->getSelected() !=
|
||||||
|
Settings::getInstance()->getString("MediaViewerHelpPrompts")) {
|
||||||
|
Settings::getInstance()->setString("MediaViewerHelpPrompts",
|
||||||
|
mediaViewerHelpPrompts->getSelected());
|
||||||
|
setNeedsSaving();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Keep videos running when viewing images.
|
// Keep videos running when viewing images.
|
||||||
auto keepVideoRunning = std::make_shared<SwitchComponent>();
|
auto keepVideoRunning = std::make_shared<SwitchComponent>();
|
||||||
keepVideoRunning->setState(Settings::getInstance()->getBool("MediaViewerKeepVideoRunning"));
|
keepVideoRunning->setState(Settings::getInstance()->getBool("MediaViewerKeepVideoRunning"));
|
||||||
|
|
|
@ -40,6 +40,8 @@ struct HelpStyle {
|
||||||
struct CustomButtonIcons {
|
struct CustomButtonIcons {
|
||||||
// Generic
|
// Generic
|
||||||
std::string dpad_updown;
|
std::string dpad_updown;
|
||||||
|
std::string dpad_up;
|
||||||
|
std::string dpad_down;
|
||||||
std::string dpad_leftright;
|
std::string dpad_leftright;
|
||||||
std::string dpad_all;
|
std::string dpad_all;
|
||||||
std::string thumbstick_click;
|
std::string thumbstick_click;
|
||||||
|
|
|
@ -168,6 +168,7 @@ void Settings::setDefaults()
|
||||||
mStringMap["RandomEntryButton"] = {"games", "games"};
|
mStringMap["RandomEntryButton"] = {"games", "games"};
|
||||||
|
|
||||||
// UI settings -> media viewer settings.
|
// UI settings -> media viewer settings.
|
||||||
|
mStringMap["MediaViewerHelpPrompts"] = {"top", "top"};
|
||||||
mBoolMap["MediaViewerKeepVideoRunning"] = {true, true};
|
mBoolMap["MediaViewerKeepVideoRunning"] = {true, true};
|
||||||
mBoolMap["MediaViewerStretchVideos"] = {false, false};
|
mBoolMap["MediaViewerStretchVideos"] = {false, false};
|
||||||
#if defined(RASPBERRY_PI)
|
#if defined(RASPBERRY_PI)
|
||||||
|
|
|
@ -228,11 +228,17 @@ void Window::input(InputConfig* config, Input input)
|
||||||
mMediaViewer->launchPDFViewer();
|
mMediaViewer->launchPDFViewer();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (config->isMappedLike("left", input) && input.value != 0) {
|
||||||
|
mMediaViewer->showPrevious();
|
||||||
|
}
|
||||||
else if (config->isMappedLike("right", input) && input.value != 0) {
|
else if (config->isMappedLike("right", input) && input.value != 0) {
|
||||||
mMediaViewer->showNext();
|
mMediaViewer->showNext();
|
||||||
}
|
}
|
||||||
else if (config->isMappedLike("left", input) && input.value != 0) {
|
else if (config->isMappedLike("lefttrigger", input) && input.value != 0) {
|
||||||
mMediaViewer->showPrevious();
|
mMediaViewer->showFirst();
|
||||||
|
}
|
||||||
|
else if (config->isMappedLike("righttrigger", input) && input.value != 0) {
|
||||||
|
mMediaViewer->showLast();
|
||||||
}
|
}
|
||||||
else if (input.value != 0) {
|
else if (input.value != 0) {
|
||||||
// Any other input stops the media viewer.
|
// Any other input stops the media viewer.
|
||||||
|
@ -249,18 +255,18 @@ void Window::input(InputConfig* config, Input input)
|
||||||
mPDFViewer->launchMediaViewer();
|
mPDFViewer->launchMediaViewer();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (config->isMappedLike("right", input) && input.value != 0) {
|
|
||||||
mPDFViewer->showNextPage();
|
|
||||||
}
|
|
||||||
else if (config->isMappedLike("left", input) && input.value != 0) {
|
else if (config->isMappedLike("left", input) && input.value != 0) {
|
||||||
mPDFViewer->showPreviousPage();
|
mPDFViewer->showPreviousPage();
|
||||||
}
|
}
|
||||||
else if (config->isMappedLike("righttrigger", input) && input.value != 0) {
|
else if (config->isMappedLike("right", input) && input.value != 0) {
|
||||||
mPDFViewer->showLastPage();
|
mPDFViewer->showNextPage();
|
||||||
}
|
}
|
||||||
else if (config->isMappedLike("lefttrigger", input) && input.value != 0) {
|
else if (config->isMappedLike("lefttrigger", input) && input.value != 0) {
|
||||||
mPDFViewer->showFirstPage();
|
mPDFViewer->showFirstPage();
|
||||||
}
|
}
|
||||||
|
else if (config->isMappedLike("righttrigger", input) && input.value != 0) {
|
||||||
|
mPDFViewer->showLastPage();
|
||||||
|
}
|
||||||
else if (input.value != 0) {
|
else if (input.value != 0) {
|
||||||
// Any other input stops the PDF viewer.
|
// Any other input stops the PDF viewer.
|
||||||
stopPDFViewer();
|
stopPDFViewer();
|
||||||
|
@ -806,6 +812,8 @@ void Window::setHelpPrompts(const std::vector<HelpPrompt>& prompts, const HelpSt
|
||||||
[](const HelpPrompt& a, const HelpPrompt& b) -> bool {
|
[](const HelpPrompt& a, const HelpPrompt& b) -> bool {
|
||||||
static const std::vector<std::string> map {"up/down/left/right",
|
static const std::vector<std::string> map {"up/down/left/right",
|
||||||
"up/down",
|
"up/down",
|
||||||
|
"up",
|
||||||
|
"down",
|
||||||
"left/right",
|
"left/right",
|
||||||
"rt",
|
"rt",
|
||||||
"lt",
|
"lt",
|
||||||
|
|
|
@ -60,9 +60,12 @@ public:
|
||||||
|
|
||||||
virtual void showNext() = 0;
|
virtual void showNext() = 0;
|
||||||
virtual void showPrevious() = 0;
|
virtual void showPrevious() = 0;
|
||||||
|
virtual void showFirst() = 0;
|
||||||
|
virtual void showLast() = 0;
|
||||||
|
|
||||||
virtual void update(int deltaTime) = 0;
|
virtual void update(int deltaTime) = 0;
|
||||||
virtual void render(const glm::mat4& parentTrans) = 0;
|
virtual void render(const glm::mat4& parentTrans) = 0;
|
||||||
|
virtual std::vector<HelpPrompt> getHelpPrompts() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PDFViewer
|
class PDFViewer
|
||||||
|
@ -78,6 +81,7 @@ public:
|
||||||
virtual void showLastPage() = 0;
|
virtual void showLastPage() = 0;
|
||||||
|
|
||||||
virtual void render(const glm::mat4& parentTrans) = 0;
|
virtual void render(const glm::mat4& parentTrans) = 0;
|
||||||
|
virtual std::vector<HelpPrompt> getHelpPrompts() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GuiLaunchScreen
|
class GuiLaunchScreen
|
||||||
|
|
|
@ -37,6 +37,11 @@ void HelpComponent::assignIcons()
|
||||||
sIconPathMap["up/down"] = mStyle.mCustomButtons.dpad_updown.empty() ?
|
sIconPathMap["up/down"] = mStyle.mCustomButtons.dpad_updown.empty() ?
|
||||||
":/graphics/help/dpad_updown.svg" :
|
":/graphics/help/dpad_updown.svg" :
|
||||||
mStyle.mCustomButtons.dpad_updown;
|
mStyle.mCustomButtons.dpad_updown;
|
||||||
|
sIconPathMap["up"] = mStyle.mCustomButtons.dpad_up.empty() ? ":/graphics/help/dpad_up.svg" :
|
||||||
|
mStyle.mCustomButtons.dpad_up;
|
||||||
|
sIconPathMap["down"] = mStyle.mCustomButtons.dpad_down.empty() ?
|
||||||
|
":/graphics/help/dpad_down.svg" :
|
||||||
|
mStyle.mCustomButtons.dpad_down;
|
||||||
sIconPathMap["left/right"] = mStyle.mCustomButtons.dpad_leftright.empty() ?
|
sIconPathMap["left/right"] = mStyle.mCustomButtons.dpad_leftright.empty() ?
|
||||||
":/graphics/help/dpad_leftright.svg" :
|
":/graphics/help/dpad_leftright.svg" :
|
||||||
mStyle.mCustomButtons.dpad_leftright;
|
mStyle.mCustomButtons.dpad_leftright;
|
||||||
|
|
|
@ -159,10 +159,20 @@ int main(int argc, char* argv[])
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::string orientation;
|
||||||
|
if (page->orientation() == poppler::page::portrait)
|
||||||
|
orientation = "portrait";
|
||||||
|
else if (page->orientation() == poppler::page::upside_down)
|
||||||
|
orientation = "upside_down";
|
||||||
|
else if (page->orientation() == poppler::page::seascape)
|
||||||
|
orientation = "seascape";
|
||||||
|
else
|
||||||
|
orientation = "landscape";
|
||||||
|
|
||||||
const poppler::rectf pageRect {page->page_rect()};
|
const poppler::rectf pageRect {page->page_rect()};
|
||||||
pageRow.append(std::to_string(i + 1))
|
pageRow.append(std::to_string(i + 1))
|
||||||
.append(";")
|
.append(";")
|
||||||
.append(page->orientation() == poppler::page::portrait ? "portrait" : "landscape")
|
.append(orientation)
|
||||||
.append(";")
|
.append(";")
|
||||||
.append(std::to_string(pageRect.width()))
|
.append(std::to_string(pageRect.width()))
|
||||||
.append(";")
|
.append(";")
|
||||||
|
@ -194,10 +204,10 @@ int main(int argc, char* argv[])
|
||||||
// pageRenderer.set_render_hint(poppler::page_renderer::text_hinting);
|
// pageRenderer.set_render_hint(poppler::page_renderer::text_hinting);
|
||||||
|
|
||||||
const poppler::rectf pageRect {page->page_rect()};
|
const poppler::rectf pageRect {page->page_rect()};
|
||||||
const bool portraitOrientation {page->orientation() == poppler::page::portrait};
|
const bool rotate {page->orientation() == poppler::page::portrait ||
|
||||||
|
page->orientation() == poppler::page::upside_down};
|
||||||
const double pageHeight {pageRect.height()};
|
const double pageHeight {pageRect.height()};
|
||||||
const double sizeFactor {static_cast<double>(portraitOrientation ? height : width) /
|
const double sizeFactor {static_cast<double>(rotate ? height : width) / pageHeight};
|
||||||
pageHeight};
|
|
||||||
|
|
||||||
poppler::image image {pageRenderer.render_page(
|
poppler::image image {pageRenderer.render_page(
|
||||||
page, static_cast<int>(std::round(72.0 * sizeFactor)),
|
page, static_cast<int>(std::round(72.0 * sizeFactor)),
|
||||||
|
|
Loading…
Reference in a new issue