aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AsyncImageLoader.cpp2
-rw-r--r--src/Body.cpp137
-rw-r--r--src/QuickMedia.cpp43
-rw-r--r--src/plugins/Matrix.cpp15
4 files changed, 134 insertions, 63 deletions
diff --git a/src/AsyncImageLoader.cpp b/src/AsyncImageLoader.cpp
index d0a67c4..9792781 100644
--- a/src/AsyncImageLoader.cpp
+++ b/src/AsyncImageLoader.cpp
@@ -164,6 +164,8 @@ namespace QuickMedia {
SHA256 sha256;
sha256.add(url.data(), url.size());
Path thumbnail_path = get_cache_dir().join("thumbnails").join(sha256.getHash());
+ if(resize_target_size.x != 0 && resize_target_size.y != 0)
+ thumbnail_path.append("_" + std::to_string(resize_target_size.x) + "x" + std::to_string(resize_target_size.y));
if(get_file_type(thumbnail_path) == FileType::REGULAR) {
thumbnail_data->loading_state = LoadingState::LOADING;
image_load_queue.push({ url, thumbnail_path, local, thumbnail_data, resize_target_size });
diff --git a/src/Body.cpp b/src/Body.cpp
index 293f516..667232e 100644
--- a/src/Body.cpp
+++ b/src/Body.cpp
@@ -136,6 +136,10 @@ namespace QuickMedia {
item_background.setFillColor(sf::Color(55, 60, 68));
sf::Vector2f loading_icon_size(loading_icon.getTexture()->getSize().x, loading_icon.getTexture()->getSize().y);
loading_icon.setOrigin(loading_icon_size.x * 0.5f, loading_icon_size.y * 0.5f);
+ const char *qm_enable_touch = getenv("QM_ENABLE_TOUCH");
+ if(qm_enable_touch && qm_enable_touch[0] == '1') {
+ experimental_use_touch = true;
+ }
}
// TODO: Make this work with wraparound enabled?
@@ -372,35 +376,48 @@ namespace QuickMedia {
}
bool Body::on_event(const sf::RenderWindow &window, const sf::Event &event) {
- #if 0
+ if(!experimental_use_touch)
+ return false;
+
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(sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
+ auto mpos = sf::Mouse::getPosition(window);
+ if(sf::FloatRect(body_pos, body_size).contains(sf::Vector2f(mpos.x, mpos.y))) {
+ mouse_left_pressed = true;
+ mouse_pos_raw = sf::Mouse::getPosition(window);
+ mouse_pos = sf::Vector2f(mouse_pos_raw.x, mouse_pos_raw.y);
+ prev_mouse_pos = mouse_pos;
+ mouse_click_pos = mouse_pos;
+ mouse_press_pixels_moved_abs = 0.0;
+ return true;
+ }
}
}
- if(event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left && !mouse_left_pressed) {
+ if(event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left && !mouse_left_pressed && sf::FloatRect(body_pos, body_size).contains(sf::Vector2f(event.mouseButton.x, event.mouseButton.y))) {
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;
+ mouse_click_pos = mouse_pos;
+ mouse_press_pixels_moved_abs = 0.0;
return true;
} else if(event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left && mouse_left_pressed) {
mouse_left_pressed = false;
+ mouse_left_clicked = true;
+ mouse_release_pos = sf::Vector2f(event.mouseButton.x, event.mouseButton.y);
return true;
} else if(event.type == sf::Event::MouseMoved && mouse_left_pressed) {
+ sf::Vector2i mouse_pos_diff(event.mouseMove.x - mouse_pos_raw.x, event.mouseMove.y - mouse_pos_raw.y);
+ mouse_press_pixels_moved_abs += std::sqrt(mouse_pos_diff.x*mouse_pos_diff.x + mouse_pos_diff.y*mouse_pos_diff.y);
mouse_pos_raw.x = event.mouseMove.x;
mouse_pos_raw.y = event.mouseMove.y;
return true;
}
- #endif
return false;
}
@@ -415,51 +432,60 @@ namespace QuickMedia {
sf::Vector2f scissor_size = size;
const float start_y = pos.y;
+ body_pos = pos;
+ body_size = size;
+
elapsed_time_sec = draw_timer.getElapsedTime().asSeconds();
-#if 0
- 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);
+ if(experimental_use_touch) {
+ 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(items_cut_off) {
+ 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;
+ }
+ }
+
+ if(!mouse_left_pressed) {
+ 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);
+ }
}
}
-#endif
//item_background.setFillColor(front_color);
//item_background.setOutlineThickness(1.0f);
@@ -483,6 +509,7 @@ namespace QuickMedia {
items_cut_off = false;
offset_to_top = 0.0f;
offset_to_bottom = 0.0f;
+ mouse_left_clicked = false;
return;
}
@@ -559,6 +586,7 @@ namespace QuickMedia {
page_scroll = 0.0f;
}
+ page_scroll = std::floor(page_scroll);
pos.y += page_scroll;
bool last_item_fully_visible_set = false;
@@ -650,6 +678,8 @@ namespace QuickMedia {
if(!items_cut_off_set)
items_cut_off = false;
+ mouse_left_clicked = false;
+
for(auto it = item_thumbnail_textures.begin(); it != item_thumbnail_textures.end();) {
if(!it->second->referenced)
it = item_thumbnail_textures.erase(it);
@@ -813,6 +843,15 @@ namespace QuickMedia {
item_pos.x = std::floor(pos.x);
item_pos.y = std::floor(pos.y);
+ if(body_item_select_callback && mouse_left_clicked) {
+ sf::FloatRect item_box(pos, sf::Vector2f(size.x, item_height));
+ // TODO: Scale mouse_press_pixels_moved_abs with monitor PPI instead of using get_ui_scale()
+ if(item_box.contains(mouse_click_pos) && item_box.contains(mouse_release_pos) && mouse_press_pixels_moved_abs <= 50.0 * get_ui_scale()) {
+ set_selected_item(item_index, false);
+ body_item_select_callback(item);
+ }
+ }
+
item_separator.setSize(sf::Vector2f(std::max(0.0f, size.x - 20.0f), 1.0f));
item_separator.setPosition(item_pos + sf::Vector2f(10.0f, std::floor(item_height + spacing_y * 0.5f)));
window.draw(item_separator);
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index d54229f..61b2d1b 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -53,6 +53,7 @@ static const sf::Color tab_selected_color(55, 60, 68);
static const float tab_margin_x = std::floor(10.0f * QuickMedia::get_ui_scale());
static int FPS_IDLE = 2;
static const double IDLE_TIMEOUT_SEC = 2.0;
+static const sf::Vector2i AVATAR_THUMBNAIL_SIZE(std::floor(32 * QuickMedia::get_ui_scale()), std::floor(32 * QuickMedia::get_ui_scale()));
// Prevent writing to broken pipe from exiting the program
static void sigpipe_handler(int) {
@@ -1100,7 +1101,9 @@ namespace QuickMedia {
window_size.x = window_size_u.x;
window_size.y = window_size_u.y;
- auto submit_handler = [this, &after_submit_handler, &json_chapters, &tabs, &tab_associated_data, &selected_tab, &loop_running, &redraw]() {
+ std::function<void()> submit_handler;
+
+ submit_handler = [this, &submit_handler, &after_submit_handler, &json_chapters, &tabs, &tab_associated_data, &selected_tab, &loop_running, &redraw]() {
BodyItem *selected_item = tabs[selected_tab].body->get_selected();
if(!selected_item)
return;
@@ -1195,6 +1198,9 @@ namespace QuickMedia {
break;
current_chat_room = matrix->get_room_by_id(selected_item->url);
}
+ tabs[selected_tab].body->body_item_select_callback = [&submit_handler](BodyItem *body_item) {
+ submit_handler();
+ };
//select_body_item_by_room(tabs[selected_tab].body.get(), current_chat_room);
current_chat_room = nullptr;
} else {
@@ -1213,6 +1219,10 @@ namespace QuickMedia {
for(size_t i = 0; i < tabs.size(); ++i) {
Tab &tab = tabs[i];
+ tab.body->body_item_select_callback = [&submit_handler](BodyItem *body_item) {
+ submit_handler();
+ };
+
TabAssociatedData &associated_data = tab_associated_data[i];
if(!tab.search_bar)
continue;
@@ -1263,6 +1273,7 @@ namespace QuickMedia {
window_size.y = event.size.height;
sf::FloatRect visible_area(0, 0, window_size.x, window_size.y);
window.setView(sf::View(visible_area));
+ idle_active_handler();
}
if(tabs[selected_tab].search_bar) {
@@ -2767,6 +2778,7 @@ namespace QuickMedia {
window_size.y = event.size.height;
sf::FloatRect visible_area(0, 0, window_size.x, window_size.y);
window.setView(sf::View(visible_area));
+ idle_active_handler();
}
if(event.type == sf::Event::Resized || event.type == sf::Event::GainedFocus)
@@ -3122,6 +3134,7 @@ namespace QuickMedia {
sf::FloatRect visible_area(0, 0, window_size.x, window_size.y);
window.setView(sf::View(visible_area));
redraw = true;
+ idle_active_handler();
} else if(event.type == sf::Event::GainedFocus) {
redraw = true;
} else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Tab) {
@@ -3178,7 +3191,7 @@ namespace QuickMedia {
body_item->thumbnail_url = room->get_user_avatar_url(message->user);
body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
// if construct is not configured to use ImageMagic then it wont give thumbnails of size 32x32 even when requested and the spec says that the server SHOULD do that
- body_item->thumbnail_size = sf::Vector2i(32, 32);
+ body_item->thumbnail_size = AVATAR_THUMBNAIL_SIZE;
}
// TODO: Show image thumbnail inline instead of url to image and showing it as the thumbnail of the body item
body_item->url = message->url;
@@ -3345,7 +3358,7 @@ namespace QuickMedia {
}
body_item->set_description("Message deleted");
body_item->set_description_color(sf::Color::White);
- body_item->thumbnail_size = sf::Vector2i(32, 32);
+ body_item->thumbnail_size = AVATAR_THUMBNAIL_SIZE;
body_item->url.clear();
};
@@ -4170,7 +4183,7 @@ namespace QuickMedia {
pinned_body_item->thumbnail_url = user_avatar_url;
pinned_body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
// if construct is not configured to use ImageMagic then it wont give thumbnails of size 32x32 even when requested and the spec says that the server SHOULD do that
- pinned_body_item->thumbnail_size = sf::Vector2i(32, 32);
+ pinned_body_item->thumbnail_size = AVATAR_THUMBNAIL_SIZE;
}
}
};
@@ -4190,7 +4203,7 @@ namespace QuickMedia {
message_body_items->thumbnail_url = user_avatar_url;
message_body_items->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
// if construct is not configured to use ImageMagic then it wont give thumbnails of size 32x32 even when requested and the spec says that the server SHOULD do that
- message_body_items->thumbnail_size = sf::Vector2i(32, 32);
+ message_body_items->thumbnail_size = AVATAR_THUMBNAIL_SIZE;
}
}
};
@@ -4209,7 +4222,7 @@ namespace QuickMedia {
pinned_body_item->thumbnail_url = current_room->get_user_avatar_url(message->user);
pinned_body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
// if construct is not configured to use ImageMagic then it wont give thumbnails of size 32x32 even when requested and the spec says that the server SHOULD do that
- pinned_body_item->thumbnail_size = sf::Vector2i(32, 32);
+ pinned_body_item->thumbnail_size = AVATAR_THUMBNAIL_SIZE;
}
}
};
@@ -4227,7 +4240,7 @@ namespace QuickMedia {
message_body_items->thumbnail_url = current_room->get_user_avatar_url(message->user);
message_body_items->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
// if construct is not configured to use ImageMagic then it wont give thumbnails of size 32x32 even when requested and the spec says that the server SHOULD do that
- message_body_items->thumbnail_size = sf::Vector2i(32, 32);
+ message_body_items->thumbnail_size = AVATAR_THUMBNAIL_SIZE;
}
}
};
@@ -4280,9 +4293,13 @@ namespace QuickMedia {
float tab_shade_height = 0.0f;
bool frame_skip_text_entry = false;
+ room_tabs[room_selected_tab].body->body_item_select_callback = [&move_room](BodyItem *body_item) {
+ move_room = true;
+ };
+
SyncData sync_data;
- while (current_page == PageType::CHAT && window.isOpen()) {
+ while (current_page == PageType::CHAT && window.isOpen() && !move_room) {
sf::Int32 frame_time_ms = frame_timer.restart().asMilliseconds();
while (window.pollEvent(event)) {
if(chat_state == ChatState::URL_SELECTION) {
@@ -4296,6 +4313,9 @@ namespace QuickMedia {
base_event_handler(event, PageType::EXIT, tabs[selected_tab].body.get(), nullptr, false, false);
event_idle_handler(event);
+ if(draw_room_list)
+ room_tabs[room_selected_tab].body->on_event(window, event);
+
if(event.type == sf::Event::KeyPressed && event.key.control && event.key.alt && (chat_state == ChatState::NAVIGATING || chat_state == ChatState::URL_SELECTION)) {
if(event.key.code == sf::Keyboard::Up || (event.key.control && event.key.code == sf::Keyboard::K)) {
room_tabs[room_selected_tab].body->select_previous_item();
@@ -4336,7 +4356,10 @@ namespace QuickMedia {
redraw = true;
} else if(event.type == sf::Event::LostFocus) {
is_window_focused = false;
- } else if(event.type == sf::Event::Resized || event.type == sf::Event::GainedFocus) {
+ } else if(event.type == sf::Event::Resized) {
+ redraw = true;
+ idle_active_handler();
+ } else if(event.type == sf::Event::GainedFocus) {
redraw = true;
} else if(event.type == sf::Event::KeyPressed && chat_state == ChatState::NAVIGATING) {
if(event.key.code == sf::Keyboard::Up || event.key.code == sf::Keyboard::PageUp || event.key.code == sf::Keyboard::Home || (event.key.control && event.key.code == sf::Keyboard::K)) {
@@ -4631,7 +4654,7 @@ namespace QuickMedia {
}
if(current_room && current_room->body_item && room_avatar_thumbnail_data->loading_state == LoadingState::NOT_LOADED)
- AsyncImageLoader::get_instance().load_thumbnail(current_room->body_item->thumbnail_url, false, sf::Vector2i(32, 32), use_tor, room_avatar_thumbnail_data);
+ AsyncImageLoader::get_instance().load_thumbnail(current_room->body_item->thumbnail_url, false, AVATAR_THUMBNAIL_SIZE, use_tor, room_avatar_thumbnail_data);
if(room_avatar_thumbnail_data->loading_state == LoadingState::FINISHED_LOADING && room_avatar_thumbnail_data->image->getSize().x > 0 && room_avatar_thumbnail_data->image->getSize().y > 0) {
if(!room_avatar_thumbnail_data->texture.loadFromImage(*room_avatar_thumbnail_data->image))
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index aa6de40..263a948 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -6,11 +6,13 @@
#include "../../include/Program.hpp"
#include "../../include/base64_url.hpp"
#include "../../include/Json.hpp"
+#include "../../include/Utils.hpp"
#include <rapidjson/document.h>
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/filereadstream.h>
#include <rapidjson/filewritestream.h>
+#include <cmath>
#include <fcntl.h>
#include <unistd.h>
#include "../../include/QuickMedia.hpp"
@@ -1602,6 +1604,11 @@ namespace QuickMedia {
return media_url.substr(start, end - start);
}
+ static std::string get_thumbnail_url(const std::string &homeserver, const std::string &mxc_id) {
+ std::string size = std::to_string(int(32 * get_ui_scale()));
+ return homeserver + "/_matrix/media/r0/thumbnail/" + mxc_id + "?width=" + size + "&height=" + size + "&method=crop";
+ }
+
std::shared_ptr<UserInfo> Matrix::parse_user_info(const rapidjson::Value &json, const std::string &user_id, RoomData *room_data) {
assert(json.IsObject());
std::string avatar_url_str;
@@ -1614,7 +1621,7 @@ namespace QuickMedia {
std::string display_name = display_name_json.IsString() ? display_name_json.GetString() : user_id;
std::string avatar_url = thumbnail_url_extract_media_id(avatar_url_str);
if(!avatar_url.empty())
- avatar_url = homeserver + "/_matrix/media/r0/thumbnail/" + avatar_url + "?width=32&height=32&method=crop"; // TODO: Remove the constant strings around to reduce memory usage (6.3mb)
+ avatar_url = get_thumbnail_url(homeserver, avatar_url); // TODO: Remove the constant strings around to reduce memory usage (6.3mb)
//auto user_info = std::make_shared<UserInfo>(room_data, user_id, std::move(display_name), std::move(avatar_url));
// Overwrites user data
//room_data->add_user(user_info);
@@ -1983,7 +1990,7 @@ namespace QuickMedia {
body = user_display_name + " changed their profile picture";
std::string new_avatar_url_str = thumbnail_url_extract_media_id(new_avatar_url_json.GetString());
if(!new_avatar_url_str.empty())
- new_avatar_url_str = homeserver + "/_matrix/media/r0/thumbnail/" + new_avatar_url_str + "?width=32&height=32&method=crop"; // TODO: Remove the constant strings around to reduce memory usage (6.3mb)
+ new_avatar_url_str = get_thumbnail_url(homeserver, new_avatar_url_str); // TODO: Remove the constant strings around to reduce memory usage (6.3mb)
room_data->set_user_avatar_url(user, std::move(new_avatar_url_str));
} else if((!new_avatar_url_json.IsString() || new_avatar_url_json.GetStringLength() == 0) && prev_avatar_url_json.IsString()) {
body = user_display_name + " removed their profile picture";
@@ -2200,7 +2207,7 @@ namespace QuickMedia {
continue;
std::string url_json_str = url_json.GetString() + 6;
- room_data->set_avatar_url(homeserver + "/_matrix/media/r0/thumbnail/" + thumbnail_url_extract_media_id(url_json_str) + "?width=32&height=32&method=crop");
+ room_data->set_avatar_url(get_thumbnail_url(homeserver, thumbnail_url_extract_media_id(url_json_str)));
room_data->avatar_is_fallback = false;
}
}
@@ -3742,7 +3749,7 @@ namespace QuickMedia {
if(avatar_url_json.IsString())
avatar_url = std::string(avatar_url_json.GetString(), avatar_url_json.GetStringLength());
if(!avatar_url.empty())
- avatar_url = homeserver + "/_matrix/media/r0/thumbnail/" + thumbnail_url_extract_media_id(avatar_url) + "?width=32&height=32&method=crop"; // TODO: Remove the constant strings around to reduce memory usage (6.3mb)
+ avatar_url = get_thumbnail_url(homeserver, thumbnail_url_extract_media_id(avatar_url)); // TODO: Remove the constant strings around to reduce memory usage (6.3mb)
room->set_user_avatar_url(user, std::move(avatar_url));
room->set_user_display_name(user, std::move(display_name));
}