From e745c2239b8bcd30e75af27de5067dbcb1707ac1 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 7 Aug 2019 23:46:24 +0200 Subject: Correctly scale images and video to window size --- src/QuickMedia.cpp | 52 +++++++++++++++------------------------------- src/Scale.cpp | 38 +++++++++++++++++++++++++++++++++ src/SearchBar.cpp | 1 - src/VideoPlayer.cpp | 60 ++++++++++++++++++++++++----------------------------- 4 files changed, 82 insertions(+), 69 deletions(-) create mode 100644 src/Scale.cpp (limited to 'src') 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 @@ -292,7 +293,7 @@ namespace QuickMedia { std::unique_ptr 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 #include #include @@ -6,6 +7,8 @@ #include #include +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; -- cgit v1.2.3