aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO4
-rw-r--r--include/Body.hpp15
-rw-r--r--src/Body.cpp379
-rw-r--r--src/QuickMedia.cpp14
4 files changed, 234 insertions, 178 deletions
diff --git a/TODO b/TODO
index ffef873..679ed4d 100644
--- a/TODO
+++ b/TODO
@@ -26,4 +26,6 @@ Also add support for full chinese and korean range.
Resize text vertex arrays to 0 when not visible on screen to reduce memory usage. Text already does this but its done incorrectly (copied from dchat codebase). (Is this really necessary?).
Speed up thumbnail creating (image resizing).
Extract thumbnail from images that are being downloaded, while its downloading and show that while the full image is downloading (upscaled, or with blurhash).
-Use one special thread to load cached files. Right now if there are multiple images on the screen and 1 needs to download while the others are cached, then the cached images wont load until that 1 image has downloaded. \ No newline at end of file
+Use one special thread to load cached files. Right now if there are multiple images on the screen and 1 needs to download while the others are cached, then the cached images wont load until that 1 image has downloaded.
+Press pgup/pgdown to scroll and entire page.
+Press home/end to scroll to top/bottom. \ No newline at end of file
diff --git a/include/Body.hpp b/include/Body.hpp
index 4987735..2f1644d 100644
--- a/include/Body.hpp
+++ b/include/Body.hpp
@@ -5,6 +5,9 @@
#include <SFML/Graphics/Text.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
+#include <SFML/Graphics/RectangleShape.hpp>
+#include <SFML/Graphics/Sprite.hpp>
+#include "../external/RoundedRectangleShape.hpp"
#include <json/value.h>
#include <thread>
@@ -125,8 +128,11 @@ namespace QuickMedia {
sf::Vector2f thumbnail_fallback_size;
sf::Color line_seperator_color;
private:
+ void draw_item(sf::RenderWindow &window, BodyItem *item, const sf::Vector2f &pos, const sf::Vector2f &size, const float item_height, const int item_index, const Json::Value &content_progress);
+ float get_item_height(BodyItem *item);
+ private:
struct ThumbnailData {
- bool referenced;
+ bool referenced = false;
std::shared_ptr<sf::Texture> texture;
bool loaded = false;
};
@@ -135,5 +141,12 @@ namespace QuickMedia {
std::unordered_map<std::string, ThumbnailData> item_thumbnail_textures;
bool loading_thumbnail;
int selected_item;
+ int prev_selected_item;
+ float page_scroll;
+ // TODO: Use a loading gif or something similar instead, to properly indicate the image is loading. Which could also have text that says "failed to load image" when image loading failed.
+ sf::RectangleShape image_fallback;
+ sf::RectangleShape item_background_shadow;
+ sf::RoundedRectangleShape item_background;
+ sf::Sprite image;
};
} \ No newline at end of file
diff --git a/src/Body.cpp b/src/Body.cpp
index 2bd5499..c849aea 100644
--- a/src/Body.cpp
+++ b/src/Body.cpp
@@ -4,15 +4,17 @@
#include "../include/base64_url.hpp"
#include "../include/ImageUtils.hpp"
#include "../plugins/Plugin.hpp"
-#include "../external/RoundedRectangleShape.hpp"
-#include <SFML/Graphics/RectangleShape.hpp>
-#include <SFML/Graphics/Sprite.hpp>
#include <SFML/OpenGL.hpp>
#include <assert.h>
#include <cmath>
const sf::Color front_color(32, 36, 42);
const sf::Color back_color(33, 35, 37);
+float image_max_height = 100.0f;
+const float spacing_y = 15.0f;
+const float padding_x = 10.0f;
+const float image_padding_x = 5.0f;
+const float padding_y = 5.0f;
namespace QuickMedia {
BodyItem::BodyItem(std::string _title) :
@@ -69,7 +71,10 @@ namespace QuickMedia {
line_seperator_color(sf::Color(32, 37, 43, 255)),
program(program),
loading_thumbnail(false),
- selected_item(0)
+ selected_item(0),
+ prev_selected_item(0),
+ page_scroll(0.0f),
+ item_background(sf::Vector2f(1.0f, 1.0f), 10.0f, 10)
{
progress_text.setFillColor(sf::Color::White);
replies_text.setFillColor(sf::Color(129, 162, 190));
@@ -77,6 +82,9 @@ namespace QuickMedia {
thumbnail_resize_target_size.y = 119;
thumbnail_fallback_size.x = 50.0f;
thumbnail_fallback_size.y = 100.0f;
+ image_fallback.setSize(thumbnail_fallback_size);
+ image_fallback.setFillColor(sf::Color::White);
+ item_background.setFillColor(sf::Color(55, 60, 68));
}
bool Body::select_previous_item() {
@@ -138,10 +146,14 @@ namespace QuickMedia {
void Body::set_selected_item(int item) {
assert(item >= 0 && item < (int)items.size());
selected_item = item;
+ prev_selected_item = selected_item;
+ page_scroll = 0.0f;
}
void Body::select_first_item() {
selected_item = 0;
+ prev_selected_item = selected_item;
+ page_scroll = 0.0f;
clamp_selection();
}
@@ -153,11 +165,15 @@ namespace QuickMedia {
}
}
selected_item = 0;
+ prev_selected_item = selected_item;
+ page_scroll = 0.0f;
}
void Body::clear_items() {
items.clear();
selected_item = 0;
+ prev_selected_item = selected_item;
+ page_scroll = 0.0f;
}
// TODO: Optimize with memcpy and changing capacity before loop
@@ -197,16 +213,20 @@ namespace QuickMedia {
for(int i = selected_item; i >= 0; --i) {
if(items[i]->visible) {
selected_item = i;
- return;
+ goto reset_scroll;
}
}
for(int i = selected_item; i < num_items; ++i) {
if(items[i]->visible) {
selected_item = i;
- return;
+ goto reset_scroll;
}
}
+
+ reset_scroll:
+ prev_selected_item = selected_item;
+ page_scroll = 0.0f;
}
static sf::Vector2f to_vec2f(const sf::Vector2u &vec) {
@@ -345,34 +365,27 @@ namespace QuickMedia {
void Body::draw(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size, const Json::Value &content_progress) {
sf::Vector2f scissor_pos = pos;
sf::Vector2f scissor_size = size;
-
- float image_max_height = 100.0f;
- const float spacing_y = 15.0f;
- const float padding_x = 10.0f;
- const float image_padding_x = 5.0f;
- const float padding_y = 5.0f;
const float start_y = pos.y;
- sf::RectangleShape image_fallback(thumbnail_fallback_size);
- image_fallback.setFillColor(sf::Color::White);
-
if(thumbnail_resize_target_size.x != 0 && thumbnail_resize_target_size.y != 0) {
image_max_height = thumbnail_resize_target_size.y;
}
- sf::Sprite image;
-
- sf::RoundedRectangleShape item_background(sf::Vector2f(1.0f, 1.0f), 10.0f, 10);
//item_background.setFillColor(front_color);
- item_background.setFillColor(sf::Color(55, 60, 68));
//item_background.setOutlineThickness(1.0f);
//item_background.setOutlineColor(sf::Color(13, 15, 17));
- sf::RectangleShape item_background_shadow;
item_background_shadow.setFillColor(line_seperator_color);
int num_items = items.size();
- if(num_items == 0)
+ if(num_items == 0 || size.y <= 0.0f) {
+ for(auto it = item_thumbnail_textures.begin(); it != item_thumbnail_textures.end();) {
+ if(!it->second.referenced)
+ it = item_thumbnail_textures.erase(it);
+ else
+ ++it;
+ }
return;
+ }
for(auto &thumbnail_it : item_thumbnail_textures) {
thumbnail_it.second.referenced = false;
@@ -413,189 +426,217 @@ namespace QuickMedia {
}
}
- // Find the starting row that can be drawn to make selected row visible as well
- int first_visible_item = selected_item;
- assert(first_visible_item >= 0 && first_visible_item < (int)items.size());
- float visible_height = 0.0f;
- for(; first_visible_item >= 0; --first_visible_item) {
- auto &item = items[first_visible_item];
- if(item->visible) {
- float item_height = 0.0f;
- if(!item->get_title().empty()) {
- item_height += item->title_text->getHeight() - 2.0f;
- }
- if(!item->get_author().empty()) {
- item_height += item->author_text->getHeight() - 2.0f;
- }
- if(item->description_text) {
- item_height += item->description_text->getHeight() - 2.0f;
- }
- if(draw_thumbnails && !item->thumbnail_url.empty()) {
- auto &item_thumbnail = item_thumbnail_textures[item->thumbnail_url];
- item_thumbnail.referenced = false;
- float image_height = image_fallback.getSize().y;
- if(item_thumbnail.texture && item_thumbnail.texture->getNativeHandle() != 0) {
- auto image_size = item_thumbnail.texture->getSize();
- image_height = std::min(image_max_height, (float)image_size.y);
- }
- item_height = std::max(item_height, image_height);
+ // TODO: Optimize this, especially when scrolling to top/bottom.
+ // TODO: Test when wrapping is enabled
+ int selected_item_diff = selected_item - prev_selected_item;
+ int selected_int_diff_abs = std::abs(selected_item_diff);
+ if(selected_item_diff > 0) {
+ int num_items_scrolled = 0;
+ int i = prev_selected_item;
+ while(num_items_scrolled < selected_int_diff_abs && i < num_items) {
+ if(items[i]->visible) {
+ page_scroll += (get_item_height(items[i].get()) + spacing_y);
}
- item_height += (spacing_y + padding_y * 2.0f);
- visible_height += item_height;
- if(visible_height >= size.y) {
- --first_visible_item;
- //pos.y += (size.y - (visible_height - item_height));
- pos.y -= (visible_height - size.y);
- break;
+ ++num_items_scrolled;
+ ++i;
+ }
+ prev_selected_item = selected_item;
+ } else if(selected_item_diff < 0) {
+ int num_items_scrolled = 0;
+ int i = prev_selected_item - 1;
+ while(num_items_scrolled < selected_int_diff_abs && i >= 0) {
+ if(items[i]->visible) {
+ page_scroll -= (get_item_height(items[i].get()) + spacing_y);
}
+ ++num_items_scrolled;
+ --i;
}
+ prev_selected_item = selected_item;
+ }
+
+ float selected_item_height = get_item_height(items[selected_item].get()) + spacing_y;
+ if(page_scroll > size.y - selected_item_height) {
+ page_scroll = size.y - selected_item_height;
+ } else if(page_scroll < 0.0f) {
+ page_scroll = 0.0f;
}
+ pos.y += page_scroll;
+
sf::Vector2u window_size = window.getSize();
glEnable(GL_SCISSOR_TEST);
glScissor(scissor_pos.x, (int)window_size.y - (int)scissor_pos.y - (int)scissor_size.y, scissor_size.x, scissor_size.y);
- for(int i = first_visible_item + 1; i < num_items; ++i) {
+ sf::Vector2f prev_pos = pos;
+ for(int i = selected_item - 1; i >= 0; --i) {
auto &item = items[i];
- if(pos.y >= start_y + size.y)
+ // TODO: Find a better solution?
+ if(!item->visible)
+ continue;
+
+ float item_height = get_item_height(item.get());
+ prev_pos.y -= item_height + spacing_y;
+
+ if(prev_pos.y + item_height <= 0.0f)
break;
+ draw_item(window, item.get(), prev_pos, size, item_height, i, content_progress);
+ }
+
+ sf::Vector2f after_pos = pos;
+ for(int i = selected_item; i < num_items; ++i) {
+ auto &item = items[i];
+
+ // TODO: Find a better solution?
if(!item->visible)
continue;
- // TODO: Instead of generating a new hash everytime to access textures, cache the hash of the thumbnail url
- // Intentionally create the item with the key item->thumbnail_url if it doesn't exist
- item_thumbnail_textures[item->thumbnail_url].referenced = true;
- auto &item_thumbnail = item_thumbnail_textures[item->thumbnail_url];
-
- float item_height = 0.0f;
- if(!item->get_title().empty()) {
- item_height += item->title_text->getHeight() - 2.0f;
- }
- if(!item->get_author().empty()) {
- item_height += item->author_text->getHeight() - 2.0f;
- }
- if(item->description_text) {
- item_height += item->description_text->getHeight() - 2.0f;
- }
- if(draw_thumbnails && !item->thumbnail_url.empty()) {
- float image_height = image_fallback.getSize().y;
- if(item_thumbnail.loaded && item_thumbnail.texture && item_thumbnail.texture->getNativeHandle() != 0) {
- auto image_size = item_thumbnail.texture->getSize();
- image_height = std::min(image_max_height, (float)image_size.y);
- }
- item_height = std::max(item_height, image_height);
- }
- item_height += (padding_y * 2.0f);
+ if(after_pos.y >= start_y + size.y)
+ break;
- if(draw_thumbnails) {
- if(!item->thumbnail_url.empty() && !loading_thumbnail && !item_thumbnail.loaded && !item_thumbnail.texture) {
- item_thumbnail.loaded = true;
- item_thumbnail.texture = load_thumbnail_from_url(item->thumbnail_url, item->thumbnail_is_local, thumbnail_resize_target_size);
- }
- }
+ float item_height = get_item_height(item.get());
+ draw_item(window, item.get(), after_pos, size, item_height, i, content_progress);
+ after_pos.y += item_height + spacing_y;
+ }
- sf::Vector2f item_pos;
- item_pos.x = std::floor(pos.x);
- item_pos.y = std::floor(pos.y);
+ glDisable(GL_SCISSOR_TEST);
- item_background_shadow.setSize(sf::Vector2f(std::max(0.0f, size.x - 20.0f), 1.0f));
- item_background_shadow.setPosition(item_pos + sf::Vector2f(10.0f, std::floor(item_height + spacing_y * 0.5f)));
- window.draw(item_background_shadow);
+ for(auto it = item_thumbnail_textures.begin(); it != item_thumbnail_textures.end();) {
+ if(!it->second.referenced)
+ it = item_thumbnail_textures.erase(it);
+ else
+ ++it;
+ }
+ }
- if(i == selected_item) {
- item_background.setPosition(item_pos);
- item_background.setSize(sf::Vector2f(size.x, item_height));
- window.draw(item_background);
- }
+ void Body::draw_item(sf::RenderWindow &window, BodyItem *item, const sf::Vector2f &pos, const sf::Vector2f &size, const float item_height, const int item_index, const Json::Value &content_progress) {
+ // TODO: Instead of generating a new hash everytime to access textures, cache the hash of the thumbnail url
+ // Intentionally create the item with the key item->thumbnail_url if it doesn't exist
+ item_thumbnail_textures[item->thumbnail_url].referenced = true;
+ auto &item_thumbnail = item_thumbnail_textures[item->thumbnail_url];
- float text_offset_x = padding_x;
- if(draw_thumbnails) {
- // TODO: Verify if this is safe. The thumbnail is being modified in another thread
- // and it might not be fully finished before the native handle is set?
- if(item_thumbnail.texture && item_thumbnail.texture->getNativeHandle() != 0) {
- image.setTexture(*item_thumbnail.texture, true);
- auto image_size = image.getTexture()->getSize();
- auto height_ratio = std::min(image_max_height, (float)image_size.y) / image_size.y;
- auto scale = image.getScale();
- auto image_scale_ratio = scale.x / scale.y;
- const float width_ratio = height_ratio * image_scale_ratio;
- image.setScale(width_ratio, height_ratio);
- image.setPosition(item_pos + sf::Vector2f(image_padding_x, padding_y));
- window.draw(image);
- text_offset_x += image_padding_x + width_ratio * image_size.x;
- } else if(!item->thumbnail_url.empty()) {
- image_fallback.setPosition(item_pos + sf::Vector2f(image_padding_x, padding_y));
- window.draw(image_fallback);
- text_offset_x += image_padding_x + image_fallback.getSize().x;
- }
+ if(draw_thumbnails) {
+ if(!item->thumbnail_url.empty() && !loading_thumbnail && !item_thumbnail.loaded && !item_thumbnail.texture) {
+ item_thumbnail.loaded = true;
+ item_thumbnail.texture = load_thumbnail_from_url(item->thumbnail_url, item->thumbnail_is_local, thumbnail_resize_target_size);
}
+ }
- if(!item->get_author().empty()) {
- item->author_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - 6.0f));
- item->author_text->setMaxWidth(size.x - text_offset_x - image_padding_x * 2.0f);
- item->author_text->draw(window);
+ sf::Vector2f item_pos;
+ item_pos.x = std::floor(pos.x);
+ item_pos.y = std::floor(pos.y);
- sf::Vector2f replies_text_pos = item->author_text->getPosition() + sf::Vector2f(0.0f, 5.0f);
- replies_text_pos.x += item->author_text->getWidth() + 5.0f;
- replies_text.setPosition(replies_text_pos);
+ item_background_shadow.setSize(sf::Vector2f(std::max(0.0f, size.x - 20.0f), 1.0f));
+ item_background_shadow.setPosition(item_pos + sf::Vector2f(10.0f, std::floor(item_height + spacing_y * 0.5f)));
+ window.draw(item_background_shadow);
- sf::String replies_text_str;
- for(size_t reply_index : item->replies) {
- BodyItem *reply_item = items[reply_index].get();
- replies_text_str += ">>";
- replies_text_str += reply_item->post_number;
- }
- replies_text.setString(std::move(replies_text_str));
- window.draw(replies_text);
+ if(item_index == selected_item) {
+ item_background.setPosition(item_pos);
+ item_background.setSize(sf::Vector2f(size.x, item_height));
+ window.draw(item_background);
+ }
- item_pos.y += item->author_text->getHeight() - 2.0f;
- }
- //title_text.setString(item->title);
- //title_text.setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y));
- //window.draw(title_text);
- if(!item->get_title().empty()) {
- item->title_text->setFillColor(item->title_color);
- item->title_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - 8.0f));
- item->title_text->setMaxWidth(size.x - text_offset_x - image_padding_x * 2.0f);
- item->title_text->draw(window);
+ float text_offset_x = padding_x;
+ if(draw_thumbnails) {
+ // TODO: Verify if this is safe. The thumbnail is being modified in another thread
+ // and it might not be fully finished before the native handle is set?
+ if(item_thumbnail.loaded && item_thumbnail.texture && item_thumbnail.texture->getNativeHandle() != 0) {
+ image.setTexture(*item_thumbnail.texture, true);
+ auto image_size = image.getTexture()->getSize();
+ auto height_ratio = std::min(image_max_height, (float)image_size.y) / image_size.y;
+ auto scale = image.getScale();
+ auto image_scale_ratio = scale.x / scale.y;
+ const float width_ratio = height_ratio * image_scale_ratio;
+ image.setScale(width_ratio, height_ratio);
+ image.setPosition(item_pos + sf::Vector2f(image_padding_x, padding_y));
+ window.draw(image);
+ text_offset_x += image_padding_x + width_ratio * image_size.x;
+ // We want the next image fallback to have the same size as the successful image rendering, because its likely the image fallback will have the same size (for example thumbnails on youtube)
+ image_fallback.setSize(sf::Vector2f(width_ratio * image_size.x, height_ratio * image_size.y));
+ } else if(!item->thumbnail_url.empty()) {
+ image_fallback.setPosition(item_pos + sf::Vector2f(image_padding_x, padding_y));
+ window.draw(image_fallback);
+ text_offset_x += image_padding_x + image_fallback.getSize().x;
}
+ }
- if(!item->get_description().empty()) {
- float height_offset = 0.0f;
- if(!item->get_title().empty()) {
- height_offset = item->title_text->getHeight();
- }
- item->description_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - 8.0f + height_offset));
- item->description_text->setMaxWidth(size.x - text_offset_x - image_padding_x * 2.0f);
- item->description_text->draw(window);
+ if(!item->get_author().empty()) {
+ item->author_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - 6.0f));
+ item->author_text->setMaxWidth(size.x - text_offset_x - image_padding_x * 2.0f);
+ item->author_text->draw(window);
+
+ sf::Vector2f replies_text_pos = item->author_text->getPosition() + sf::Vector2f(0.0f, 5.0f);
+ replies_text_pos.x += item->author_text->getWidth() + 5.0f;
+ replies_text.setPosition(replies_text_pos);
+
+ sf::String replies_text_str;
+ for(size_t reply_index : item->replies) {
+ BodyItem *reply_item = items[reply_index].get();
+ replies_text_str += ">>";
+ replies_text_str += reply_item->post_number;
}
+ replies_text.setString(std::move(replies_text_str));
+ window.draw(replies_text);
- // TODO: Do the same for non-manga content.
- // TODO: Cache this instead of hash access every item every frame.
- const Json::Value &item_progress = content_progress[item->get_title()];
- if(item_progress.isObject()) {
- const Json::Value &current_json = item_progress["current"];
- const Json::Value &total_json = item_progress["total"];
- if(current_json.isNumeric() && total_json.isNumeric()) {
- progress_text.setString(std::string("Page: ") + std::to_string(current_json.asInt()) + "/" + std::to_string(total_json.asInt()));
- auto bounds = progress_text.getLocalBounds();
- progress_text.setPosition(std::floor(item_pos.x + size.x - bounds.width - padding_x), std::floor(item_pos.y + padding_y));
- window.draw(progress_text);
- }
+ item_pos.y += item->author_text->getHeight() - 2.0f;
+ }
+ //title_text.setString(item->title);
+ //title_text.setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y));
+ //window.draw(title_text);
+ if(!item->get_title().empty()) {
+ item->title_text->setFillColor(item->title_color);
+ item->title_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - 8.0f));
+ item->title_text->setMaxWidth(size.x - text_offset_x - image_padding_x * 2.0f);
+ item->title_text->draw(window);
+ }
+
+ if(!item->get_description().empty()) {
+ float height_offset = 0.0f;
+ if(!item->get_title().empty()) {
+ height_offset = item->title_text->getHeight();
}
+ item->description_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - 8.0f + height_offset));
+ item->description_text->setMaxWidth(size.x - text_offset_x - image_padding_x * 2.0f);
+ item->description_text->draw(window);
+ }
- pos.y += item_height + spacing_y;
+ // TODO: Do the same for non-manga content.
+ // TODO: Cache this instead of hash access every item every frame.
+ const Json::Value &item_progress = content_progress[item->get_title()];
+ if(item_progress.isObject()) {
+ const Json::Value &current_json = item_progress["current"];
+ const Json::Value &total_json = item_progress["total"];
+ if(current_json.isNumeric() && total_json.isNumeric()) {
+ progress_text.setString(std::string("Page: ") + std::to_string(current_json.asInt()) + "/" + std::to_string(total_json.asInt()));
+ auto bounds = progress_text.getLocalBounds();
+ progress_text.setPosition(std::floor(item_pos.x + size.x - bounds.width - padding_x), std::floor(item_pos.y + padding_y));
+ window.draw(progress_text);
+ }
}
- glDisable(GL_SCISSOR_TEST);
+ }
- for(auto it = item_thumbnail_textures.begin(); it != item_thumbnail_textures.end();) {
- if(!it->second.referenced)
- it = item_thumbnail_textures.erase(it);
- else
- ++it;
+ float Body::get_item_height(BodyItem *item) {
+ float item_height = 0.0f;
+ if(!item->get_title().empty()) {
+ item_height += item->title_text->getHeight() - 2.0f;
+ }
+ if(!item->get_author().empty()) {
+ item_height += item->author_text->getHeight() - 2.0f;
+ }
+ if(item->description_text) {
+ item_height += item->description_text->getHeight() - 2.0f;
+ }
+ if(draw_thumbnails && !item->thumbnail_url.empty()) {
+ auto &item_thumbnail = item_thumbnail_textures[item->thumbnail_url];
+ float image_height = image_fallback.getSize().y;
+ if(item_thumbnail.texture && item_thumbnail.texture->getNativeHandle() != 0) {
+ auto image_size = item_thumbnail.texture->getSize();
+ image_height = std::min(image_max_height, (float)image_size.y);
+ }
+ item_height = std::max(item_height, image_height);
}
+ return item_height + padding_y * 2.0f;
}
//static
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 1039ca7..9300059 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -1040,7 +1040,7 @@ namespace QuickMedia {
update_search_text = text;
else {
tabs[selected_tab].body->filter_search_fuzzy(text);
- tabs[selected_tab].body->clamp_selection();
+ tabs[selected_tab].body->select_first_item();
}
if(tabs[selected_tab].body == recommended_body.get())
recommended_filter = text;
@@ -1104,7 +1104,7 @@ namespace QuickMedia {
} else if(event.key.code == sf::Keyboard::Left) {
if(tabs[selected_tab].body) {
tabs[selected_tab].body->filter_search_fuzzy("");
- tabs[selected_tab].body->clamp_selection();
+ tabs[selected_tab].body->select_first_item();
tabs[selected_tab].body->clear_thumbnails();
}
selected_tab = std::max(0, selected_tab - 1);
@@ -1112,7 +1112,7 @@ namespace QuickMedia {
} else if(event.key.code == sf::Keyboard::Right) {
if(tabs[selected_tab].body) {
tabs[selected_tab].body->filter_search_fuzzy("");
- tabs[selected_tab].body->clamp_selection();
+ tabs[selected_tab].body->select_first_item();
tabs[selected_tab].body->clear_thumbnails();
}
selected_tab = std::min((int)tabs.size() - 1, selected_tab + 1);
@@ -1800,7 +1800,7 @@ namespace QuickMedia {
search_bar->onTextUpdateCallback = [&tabs, &selected_tab](const std::string &text) {
tabs[selected_tab].body->filter_search_fuzzy(text);
- tabs[selected_tab].body->clamp_selection();
+ tabs[selected_tab].body->select_first_item();
};
search_bar->onTextSubmitCallback = [this, &tabs, &selected_tab, &json_chapters](const std::string&) -> bool {
@@ -1886,13 +1886,13 @@ namespace QuickMedia {
search_bar->clear();
} else if(event.key.code == sf::Keyboard::Left) {
tabs[selected_tab].body->filter_search_fuzzy("");
- tabs[selected_tab].body->clamp_selection();
+ tabs[selected_tab].body->select_first_item();
tabs[selected_tab].body->clear_thumbnails();
selected_tab = std::max(0, selected_tab - 1);
search_bar->clear();
} else if(event.key.code == sf::Keyboard::Right) {
tabs[selected_tab].body->filter_search_fuzzy("");
- tabs[selected_tab].body->clamp_selection();
+ tabs[selected_tab].body->select_first_item();
tabs[selected_tab].body->clear_thumbnails();
selected_tab = std::min((int)tabs.size() - 1, selected_tab + 1);
search_bar->clear();
@@ -1934,7 +1934,7 @@ namespace QuickMedia {
{
tab.body->items = tab.creator_page_download_future.get();
tab.body->filter_search_fuzzy(search_bar->get_text());
- tab.body->clamp_selection();
+ tab.body->select_first_item();
}
if(i == selected_tab) {