diff options
Diffstat (limited to 'src/Body.cpp')
-rw-r--r-- | src/Body.cpp | 164 |
1 files changed, 134 insertions, 30 deletions
diff --git a/src/Body.cpp b/src/Body.cpp index 8a32f76..d14a3c5 100644 --- a/src/Body.cpp +++ b/src/Body.cpp @@ -3,26 +3,28 @@ #include "../include/Scale.hpp" #include "../include/ResourceLoader.hpp" #include "../include/AsyncImageLoader.hpp" +#include "../include/Utils.hpp" #include "../plugins/Plugin.hpp" #include <SFML/Graphics/CircleShape.hpp> +#include <SFML/Window/Event.hpp> #include <SFML/OpenGL.hpp> #include <assert.h> #include <cmath> static const sf::Color front_color(32, 36, 42); static const sf::Color back_color(33, 35, 37); -static const float spacing_y = 15.0f; -static const float padding_x = 10.0f; -static const float image_padding_x = 5.0f; -static const float padding_y = 5.0f; -static const float embedded_item_padding_y = 0.0f; +static const float spacing_y = 15.0f * QuickMedia::get_ui_scale(); +static const float padding_x = 10.0f * QuickMedia::get_ui_scale(); +static const float image_padding_x = 5.0f * QuickMedia::get_ui_scale(); +static const float padding_y = 5.0f * QuickMedia::get_ui_scale(); +static const float embedded_item_padding_y = 0.0f * QuickMedia::get_ui_scale(); static const double thumbnail_fade_duration_sec = 0.1; -static const float reaction_background_padding_x = 7.0f; -static const float reaction_background_padding_y = 3.0f; -static const float reaction_spacing_x = 5.0f; -static const float reaction_padding_y = 7.0f; -static const int embedded_item_font_size = 14; +static const float reaction_background_padding_x = 7.0f * QuickMedia::get_ui_scale(); +static const float reaction_background_padding_y = 3.0f * QuickMedia::get_ui_scale(); +static const float reaction_spacing_x = 5.0f * QuickMedia::get_ui_scale(); +static const float reaction_padding_y = 7.0f * QuickMedia::get_ui_scale(); +static const int embedded_item_font_size = 14 * QuickMedia::get_ui_scale(); namespace QuickMedia { BodyItem::BodyItem(std::string _title) : @@ -99,9 +101,17 @@ namespace QuickMedia { return *this; } + void BodyItem::add_reaction(std::string text, void *userdata) { + sf::String str = sf::String::fromUtf8(text.begin(), text.end()); + Reaction reaction; + reaction.text = std::make_unique<Text>(std::move(str), false, 14 * get_ui_scale(), 0.0f); + reaction.userdata = userdata; + reactions.push_back(std::move(reaction)); + } + Body::Body(Program *program, sf::Texture &loading_icon_texture) : - progress_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), 14), - replies_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), 14), + progress_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), 14 * get_ui_scale()), + replies_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), 14 * get_ui_scale()), embedded_item_load_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), embedded_item_font_size), draw_thumbnails(true), wrap_around(false), @@ -116,6 +126,7 @@ namespace QuickMedia { loading_icon(loading_icon_texture), num_visible_items(0), last_item_fully_visible(true), + first_fully_visible_item(-1), last_fully_visible_item(-1) { progress_text.setFillColor(sf::Color::White); @@ -180,6 +191,8 @@ namespace QuickMedia { break; } + // selected_scrolled = 0.0f; + if(selected_item == new_selected_item) return false; selected_item = new_selected_item; @@ -213,6 +226,8 @@ namespace QuickMedia { break; } + //selected_scrolled = 0.0f; + if(selected_item == new_selected_item) return false; selected_item = new_selected_item; @@ -221,6 +236,8 @@ namespace QuickMedia { void Body::set_selected_item(int item, bool reset_prev_selected_item) { //assert(item >= 0 && item < (int)items.size()); + if(item != selected_item) + selected_scrolled = 0.0f; selected_item = item; if(reset_prev_selected_item) prev_selected_item = selected_item; @@ -241,6 +258,8 @@ namespace QuickMedia { } void Body::select_first_item() { + if(selected_item != 0) + selected_scrolled = 0.0f; selected_item = 0; prev_selected_item = selected_item; page_scroll = 0.0f; @@ -248,13 +267,18 @@ namespace QuickMedia { } void Body::select_last_item() { - selected_item = std::max(0, (int)items.size() - 1); + int new_selected_item = std::max(0, (int)items.size() - 1); + if(selected_item != new_selected_item) + selected_scrolled = 0.0f; + selected_item = new_selected_item; //prev_selected_item = selected_item; //page_scroll = 0.0f; clamp_selection(); } void Body::clear_items() { + if(selected_item != 0) + selected_scrolled = 0.0f; items.clear(); selected_item = 0; prev_selected_item = selected_item; @@ -347,6 +371,39 @@ namespace QuickMedia { } } + bool Body::on_event(const sf::RenderWindow &window, const sf::Event &event) { + #if 0 + if(!mouse_state_set) { + mouse_state_set = true; + mouse_left_pressed = sf::Mouse::isButtonPressed(sf::Mouse::Left); + if(mouse_left_pressed) { + mouse_pos_raw = sf::Mouse::getPosition(window); + mouse_pos = sf::Vector2f(mouse_pos_raw.x, mouse_pos_raw.y); + prev_mouse_pos = mouse_pos; + return true; + } + } + + if(event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left && !mouse_left_pressed) { + mouse_left_pressed = true; + mouse_pos_raw.x = event.mouseButton.x; + mouse_pos_raw.y = event.mouseButton.y; + mouse_pos = sf::Vector2f(mouse_pos_raw.x, mouse_pos_raw.y); + prev_mouse_pos = mouse_pos; + return true; + } else if(event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left && mouse_left_pressed) { + mouse_left_pressed = false; + return true; + } else if(event.type == sf::Event::MouseMoved && mouse_left_pressed) { + mouse_pos_raw.x = event.mouseMove.x; + mouse_pos_raw.y = event.mouseMove.y; + return true; + } + + #endif + return false; + } + void Body::draw(sf::RenderWindow &window, sf::Vector2f pos, sf::Vector2f size) { draw(window, pos, size, Json::Value::nullSingleton()); } @@ -359,12 +416,55 @@ namespace QuickMedia { const float start_y = pos.y; elapsed_time_sec = draw_timer.getElapsedTime().asSeconds(); + float frame_time = frame_timer.restart().asSeconds(); + if(frame_time > 2.0f) + frame_time = 2.0f; + + const sf::Vector2f mouse_pos_diff(mouse_pos_raw.x - mouse_pos.x, mouse_pos_raw.y - mouse_pos.y); + const float move_speed = 25.0f; + mouse_pos.x += (mouse_pos_diff.x * frame_time * move_speed); + mouse_pos.y += (mouse_pos_diff.y * frame_time * move_speed); + + sf::Vector2f mouse_smooth_diff(mouse_pos.x - prev_mouse_pos.x, mouse_pos.y - prev_mouse_pos.y); + prev_mouse_pos = mouse_pos; + + if(mouse_left_pressed) { + selected_scrolled += mouse_smooth_diff.y; + page_scroll += mouse_smooth_diff.y; + mouse_scroll_accel = mouse_smooth_diff; + } else { + selected_scrolled += mouse_scroll_accel.y; + page_scroll += mouse_scroll_accel.y; + const float scroll_deaccel = 1.02f; + double deaccel = scroll_deaccel * (1.0 + frame_time); + if(deaccel < 0.0001) + deaccel = 1.0; + + mouse_scroll_accel.x /= deaccel; + if(fabs(mouse_scroll_accel.x) < 0.0001) + mouse_scroll_accel.x = 0.0; + + mouse_scroll_accel.y /= deaccel; + if(fabs(mouse_scroll_accel.y) < 0.0001) + mouse_scroll_accel.y = 0.0; + } + + if(selected_item != -1) { + if(selected_scrolled <= -selected_item_height) { + selected_scrolled += selected_item_height; + select_next_item(false); + } else if(selected_scrolled >= selected_item_height) { + selected_scrolled -= selected_item_height; + select_previous_item(false); + } + } //item_background.setFillColor(front_color); //item_background.setOutlineThickness(1.0f); //item_background.setOutlineColor(sf::Color(13, 15, 17)); item_separator.setFillColor(line_separator_color); num_visible_items = 0; + first_fully_visible_item = -1; last_fully_visible_item = -1; selected_line_top_visible = true; selected_line_bottom_visible = true; @@ -424,7 +524,7 @@ namespace QuickMedia { prev_selected_item = selected_item; } - float selected_item_height = get_item_height(items[selected_item].get(), size.x) + spacing_y; + selected_item_height = get_item_height(items[selected_item].get(), size.x) + spacing_y; bool selected_item_fits_on_screen = selected_item_height <= size.y; selected_line_top_visible = pos.y - start_y + page_scroll >= 0.0f; selected_line_bottom_visible = pos.y - start_y + page_scroll + selected_item_height <= size.y; @@ -491,6 +591,7 @@ namespace QuickMedia { draw_item(window, item.get(), prev_pos, size, item_height, i, content_progress); glDisable(GL_SCISSOR_TEST); ++num_visible_items; + first_fully_visible_item = i; } offset_to_top = prev_pos.y - start_y; @@ -535,6 +636,8 @@ namespace QuickMedia { } } + if(first_fully_visible_item == -1) + first_fully_visible_item = selected_item; if(last_fully_visible_item == -1) last_fully_visible_item = selected_item; @@ -571,7 +674,7 @@ namespace QuickMedia { if(body_item->title_text) body_item->title_text->setString(std::move(str)); else - body_item->title_text = std::make_unique<Text>(std::move(str), false, 16, width); + body_item->title_text = std::make_unique<Text>(std::move(str), false, 16 * get_ui_scale(), width); body_item->title_text->setFillColor(body_item->get_title_color()); body_item->title_text->updateGeometry(); } @@ -582,7 +685,7 @@ namespace QuickMedia { if(body_item->description_text) body_item->description_text->setString(std::move(str)); else - body_item->description_text = std::make_unique<Text>(std::move(str), false, 14, width); + body_item->description_text = std::make_unique<Text>(std::move(str), false, 14 * get_ui_scale(), width); body_item->description_text->setFillColor(body_item->get_description_color()); body_item->description_text->updateGeometry(); } @@ -593,7 +696,7 @@ namespace QuickMedia { if(body_item->author_text) body_item->author_text->setString(std::move(str)); else - body_item->author_text = std::make_unique<Text>(std::move(str), true, 14, width); + body_item->author_text = std::make_unique<Text>(std::move(str), true, 14 * get_ui_scale(), width); body_item->author_text->setFillColor(body_item->get_author_color()); body_item->author_text->updateGeometry(); } @@ -621,7 +724,7 @@ namespace QuickMedia { if(body_item->timestamp_text) body_item->timestamp_text->setString(time_str); else - body_item->timestamp_text = std::make_unique<sf::Text>(time_str, *FontLoader::get_font(FontLoader::FontType::LATIN), 10); + body_item->timestamp_text = std::make_unique<sf::Text>(time_str, *FontLoader::get_font(FontLoader::FontType::LATIN), 10 * get_ui_scale()); body_item->timestamp_text->setFillColor(sf::Color(185, 190, 198, 100)); } @@ -648,10 +751,11 @@ namespace QuickMedia { sf::Vector2i Body::get_item_thumbnail_size(BodyItem *item) const { sf::Vector2i content_size; + sf::Vector2i thumbnail_max_size_scaled(thumbnail_max_size.x * get_ui_scale(), thumbnail_max_size.y * get_ui_scale()); if(item->thumbnail_size.x > 0 && item->thumbnail_size.y > 0) - content_size = clamp_to_size(item->thumbnail_size, thumbnail_max_size); + content_size = clamp_to_size(sf::Vector2i(item->thumbnail_size.x * get_ui_scale(), item->thumbnail_size.y * get_ui_scale()), thumbnail_max_size_scaled); else - content_size = thumbnail_max_size; + content_size = thumbnail_max_size_scaled; return content_size; } @@ -779,9 +883,9 @@ namespace QuickMedia { } } - const float timestamp_text_y = std::floor(item_pos.y + padding_y - 6.0f); + const float timestamp_text_y = std::floor(item_pos.y + padding_y - 6.0f * get_ui_scale()); if(item->author_text) { - item->author_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - 6.0f)); + item->author_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - 6.0f * get_ui_scale())); item->author_text->setMaxWidth(size.x - text_offset_x - image_padding_x); item->author_text->draw(window); @@ -798,7 +902,7 @@ namespace QuickMedia { replies_text.setString(std::move(replies_text_str)); window.draw(replies_text); - item_pos.y += item->author_text->getHeight() - 2.0f; + item_pos.y += item->author_text->getHeight() - 2.0f + 3.0f * get_ui_scale(); } if(include_embedded_item && item->embedded_item_status != FetchStatus::NONE) { @@ -826,15 +930,15 @@ namespace QuickMedia { //title_text.setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y)); //window.draw(title_text); if(item->title_text) { - item->title_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - 6.0f)); + item->title_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - 6.0f * get_ui_scale())); item->title_text->setMaxWidth(size.x - text_offset_x - image_padding_x); item->title_text->draw(window); - item_pos.y += item->title_text->getHeight() - 2.0f; + item_pos.y += item->title_text->getHeight() - 2.0f + 3.0f * get_ui_scale(); } if(item->description_text) { float height_offset = 0.0f; - item->description_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - 6.0f + height_offset)); + item->description_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - 6.0f * get_ui_scale() + height_offset)); item->description_text->setMaxWidth(size.x - text_offset_x - image_padding_x); item->description_text->draw(window); item_pos.y += item->description_text->getHeight() - 2.0f; @@ -860,7 +964,7 @@ namespace QuickMedia { reaction.text->draw(window); if(text_offset_x + reaction_offset_x + reaction.text->getWidth() + reaction_background_padding_x * 2.0f > size.x && i < (int)item->reactions.size() - 1) { reaction_offset_x = 0.0f; - item_pos.y += reaction.text->getHeight() + reaction_padding_y + 6.0f; + item_pos.y += reaction.text->getHeight() + reaction_padding_y + 6.0f * get_ui_scale(); reaction_max_height = reaction.text->getHeight(); } } @@ -884,7 +988,7 @@ namespace QuickMedia { 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), timestamp_text_y + 6.0f); + progress_text.setPosition(std::floor(item_pos.x + size.x - bounds.width - padding_x), timestamp_text_y + 6.0f * get_ui_scale()); window.draw(progress_text); } } @@ -941,10 +1045,10 @@ namespace QuickMedia { float item_height = 0.0f; if(item->title_text) { - item_height += item->title_text->getHeight() - 2.0f; + item_height += item->title_text->getHeight() - 2.0f + 3.0f * get_ui_scale(); } if(item->author_text) { - item_height += item->author_text->getHeight() - 2.0f; + item_height += item->author_text->getHeight() - 2.0f + 3.0f * get_ui_scale(); } if(include_embedded_item && item->embedded_item_status != FetchStatus::NONE) { if(item->embedded_item) |