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:
Leon Styhre 2023-06-28 20:32:49 +02:00
parent 974ae11461
commit 610da5d771
11 changed files with 340 additions and 41 deletions

View file

@ -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);
}

View file

@ -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

View file

@ -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);
} }

View file

@ -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

View file

@ -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"));

View file

@ -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;

View file

@ -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)

View file

@ -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",

View file

@ -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

View file

@ -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;

View file

@ -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)),