aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AsyncImageLoader.cpp1
-rw-r--r--src/Body.cpp51
-rw-r--r--src/QuickMedia.cpp30
-rw-r--r--src/plugins/Matrix.cpp9
4 files changed, 60 insertions, 31 deletions
diff --git a/src/AsyncImageLoader.cpp b/src/AsyncImageLoader.cpp
index eaf4564..bfef294 100644
--- a/src/AsyncImageLoader.cpp
+++ b/src/AsyncImageLoader.cpp
@@ -70,6 +70,7 @@ namespace QuickMedia {
return "";
}
+ // TODO: Run in 5 different threads, and add download_to_file(_cache) to reduce memory usage in each (use -O curl option)
bool AsyncImageLoader::load_thumbnail(const std::string &url, bool local, sf::Vector2i resize_target_size, bool use_tor, std::shared_ptr<ThumbnailData> thumbnail_data) {
update();
diff --git a/src/Body.cpp b/src/Body.cpp
index f6800b8..11692aa 100644
--- a/src/Body.cpp
+++ b/src/Body.cpp
@@ -2,6 +2,7 @@
#include "../include/QuickMedia.hpp"
#include "../include/Scale.hpp"
#include "../plugins/Plugin.hpp"
+#include <SFML/Graphics/CircleShape.hpp>
#include <SFML/OpenGL.hpp>
#include <assert.h>
#include <cmath>
@@ -43,6 +44,8 @@ namespace QuickMedia {
draw_thumbnails(false),
wrap_around(false),
line_seperator_color(sf::Color(32, 37, 43, 255)),
+ body_item_render_callback(nullptr),
+ thumbnail_mask_shader(nullptr),
program(program),
selected_item(0),
prev_selected_item(0),
@@ -179,18 +182,12 @@ namespace QuickMedia {
page_scroll = 0.0f;
}
- // TODO: Optimize with memcpy and changing capacity before loop
void Body::prepend_items(BodyItems new_items) {
- for(auto &body_item : new_items) {
- items.insert(items.begin(), std::move(body_item));
- }
+ items.insert(items.begin(), std::make_move_iterator(new_items.begin()), std::make_move_iterator(new_items.end()));
}
- // TODO: Optimize with memcpy and changing capacity before loop
void Body::append_items(BodyItems new_items) {
- for(auto &body_item : new_items) {
- items.push_back(std::move(body_item));
- }
+ items.insert(items.end(), std::make_move_iterator(new_items.begin()), std::make_move_iterator(new_items.end()));
}
void Body::insert_item_by_timestamp(std::shared_ptr<BodyItem> body_item) {
@@ -383,19 +380,13 @@ namespace QuickMedia {
if(!item->visible)
continue;
- update_dirty_state(item.get(), size);
- item->last_drawn_time = elapsed_time;
-
- float item_height = get_item_height(item.get());
-
- if((after_pos.y - start_y) + item_height + spacing_y > size.y)
- last_item_fully_visible = false;
- else
- last_fully_visible_item = i;
-
if(after_pos.y - start_y >= size.y)
break;
+ float item_height = get_item_height(item.get());
+ update_dirty_state(item.get(), size);
+ item->last_drawn_time = elapsed_time;
+
// This is needed here rather than above the loop, since update_dirty_text cant be called inside scissor because it corrupts the text for some reason
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);
@@ -403,6 +394,11 @@ namespace QuickMedia {
glDisable(GL_SCISSOR_TEST);
after_pos.y += item_height + spacing_y;
++num_visible_items;
+
+ if(after_pos.y - start_y > size.y)
+ last_item_fully_visible = false;
+ else
+ last_fully_visible_item = i;
}
if(last_fully_visible_item == -1)
@@ -576,13 +572,26 @@ namespace QuickMedia {
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);
+ if(thumbnail_mask_shader && item->thumbnail_mask_type == ThumbnailMaskType::CIRCLE)
+ window.draw(image, thumbnail_mask_shader);
+ else
+ 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);
+ if(thumbnail_mask_shader && item->thumbnail_mask_type == ThumbnailMaskType::CIRCLE) {
+ // TODO: Use the mask shader instead, but a vertex shader is also needed for that to pass the vertex coordinates since
+ // shapes dont have texture coordinates.
+ // TODO: Cache circle shape
+ sf::CircleShape circle_shape(image_fallback.getSize().x * 0.5f);
+ circle_shape.setFillColor(sf::Color::White);
+ circle_shape.setPosition(item_pos + sf::Vector2f(image_padding_x, padding_y));
+ window.draw(circle_shape);
+ } else {
+ 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;
}
}
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index bd4b2d4..a2c936f 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -349,6 +349,11 @@ namespace QuickMedia {
abort();
}
+ if(!circle_mask_shader.loadFromFile(resources_root + "shaders/circle_mask.glsl", sf::Shader::Type::Fragment)) {
+ fprintf(stderr, "Failed to load %s/shaders/circle_mask.glsl", resources_root.c_str());
+ abort();
+ }
+
struct sigaction action;
action.sa_handler = sigpipe_handler;
sigemptyset(&action.sa_mask);
@@ -2896,8 +2901,10 @@ namespace QuickMedia {
body_item->thumbnail_url = message->thumbnail_url;
else if(!message->url.empty() && message->type == MessageType::IMAGE)
body_item->thumbnail_url = message->url;
- else
+ else {
body_item->thumbnail_url = message->user->avatar_url;
+ body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
+ }
// 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;
body_item->author_color = message->user->display_name_color;
@@ -2931,6 +2938,7 @@ namespace QuickMedia {
messages_tab.body->thumbnail_resize_target_size.y = 337;
messages_tab.body->thumbnail_fallback_size.x = 32;
messages_tab.body->thumbnail_fallback_size.y = 32;
+ messages_tab.body->thumbnail_mask_shader = &circle_mask_shader;
//messages_tab.body->line_seperator_color = sf::Color::Transparent;
messages_tab.text = sf::Text("Messages", *font, tab_text_size);
tabs.push_back(std::move(messages_tab));
@@ -2942,6 +2950,7 @@ namespace QuickMedia {
//rooms_tab.body->line_seperator_color = sf::Color::Transparent;
rooms_tab.body->thumbnail_fallback_size.x = 32;
rooms_tab.body->thumbnail_fallback_size.y = 32;
+ rooms_tab.body->thumbnail_mask_shader = &circle_mask_shader;
rooms_tab.text = sf::Text("Rooms", *font, tab_text_size);
tabs.push_back(std::move(rooms_tab));
@@ -3182,7 +3191,7 @@ namespace QuickMedia {
const float tab_vertical_offset = 10.0f;
- sf::Text room_name_text("", *font, 18);
+ sf::Text room_name_text("", *bold_font, 18);
const float room_name_text_height = 20.0f;
const float room_name_text_padding_y = 10.0f;
const float room_name_total_height = room_name_text_height + room_name_text_padding_y * 2.0f;
@@ -3308,6 +3317,7 @@ namespace QuickMedia {
auto body_item = BodyItem::create(std::move(room_name));
body_item->thumbnail_url = room->avatar_url;
body_item->userdata = room.get(); // Note: this has to be valid as long as the room list is valid!
+ body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
tabs[ROOMS_TAB_INDEX].body->items.push_back(body_item);
body_items_by_room[room] = { body_item, true, 0 };
}
@@ -3344,8 +3354,12 @@ namespace QuickMedia {
auto body_item = find_body_item_by_event_id(body_items, num_body_items, message->related_event_id);
if(body_item) {
body_item->set_description(message->body);
- if(message->related_event_type == RelatedEventType::REDACTION)
+ if(message->related_event_type == RelatedEventType::REDACTION) {
+ body_item->embedded_item = nullptr;
+ body_item->embedded_item_status = EmbeddedItemStatus::NONE;
body_item->thumbnail_url = message->user->avatar_url;
+ body_item->thumbnail_mask_type = ThumbnailMaskType::NONE;
+ }
it = unreferenced_events.erase(it);
} else {
++it;
@@ -3366,8 +3380,12 @@ namespace QuickMedia {
auto body_item = find_body_item_by_event_id(body_items.data(), body_items.size(), message->related_event_id);
if(body_item) {
body_item->set_description(message->body);
- if(message->related_event_type == RelatedEventType::REDACTION)
+ if(message->related_event_type == RelatedEventType::REDACTION) {
+ body_item->embedded_item = nullptr;
+ body_item->embedded_item_status = EmbeddedItemStatus::NONE;
body_item->thumbnail_url = message->user->avatar_url;
+ body_item->thumbnail_mask_type = ThumbnailMaskType::NONE;
+ }
} else {
unreferenced_events.push_back(message);
}
@@ -3883,10 +3901,10 @@ namespace QuickMedia {
room_avatar_texture_size.x *= room_avatar_sprite.getScale().x;
room_avatar_texture_size.y *= room_avatar_sprite.getScale().y;
room_avatar_sprite.setPosition(body_pos.x, room_name_total_height * 0.5f - room_avatar_texture_size.y * 0.5f + 5.0f);
- window.draw(room_avatar_sprite);
+ window.draw(room_avatar_sprite, &circle_mask_shader);
room_name_text_offset_x += room_avatar_texture_size.x + 10.0f;
}
- room_name_text.setPosition(body_pos.x + room_name_text_offset_x, room_name_text_padding_y);
+ room_name_text.setPosition(body_pos.x + room_name_text_offset_x, room_name_text_padding_y + 4.0f);
window.draw(room_name_text);
}
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index 1cb2aa5..ea5f86c 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -269,10 +269,11 @@ namespace QuickMedia {
for(unsigned char c : user_id) {
color = (color * 16777619) ^ c;
}
- sf::Color result = (sf::Color)color;
- result.r = 64 + std::max(0, (int)result.r - 64);
- result.g = 64 + std::max(0, (int)result.g - 64);
- result.b = 64 + std::max(0, (int)result.b - 64);
+ sf::Uint8 *col = (sf::Uint8*)&color;
+ sf::Color result(col[0], col[1], col[2]);
+ result.r = std::min(255, 80 + (int)result.r);
+ result.g = std::min(255, 80 + (int)result.g);
+ result.b = std::min(255, 80 + (int)result.b);
result.a = 255;
return result;
}