UI: Better way of showing game/savedata images. Fixes #12408

This commit is contained in:
Henrik Rydgård 2019-10-11 17:34:38 +02:00
parent 0b17dd04e6
commit 1f742fd07a
7 changed files with 61 additions and 63 deletions

View File

@ -18,11 +18,8 @@
#include <algorithm>
#include "ppsspp_config.h"
#include "base/colorutil.h"
#include "base/timeutil.h"
#include "gfx_es2/draw_buffer.h"
#include "i18n/i18n.h"
#include "math/curves.h"
#include "util/text/utf8.h"
#include "ui/ui_context.h"
#include "ui/view.h"
@ -71,7 +68,7 @@ void GameScreen::CreateViews() {
leftColumn->Add(new Choice(di->T("Back"), "", false, new AnchorLayoutParams(150, WRAP_CONTENT, 10, NONE, NONE, 10)))->OnClick.Handle(this, &GameScreen::OnSwitchBack);
if (info) {
texvGameIcon_ = leftColumn->Add(new TextureView(0, IS_DEFAULT, new AnchorLayoutParams(144 * 2, 80 * 2, 10, 10, NONE, NONE)));
leftColumn->Add(new GameIconView(gamePath_, new AnchorLayoutParams(144 * 2, 80 * 2, 10, 10, NONE, NONE)));
LinearLayout *infoLayout = new LinearLayout(ORIENT_VERTICAL, new AnchorLayoutParams(10, 200, NONE, NONE));
leftColumn->Add(infoLayout);
@ -91,7 +88,6 @@ void GameScreen::CreateViews() {
tvRegion_ = infoLayout->Add(new TextView("", ALIGN_LEFT, true, new LinearLayoutParams(FILL_PARENT, WRAP_CONTENT)));
tvRegion_->SetShadow(true);
} else {
texvGameIcon_ = nullptr;
tvTitle_ = nullptr;
tvGameSize_ = nullptr;
tvSaveDataSize_ = nullptr;
@ -198,20 +194,8 @@ void GameScreen::render() {
std::shared_ptr<GameInfo> info = g_gameInfoCache->GetInfo(thin3d, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
if (tvTitle_)
if (tvTitle_) {
tvTitle_->SetText(info->GetTitle() + " (" + info->id + ")");
if (info->icon.texture && texvGameIcon_) {
texvGameIcon_->SetTexture(info->icon.texture->GetTexture());
// Fade the icon with the background.
double loadTime = info->icon.timeLoaded;
if (info->pic1.texture) {
loadTime = std::max(loadTime, info->pic1.timeLoaded);
}
if (info->pic0.texture) {
loadTime = std::max(loadTime, info->pic0.timeLoaded);
}
uint32_t color = whiteAlpha(ease((time_now_d() - loadTime) * 3));
texvGameIcon_->SetColor(color);
}
if (info->gameSize) {
@ -252,6 +236,7 @@ void GameScreen::render() {
btnSetBackground_->SetVisibility(UI::V_VISIBLE);
}
}
if (!info->pending) {
// At this point, the above buttons won't become visible. We can show these now.
for (UI::Choice *choice : otherChoices_) {

View File

@ -62,7 +62,6 @@ private:
UI::EventReturn OnSetBackground(UI::EventParams &e);
// As we load metadata in the background, we need to be able to update these after the fact.
UI::TextureView *texvGameIcon_;
UI::TextView *tvTitle_;
UI::TextView *tvGameSize_;
UI::TextView *tvSaveDataSize_;

View File

@ -86,7 +86,7 @@ public:
std::string savedata_title = ginfo->paramSFO.GetValueString("SAVEDATA_TITLE");
if (ginfo->icon.texture) {
toprow->Add(new TextureView(ginfo->icon.texture->GetTexture(), IS_FIXED, new LinearLayoutParams(Margins(10, 5))));
toprow->Add(new GameIconView(savePath_, new LinearLayoutParams(Margins(10, 5))));
}
LinearLayout *topright = new LinearLayout(ORIENT_VERTICAL, new LinearLayoutParams(WRAP_CONTENT, WRAP_CONTENT, 1.0f));
topright->SetSpacing(1.0f);

View File

@ -1,13 +1,20 @@
#include <algorithm>
#include "base/colorutil.h"
#include "base/timeutil.h"
#include "thin3d/thin3d.h"
#include "image/zim_load.h"
#include "image/png_load.h"
#include "math/math_util.h"
#include "math/curves.h"
#include "file/vfs.h"
#include "ext/jpge/jpgd.h"
#include "UI/TextureUtil.h"
#include "ui/view.h"
#include "ui/ui_context.h"
#include "gfx_es2/draw_buffer.h"
#include "Common/Log.h"
#include "UI/TextureUtil.h"
#include "UI/GameInfoCache.h"
static Draw::DataFormat ZimToT3DFormat(int zim) {
switch (zim) {
@ -209,3 +216,36 @@ std::unique_ptr<ManagedTexture> CreateTextureFromFileData(Draw::DrawContext *dra
return std::unique_ptr<ManagedTexture>();
}
}
void GameIconView::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
w = textureWidth_;
h = textureHeight_;
}
void GameIconView::Draw(UIContext &dc) {
using namespace UI;
std::shared_ptr<GameInfo> info = g_gameInfoCache->GetInfo(NULL, gamePath_, GAMEINFO_WANTBG | GAMEINFO_WANTSIZE);
if (!info->icon.texture) {
return;
}
textureWidth_ = info->icon.texture->Width();
textureHeight_ = info->icon.texture->Height();
// Fade icon with the backgrounds.
double loadTime = info->icon.timeLoaded;
if (info->pic1.texture) {
loadTime = std::max(loadTime, info->pic1.timeLoaded);
}
if (info->pic0.texture) {
loadTime = std::max(loadTime, info->pic0.timeLoaded);
}
uint32_t color = whiteAlpha(ease((time_now_d() - loadTime) * 3));
dc.Flush();
dc.GetDrawContext()->BindTexture(0, info->icon.texture->GetTexture());
dc.Draw()->Rect(bounds_.x, bounds_.y, bounds_.w, bounds_.h, color);
dc.Flush();
dc.RebindTexture();
}

View File

@ -3,6 +3,7 @@
#include <memory>
#include "thin3d/thin3d.h"
#include "ui/view.h"
enum ImageFileType {
PNG,
@ -39,4 +40,18 @@ private:
};
std::unique_ptr<ManagedTexture> CreateTextureFromFile(Draw::DrawContext *draw, const char *filename, ImageFileType fileType, bool generateMips = false);
std::unique_ptr<ManagedTexture> CreateTextureFromFileData(Draw::DrawContext *draw, const uint8_t *data, int size, ImageFileType fileType, bool generateMips = false);
std::unique_ptr<ManagedTexture> CreateTextureFromFileData(Draw::DrawContext *draw, const uint8_t *data, int size, ImageFileType fileType, bool generateMips = false);
class GameIconView : public UI::InertView {
public:
GameIconView(std::string gamePath, UI::LayoutParams *layoutParams = 0)
: InertView(layoutParams), gamePath_(gamePath) {}
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
void Draw(UIContext &dc) override;
private:
std::string gamePath_;
int textureWidth_ = 0;
int textureHeight_ = 0;
};

View File

@ -824,28 +824,6 @@ void ImageView::Draw(UIContext &dc) {
dc.Draw()->DrawImage(atlasImage_, bounds_.x, bounds_.y, scale, 0xFFFFFFFF, ALIGN_TOPLEFT);
}
void TextureView::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
// TODO: involve sizemode
if (texture_) {
w = (float)texture_->Width();
h = (float)texture_->Height();
} else {
w = 16;
h = 16;
}
}
void TextureView::Draw(UIContext &dc) {
// TODO: involve sizemode
if (texture_) {
dc.Flush();
dc.GetDrawContext()->BindTexture(0, texture_);
dc.Draw()->Rect(bounds_.x, bounds_.y, bounds_.w, bounds_.h, color_);
dc.Flush();
dc.RebindTexture();
}
}
void TextView::GetContentDimensionsBySpec(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert, float &w, float &h) const {
Bounds bounds(0, 0, layoutParams_->width, layoutParams_->height);
if (bounds.w < 0) {

View File

@ -864,25 +864,6 @@ private:
ImageSizeMode sizeMode_;
};
// TextureView takes a texture that is assumed to be alive during the lifetime
// of the view.
class TextureView : public InertView {
public:
TextureView(Draw::Texture *texture, ImageSizeMode sizeMode, LayoutParams *layoutParams = 0)
: InertView(layoutParams), texture_(texture), color_(0xFFFFFFFF), sizeMode_(sizeMode) {}
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
void Draw(UIContext &dc) override;
void SetTexture(Draw::Texture *texture) { texture_ = texture; }
void SetColor(uint32_t color) { color_ = color; }
private:
Draw::Texture *texture_;
uint32_t color_;
ImageSizeMode sizeMode_;
};
class ProgressBar : public InertView {
public:
ProgressBar(LayoutParams *layoutParams = 0)