mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 14:15:38 +00:00
Merge pull request #102 from jrassa/videoMaxSize
implement maxSize for videos
This commit is contained in:
commit
87098bcb09
|
@ -89,6 +89,7 @@ std::map< std::string, ElementMapType > ThemeData::sElementMap = boost::assign::
|
|||
("video", makeMap(boost::assign::map_list_of
|
||||
("pos", NORMALIZED_PAIR)
|
||||
("size", NORMALIZED_PAIR)
|
||||
("maxSize", NORMALIZED_PAIR)
|
||||
("origin", NORMALIZED_PAIR)
|
||||
("default", PATH)
|
||||
("delay", FLOAT)
|
||||
|
|
|
@ -39,7 +39,10 @@ VideoComponent::VideoComponent(Window* window) :
|
|||
mVideoWidth(0),
|
||||
mStartDelayed(false),
|
||||
mIsPlaying(false),
|
||||
mShowing(false)
|
||||
mShowing(false),
|
||||
mTargetIsMax(false),
|
||||
mOrigin(0, 0),
|
||||
mTargetSize(0, 0)
|
||||
{
|
||||
memset(&mContext, 0, sizeof(mContext));
|
||||
|
||||
|
@ -69,12 +72,89 @@ void VideoComponent::setOrigin(float originX, float originY)
|
|||
mStaticImage.setOrigin(originX, originY);
|
||||
}
|
||||
|
||||
void VideoComponent::setResize(float width, float height)
|
||||
{
|
||||
mTargetSize << width, height;
|
||||
mTargetIsMax = false;
|
||||
mStaticImage.setResize(width, height);
|
||||
resize();
|
||||
}
|
||||
|
||||
void VideoComponent::setMaxSize(float width, float height)
|
||||
{
|
||||
mTargetSize << width, height;
|
||||
mTargetIsMax = true;
|
||||
mStaticImage.setMaxSize(width, height);
|
||||
resize();
|
||||
}
|
||||
|
||||
Eigen::Vector2f VideoComponent::getCenter() const
|
||||
{
|
||||
return Eigen::Vector2f(mPosition.x() - (getSize().x() * mOrigin.x()) + getSize().x() / 2,
|
||||
mPosition.y() - (getSize().y() * mOrigin.y()) + getSize().y() / 2);
|
||||
}
|
||||
|
||||
void VideoComponent::resize()
|
||||
{
|
||||
if(!mTexture)
|
||||
return;
|
||||
|
||||
const Eigen::Vector2f textureSize(mVideoWidth, mVideoHeight);
|
||||
|
||||
if(textureSize.isZero())
|
||||
return;
|
||||
|
||||
// SVG rasterization is determined by height (see SVGResource.cpp), and rasterization is done in terms of pixels
|
||||
// if rounding is off enough in the rasterization step (for images with extreme aspect ratios), it can cause cutoff when the aspect ratio breaks
|
||||
// so, we always make sure the resultant height is an integer to make sure cutoff doesn't happen, and scale width from that
|
||||
// (you'll see this scattered throughout the function)
|
||||
// this is probably not the best way, so if you're familiar with this problem and have a better solution, please make a pull request!
|
||||
|
||||
if(mTargetIsMax)
|
||||
{
|
||||
|
||||
mSize = textureSize;
|
||||
|
||||
Eigen::Vector2f resizeScale((mTargetSize.x() / mSize.x()), (mTargetSize.y() / mSize.y()));
|
||||
|
||||
if(resizeScale.x() < resizeScale.y())
|
||||
{
|
||||
mSize[0] *= resizeScale.x();
|
||||
mSize[1] *= resizeScale.x();
|
||||
}else{
|
||||
mSize[0] *= resizeScale.y();
|
||||
mSize[1] *= resizeScale.y();
|
||||
}
|
||||
|
||||
// for SVG rasterization, always calculate width from rounded height (see comment above)
|
||||
mSize[1] = round(mSize[1]);
|
||||
mSize[0] = (mSize[1] / textureSize.y()) * textureSize.x();
|
||||
|
||||
}else{
|
||||
// if both components are set, we just stretch
|
||||
// if no components are set, we don't resize at all
|
||||
mSize = mTargetSize.isZero() ? textureSize : mTargetSize;
|
||||
|
||||
// if only one component is set, we resize in a way that maintains aspect ratio
|
||||
// for SVG rasterization, we always calculate width from rounded height (see comment above)
|
||||
if(!mTargetSize.x() && mTargetSize.y())
|
||||
{
|
||||
mSize[1] = round(mTargetSize.y());
|
||||
mSize[0] = (mSize.y() / textureSize.y()) * textureSize.x();
|
||||
}else if(mTargetSize.x() && !mTargetSize.y())
|
||||
{
|
||||
mSize[1] = round((mTargetSize.x() / textureSize.x()) * textureSize.y());
|
||||
mSize[0] = (mSize.y() / textureSize.y()) * textureSize.x();
|
||||
}
|
||||
}
|
||||
|
||||
// mSize.y() should already be rounded
|
||||
mTexture->rasterizeAt((int)round(mSize.x()), (int)round(mSize.y()));
|
||||
|
||||
onSizeChanged();
|
||||
}
|
||||
|
||||
|
||||
void VideoComponent::onSizeChanged()
|
||||
{
|
||||
// Update the embeded static image
|
||||
|
@ -111,8 +191,6 @@ void VideoComponent::setImage(std::string path)
|
|||
return;
|
||||
|
||||
mStaticImage.setImage(path);
|
||||
// Make the image stretch to fill the video region
|
||||
mStaticImage.setSize(getSize());
|
||||
mFadeIn = 0.0f;
|
||||
mStaticImagePath = path;
|
||||
}
|
||||
|
@ -243,11 +321,15 @@ void VideoComponent::applyTheme(const std::shared_ptr<ThemeData>& theme, const s
|
|||
{
|
||||
Eigen::Vector2f denormalized = elem->get<Eigen::Vector2f>("pos").cwiseProduct(scale);
|
||||
setPosition(Eigen::Vector3f(denormalized.x(), denormalized.y(), 0));
|
||||
mStaticImage.setPosition(Eigen::Vector3f(denormalized.x(), denormalized.y(), 0));
|
||||
}
|
||||
|
||||
if ((properties & ThemeFlags::SIZE) && elem->has("size"))
|
||||
if(properties & ThemeFlags::SIZE)
|
||||
{
|
||||
setSize(elem->get<Eigen::Vector2f>("size").cwiseProduct(scale));
|
||||
if(elem->has("size"))
|
||||
setResize(elem->get<Eigen::Vector2f>("size").cwiseProduct(scale));
|
||||
else if(elem->has("maxSize"))
|
||||
setMaxSize(elem->get<Eigen::Vector2f>("maxSize").cwiseProduct(scale));
|
||||
}
|
||||
|
||||
// position + size also implies origin
|
||||
|
@ -265,11 +347,6 @@ void VideoComponent::applyTheme(const std::shared_ptr<ThemeData>& theme, const s
|
|||
|
||||
if (elem->has("showSnapshotDelay"))
|
||||
mConfig.showSnapshotDelay = elem->get<bool>("showSnapshotDelay");
|
||||
|
||||
// Update the embeded static image
|
||||
mStaticImage.setPosition(getPosition());
|
||||
mStaticImage.setMaxSize(getSize());
|
||||
mStaticImage.setSize(getSize());
|
||||
}
|
||||
|
||||
std::vector<HelpPrompt> VideoComponent::getHelpPrompts()
|
||||
|
@ -287,6 +364,7 @@ void VideoComponent::setupContext()
|
|||
mContext.surface = SDL_CreateRGBSurface(SDL_SWSURFACE, (int)mVideoWidth, (int)mVideoHeight, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
|
||||
mContext.mutex = SDL_CreateMutex();
|
||||
mContext.valid = true;
|
||||
resize();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,19 @@ public:
|
|||
void onSizeChanged() override;
|
||||
void setOpacity(unsigned char opacity) override;
|
||||
|
||||
// Resize the video to fit this size. If one axis is zero, scale that axis to maintain aspect ratio.
|
||||
// If both are non-zero, potentially break the aspect ratio. If both are zero, no resizing.
|
||||
// Can be set before or after a video is loaded.
|
||||
// setMaxSize() and setResize() are mutually exclusive.
|
||||
void setResize(float width, float height);
|
||||
inline void setResize(const Eigen::Vector2f& size) { setResize(size.x(), size.y()); }
|
||||
|
||||
// Resize the video to be as large as possible but fit within a box of this size.
|
||||
// Can be set before or after a video is loaded.
|
||||
// Never breaks the aspect ratio. setMaxSize() and setResize() are mutually exclusive.
|
||||
void setMaxSize(float width, float height);
|
||||
inline void setMaxSize(const Eigen::Vector2f& size) { setMaxSize(size.x(), size.y()); }
|
||||
|
||||
void render(const Eigen::Affine3f& parentTrans) override;
|
||||
|
||||
virtual void applyTheme(const std::shared_ptr<ThemeData>& theme, const std::string& view, const std::string& element, unsigned int properties) override;
|
||||
|
@ -67,6 +80,10 @@ public:
|
|||
virtual void update(int deltaTime);
|
||||
|
||||
private:
|
||||
// Calculates the correct mSize from our resizing information (set by setResize/setMaxSize).
|
||||
// Used internally whenever the resizing parameters or texture change.
|
||||
void resize();
|
||||
|
||||
// Start the video Immediately
|
||||
void startVideo();
|
||||
// Start the video after any configured delay
|
||||
|
@ -94,6 +111,7 @@ private:
|
|||
unsigned mVideoWidth;
|
||||
unsigned mVideoHeight;
|
||||
Eigen::Vector2f mOrigin;
|
||||
Eigen::Vector2f mTargetSize;
|
||||
std::shared_ptr<TextureResource> mTexture;
|
||||
float mFadeIn;
|
||||
std::string mStaticImagePath;
|
||||
|
@ -105,6 +123,7 @@ private:
|
|||
unsigned mStartTime;
|
||||
bool mIsPlaying;
|
||||
bool mShowing;
|
||||
bool mTargetIsMax;
|
||||
|
||||
Configuration mConfig;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue