aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Body.cpp164
-rw-r--r--src/Entry.cpp15
-rw-r--r--src/QuickMedia.cpp103
-rw-r--r--src/SearchBar.cpp21
-rw-r--r--src/Text.cpp23
-rw-r--r--src/Utils.cpp58
-rw-r--r--src/plugins/Matrix.cpp4
7 files changed, 289 insertions, 99 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)
diff --git a/src/Entry.cpp b/src/Entry.cpp
index c18006f..facb615 100644
--- a/src/Entry.cpp
+++ b/src/Entry.cpp
@@ -1,22 +1,23 @@
#include "../include/Entry.hpp"
#include "../include/ResourceLoader.hpp"
+#include "../include/Utils.hpp"
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Window/Event.hpp>
#include <cmath>
-const float background_margin_horizontal = 5.0f;
-const float padding_vertical = 3.0f;
-const float background_margin_vertical = 0.0f;
+const float background_margin_horizontal = 5.0f * QuickMedia::get_ui_scale();
+const float padding_vertical = 3.0f * QuickMedia::get_ui_scale();
+const float background_margin_vertical = 0.0f * QuickMedia::get_ui_scale();
namespace QuickMedia {
Entry::Entry(const std::string &placeholder_text) :
on_submit_callback(nullptr),
draw_background(true),
- text("", false, 16, 0.0f),
+ text("", false, 16 * get_ui_scale(), 0.0f),
width(0.0f),
background(sf::Vector2f(1.0f, 1.0f), 7.0f, 10),
- placeholder(placeholder_text, *FontLoader::get_font(FontLoader::FontType::LATIN), 16)
+ placeholder(placeholder_text, *FontLoader::get_font(FontLoader::FontType::LATIN), 16 * get_ui_scale())
{
text.setEditable(true);
background.setFillColor(sf::Color(55, 60, 68));
@@ -74,8 +75,8 @@ namespace QuickMedia {
void Entry::set_position(const sf::Vector2f &pos) {
background.setPosition(pos);
- text.setPosition(pos + sf::Vector2f(background_margin_horizontal, background_margin_vertical - 3.0f));
- placeholder.setPosition(pos + sf::Vector2f(background_margin_horizontal, background_margin_vertical + 3.0f));
+ text.setPosition(pos + sf::Vector2f(background_margin_horizontal, background_margin_vertical - 3.0f * get_ui_scale()));
+ placeholder.setPosition(pos + sf::Vector2f(background_margin_horizontal, background_margin_vertical + 3.0f * get_ui_scale()));
}
void Entry::set_max_width(float width) {
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index e515c7a..e080cbc 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -25,6 +25,7 @@
#include "../include/SfmlFixes.hpp"
#include "../include/ResourceLoader.hpp"
#include "../include/AsyncTask.hpp"
+#include "../include/Utils.hpp"
#include "../external/hash-library/sha256.h"
#include <assert.h>
@@ -46,10 +47,10 @@
static const sf::Color back_color(21, 25, 30);
static const std::string fourchan_google_captcha_api_key = "6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc";
-static const float tab_text_size = 16.0f;
-static const float tab_height = tab_text_size + 10.0f;
+static const float tab_text_size = 16.0f * QuickMedia::get_ui_scale();
+static const float tab_height = tab_text_size + 10.0f * QuickMedia::get_ui_scale();
static const sf::Color tab_selected_color(55, 60, 68);
-static const float tab_margin_x = 10.0f;
+static const float tab_margin_x = 10.0f * QuickMedia::get_ui_scale();
static int FPS_IDLE = 2;
static const double IDLE_TIMEOUT_SEC = 2.0;
@@ -747,12 +748,15 @@ namespace QuickMedia {
}
void Program::event_idle_handler(const sf::Event &event) {
- if(event.type == sf::Event::KeyPressed || event.type == sf::Event::TextEntered) {
- if(idle)
- window.setFramerateLimit(monitor_hz);
- idle = false;
- idle_timer.restart();
- }
+ if(event.type == sf::Event::KeyPressed || event.type == sf::Event::TextEntered)
+ idle_active_handler();
+ }
+
+ void Program::idle_active_handler() {
+ if(idle)
+ window.setFramerateLimit(monitor_hz);
+ idle = false;
+ idle_timer.restart();
}
void Program::update_idle_state() {
@@ -925,12 +929,12 @@ namespace QuickMedia {
static void get_body_dimensions(const sf::Vector2f &window_size, SearchBar *search_bar, sf::Vector2f &body_pos, sf::Vector2f &body_size, bool has_tabs = false) {
float body_padding_horizontal = 25.0f;
- float body_padding_vertical = 25.0f;
+ float body_padding_vertical = 25.0f * get_ui_scale();
float body_width = window_size.x - body_padding_horizontal * 2.0f;
if(body_width <= 480.0f) {
body_width = window_size.x;
body_padding_horizontal = 0.0f;
- body_padding_vertical = 10.0f;
+ body_padding_vertical = 10.0f * get_ui_scale();
}
float tab_h = tab_height;
@@ -997,17 +1001,17 @@ namespace QuickMedia {
{
float shade_extra_height = 0.0f;
if(!tabs[selected_tab].search_bar)
- shade_extra_height = 10.0f;
+ shade_extra_height = 10.0f * get_ui_scale();
const float width_per_tab = window_size.x / tabs.size();
tab_background.setSize(sf::Vector2f(std::floor(width_per_tab - tab_margin_x * 2.0f), tab_height));
float tab_vertical_offset = tabs[selected_tab].search_bar ? tabs[selected_tab].search_bar->getBottomWithoutShadow() : 0.0f;
tabs[selected_tab].body->draw(window, body_pos, body_size, *json_chapters);
- const float tab_y = std::floor(tab_vertical_offset + tab_height * 0.5f - (tab_text_size + 5.0f) * 0.5f) + shade_extra_height;
+ const float tab_y = std::floor(tab_vertical_offset + tab_height * 0.5f - (tab_text_size + 5.0f * get_ui_scale()) * 0.5f) + shade_extra_height;
tab_shade.setPosition(0.0f, std::floor(tab_vertical_offset));
- tab_shade.setSize(sf::Vector2f(window_size.x, shade_extra_height + tab_height + 10.0f));
+ tab_shade.setSize(sf::Vector2f(window_size.x, shade_extra_height + tab_height + 10.0f * get_ui_scale()));
window.draw(tab_shade);
int i = 0;
@@ -1076,7 +1080,7 @@ namespace QuickMedia {
std::vector<TabAssociatedData> tab_associated_data;
for(size_t i = 0; i < tabs.size(); ++i) {
TabAssociatedData data;
- data.search_result_text = sf::Text("", *FontLoader::get_font(FontLoader::FontType::LATIN), 30);
+ data.search_result_text = sf::Text("", *FontLoader::get_font(FontLoader::FontType::LATIN), 30 * get_ui_scale());
tab_associated_data.push_back(std::move(data));
}
@@ -1247,7 +1251,11 @@ namespace QuickMedia {
while (window.isOpen() && loop_running) {
sf::Int32 frame_time_ms = frame_timer.restart().asMilliseconds();
while (window.pollEvent(event)) {
- event_idle_handler(event);
+ if(tabs[selected_tab].body->on_event(window, event))
+ idle_active_handler();
+ else
+ event_idle_handler(event);
+
if (event.type == sf::Event::Closed) {
window.close();
} else if(event.type == sf::Event::Resized) {
@@ -2258,7 +2266,7 @@ namespace QuickMedia {
sf::Texture image_texture;
sf::Sprite image;
- sf::Text error_message("", *FontLoader::get_font(FontLoader::FontType::LATIN), 30);
+ sf::Text error_message("", *FontLoader::get_font(FontLoader::FontType::LATIN), 30 * get_ui_scale());
error_message.setFillColor(sf::Color::White);
bool download_in_progress = false;
@@ -2322,7 +2330,7 @@ namespace QuickMedia {
bool error = !error_message.getString().isEmpty();
bool redraw = true;
- sf::Text chapter_text(images_page->manga_name + " | " + images_page->get_chapter_name() + " | Page " + std::to_string(image_index + 1) + "/" + std::to_string(num_images), *FontLoader::get_font(FontLoader::FontType::LATIN), 14);
+ sf::Text chapter_text(images_page->manga_name + " | " + images_page->get_chapter_name() + " | Page " + std::to_string(image_index + 1) + "/" + std::to_string(num_images), *FontLoader::get_font(FontLoader::FontType::LATIN), 14 * get_ui_scale());
if(image_index == num_images)
chapter_text.setString(images_page->manga_name + " | " + images_page->get_chapter_name() + " | End");
chapter_text.setFillColor(sf::Color::White);
@@ -2591,7 +2599,7 @@ namespace QuickMedia {
sf::Sprite attached_image_sprite;
GoogleCaptchaChallengeInfo challenge_info;
- sf::Text challenge_description_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), 24);
+ sf::Text challenge_description_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), 24 * get_ui_scale());
challenge_description_text.setFillColor(sf::Color::White);
const size_t captcha_num_columns = 3;
const size_t captcha_num_rows = 3;
@@ -2713,14 +2721,14 @@ namespace QuickMedia {
comment_input_shade.setFillColor(sf::Color(31, 35, 41));
sf::Sprite logo_sprite(plugin_logo);
- logo_sprite.setScale(0.8f, 0.8f);
+ logo_sprite.setScale(0.8f * get_ui_scale(), 0.8f * get_ui_scale());
sf::Vector2f logo_size(plugin_logo.getSize().x * logo_sprite.getScale().x, plugin_logo.getSize().y * logo_sprite.getScale().y);
float prev_chat_height = comment_input.get_height();
float chat_input_height_full = 0.0f;
- const float logo_padding_x = 15.0f;
- const float chat_input_padding_x = 10.0f;
- const float chat_input_padding_y = 10.0f;
+ const float logo_padding_x = 15.0f * get_ui_scale();
+ const float chat_input_padding_x = 10.0f * get_ui_scale();
+ const float chat_input_padding_y = 10.0f * get_ui_scale();
sf::Vector2f body_pos;
sf::Vector2f body_size;
@@ -2733,6 +2741,11 @@ namespace QuickMedia {
while (current_page == PageType::IMAGE_BOARD_THREAD && window.isOpen()) {
while (window.pollEvent(event)) {
+ if(navigation_stage == NavigationStage::REPLYING || navigation_stage == NavigationStage::VIEWING_COMMENTS) {
+ if(thread_body->on_event(window, event))
+ idle_active_handler();
+ }
+
event_idle_handler(event);
if(navigation_stage == NavigationStage::REPLYING && !frame_skip_text_entry) {
comment_input.process_event(event);
@@ -2927,7 +2940,7 @@ namespace QuickMedia {
comment_input.set_position(sf::Vector2f(std::floor(logo_padding_x + logo_size.x + chat_input_padding_x), chat_input_padding_y));
float body_padding_horizontal = 25.0f;
- float body_padding_vertical = 5.0f;
+ float body_padding_vertical = 5.0f * get_ui_scale();
float body_width = window_size.x - body_padding_horizontal * 2.0f;
if(body_width <= 480.0f) {
body_width = window_size.x;
@@ -3056,7 +3069,7 @@ namespace QuickMedia {
SearchBar password_input(nullptr, "Password", true);
SearchBar homeserver_input(nullptr, "Homeserver");
- sf::Text status_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), 18);
+ sf::Text status_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), 18 * get_ui_scale());
const int num_inputs = 3;
SearchBar *inputs[num_inputs] = { &login_input, &password_input, &homeserver_input };
@@ -3095,7 +3108,11 @@ namespace QuickMedia {
while (current_page == PageType::CHAT_LOGIN && window.isOpen()) {
while (window.pollEvent(event)) {
- event_idle_handler(event);
+ if(body->on_event(window, event))
+ idle_active_handler();
+ else
+ event_idle_handler(event);
+
if (event.type == sf::Event::Closed) {
current_page = PageType::EXIT;
window.close();
@@ -3270,15 +3287,15 @@ namespace QuickMedia {
ChatState chat_state = ChatState::NAVIGATING;
std::shared_ptr<BodyItem> currently_operating_on_item;
- sf::Text replying_to_text("Replying to:", *FontLoader::get_font(FontLoader::FontType::LATIN), 18);
+ sf::Text replying_to_text("Replying to:", *FontLoader::get_font(FontLoader::FontType::LATIN), 18 * get_ui_scale());
sf::Sprite logo_sprite(plugin_logo);
- logo_sprite.setScale(0.8f, 0.8f);
+ logo_sprite.setScale(0.8f * get_ui_scale(), 0.8f * get_ui_scale());
sf::Vector2f logo_size(plugin_logo.getSize().x * logo_sprite.getScale().x, plugin_logo.getSize().y * logo_sprite.getScale().y);
- sf::Text room_name_text("", *FontLoader::get_font(FontLoader::FontType::LATIN_BOLD), 18);
- const float room_name_text_height = 20.0f;
- const float room_name_text_padding_y = 10.0f;
+ sf::Text room_name_text("", *FontLoader::get_font(FontLoader::FontType::LATIN_BOLD), 18 * get_ui_scale());
+ const float room_name_text_height = 18.0f * get_ui_scale();
+ const float room_name_text_padding_y = 10.0f * get_ui_scale();
const float room_name_total_height = room_name_text_height + room_name_text_padding_y * 2.0f;
const float room_avatar_height = 32.0f;
@@ -4015,9 +4032,9 @@ namespace QuickMedia {
float prev_chat_height = chat_input.get_height();
float chat_input_height_full = 0.0f;
- const float logo_padding_x = 15.0f;
- const float chat_input_padding_x = 10.0f;
- const float chat_input_padding_y = 10.0f;
+ const float logo_padding_x = 15.0f * get_ui_scale();
+ const float chat_input_padding_x = 10.0f * get_ui_scale();
+ const float chat_input_padding_y = 10.0f * get_ui_scale();
auto launch_url = [this, &video_page, &redraw](const std::string &url) mutable {
if(url.empty())
@@ -4268,6 +4285,14 @@ namespace QuickMedia {
while (current_page == PageType::CHAT && window.isOpen()) {
sf::Int32 frame_time_ms = frame_timer.restart().asMilliseconds();
while (window.pollEvent(event)) {
+ if(chat_state == ChatState::URL_SELECTION) {
+ if(url_selection_body.on_event(window, event))
+ idle_active_handler();
+ } else {
+ if(tabs[selected_tab].body->on_event(window, event))
+ idle_active_handler();
+ }
+
base_event_handler(event, PageType::EXIT, tabs[selected_tab].body.get(), nullptr, false, false);
event_idle_handler(event);
@@ -4622,7 +4647,7 @@ namespace QuickMedia {
float width_ratio = (float)texture_size.x / (float)texture_size.y;
float height_scale = room_avatar_height / (float)texture_size.y;
float width_scale = height_scale * width_ratio;
- room_avatar_sprite.setScale(width_scale, height_scale);
+ room_avatar_sprite.setScale(width_scale * get_ui_scale(), height_scale * get_ui_scale());
}
}
@@ -4647,13 +4672,13 @@ namespace QuickMedia {
float padding_bottom = 0.0f;
if(selected_tab == MESSAGES_TAB_INDEX || selected_tab == PINNED_TAB_INDEX) {
room_name_padding_y = 10.0f + room_name_total_height;
- tab_vertical_offset = 10.0f;
+ tab_vertical_offset = 10.0f * get_ui_scale();
}
tab_shade_height = tab_spacer_height + std::floor(tab_vertical_offset) + tab_height + room_name_padding_y + padding_bottom;
float body_padding_horizontal = 25.0f;
- float body_padding_vertical = 5.0f;
+ float body_padding_vertical = 5.0f * get_ui_scale();
float body_width = window_size.x - body_padding_horizontal * 2.0f;
if(body_width <= 480.0f) {
body_width = window_size.x;
@@ -4661,8 +4686,8 @@ namespace QuickMedia {
}
this->body_pos = sf::Vector2f(0.0f, tab_shade_height);
- if(body_width > 640.0f && show_room_side_panel) {
- this->body_size = sf::Vector2f(300.0f, window_size.y - tab_shade_height);
+ if(window_size.x > 900.0f && show_room_side_panel) {
+ this->body_size = sf::Vector2f(300.0f * get_ui_scale(), window_size.y - tab_shade_height);
draw_room_list = true;
} else {
this->body_size = sf::Vector2f(0.0f, 0.0f);
diff --git a/src/SearchBar.cpp b/src/SearchBar.cpp
index 9b5e882..8232033 100644
--- a/src/SearchBar.cpp
+++ b/src/SearchBar.cpp
@@ -1,6 +1,7 @@
#include "../include/SearchBar.hpp"
#include "../include/Scale.hpp"
#include "../include/ResourceLoader.hpp"
+#include "../include/Utils.hpp"
#include <SFML/Window/Event.hpp>
#include <SFML/Window/Clipboard.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
@@ -11,11 +12,11 @@
static const sf::Color text_placeholder_color(255, 255, 255, 100);
static const sf::Color front_color(55, 60, 68);
-static const float background_margin_horizontal = 15.0f;
-static const float PADDING_HORIZONTAL = 25.0f;
-static const float padding_top = 10.0f;
-static const float padding_bottom = 15.0f;
-static const float background_margin_vertical = 4.0f;
+static const float background_margin_horizontal = 10.0f + 5.0f * QuickMedia::get_ui_scale();
+static const float PADDING_HORIZONTAL = 25.0f * QuickMedia::get_ui_scale();
+static const float padding_top = 10.0f * QuickMedia::get_ui_scale();
+static const float padding_bottom = 15.0f * QuickMedia::get_ui_scale();
+static const float background_margin_vertical = 4.0f * QuickMedia::get_ui_scale();
namespace QuickMedia {
SearchBar::SearchBar(sf::Texture *plugin_logo, const std::string &placeholder, bool input_masked) :
@@ -26,8 +27,8 @@ namespace QuickMedia {
text_autosearch_delay(0),
autocomplete_search_delay(0),
caret_visible(true),
- text(placeholder, *FontLoader::get_font(FontLoader::FontType::LATIN), 16),
- autocomplete_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), 16),
+ text(placeholder, *FontLoader::get_font(FontLoader::FontType::LATIN), 16 * get_ui_scale()),
+ autocomplete_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), 16 * get_ui_scale()),
background(sf::Vector2f(1.0f, 1.0f), 10.0f, 10),
placeholder_str(placeholder),
show_placeholder(true),
@@ -144,14 +145,14 @@ namespace QuickMedia {
sf::Vector2f texture_size_f(texture_size.x, texture_size.y);
sf::Vector2f new_size = wrap_to_size(texture_size_f, sf::Vector2f(200.0f, one_line_height));
plugin_logo_sprite.setScale(get_ratio(texture_size_f, new_size));
- plugin_logo_sprite.setPosition(25.0f, padding_top + vertical_pos);
+ plugin_logo_sprite.setPosition(25.0f, padding_top + vertical_pos + rect_height * 0.5f - plugin_logo_sprite.getTexture()->getSize().y * plugin_logo_sprite.getScale().y * 0.5f);
offset_x = 25.0f + new_size.x + 25.0f;
}
- const float width = std::floor(window_size.x - offset_x - padding_horizontal);
+ const float width = std::floor(window_size.x - offset_x - 25.0f);
background.setSize(sf::Vector2f(width, rect_height));
shade.setSize(sf::Vector2f(window_size.x, padding_top + rect_height + padding_bottom));
- caret.setSize(sf::Vector2f(2.0f, text.getCharacterSize() + 2.0f));
+ caret.setSize(sf::Vector2f(2.0f * get_ui_scale(), text.getCharacterSize() + 2.0f * get_ui_scale()));
background_shadow.setSize(sf::Vector2f(window_size.x, 5.0f));
background.setPosition(offset_x, padding_top + vertical_pos);
diff --git a/src/Text.cpp b/src/Text.cpp
index ca59146..a84a824 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -1,5 +1,6 @@
#include "../include/Text.hpp"
#include "../include/ResourceLoader.hpp"
+#include "../include/Utils.hpp"
#include "../generated/Emoji.hpp"
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Window/Clipboard.hpp>
@@ -11,9 +12,9 @@
namespace QuickMedia
{
- const float TAB_WIDTH = 4.0f;
-
- const sf::Color URL_COLOR(15, 192, 252);
+ static const float TAB_WIDTH = 4.0f;
+ static const sf::Color URL_COLOR(15, 192, 252);
+ static const float WORD_WRAP_MIN_SIZE = 80.0f;
size_t StringViewUtf32::find(const StringViewUtf32 &other, size_t offset) const {
if(offset >= size)
@@ -365,10 +366,10 @@ namespace QuickMedia
EmojiRectangle emoji_rec = emoji_get_extents(codePoint);
const float font_height_offset = -latin_font_height * 1.2f;
- sf::Vector2f vertexTopLeft(glyphPos.x, glyphPos.y + font_height_offset - emoji_rec.height * 0.5f);
- sf::Vector2f vertexTopRight(glyphPos.x + emoji_rec.width, glyphPos.y + font_height_offset - emoji_rec.height * 0.5f);
- sf::Vector2f vertexBottomLeft(glyphPos.x, glyphPos.y + font_height_offset + emoji_rec.height * 0.5f);
- sf::Vector2f vertexBottomRight(glyphPos.x + emoji_rec.width, glyphPos.y + font_height_offset + emoji_rec.height * 0.5f);
+ sf::Vector2f vertexTopLeft(glyphPos.x, glyphPos.y + font_height_offset - emoji_rec.height * get_ui_scale() * 0.5f);
+ sf::Vector2f vertexTopRight(glyphPos.x + emoji_rec.width * get_ui_scale(), glyphPos.y + font_height_offset - emoji_rec.height * get_ui_scale() * 0.5f);
+ sf::Vector2f vertexBottomLeft(glyphPos.x, glyphPos.y + font_height_offset + emoji_rec.height * get_ui_scale() * 0.5f);
+ sf::Vector2f vertexBottomRight(glyphPos.x + emoji_rec.width * get_ui_scale(), glyphPos.y + font_height_offset + emoji_rec.height * get_ui_scale() * 0.5f);
sf::Vector2f textureTopLeft(emoji_rec.x, emoji_rec.y);
sf::Vector2f textureTopRight(emoji_rec.x + emoji_rec.width, emoji_rec.y);
@@ -525,7 +526,7 @@ namespace QuickMedia
}
float vertex_right_side = get_text_quad_right_side(vertex_ref);
- if(vertex_right_side > maxWidth) {
+ if(vertex_right_side > maxWidth && maxWidth > WORD_WRAP_MIN_SIZE) {
++num_lines;
// TODO: Ignore line wrap on space
if(last_space_index != -1 && last_space_index != i) {
@@ -887,10 +888,10 @@ namespace QuickMedia
if(!editable) return true;
pos.y -= floor(vspace * 2.0f);
- const float caret_margin = 2.0f;
+ const float caret_margin = 2.0f * get_ui_scale();
- sf::RectangleShape caretRect(sf::Vector2f(2.0f, floor(vspace - caret_margin * 2.0f)));
- caretRect.setPosition(floor(pos.x + caretPosition.x), floor(pos.y + caretPosition.y + caret_margin + 4.0f));
+ sf::RectangleShape caretRect(sf::Vector2f(2.0f * get_ui_scale(), floor(vspace - caret_margin * 2.0f)));
+ caretRect.setPosition(floor(pos.x + caretPosition.x), floor(pos.y + caretPosition.y + caret_margin + 4.0f * get_ui_scale()));
target.draw(caretRect);
return true;
}
diff --git a/src/Utils.cpp b/src/Utils.cpp
new file mode 100644
index 0000000..2c3bfb7
--- /dev/null
+++ b/src/Utils.cpp
@@ -0,0 +1,58 @@
+#include "../include/Utils.hpp"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <locale.h>
+
+namespace QuickMedia {
+ static float scale = 1.0f;
+ static bool scale_set = false;
+
+ static const int XFT_DPI_DEFAULT = 96;
+ // Returns 96 on error
+ static int xrdb_get_dpi() {
+ int xft_dpi = XFT_DPI_DEFAULT;
+
+ FILE *xrdb_query = popen("xrdb -query", "r");
+ if(!xrdb_query)
+ return xft_dpi;
+
+ char line[512];
+ while(fgets(line, sizeof(line), xrdb_query)) {
+ int line_length = strlen(line);
+ if(line_length > 0 && line[line_length - 1] == '\n') {
+ line[line_length - 1] = '\0';
+ line_length--;
+ }
+
+ if(line_length > 8 && memcmp(line, "Xft.dpi:", 8) == 0) {
+ int xft_dpi_file = atoi(line + 8);
+ if(xft_dpi_file > 0) {
+ xft_dpi = xft_dpi_file;
+ break;
+ }
+ }
+ }
+
+ pclose(xrdb_query);
+ return xft_dpi;
+ }
+
+ float get_ui_scale() {
+ if(scale_set)
+ return scale;
+
+ char *gdk_scale = getenv("GDK_SCALE");
+ if(gdk_scale) {
+ setlocale(LC_ALL, "C"); // Sigh... stupid C
+ scale = atof(gdk_scale);
+ if(scale < 0.0001f)
+ scale = 1.0f;
+ } else {
+ scale = (float)xrdb_get_dpi() / (float)XFT_DPI_DEFAULT;
+ }
+
+ scale_set = true;
+ return scale;
+ }
+} \ No newline at end of file
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index 046fe91..aa6de40 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -3005,7 +3005,7 @@ namespace QuickMedia {
auto fetched_message_it = room->fetched_messages_by_event_id.find(event_id);
if(fetched_message_it != room->fetched_messages_by_event_id.end())
return fetched_message_it->second;
-#if 0
+#if 1
rapidjson::Document request_data(rapidjson::kObjectType);
request_data.AddMember("lazy_load_members", true, request_data.GetAllocator());
@@ -3084,7 +3084,7 @@ namespace QuickMedia {
events_add_user_info(state_json, room);
#endif
//events_set_room_name(state_json, room);
-#if 0
+#if 1
const rapidjson::Value &event_json = GetMember(json_root, "event");
std::shared_ptr<Message> new_message = parse_message_event(event_json, room);
#else