aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-08-07 23:46:24 +0200
committerdec05eba <dec05eba@protonmail.com>2019-08-07 23:46:27 +0200
commite745c2239b8bcd30e75af27de5067dbcb1707ac1 (patch)
treeaa15d0452b8d26fd255880defb056c4bb13add52
parent852c6bc48b7044c54923b722ab5d9363a27ceb6c (diff)
Correctly scale images and video to window size
-rw-r--r--README.md3
-rw-r--r--include/Scale.hpp9
-rw-r--r--include/VideoPlayer.hpp11
-rw-r--r--src/QuickMedia.cpp52
-rw-r--r--src/Scale.cpp38
-rw-r--r--src/SearchBar.cpp1
-rw-r--r--src/VideoPlayer.cpp60
7 files changed, 100 insertions, 74 deletions
diff --git a/README.md b/README.md
index af4fe69..d95d51b 100644
--- a/README.md
+++ b/README.md
@@ -21,4 +21,5 @@ Disable ytdl_hook subtitles. If a video has subtitles for many languages, then i
until all subtitles have been downloaded and loaded.
Figure out why memory usage doesn't drop much when killing the video player. Is it a bug in proprietary nvidia drivers on gnu/linux?
Add grid-view when thumbnails are visible.
-Add scrollbar. \ No newline at end of file
+Add scrollbar.
+Add option to scale image to window size. \ No newline at end of file
diff --git a/include/Scale.hpp b/include/Scale.hpp
new file mode 100644
index 0000000..4ab2882
--- /dev/null
+++ b/include/Scale.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <SFML/System/Vector2.hpp>
+
+namespace QuickMedia {
+ sf::Vector2f wrap_to_size(const sf::Vector2f &size, const sf::Vector2f &clamp_size);
+ sf::Vector2f clamp_to_size(const sf::Vector2f &size, const sf::Vector2f &clamp_size);
+ sf::Vector2f get_ratio(const sf::Vector2f &original_size, const sf::Vector2f &new_size);
+} \ No newline at end of file
diff --git a/include/VideoPlayer.hpp b/include/VideoPlayer.hpp
index 6bd8f4f..0ae05b0 100644
--- a/include/VideoPlayer.hpp
+++ b/include/VideoPlayer.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <SFML/Graphics/RenderWindow.hpp>
+#include <SFML/Window/Event.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
@@ -25,11 +26,12 @@ namespace QuickMedia {
class VideoPlayer {
public:
// Throws VideoInitializationException on error
- VideoPlayer(unsigned int width, unsigned int height, sf::WindowHandle window_handle, const char *file, bool loop = false);
+ VideoPlayer(sf::RenderWindow &window, unsigned int width, unsigned int height, const char *file, bool loop = false);
~VideoPlayer();
+ void handleEvent(sf::Event &event);
void setPosition(float x, float y);
- void resize(const sf::Vector2i &size);
+ void resize(const sf::Vector2f &size);
void draw(sf::RenderWindow &window);
// @path can also be an url if youtube-dl is installed
@@ -40,7 +42,7 @@ namespace QuickMedia {
std::atomic_bool event_update;
PlaybackEndedCallback onPlaybackEndedCallback;
private:
- void handle_events();
+ void handle_mpv_events();
private:
mpv_handle *mpv;
mpv_render_context *mpvGl;
@@ -49,8 +51,9 @@ namespace QuickMedia {
sf::Texture texture;
sf::Uint8 *textureBuffer;
sf::Vector2i video_size;
- sf::Vector2i desired_size;
+ sf::Vector2f desired_size;
sf::RectangleShape seekbar;
sf::RectangleShape seekbar_background;
+ sf::Clock cursor_last_active_timer;
};
}
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 1a88776..a219413 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -2,6 +2,7 @@
#include "../plugins/Manganelo.hpp"
#include "../plugins/Youtube.hpp"
#include "../include/VideoPlayer.hpp"
+#include "../include/Scale.hpp"
#include "../include/Program.h"
#include <cppcodec/base64_rfc4648.hpp>
@@ -292,7 +293,7 @@ namespace QuickMedia {
std::unique_ptr<VideoPlayer> video_player = nullptr;
try {
printf("Play video: %s\n", video_url.c_str());
- video_player.reset(new VideoPlayer(window_size.x, window_size.y, window.getSystemHandle(), video_url.c_str()));
+ video_player.reset(new VideoPlayer(window, window_size.x, window_size.y, video_url.c_str()));
} catch(VideoInitializationException &e) {
fprintf(stderr, "Failed to create video player!. TODO: Show this to the user");
video_player = nullptr;
@@ -331,9 +332,10 @@ namespace QuickMedia {
while (current_page == Page::VIDEO_CONTENT && !reload) {
while (window.pollEvent(event)) {
base_event_handler(event, Page::SEARCH_SUGGESTION);
- if(event.type == sf::Event::Resized) {
- if(video_player)
- video_player->resize(sf::Vector2i(window_size.x, window_size.y));
+ if(video_player) {
+ if(event.type == sf::Event::Resized)
+ video_player->resize(window_size);
+ video_player->handleEvent(event);
}
}
@@ -441,33 +443,6 @@ namespace QuickMedia {
}
}
- // TODO: Add option to scale image to window size.
- // TODO: Fix scaling, it'ss a bit broken
- static void clamp_sprite_to_size(sf::Sprite &sprite, const sf::Vector2f &size) {
- auto texture_size = sprite.getTexture()->getSize();
- auto image_size = sf::Vector2f(texture_size.x, texture_size.y);
-
- double overflow_x = image_size.x - size.x;
- double overflow_y = image_size.y - size.y;
- if(overflow_x <= 0.0f && overflow_y <= 0.0f) {
- sprite.setScale(1.0f, 1.0f);
- return;
- }
-
- auto scale = sprite.getScale();
- float scale_ratio = scale.x / scale.y;
-
- if(overflow_x * scale_ratio > overflow_y) {
- float overflow_ratio = overflow_x / image_size.x;
- float scale_x = 1.0f - overflow_ratio;
- sprite.setScale(scale_x, scale_x * scale_ratio);
- } else {
- float overflow_ratio = overflow_y / image_size.y;
- float scale_y = 1.0f - overflow_ratio;
- sprite.setScale(scale_y * scale_ratio, scale_y);
- }
- }
-
void Program::image_page() {
search_bar->onTextUpdateCallback = nullptr;
search_bar->onTextSubmitCallback = nullptr;
@@ -535,6 +510,13 @@ namespace QuickMedia {
sf::RectangleShape chapter_text_background;
chapter_text_background.setFillColor(sf::Color(0, 0, 0, 150));
+ sf::Vector2u texture_size;
+ sf::Vector2f texture_size_f;
+ if(!error) {
+ texture_size = image.getTexture()->getSize();
+ texture_size_f = sf::Vector2f(texture_size.x, texture_size.y);
+ }
+
// TODO: Show to user if a certain page is missing (by checking page name (number) and checking if some are skipped)
while (current_page == Page::IMAGES) {
if(window.waitEvent(event)) {
@@ -575,10 +557,10 @@ namespace QuickMedia {
auto bounds = error_message.getLocalBounds();
error_message.setPosition(std::floor(content_size.x * 0.5f - bounds.width * 0.5f), std::floor(content_size.y * 0.5f - bounds.height));
} else {
- clamp_sprite_to_size(image, content_size);
- auto texture_size = image.getTexture()->getSize();
- auto image_scale = image.getScale();
- auto image_size = sf::Vector2f(texture_size.x, texture_size.y);
+ auto image_scale = get_ratio(texture_size_f, clamp_to_size(texture_size_f, content_size));
+ image.setScale(image_scale);
+
+ auto image_size = texture_size_f;
image_size.x *= image_scale.x;
image_size.y *= image_scale.y;
image.setPosition(std::floor(content_size.x * 0.5f - image_size.x * 0.5f), std::floor(content_size.y * 0.5f - image_size.y * 0.5f));
diff --git a/src/Scale.cpp b/src/Scale.cpp
new file mode 100644
index 0000000..ab7ea2e
--- /dev/null
+++ b/src/Scale.cpp
@@ -0,0 +1,38 @@
+#include "../include/Scale.hpp"
+
+namespace QuickMedia {
+ static sf::Vector2f wrap_to_size_x(const sf::Vector2f &size, const sf::Vector2f &clamp_size) {
+ sf::Vector2f new_size;
+ auto size_ratio = size.y / size.x;
+ new_size.x = clamp_size.x;
+ new_size.y = new_size.x * size_ratio;
+ return new_size;
+ }
+
+ static sf::Vector2f wrap_to_size_y(const sf::Vector2f &size, const sf::Vector2f &clamp_size) {
+ sf::Vector2f new_size;
+ auto size_ratio = size.x / size.y;
+ new_size.y = clamp_size.y;
+ new_size.x = new_size.y * size_ratio;
+ return new_size;
+ }
+
+ sf::Vector2f wrap_to_size(const sf::Vector2f &size, const sf::Vector2f &clamp_size) {
+ sf::Vector2f new_size;
+ new_size = wrap_to_size_x(size, clamp_size);
+ if(new_size.y > clamp_size.y)
+ new_size = wrap_to_size_y(size, clamp_size);
+ return new_size;
+ }
+
+ sf::Vector2f clamp_to_size(const sf::Vector2f &size, const sf::Vector2f &clamp_size) {
+ sf::Vector2f new_size = size;
+ if(size.x > clamp_size.x || size.y > clamp_size.y)
+ new_size = wrap_to_size(new_size, clamp_size);
+ return new_size;
+ }
+
+ sf::Vector2f get_ratio(const sf::Vector2f &original_size, const sf::Vector2f &new_size) {
+ return sf::Vector2f(new_size.x / original_size.x, new_size.y / original_size.y);
+ }
+} \ No newline at end of file
diff --git a/src/SearchBar.cpp b/src/SearchBar.cpp
index a5f2705..f7ac48d 100644
--- a/src/SearchBar.cpp
+++ b/src/SearchBar.cpp
@@ -3,7 +3,6 @@
const sf::Color text_placeholder_color(255, 255, 255, 100);
const sf::Color front_color(43, 45, 47);
-const sf::Color back_color(33, 35, 37);
const float background_margin_horizontal = 8.0f;
const float background_margin_vertical = 4.0f;
const float padding_horizontal = 10.0f;
diff --git a/src/VideoPlayer.cpp b/src/VideoPlayer.cpp
index 1a2cc9a..d329123 100644
--- a/src/VideoPlayer.cpp
+++ b/src/VideoPlayer.cpp
@@ -1,4 +1,5 @@
#include "../include/VideoPlayer.hpp"
+#include "../include/Scale.hpp"
#include <SFML/Window/Mouse.hpp>
#include <mpv/client.h>
#include <mpv/render_gl.h>
@@ -6,6 +7,8 @@
#include <clocale>
#include <cmath>
+const int UI_VISIBLE_TIMEOUT_MS = 2500;
+
namespace QuickMedia {
static void* getProcAddressMpv(void *funcContext, const char *name) {
return (void*)sf::Context::getFunction(name);
@@ -48,7 +51,7 @@ namespace QuickMedia {
sf::Context *context;
};
- VideoPlayer::VideoPlayer(unsigned int width, unsigned int height, sf::WindowHandle window_handle, const char *file, bool loop) :
+ VideoPlayer::VideoPlayer(sf::RenderWindow &window, unsigned int width, unsigned int height, const char *file, bool loop) :
redraw(false),
event_update(false),
onPlaybackEndedCallback(nullptr),
@@ -74,7 +77,7 @@ namespace QuickMedia {
check_error(mpv_set_option_string(mpv, "demuxer-max-back-bytes", "10M"));
//mpv_set_option_bool(mpv, "osc", true);
- //mpv_set_option_int64(mpv, "wid", window_handle);
+ //mpv_set_option_int64(mpv, "wid", window.getSystemHandle());
if(mpv_initialize(mpv) < 0)
throw VideoInitializationException("Failed to initialize mpv");
@@ -131,46 +134,34 @@ namespace QuickMedia {
mpv_terminate_destroy(mpv);
}
}
+
+ void VideoPlayer::handleEvent(sf::Event &event) {
+ if(event.type == sf::Event::MouseMoved) {
+ cursor_last_active_timer.restart();
+ }
+ }
void VideoPlayer::setPosition(float x, float y) {
sprite.setPosition(x, y);
}
- // TODO: Fix this, it's incorrect
- static void wrap_sprite_to_size(sf::Sprite &sprite, sf::Vector2i texture_size, const sf::Vector2f &size) {
- auto image_size = sf::Vector2f(texture_size.x, texture_size.y);
-
- double overflow_x = image_size.x - size.x;
- double overflow_y = image_size.y - size.y;
-
- auto scale = sprite.getScale();
- float scale_ratio = scale.x / scale.y;
- bool reverse = overflow_x < 0.0f && overflow_y < 0.0f;
-
- if((reverse && overflow_x * scale_ratio < overflow_y) || overflow_x * scale_ratio > overflow_y) {
- float overflow_ratio = overflow_x / image_size.x;
- float scale_x = 1.0f - overflow_ratio;
- sprite.setScale(scale_x, scale_x * scale_ratio);
- } else {
- float overflow_ratio = overflow_y / image_size.y;
- float scale_y = 1.0f - overflow_ratio;
- sprite.setScale(scale_y * scale_ratio, scale_y);
- }
- }
-
- void VideoPlayer::resize(const sf::Vector2i &size) {
- desired_size = size;
+ // TODO: Make this work in the future when video size and sprite texture size wont be the same
+ void VideoPlayer::resize(const sf::Vector2f &size) {
+ desired_size = sf::Vector2f(size.x, size.y);
if(!textureBuffer)
return;
- wrap_sprite_to_size(sprite, video_size, sf::Vector2f(desired_size.x, desired_size.y));
- auto image_scale = sprite.getScale();
- auto image_size = sf::Vector2f(video_size.x, video_size.y);
- image_size.x *= image_scale.x;
- image_size.y *= image_scale.y;
+
+ sf::Vector2f video_size_f(video_size.x, video_size.y);
+ auto video_scale = get_ratio(video_size_f, wrap_to_size(video_size_f, desired_size));
+ sprite.setScale(video_scale);
+
+ auto image_size = video_size_f;
+ image_size.x *= video_scale.x;
+ image_size.y *= video_scale.y;
sprite.setPosition(std::floor(desired_size.x * 0.5f - image_size.x * 0.5f), std::floor(desired_size.y * 0.5f - image_size.y * 0.5f));
}
- void VideoPlayer::handle_events() {
+ void VideoPlayer::handle_mpv_events() {
while(true) {
mpv_event *mpvEvent = mpv_wait_event(mpv, 0.0);
if(mpvEvent->event_id == MPV_EVENT_NONE)
@@ -209,7 +200,7 @@ namespace QuickMedia {
void VideoPlayer::draw(sf::RenderWindow &window) {
if(event_update.exchange(false))
- handle_events();
+ handle_mpv_events();
if(textureBuffer && redraw) {
uint64_t update_flags = mpv_render_context_update(mpvGl);
@@ -239,6 +230,9 @@ namespace QuickMedia {
}
window.draw(sprite);
+ if(cursor_last_active_timer.getElapsedTime().asMilliseconds() > UI_VISIBLE_TIMEOUT_MS)
+ return;
+
double pos = 0.0;
mpv_get_property(mpv, "percent-pos", MPV_FORMAT_DOUBLE, &pos);
pos *= 0.01;