aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-09-11 00:11:03 +0200
committerdec05eba <dec05eba@protonmail.com>2021-09-11 00:11:03 +0200
commit381f449e7153d5305df5ae5218cb6a8dfcf20184 (patch)
tree2a3674afda8a10bc4d30057ac14c09bc745fa2f7 /src
parent5a02e569a307293f1ec6c837335bd0a498898ed1 (diff)
Add 4chan image zoom/panning
Diffstat (limited to 'src')
-rw-r--r--src/QuickMedia.cpp97
1 files changed, 82 insertions, 15 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 258249b..d91f2a1 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -3821,6 +3821,22 @@ namespace QuickMedia {
return true;
}
+ struct ImageControl {
+ float zoom = 1.0f;
+ bool pressed = false;
+ bool moved = false;
+ sf::Vector2f offset; // relative to center
+ sf::Vector2i prev_mouse_pos;
+ };
+
+ static sf::Vector2f to_vec2f(sf::Vector2i vec) {
+ return sf::Vector2f(vec.x, vec.y);
+ }
+
+ static sf::Vector2f to_vec2f(sf::Vector2u vec) {
+ return sf::Vector2f(vec.x, vec.y);
+ }
+
void Program::image_board_thread_page(ImageBoardThreadPage *thread_page, Body *thread_body) {
// TODO: Instead of using stage here, use different pages for each stage
enum class NavigationStage {
@@ -3844,6 +3860,8 @@ namespace QuickMedia {
std::string attached_image_url;
ImageBoardCaptchaChallenge captcha_challenge;
+ ImageControl image_control;
+
captcha_texture.setSmooth(true);
captcha_bg_texture.setSmooth(true);
@@ -4048,17 +4066,19 @@ namespace QuickMedia {
} else {
BodyItem *selected_item = thread_body->get_selected();
if(selected_item && !selected_item->url.empty()) {
- navigation_stage = NavigationStage::VIEWING_ATTACHED_IMAGE;
attached_image_url = selected_item->url;
sf::Image image;
TaskResult task_result = run_task_with_loading_screen([&attached_image_url, &image]{
- std::string image_data;
- if(download_to_string_cache(attached_image_url, image_data, {}) != DownloadResult::OK) {
+ SHA256 sha256;
+ sha256.add(attached_image_url.data(), attached_image_url.size());
+ Path media_file_path = get_cache_dir().join("media").join(sha256.getHash());
+
+ if(get_file_type(media_file_path) == FileType::FILE_NOT_FOUND && download_to_file(attached_image_url, media_file_path.data, {}, true) != DownloadResult::OK) {
show_notification("QuickMedia", "Failed to download image: " + attached_image_url, Urgency::CRITICAL);
return false;
}
- if(!load_image_from_memory(image, image_data.data(), image_data.size())) {
+ if(!load_image_from_file(image, media_file_path.data)) {
show_notification("QuickMedia", "Failed to load image: " + attached_image_url, Urgency::CRITICAL);
return false;
}
@@ -4070,7 +4090,16 @@ namespace QuickMedia {
if(attached_image_texture->loadFromImage(image)) {
attached_image_texture->setSmooth(true);
attached_image_sprite.setTexture(*attached_image_texture, true);
+ attached_image_sprite.setOrigin(0.0f, 0.0f);
+ attached_image_sprite.setScale(1.0f, 1.0f);
navigation_stage = NavigationStage::VIEWING_ATTACHED_IMAGE;
+
+ image_control.zoom = 1.0f;
+ image_control.offset = to_vec2f(attached_image_texture->getSize()) * 0.5f;
+ image_control.pressed = sf::Mouse::isButtonPressed(sf::Mouse::Left);
+ image_control.moved = false;
+ if(image_control.pressed)
+ image_control.prev_mouse_pos = sf::Mouse::getPosition(window);
} else {
show_notification("QuickMedia", "Failed to load image: " + attached_image_url, Urgency::CRITICAL);
}
@@ -4214,6 +4243,36 @@ namespace QuickMedia {
}
}
+ if(navigation_stage == NavigationStage::VIEWING_ATTACHED_IMAGE) {
+ if(event.type == sf::Event::MouseWheelScrolled) {
+ image_control.zoom *= (1.0f + event.mouseWheelScroll.delta * 0.1f);
+ if(image_control.zoom < 0.01f)
+ image_control.zoom = 0.01f;
+ image_control.moved = true;
+ } else if(event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left) {
+ image_control.pressed = true;
+ image_control.prev_mouse_pos.x = event.mouseButton.x;
+ image_control.prev_mouse_pos.y = event.mouseButton.y;
+ } else if(event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left) {
+ image_control.pressed = false;
+ } else if(event.type == sf::Event::MouseMoved && image_control.pressed) {
+ const sf::Vector2i mouse_diff = sf::Vector2i(event.mouseMove.x, event.mouseMove.y) - image_control.prev_mouse_pos;
+ image_control.prev_mouse_pos.x = event.mouseMove.x;
+ image_control.prev_mouse_pos.y = event.mouseMove.y;
+ image_control.offset -= (to_vec2f(mouse_diff) / image_control.zoom);
+ image_control.moved = true;
+ idle_active_handler();
+ } else if(event.type == sf::Event::KeyPressed) {
+ if(event.key.code == sf::Keyboard::W) {
+ image_control.zoom = 1.0f;
+ image_control.moved = false;
+ image_control.offset = to_vec2f(attached_image_texture->getSize()) * 0.5f;
+ attached_image_sprite.setOrigin(0.0f, 0.0f);
+ attached_image_sprite.setScale(1.0f, 1.0f);
+ }
+ }
+ }
+
if(event.type == sf::Event::KeyPressed && navigation_stage == NavigationStage::VIEWING_ATTACHED_IMAGE) {
if(event.key.code == sf::Keyboard::Escape || event.key.code == sf::Keyboard::BackSpace) {
navigation_stage = NavigationStage::VIEWING_COMMENTS;
@@ -4440,17 +4499,25 @@ namespace QuickMedia {
window.draw(captcha_solution_text);
} else if(navigation_stage == NavigationStage::VIEWING_ATTACHED_IMAGE) {
if(attached_image_texture->getNativeHandle() != 0) {
- auto content_size = window_size;
- sf::Vector2u texture_size = attached_image_texture->getSize();
- sf::Vector2f texture_size_f(texture_size.x, texture_size.y);
- auto image_scale = get_ratio(texture_size_f, clamp_to_size(texture_size_f, content_size));
- attached_image_sprite.setScale(image_scale);
-
- auto image_size = texture_size_f;
- image_size.x *= image_scale.x;
- image_size.y *= image_scale.y;
- attached_image_sprite.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));
- window.draw(attached_image_sprite);
+ if(image_control.moved) {
+ attached_image_sprite.setOrigin(image_control.offset);
+ attached_image_sprite.setScale(image_control.zoom, image_control.zoom);
+ attached_image_sprite.setPosition(window_size * 0.5f);
+ window.draw(attached_image_sprite);
+ } else {
+ auto content_size = window_size;
+ sf::Vector2u texture_size = attached_image_texture->getSize();
+ sf::Vector2f texture_size_f(texture_size.x, texture_size.y);
+ auto image_scale = get_ratio(texture_size_f, clamp_to_size(texture_size_f, content_size));
+ image_control.zoom = std::min(image_scale.x, image_scale.y);
+ attached_image_sprite.setScale(image_scale);
+
+ auto image_size = texture_size_f;
+ image_size.x *= image_scale.x;
+ image_size.y *= image_scale.y;
+ attached_image_sprite.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));
+ window.draw(attached_image_sprite);
+ }
} else {
sf::RectangleShape rect(sf::Vector2f(640.0f, 480.0f));
rect.setFillColor(get_theme().image_loading_background_color);