aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-06-21 06:25:13 +0200
committerdec05eba <dec05eba@protonmail.com>2021-06-21 06:25:17 +0200
commit933ceeabb339cdf0583a8687528941593381a268 (patch)
treee3963cd74eb726a63f6e91f2f22f485fac65084a /src
parentd137dcfa6dd248ffa94e58e7aef4487682bc12dc (diff)
Add color themeing, (Theme.hpp/Theme.cpp) and the env var QM_THEME
Diffstat (limited to 'src')
-rw-r--r--src/Body.cpp37
-rw-r--r--src/Entry.cpp5
-rw-r--r--src/QuickMedia.cpp132
-rw-r--r--src/SearchBar.cpp17
-rw-r--r--src/Tabs.cpp11
-rw-r--r--src/Text.cpp8
-rw-r--r--src/Theme.cpp62
-rw-r--r--src/gui/Button.cpp3
-rw-r--r--src/plugins/FileManager.cpp3
-rw-r--r--src/plugins/MangaGeneric.cpp3
-rw-r--r--src/plugins/Mangadex.cpp5
-rw-r--r--src/plugins/Manganelo.cpp5
-rw-r--r--src/plugins/Matrix.cpp19
-rw-r--r--src/plugins/Soundcloud.cpp3
-rw-r--r--src/plugins/Youtube.cpp7
15 files changed, 195 insertions, 125 deletions
diff --git a/src/Body.cpp b/src/Body.cpp
index ba99c62..c841f98 100644
--- a/src/Body.cpp
+++ b/src/Body.cpp
@@ -4,6 +4,7 @@
#include "../include/ResourceLoader.hpp"
#include "../include/AsyncImageLoader.hpp"
#include "../include/Utils.hpp"
+#include "../include/Theme.hpp"
#include "../include/StringUtils.hpp"
#include "../plugins/Plugin.hpp"
#include <SFML/Graphics/CircleShape.hpp>
@@ -99,9 +100,9 @@ namespace QuickMedia {
thumbnail_is_local(false),
userdata(nullptr),
timestamp(0),
- title_color(sf::Color::White),
- author_color(sf::Color::White),
- description_color(sf::Color::White)
+ title_color(get_current_theme().text_color),
+ author_color(get_current_theme().text_color),
+ description_color(get_current_theme().text_color)
{
if(!_title.empty())
set_title(std::move(_title));
@@ -176,16 +177,16 @@ namespace QuickMedia {
num_visible_items(0),
top_cut_off(false),
bottom_cut_off(false),
- item_background(sf::Vector2f(1.0f, 1.0f), 10.0f, sf::Color(55, 60, 68), rounded_rectangle_shader),
- reaction_background(sf::Vector2f(1.0f, 1.0f), 10.0f, sf::Color(33, 37, 44), rounded_rectangle_shader),
+ item_background(sf::Vector2f(1.0f, 1.0f), 10.0f, get_current_theme().selected_color, rounded_rectangle_shader),
+ reaction_background(sf::Vector2f(1.0f, 1.0f), 10.0f, get_current_theme().shade_color, rounded_rectangle_shader),
rounded_rectangle_mask_shader(rounded_rectangle_mask_shader)
{
assert(rounded_rectangle_shader);
assert(rounded_rectangle_mask_shader);
init_body_themes();
embedded_item_load_text = sf::Text("", *FontLoader::get_font(FontLoader::FontType::LATIN), body_spacing[body_theme].embedded_item_font_size);
- progress_text.setFillColor(sf::Color::White);
- replies_text.setFillColor(sf::Color(129, 162, 190));
+ progress_text.setFillColor(get_current_theme().text_color);
+ replies_text.setFillColor(get_current_theme().replies_text_color);
thumbnail_max_size.x = 250;
thumbnail_max_size.y = 141;
sf::Vector2f loading_icon_size(loading_icon.getTexture()->getSize().x, loading_icon.getTexture()->getSize().y);
@@ -866,7 +867,7 @@ namespace QuickMedia {
body_item->timestamp_text = std::make_unique<sf::Text>(time_str, *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(10 * get_ui_scale()));
}
- body_item->timestamp_text->setFillColor(sf::Color(185, 190, 198, 100));
+ body_item->timestamp_text->setFillColor(get_current_theme().timestamp_text_color);
}
}
}
@@ -967,7 +968,7 @@ namespace QuickMedia {
if(prev_num_visible_items > 0 && render_selected_item_bg && body_theme == BODY_THEME_MINIMAL) {
item_background.set_position(sf::Vector2f(pos.x, item_background_prev_pos.y));
item_background.set_size(item_background_prev_size);
- item_background.set_color(sf::Color(55, 60, 68));
+ item_background.set_color(get_current_theme().selected_color);
item_background.set_band(sf::Vector2f(0.0f, 0.0f), sf::Vector2f(0.0f, 0.0f));
item_background.draw(window);
}
@@ -1176,9 +1177,9 @@ namespace QuickMedia {
item_background.set_position(pos + pos_offset);
item_background.set_size(sf::Vector2f(card_width, item_height));
- item_background.set_color(sf::Color(28, 32, 39));
+ item_background.set_color(get_current_theme().card_item_background_color);
item_background.set_band(item_background_prev_pos - (pos + pos_offset), item_background_prev_size);
- item_background.set_band_color(sf::Color(55, 60, 68));
+ item_background.set_band_color(get_current_theme().selected_color);
item_background.draw(window);
{
@@ -1248,7 +1249,7 @@ namespace QuickMedia {
const float gradient_height = 5.0f;
if(text_offset_y >= text_height - gradient_height && std::abs(item_height - card_height) < 1) {
const sf::Vector2f card_bottom(text_pos.x, text_height);
- const sf::Color color = item_index == selected_item ? sf::Color(55, 60, 68) : sf::Color(28, 32, 39);
+ const sf::Color color = item_index == selected_item ? get_current_theme().selected_color : get_current_theme().card_item_background_color;
sf::Vertex gradient_points[4];
gradient_points[0] = sf::Vertex(card_bottom + sf::Vector2f(0.0f, -gradient_height), sf::Color(color.r, color.g, color.b, 0));
@@ -1320,9 +1321,9 @@ namespace QuickMedia {
if(item_index != -1 && body_theme == BODY_THEME_MODERN_SPACIOUS) {
item_background.set_size(sf::Vector2f(size.x, item_height));
item_background.set_position(item_pos);
- item_background.set_color(sf::Color(33, 37, 44));
+ item_background.set_color(get_current_theme().shade_color);
item_background.set_band(item_background_prev_pos - pos, item_background_prev_size);
- item_background.set_band_color(sf::Color(55, 60, 68));
+ item_background.set_band_color(get_current_theme().selected_color);
item_background.draw(window);
}
@@ -1356,18 +1357,17 @@ namespace QuickMedia {
} else if(!item->thumbnail_url.empty()) {
sf::Vector2f content_size = to_vec2f(thumbnail_size);
- sf::Color fallback_color(52, 58, 70);
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(content_size.x * 0.5f);
- circle_shape.setFillColor(fallback_color);
+ circle_shape.setFillColor(get_current_theme().image_loading_background_color);
circle_shape.setPosition(item_pos + sf::Vector2f(body_spacing[body_theme].image_padding_x, padding_y));
window.draw(circle_shape);
} else {
image_fallback.setSize(content_size);
- image_fallback.setFillColor(fallback_color);
+ image_fallback.setFillColor(get_current_theme().image_loading_background_color);
image_fallback.setPosition(item_pos + sf::Vector2f(body_spacing[body_theme].image_padding_x, padding_y));
window.draw(image_fallback);
}
@@ -1384,7 +1384,6 @@ namespace QuickMedia {
text_offset_x += body_spacing[body_theme].image_padding_x + thumbnail_size.x;
}
- const float text_max_width = size.x - text_offset_x - body_spacing[body_theme].image_padding_x;
const float text_offset_y = std::floor(6.0f * get_ui_scale());
const float timestamp_text_y = std::floor(item_pos.y + padding_y - text_offset_y);
@@ -1413,7 +1412,7 @@ namespace QuickMedia {
const float embedded_item_width = std::floor(size.x - text_offset_x - border_width - body_spacing[body_theme].padding_x);
float embedded_item_height = item->embedded_item ? get_item_height(item->embedded_item.get(), embedded_item_width, true, false) : ((body_spacing[body_theme].embedded_item_font_size + 5.0f) + body_spacing[body_theme].embedded_item_padding_y * 2.0f);
sf::RectangleShape border_left(sf::Vector2f(border_width, std::floor(embedded_item_height)));
- border_left.setFillColor(sf::Color::White);
+ border_left.setFillColor(get_current_theme().embedded_item_border_color);
border_left.setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + body_spacing[body_theme].embedded_item_padding_y + 2.0f));
window.draw(border_left);
diff --git a/src/Entry.cpp b/src/Entry.cpp
index 8e1fbfb..ce86f8f 100644
--- a/src/Entry.cpp
+++ b/src/Entry.cpp
@@ -1,6 +1,7 @@
#include "../include/Entry.hpp"
#include "../include/ResourceLoader.hpp"
#include "../include/Utils.hpp"
+#include "../include/Theme.hpp"
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Window/Event.hpp>
@@ -16,12 +17,12 @@ namespace QuickMedia {
draw_background(true),
text("", false, std::floor(16 * get_ui_scale()), 0.0f),
width(0.0f),
- background(sf::Vector2f(1.0f, 1.0f), 10.0f, sf::Color(55, 60, 68), rounded_rectangle_shader),
+ background(sf::Vector2f(1.0f, 1.0f), 10.0f, get_current_theme().selected_color, rounded_rectangle_shader),
placeholder(placeholder_text, *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(16 * get_ui_scale())),
mouse_left_inside(false)
{
text.setEditable(true);
- placeholder.setFillColor(sf::Color(255, 255, 255, 100));
+ placeholder.setFillColor(get_current_theme().placeholder_text_color);
}
void Entry::process_event(sf::Event &event) {
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 9613199..bcd9a53 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -28,6 +28,7 @@
#include "../include/ResourceLoader.hpp"
#include "../include/Utils.hpp"
#include "../include/Tabs.hpp"
+#include "../include/Theme.hpp"
#include "../include/gui/Button.hpp"
#include "../external/hash-library/sha256.h"
@@ -50,7 +51,6 @@
#include <X11/extensions/Xrandr.h>
#include <GL/glx.h>
-static const sf::Color back_color(21, 25, 30);
static const std::string fourchan_google_captcha_api_key = "6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc";
static int FPS_IDLE = 2;
static const double IDLE_TIMEOUT_SEC = 2.0;
@@ -312,7 +312,7 @@ namespace QuickMedia {
auto body_item = BodyItem::create(std::move(title));
if(!description.empty()) {
body_item->set_description(std::move(description));
- body_item->set_description_color(sf::Color(179, 179, 179));
+ body_item->set_description_color(get_current_theme().faded_text_color);
}
body_item->url = std::to_string(handlers.size());
handlers.push_back(std::move(handler));
@@ -658,6 +658,7 @@ namespace QuickMedia {
}
set_resource_loader_root_path(resources_root.c_str());
+ init_themes();
if(!is_touch_enabled()) {
if(!circle_mask_shader.loadFromFile(resources_root + "shaders/circle_mask.glsl", sf::Shader::Type::Fragment)) {
@@ -1332,7 +1333,7 @@ namespace QuickMedia {
body_item->url = "https://www.youtube.com/watch?v=" + video_id_str;
body_item->thumbnail_url = "https://img.youtube.com/vi/" + video_id_str + "/mqdefault.jpg";
body_item->set_description("Watched " + seconds_to_relative_time_str(time_now - timestamp.asInt64()));
- body_item->set_description_color(sf::Color(179, 179, 179));
+ body_item->set_description_color(get_current_theme().faded_text_color);
body_item->thumbnail_size = sf::Vector2i(192, 108);
body_items.push_back(std::move(body_item));
}
@@ -1411,7 +1412,7 @@ namespace QuickMedia {
// TODO: Add thumbnail
auto body_item = BodyItem::create(manga_name.asString());
body_item->set_description("Last read " + seconds_to_relative_time_str(now - last_modified_time));
- body_item->set_description_color(sf::Color(179, 179, 179));
+ body_item->set_description_color(get_current_theme().faded_text_color);
if(strcmp(plugin_name, "manganelo") == 0)
body_item->url = "https://manganelo.com/manga/" + base64_decode(filename.string());
@@ -1564,7 +1565,7 @@ namespace QuickMedia {
if(!tabs[selected_tab].search_bar) {
shade_extra_height = std::floor(10.0f * get_ui_scale());
sf::RectangleShape shade_top(sf::Vector2f(window_size.x, shade_extra_height));
- shade_top.setFillColor(sf::Color(33, 37, 44));
+ shade_top.setFillColor(get_current_theme().shade_color);
window.draw(shade_top);
}
@@ -2013,18 +2014,18 @@ namespace QuickMedia {
if(tab_associated_data[selected_tab].fetching_next_page_running) {
double progress = 0.5 + std::sin(std::fmod(gradient_inc, 360.0) * 0.017453292519943295 - 1.5707963267948966*0.5) * 0.5;
gradient_inc += (frame_time_ms * 0.5);
- sf::Color bottom_color = interpolate_colors(back_color, sf::Color(175, 180, 188), progress);
+ sf::Color bottom_color = interpolate_colors(get_current_theme().background_color, get_current_theme().loading_bar_color, progress);
if(tabs[selected_tab].body->attach_side == AttachSide::TOP) {
- gradient_points[0].color = back_color;
- gradient_points[1].color = back_color;
+ gradient_points[0].color = get_current_theme().background_color;
+ gradient_points[1].color = get_current_theme().background_color;
gradient_points[2].color = bottom_color;
gradient_points[3].color = bottom_color;
} else if(tabs[selected_tab].body->attach_side == AttachSide::BOTTOM) {
gradient_points[0].color = bottom_color;
gradient_points[1].color = bottom_color;
- gradient_points[2].color = back_color;
- gradient_points[3].color = back_color;
+ gradient_points[2].color = get_current_theme().background_color;
+ gradient_points[3].color = get_current_theme().background_color;
}
}
@@ -2164,7 +2165,7 @@ namespace QuickMedia {
ui_tabs.set_text(i, tab.page->get_title());
}
- window.clear(back_color);
+ window.clear(get_current_theme().background_color);
page_loop_render(window, tabs, selected_tab, tab_associated_data[selected_tab], json_chapters, ui_tabs);
AsyncImageLoader::get_instance().update();
window.display();
@@ -2331,7 +2332,7 @@ namespace QuickMedia {
goto task_end;
}
- window.clear(back_color);
+ window.clear(get_current_theme().background_color);
load_sprite.setPosition(window_size.x * 0.5f, window_size.y * 0.5f);
load_sprite.setRotation(load_sprite_timer.getElapsedTime().asSeconds() * 400.0);
window.draw(load_sprite);
@@ -2943,7 +2944,7 @@ namespace QuickMedia {
AsyncImageLoader::get_instance().update();
if(!video_loaded) {
- window.clear(back_color);
+ window.clear(get_current_theme().background_color);
load_sprite.setPosition(window_size.x * 0.5f, window_size.y * 0.5f);
load_sprite.setRotation(load_sprite_timer.getElapsedTime().asSeconds() * 400.0);
window.draw(load_sprite);
@@ -3194,7 +3195,7 @@ namespace QuickMedia {
break;
}
- window.clear(back_color);
+ window.clear(get_current_theme().background_color);
load_sprite.setPosition(window_size.x * 0.5f, window_size.y * 0.5f);
load_sprite.setRotation(load_sprite_timer.getElapsedTime().asSeconds() * 400.0);
window.draw(load_sprite);
@@ -3217,7 +3218,7 @@ namespace QuickMedia {
sf::Texture image_texture;
sf::Sprite image;
sf::Text error_message("", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(30 * get_ui_scale()));
- error_message.setFillColor(sf::Color::White);
+ error_message.setFillColor(get_current_theme().text_color);
bool download_in_progress = false;
sf::Event event;
@@ -3381,7 +3382,7 @@ namespace QuickMedia {
image.setPosition(std::floor(content_size.x * 0.5f - image_size.x * 0.5f), std::floor(content_size.y * 0.5f - image_size.y * 0.5f));
}
- window.clear(back_color);
+ window.clear(get_current_theme().background_color);
if(error) {
window.draw(error_message);
@@ -3453,7 +3454,7 @@ namespace QuickMedia {
while(current_page == PageType::IMAGES_CONTINUOUS && window.isOpen()) {
handle_window_close();
- window.clear(back_color);
+ window.clear(get_current_theme().background_color);
ImageViewerAction action = image_viewer.draw();
switch(action) {
case ImageViewerAction::NONE:
@@ -3514,7 +3515,7 @@ namespace QuickMedia {
GoogleCaptchaChallengeInfo challenge_info;
sf::Text challenge_description_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(24 * get_ui_scale()));
- challenge_description_text.setFillColor(sf::Color::White);
+ challenge_description_text.setFillColor(get_current_theme().text_color);
const size_t captcha_num_columns = 3;
const size_t captcha_num_rows = 3;
std::array<bool, captcha_num_columns * captcha_num_rows> selected_captcha_images;
@@ -3654,7 +3655,7 @@ namespace QuickMedia {
};
sf::RectangleShape comment_input_shade;
- comment_input_shade.setFillColor(sf::Color(33, 37, 44));
+ comment_input_shade.setFillColor(get_current_theme().shade_color);
sf::Sprite logo_sprite(plugin_logo);
logo_sprite.setScale(0.8f * get_ui_scale(), 0.8f * get_ui_scale());
@@ -3981,7 +3982,7 @@ namespace QuickMedia {
//comment_input.update();
- window.clear(back_color);
+ window.clear(get_current_theme().background_color);
if(navigation_stage == NavigationStage::SOLVING_POST_CAPTCHA) {
std::lock_guard<std::mutex> lock(captcha_image_mutex);
if(captcha_texture.getNativeHandle() != 0) {
@@ -4051,7 +4052,7 @@ namespace QuickMedia {
window.draw(attached_image_sprite);
} else {
sf::RectangleShape rect(sf::Vector2f(640.0f, 480.0f));
- rect.setFillColor(sf::Color(52, 58, 70));
+ rect.setFillColor(get_current_theme().image_loading_background_color);
auto content_size = window_size;
auto rect_size = clamp_to_size(rect.getSize(), content_size);
rect.setSize(rect_size);
@@ -4093,7 +4094,7 @@ namespace QuickMedia {
SearchBar *inputs[num_inputs] = { &login_input, &password_input, &homeserver_input };
int focused_input = 0;
- RoundedRectangle background(sf::Vector2f(1.0f, 1.0f), 10.0f, sf::Color(33, 37, 44), &rounded_rectangle_shader);
+ RoundedRectangle background(sf::Vector2f(1.0f, 1.0f), 10.0f, get_current_theme().shade_color, &rounded_rectangle_shader);
auto text_submit_callback = [this, inputs](const sf::String&) {
for(int i = 0; i < num_inputs; ++i) {
@@ -4173,7 +4174,7 @@ namespace QuickMedia {
}
}
- window.clear(back_color);
+ window.clear(get_current_theme().background_color);
background.draw(window);
for(int i = 0; i < num_inputs; ++i) {
inputs[i]->update();
@@ -4220,9 +4221,9 @@ namespace QuickMedia {
body_item->embedded_item->embedded_item = nullptr;
body_item->embedded_item->reactions.clear();
if(message->user->user_id != my_user_id && ((related_body_item->userdata && static_cast<Message*>(related_body_item->userdata)->user.get() == me) || message_contains_user_mention(body_item->get_description(), my_display_name) || message_contains_user_mention(body_item->get_description(), my_user_id)))
- body_item->set_description_color(sf::Color(255, 100, 100));
+ body_item->set_description_color(get_current_theme().attention_alert_text_color);
else
- body_item->set_description_color(sf::Color::White);
+ body_item->set_description_color(get_current_theme().text_color);
body_item->embedded_item_status = FetchStatus::FINISHED_LOADING;
return true;
}
@@ -4255,7 +4256,7 @@ namespace QuickMedia {
if(message->related_event_type == RelatedEventType::REDACTION || message->related_event_type == RelatedEventType::EDIT || message->related_event_type == RelatedEventType::REACTION)
body_item->visible = false;
if(message->user->user_id != my_user_id && (message_contains_user_mention(body_item->get_description(), my_display_name) || message_contains_user_mention(body_item->get_description(), my_user_id)))
- body_item->set_description_color(sf::Color(255, 100, 100));
+ body_item->set_description_color(get_current_theme().attention_alert_text_color);
return body_item;
}
@@ -4367,7 +4368,7 @@ namespace QuickMedia {
tab.body->show_drop_shadow = false;
}
- Tabs ui_tabs(&rounded_rectangle_shader, is_touch_enabled() ? sf::Color::Transparent : back_color);
+ Tabs ui_tabs(&rounded_rectangle_shader, is_touch_enabled() ? sf::Color::Transparent : get_current_theme().background_color);
const int PINNED_TAB_INDEX = ui_tabs.add_tab("Pinned messages (0)", tabs[0].body.get());
const int MESSAGES_TAB_INDEX = ui_tabs.add_tab("Messages", tabs[1].body.get());
const int USERS_TAB_INDEX = ui_tabs.add_tab("Users (0)", tabs[2].body.get());
@@ -4450,7 +4451,7 @@ namespace QuickMedia {
const float room_topic_text_height = std::floor(12.0f * get_ui_scale());
sf::Text room_topic_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), room_topic_text_height);
- room_topic_text.setFillColor(sf::Color(179, 179, 179));
+ room_topic_text.setFillColor(get_current_theme().faded_text_color);
sf::Text room_label(matrix_chat_page->rooms_page->get_title(), *FontLoader::get_font(FontLoader::FontType::LATIN_BOLD), std::floor(18 * get_ui_scale()));
room_label.setPosition(15.0f, room_name_text_padding_y + 4.0f);
@@ -4475,7 +4476,7 @@ namespace QuickMedia {
body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
}
body_item->set_description("Message deleted");
- body_item->set_description_color(sf::Color::White);
+ body_item->set_description_color(get_current_theme().text_color);
body_item->thumbnail_size = AVATAR_THUMBNAIL_SIZE;
body_item->url.clear();
};
@@ -4502,9 +4503,9 @@ namespace QuickMedia {
Message *orig_message = get_original_message(reply_to_message);
body_item->set_description(strip(message_get_body_remove_formatting(message.get())));
if(message->user != me && (message_contains_user_mention(body_item->get_description(), my_display_name) || message_contains_user_mention(body_item->get_description(), me->user_id) || (orig_message && orig_message->user == me)))
- body_item->set_description_color(sf::Color(255, 100, 100));
+ body_item->set_description_color(get_current_theme().attention_alert_text_color);
else
- body_item->set_description_color(sf::Color::White);
+ body_item->set_description_color(get_current_theme().text_color);
message->replaces = reply_to_message;
reply_to_message->replaced_by = message;
}
@@ -4540,9 +4541,9 @@ namespace QuickMedia {
Message *orig_message = get_original_message(reply_to_message);
body_item->set_description(strip(message_get_body_remove_formatting(message.get())));
if(message->user != me && (message_contains_user_mention(body_item->get_description(), my_display_name) || message_contains_user_mention(body_item->get_description(), me->user_id) || (orig_message && orig_message->user == me)))
- body_item->set_description_color(sf::Color(255, 100, 100));
+ body_item->set_description_color(get_current_theme().attention_alert_text_color);
else
- body_item->set_description_color(sf::Color::White);
+ body_item->set_description_color(get_current_theme().text_color);
message->replaces = reply_to_message;
reply_to_message->replaced_by = message;
}
@@ -4897,8 +4898,6 @@ namespace QuickMedia {
message->type = MessageType::TEXT;
message->timestamp = time(NULL) * 1000;
- const sf::Color provisional_message_color(255, 255, 255, 150);
-
int num_items = tabs[MESSAGES_TAB_INDEX].body->items.size();
bool scroll_to_end = num_items == 0;
if(tabs[MESSAGES_TAB_INDEX].body->is_selected_item_last_visible_item() && selected_tab == MESSAGES_TAB_INDEX)
@@ -4931,7 +4930,7 @@ namespace QuickMedia {
});
} else {
auto body_item = message_to_body_item(current_room, message.get(), current_room->get_user_avatar_url(me), me->user_id);
- body_item->set_description_color(provisional_message_color);
+ body_item->set_description_color(get_current_theme().provisional_message_color);
load_cached_related_embedded_item(body_item.get(), message.get(), me, current_room, tabs[MESSAGES_TAB_INDEX].body->items);
tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps({body_item});
post_task_queue.push([this, &current_room, text, msgtype, body_item, message]() {
@@ -4956,7 +4955,7 @@ namespace QuickMedia {
message->related_event_type = RelatedEventType::REPLY;
message->related_event_id = static_cast<Message*>(related_to_message)->event_id;
auto body_item = message_to_body_item(current_room, message.get(), current_room->get_user_avatar_url(me), me->user_id);
- body_item->set_description_color(provisional_message_color);
+ body_item->set_description_color(get_current_theme().provisional_message_color);
load_cached_related_embedded_item(body_item.get(), message.get(), me, current_room, tabs[MESSAGES_TAB_INDEX].body->items);
tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps({body_item});
post_task_queue.push([this, &current_room, text, related_to_message, body_item, message, transaction_id]() {
@@ -4982,7 +4981,7 @@ namespace QuickMedia {
if(body_item) {
auto body_item_shared_ptr = tabs[MESSAGES_TAB_INDEX].body->items[body_item_index];
body_item_shared_ptr->set_description(text);
- body_item_shared_ptr->set_description_color(provisional_message_color);
+ body_item_shared_ptr->set_description_color(get_current_theme().provisional_message_color);
auto edit_body_item = message_to_body_item(current_room, message.get(), current_room->get_user_avatar_url(me), me->user_id);
edit_body_item->visible = false;
@@ -5070,9 +5069,9 @@ namespace QuickMedia {
*body_item = *related_body_item;
body_item->reactions.clear();
if(message_contains_user_mention(related_body_item->get_description(), current_room->get_user_display_name(me)) || message_contains_user_mention(related_body_item->get_description(), me->user_id))
- body_item->set_description_color(sf::Color(255, 100, 100));
+ body_item->set_description_color(get_current_theme().attention_alert_text_color);
else
- body_item->set_description_color(sf::Color::White);
+ body_item->set_description_color(get_current_theme().text_color);
event_data->status = FetchStatus::FINISHED_LOADING;
event_data->message = static_cast<Message*>(related_body_item->userdata);
body_item->userdata = event_data;
@@ -5158,10 +5157,10 @@ namespace QuickMedia {
};
sf::RectangleShape more_messages_below_rect;
- more_messages_below_rect.setFillColor(sf::Color(128, 50, 50));
+ more_messages_below_rect.setFillColor(get_current_theme().new_items_alert_color);
sf::RectangleShape chat_input_shade;
- chat_input_shade.setFillColor(sf::Color(33, 37, 44));
+ chat_input_shade.setFillColor(get_current_theme().shade_color);
float tab_vertical_offset = 0.0f;
@@ -5721,11 +5720,11 @@ namespace QuickMedia {
if(!provisional_message->event_id.empty()) {
provisional_message->message->event_id = std::move(provisional_message->event_id);
- provisional_message->body_item->set_description_color(sf::Color::White);
+ provisional_message->body_item->set_description_color(get_current_theme().text_color);
sent_messages[provisional_message->message->event_id] = std::move(provisional_message.value());
} else if(provisional_message->body_item) {
provisional_message->body_item->set_description("Failed to send: " + provisional_message->body_item->get_description());
- provisional_message->body_item->set_description_color(sf::Color::Red);
+ provisional_message->body_item->set_description_color(get_current_theme().failed_text_color);
provisional_message->body_item->userdata = nullptr;
}
}
@@ -5942,7 +5941,7 @@ namespace QuickMedia {
fetch_body_item->embedded_item = message_to_body_item(current_room, fetch_message_result.message.get(), current_room->get_user_display_name(me), me->user_id);
fetch_body_item->embedded_item_status = FetchStatus::FINISHED_LOADING;
if(fetch_message_result.message->user == me)
- fetch_body_item->set_description_color(sf::Color(255, 100, 100));
+ fetch_body_item->set_description_color(get_current_theme().attention_alert_text_color);
} else {
fetch_body_item->embedded_item_status = FetchStatus::FAILED_TO_LOAD;
}
@@ -5951,7 +5950,7 @@ namespace QuickMedia {
fetch_message_tab = -1;
}
- window.clear(back_color);
+ window.clear(get_current_theme().background_color);
if(chat_state == ChatState::URL_SELECTION) {
url_selection_body.draw(window, body_pos, body_size);
@@ -5960,7 +5959,7 @@ namespace QuickMedia {
if(selected_tab == MESSAGES_TAB_INDEX && mention.visible && chat_state == ChatState::TYPING_MESSAGE) {
sf::RectangleShape user_mention_background(sf::Vector2f(body_size.x, user_mention_body_height));
user_mention_background.setPosition(sf::Vector2f(body_pos.x, body_pos.y + body_size.y - user_mention_body_height));
- user_mention_background.setFillColor(sf::Color(33, 37, 44));
+ user_mention_background.setFillColor(get_current_theme().shade_color);
window.draw(user_mention_background);
tabs[USERS_TAB_INDEX].body->draw(window, user_mention_background.getPosition(), user_mention_background.getSize());
@@ -5992,7 +5991,7 @@ namespace QuickMedia {
if(draw_room_list) {
sf::RectangleShape room_list_background(sf::Vector2f(this->body_size.x, window_size.y));
//room_list_background.setPosition(this->body_pos);
- room_list_background.setFillColor(sf::Color(33, 37, 44));
+ room_list_background.setFillColor(get_current_theme().shade_color);
glEnable(GL_SCISSOR_TEST);
glScissor(0.0f, 0.0f, this->body_size.x, window_size.y);
window.draw(room_list_background);
@@ -6008,7 +6007,7 @@ namespace QuickMedia {
if(previous_messages_future.valid() && selected_tab == MESSAGES_TAB_INDEX) {
double progress = 0.5 + std::sin(std::fmod(gradient_inc, 360.0) * 0.017453292519943295 - 1.5707963267948966*0.5) * 0.5;
gradient_inc += (frame_time_ms * 0.5);
- sf::Color top_color = interpolate_colors(back_color, sf::Color(175, 180, 188), progress);
+ sf::Color top_color = interpolate_colors(get_current_theme().background_color, get_current_theme().loading_page_color, progress);
gradient_points[0].position.x = chat_input_shade.getPosition().x;
gradient_points[0].position.y = tab_shade_height;
@@ -6024,8 +6023,8 @@ namespace QuickMedia {
gradient_points[0].color = top_color;
gradient_points[1].color = top_color;
- gradient_points[2].color = back_color;
- gradient_points[3].color = back_color;
+ gradient_points[2].color = get_current_theme().background_color;
+ gradient_points[3].color = get_current_theme().background_color;
window.draw(gradient_points, 4, sf::Quads); // Note: sf::Quads doesn't work with egl
}
@@ -6050,13 +6049,13 @@ namespace QuickMedia {
sf::RectangleShape item_background(sf::Vector2f(window_size.x, body_item_size.y + chat_input_height_full + replying_to_text_height + margin));
item_background.setPosition(sf::Vector2f(0.0f, window_size.y - (body_item_size.y + chat_input_height_full + replying_to_text_height + margin)));
- item_background.setFillColor(back_color);
+ item_background.setFillColor(get_current_theme().background_color);
window.draw(item_background);
if(mention.visible) {
sf::RectangleShape user_mention_background(sf::Vector2f(window_size.x, user_mention_body_height));
user_mention_background.setPosition(sf::Vector2f(0.0f, item_background.getPosition().y - user_mention_body_height));
- user_mention_background.setFillColor(sf::Color(33, 37, 44));
+ user_mention_background.setFillColor(get_current_theme().shade_color);
window.draw(user_mention_background);
tabs[USERS_TAB_INDEX].body->draw(window,
@@ -6093,9 +6092,9 @@ namespace QuickMedia {
room_desc.erase(room_desc.begin() + last_line_start - 1, room_desc.end());
}
current_room->body_item->set_description(std::move(room_desc));
- current_room->body_item->set_description_color(sf::Color(179, 179, 179));
+ current_room->body_item->set_description_color(get_current_theme().faded_text_color);
// TODO: Show a line like nheko instead for unread messages, or something else
- current_room->body_item->set_title_color(sf::Color::White);
+ current_room->body_item->set_title_color(get_current_theme().text_color);
current_room->last_message_read = true;
// TODO: Maybe set this instead when the mention is visible on the screen?
current_room->unread_notification_count = 0;
@@ -6670,13 +6669,13 @@ namespace QuickMedia {
}
idle_active_handler();
- window.clear(back_color);
+ window.clear(get_current_theme().background_color);
window.display();
const float loading_bar_padding_x = std::floor(4.0f * get_ui_scale());
const float loading_bar_padding_y = std::floor(4.0f * get_ui_scale());
- RoundedRectangle loading_bar_background(sf::Vector2f(1.0f, 1.0f), std::floor(10.0f * get_ui_scale()), sf::Color(21, 25, 30), &rounded_rectangle_shader);
- RoundedRectangle loading_bar(sf::Vector2f(1.0f, 1.0f), std::floor(10.0f * get_ui_scale() - loading_bar_padding_y), sf::Color(31, 117, 255), &rounded_rectangle_shader);
+ RoundedRectangle loading_bar_background(sf::Vector2f(1.0f, 1.0f), std::floor(10.0f * get_ui_scale()), get_current_theme().background_color, &rounded_rectangle_shader);
+ RoundedRectangle loading_bar(sf::Vector2f(1.0f, 1.0f), std::floor(10.0f * get_ui_scale() - loading_bar_padding_y), get_current_theme().loading_bar_color, &rounded_rectangle_shader);
const float padding_x = std::floor(30.0f * get_ui_scale());
const float spacing_y = std::floor(15.0f * get_ui_scale());
@@ -6685,9 +6684,9 @@ namespace QuickMedia {
sf::Text progress_text("0kb/Unknown", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(20.0f * get_ui_scale()));
sf::Text status_text("Downloading", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(20.0f * get_ui_scale()));
sf::Text filename_text(filename.c_str(), *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(14.0f * get_ui_scale()));
- filename_text.setFillColor(sf::Color(179, 179, 179));
+ filename_text.setFillColor(get_current_theme().faded_text_color);
sf::Text download_speed_text("0 bytes/s", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(14.0f * get_ui_scale()));
- download_speed_text.setFillColor(sf::Color(179, 179, 179));
+ download_speed_text.setFillColor(get_current_theme().faded_text_color);
bool redraw = true;
sf::Event event;
@@ -6779,7 +6778,7 @@ namespace QuickMedia {
std::floor((loading_bar_background.get_size().x - loading_bar_padding_x * 2.0f) * ui_progress),
loading_bar_height - loading_bar_padding_y * 2.0f));
- window.clear(sf::Color(33, 37, 44));
+ window.clear(get_current_theme().shade_color);
loading_bar_background.draw(window);
loading_bar.draw(window);
window.draw(progress_text);
@@ -6854,10 +6853,10 @@ namespace QuickMedia {
const float bottom_panel_spacing = 10.0f;
Button cancel_button("Cancel", FontLoader::get_font(FontLoader::FontType::LATIN), 16, 100.0f, &rounded_rectangle_shader, get_ui_scale());
- cancel_button.set_background_color(sf::Color(41, 45, 50));
+ cancel_button.set_background_color(get_current_theme().cancel_button_background_color);
Button save_button("Save", FontLoader::get_font(FontLoader::FontType::LATIN), 16, 100.0f, &rounded_rectangle_shader, get_ui_scale());
- save_button.set_background_color(sf::Color(31, 117, 255));
+ save_button.set_background_color(get_current_theme().confirm_button_background_color);
sf::Text file_name_label("File name:", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(16.0f * get_ui_scale()));
@@ -6867,11 +6866,9 @@ namespace QuickMedia {
file_name_entry.set_editable(false);
sf::RectangleShape bottom_panel_background;
- bottom_panel_background.setFillColor(sf::Color(33, 37, 44));
+ bottom_panel_background.setFillColor(get_current_theme().shade_color);
- const sf::Color color(0, 0, 0, 50);
const float gradient_height = 5.0f;
-
sf::Vertex gradient_points[4];
auto save_file = [this, &file_name_entry, &file_manager_page]() -> std::string {
@@ -6976,13 +6973,14 @@ namespace QuickMedia {
bottom_panel_background.setPosition(0.0f, window_size.y - std::floor(bottom_panel_padding * 2.0f + file_name_entry.get_height()));
bottom_panel_background.setSize(sf::Vector2f(window_size.x, std::floor(bottom_panel_padding * 2.0f + file_name_entry.get_height())));
+ const sf::Color color(0, 0, 0, 50);
gradient_points[0] = sf::Vertex(bottom_panel_background.getPosition() + sf::Vector2f(0.0f, -gradient_height), sf::Color(color.r, color.g, color.b, 0));
gradient_points[1] = sf::Vertex(bottom_panel_background.getPosition() + sf::Vector2f(bottom_panel_background.getSize().x, -gradient_height), sf::Color(color.r, color.g, color.b, 0));
gradient_points[2] = sf::Vertex(bottom_panel_background.getPosition() + sf::Vector2f(bottom_panel_background.getSize().x, 0.0f), color);
gradient_points[3] = sf::Vertex(bottom_panel_background.getPosition() + sf::Vector2f(0.0f, 0.0f), color);
}
- window.clear(back_color);
+ window.clear(get_current_theme().background_color);
ui_tabs.draw(window, sf::Vector2f(0.0f, search_bar->getBottomWithoutShadow()), window_size.x);
search_bar->draw(window, window_size, true);
diff --git a/src/SearchBar.cpp b/src/SearchBar.cpp
index 3fd2296..0634ae8 100644
--- a/src/SearchBar.cpp
+++ b/src/SearchBar.cpp
@@ -1,4 +1,5 @@
#include "../include/SearchBar.hpp"
+#include "../include/Theme.hpp"
#include "../include/Scale.hpp"
#include "../include/ResourceLoader.hpp"
#include "../include/Utils.hpp"
@@ -10,8 +11,6 @@
// TODO: Use a seperate placeholder sf::Text instead of switching the text to placeholder text....
-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 = 10.0f + std::floor(5.0f * QuickMedia::get_ui_scale());
static const float padding_top_default = std::floor(10.0f * QuickMedia::get_ui_scale());
static const float padding_bottom_default = std::floor(15.0f * QuickMedia::get_ui_scale());
@@ -28,7 +27,7 @@ namespace QuickMedia {
caret_visible(true),
text(placeholder, *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(16 * get_ui_scale())),
autocomplete_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(16 * get_ui_scale())),
- background(sf::Vector2f(1.0f, 1.0f), 10.0f, front_color, rounded_rectangle_shader),
+ background(sf::Vector2f(1.0f, 1.0f), 10.0f, get_current_theme().selected_color, rounded_rectangle_shader),
placeholder_str(placeholder),
show_placeholder(true),
updated_search(false),
@@ -44,9 +43,9 @@ namespace QuickMedia {
{
padding_top = padding_top_default;
padding_bottom = padding_bottom_default;
- text.setFillColor(text_placeholder_color);
- autocomplete_text.setFillColor(text_placeholder_color);
- shade.setFillColor(sf::Color(33, 37, 44));
+ text.setFillColor(get_current_theme().placeholder_text_color);
+ autocomplete_text.setFillColor(get_current_theme().placeholder_text_color);
+ shade.setFillColor(get_current_theme().shade_color);
if(plugin_logo && plugin_logo->getNativeHandle() != 0)
plugin_logo_sprite.setTexture(*plugin_logo, true);
}
@@ -201,7 +200,7 @@ namespace QuickMedia {
if(str.getSize() == 0) {
show_placeholder = true;
text.setString(placeholder_str);
- text.setFillColor(text_placeholder_color);
+ text.setFillColor(get_current_theme().placeholder_text_color);
autocomplete_text.setString("");
} else {
clear_autocomplete_if_text_not_substring();
@@ -235,7 +234,7 @@ namespace QuickMedia {
return;
show_placeholder = true;
text.setString(placeholder_str);
- text.setFillColor(text_placeholder_color);
+ text.setFillColor(get_current_theme().placeholder_text_color);
autocomplete_text.setString("");
needs_update = true;
updated_search = false;
@@ -267,7 +266,7 @@ namespace QuickMedia {
updated_autocomplete = true;
time_since_search_update.restart();
backspace_pressed = false;
- if(str[str.getSize() - 1] == '\n')
+ if(text_to_add.find('\n') != std::string::npos)
needs_update = true;
}
diff --git a/src/Tabs.cpp b/src/Tabs.cpp
index b943615..62a6fe4 100644
--- a/src/Tabs.cpp
+++ b/src/Tabs.cpp
@@ -2,6 +2,7 @@
#include "../include/Body.hpp"
#include "../include/ResourceLoader.hpp"
#include "../include/Utils.hpp"
+#include "../include/Theme.hpp"
#include <SFML/Window/Event.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/OpenGL.hpp>
@@ -10,8 +11,6 @@
namespace QuickMedia {
static const float tab_text_size = std::floor(16.0f * QuickMedia::get_ui_scale());
static const float tab_height = tab_text_size + std::floor(10.0f * QuickMedia::get_ui_scale());
- static const sf::Color tab_selected_color(55, 60, 68);
- static const sf::Color arrow_color(255, 255, 255, 175);
static const float tab_min_width = 250.0f;
static const float tab_margin_x = 10.0f;
@@ -25,10 +24,12 @@ namespace QuickMedia {
return tab_height + std::floor(10.0f * get_ui_scale());
}
- Tabs::Tabs(sf::Shader *rounded_rectangle_shader, sf::Color shade_color) : background(sf::Vector2f(1.0f, 1.0f), 10.0f, tab_selected_color, rounded_rectangle_shader), shade_color(shade_color) {
+ Tabs::Tabs(sf::Shader *rounded_rectangle_shader, sf::Color shade_color) : background(sf::Vector2f(1.0f, 1.0f), 10.0f, get_current_theme().selected_color, rounded_rectangle_shader), shade_color(shade_color) {
shade.setFillColor(shade_color);
}
+ Tabs::Tabs(sf::Shader *rounded_rectangle_shader) : Tabs(rounded_rectangle_shader, get_current_theme().shade_color) {}
+
int Tabs::add_tab(const std::string &title, Body *body) {
assert(body);
tabs.push_back({ sf::Text(title, *FontLoader::get_font(FontLoader::FontType::LATIN), tab_text_size), title, body} );
@@ -164,7 +165,7 @@ namespace QuickMedia {
window.draw(gradient_points, 4, sf::Quads);
sf::RectangleShape line(sf::Vector2f(std::floor(10.0f * get_ui_scale()), std::floor(2.0f * get_ui_scale())));
- line.setFillColor(arrow_color);
+ line.setFillColor(get_current_theme().arrow_color);
line.setOrigin(line.getSize().x * 0.5f, line.getSize().y * 0.5f);
line.rotate(-45.0f);
@@ -191,7 +192,7 @@ namespace QuickMedia {
window.draw(gradient_points, 4, sf::Quads);
sf::RectangleShape line(sf::Vector2f(std::floor(10.0f * get_ui_scale()), std::floor(2.0f * get_ui_scale())));
- line.setFillColor(arrow_color);
+ line.setFillColor(get_current_theme().arrow_color);
line.setOrigin(line.getSize().x * 0.5f, line.getSize().y * 0.5f);
line.rotate(45.0f);
diff --git a/src/Text.cpp b/src/Text.cpp
index 32aae2e..3cde45f 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -1,6 +1,7 @@
#include "../include/Text.hpp"
#include "../include/ResourceLoader.hpp"
#include "../include/Utils.hpp"
+#include "../include/Theme.hpp"
#include "../generated/Emoji.hpp"
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Window/Clipboard.hpp>
@@ -14,7 +15,6 @@ namespace QuickMedia
{
static const float TAB_WIDTH = 4.0f;
static const float WORD_WRAP_MIN_SIZE = 80.0f;
- static const sf::Color URL_COLOR(35, 140, 245);
static const size_t FONT_INDEX_LATIN = 0;
static const size_t FONT_INDEX_CJK = 1;
@@ -39,7 +39,7 @@ namespace QuickMedia
bold_font(bold_font),
characterSize(characterSize),
maxWidth(maxWidth),
- color(sf::Color::White),
+ color(get_current_theme().text_color),
dirty(true),
dirtyText(false),
dirtyCaret(false),
@@ -396,6 +396,8 @@ namespace QuickMedia
float hspace = latin_font_height + characterSpacing;
float vspace = latin_font->getLineSpacing(characterSize); // TODO: What about japanese font???
+ const sf::Color url_color = get_current_theme().url_text_color;
+
size_t url_range_index = 0;
sf::Vector2f glyphPos;
@@ -455,7 +457,7 @@ namespace QuickMedia
if(url_range_index < url_ranges.size()) {
size_t string_offset = (textElement.text.data + i) - str.getData();
if(string_offset >= url_ranges[url_range_index].start && string_offset < url_ranges[url_range_index].start + url_ranges[url_range_index].length) {
- text_color = URL_COLOR;
+ text_color = url_color;
text_color.a = color.a;
if(string_offset + 1 == url_ranges[url_range_index].start + url_ranges[url_range_index].length)
++url_range_index;
diff --git a/src/Theme.cpp b/src/Theme.cpp
new file mode 100644
index 0000000..1f4feca
--- /dev/null
+++ b/src/Theme.cpp
@@ -0,0 +1,62 @@
+#include "../include/Theme.hpp"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+
+namespace QuickMedia {
+ static bool themes_initialized = false;
+ static int current_theme = Theme::THEME_DARK;
+
+ static Theme themes[1];
+
+ static void init_theme_dark() {
+ themes[Theme::THEME_DARK].background_color = sf::Color(21, 25, 30);
+ themes[Theme::THEME_DARK].text_color = sf::Color(255, 255, 255);
+ themes[Theme::THEME_DARK].faded_text_color = sf::Color(255, 255, 255, 179);
+ themes[Theme::THEME_DARK].shade_color = sf::Color(33, 37, 44);
+ themes[Theme::THEME_DARK].selected_color = sf::Color(55, 60, 68);
+ themes[Theme::THEME_DARK].card_item_background_color = sf::Color(28, 32, 39);
+ themes[Theme::THEME_DARK].replies_text_color = sf::Color(129, 162, 190);
+ themes[Theme::THEME_DARK].placeholder_text_color = sf::Color(255, 255, 255, 100);
+ themes[Theme::THEME_DARK].image_loading_background_color = sf::Color(52, 58, 70);
+ themes[Theme::THEME_DARK].attention_alert_text_color = sf::Color(255, 100, 100);
+ themes[Theme::THEME_DARK].cancel_button_background_color = sf::Color(41, 45, 50);
+ themes[Theme::THEME_DARK].confirm_button_background_color = sf::Color(31, 117, 255);
+ themes[Theme::THEME_DARK].loading_bar_color = sf::Color(31, 117, 255);
+ themes[Theme::THEME_DARK].embedded_item_border_color = sf::Color(255, 255, 255);
+ themes[Theme::THEME_DARK].provisional_message_color = sf::Color(255, 255, 255, 150);
+ themes[Theme::THEME_DARK].failed_text_color = sf::Color(255, 0, 0);
+ themes[Theme::THEME_DARK].timestamp_text_color = sf::Color(185, 190, 198, 100);
+ themes[Theme::THEME_DARK].new_items_alert_color = sf::Color(128, 50, 50);
+ themes[Theme::THEME_DARK].arrow_color = sf::Color(255, 255, 255, 175);
+ themes[Theme::THEME_DARK].url_text_color = sf::Color(35, 140, 245);
+ themes[Theme::THEME_DARK].loading_page_color = sf::Color(175, 180, 188);
+ }
+
+ void init_themes() {
+ if(themes_initialized)
+ return;
+
+ init_theme_dark();
+ themes_initialized = true;
+
+ char *theme = getenv("QM_THEME");
+ if(!theme)
+ return;
+
+ if(strcmp(theme, "default") == 0)
+ set_current_theme(Theme::THEME_DARK);
+ else
+ fprintf(stderr, "Warning: Invalid theme %s, using the default theme...\n", theme);
+ }
+
+ void set_current_theme(int theme) {
+ current_theme = theme;
+ }
+
+ Theme& get_current_theme() {
+ assert(themes_initialized);
+ return themes[current_theme];
+ }
+} \ No newline at end of file
diff --git a/src/gui/Button.cpp b/src/gui/Button.cpp
index ebbb8bb..1f84335 100644
--- a/src/gui/Button.cpp
+++ b/src/gui/Button.cpp
@@ -1,4 +1,5 @@
#include "../../include/gui/Button.hpp"
+#include "../../include/Theme.hpp"
#include <SFML/Graphics/RenderTarget.hpp>
#include <SFML/Window/Event.hpp>
#include <cmath>
@@ -8,7 +9,7 @@ namespace QuickMedia {
Button::Button(const std::string &label, sf::Font *font, unsigned int character_size, float width, sf::Shader *rounded_rectangle_shader, float scale) :
label(label, *font, character_size * scale),
- background(sf::Vector2f(1.0f, 1.0f), 10.0f, sf::Color(33, 37, 44), rounded_rectangle_shader),
+ background(sf::Vector2f(1.0f, 1.0f), 10.0f, get_current_theme().shade_color, rounded_rectangle_shader),
scale(scale)
{
background.set_size(sf::Vector2f(std::floor(width * scale), get_height()));
diff --git a/src/plugins/FileManager.cpp b/src/plugins/FileManager.cpp
index 6532f3a..f78265b 100644
--- a/src/plugins/FileManager.cpp
+++ b/src/plugins/FileManager.cpp
@@ -1,6 +1,7 @@
#include "../../plugins/FileManager.hpp"
#include "../../include/FileAnalyzer.hpp"
#include "../../include/ResourceLoader.hpp"
+#include "../../include/Theme.hpp"
#include "../../include/QuickMedia.hpp"
namespace QuickMedia {
@@ -139,7 +140,7 @@ namespace QuickMedia {
description += "\nDirectory";
}
body_item->set_description(std::move(description));
- body_item->set_description_color(sf::Color(179, 179, 179));
+ body_item->set_description_color(get_current_theme().faded_text_color);
result_items.push_back(std::move(body_item));
}
diff --git a/src/plugins/MangaGeneric.cpp b/src/plugins/MangaGeneric.cpp
index e6fc11d..2d0df6a 100644
--- a/src/plugins/MangaGeneric.cpp
+++ b/src/plugins/MangaGeneric.cpp
@@ -1,5 +1,6 @@
#include "../../plugins/MangaGeneric.hpp"
#include "../../include/StringUtils.hpp"
+#include "../../include/Theme.hpp"
#include <quickmedia/HtmlSearch.h>
#include <assert.h>
@@ -103,7 +104,7 @@ namespace QuickMedia {
std::string field_stripped = strip(field_value);
const char *prefix = merge_userdata->desc_prefix ? merge_userdata->desc_prefix : "";
(*body_item_image_context.body_items)[body_item_image_context.index]->set_description(prefix + field_stripped);
- (*body_item_image_context.body_items)[body_item_image_context.index]->set_description_color(sf::Color(179, 179, 179));
+ (*body_item_image_context.body_items)[body_item_image_context.index]->set_description_color(get_current_theme().faded_text_color);
}
body_item_image_context.index++;
}
diff --git a/src/plugins/Mangadex.cpp b/src/plugins/Mangadex.cpp
index 3953215..477608e 100644
--- a/src/plugins/Mangadex.cpp
+++ b/src/plugins/Mangadex.cpp
@@ -1,5 +1,6 @@
#include "../../plugins/Mangadex.hpp"
#include "../../include/Utils.hpp"
+#include "../../include/Theme.hpp"
#include <json/writer.h>
namespace QuickMedia {
@@ -194,7 +195,7 @@ namespace QuickMedia {
const Json::Value &en_json = description_json["en"];
if(en_json.isString()) {
body_item->set_description(en_json.asString());
- body_item->set_description_color(sf::Color(179, 179, 179));
+ body_item->set_description_color(get_current_theme().faded_text_color);
}
}
result_items.push_back(std::move(body_item));
@@ -282,7 +283,7 @@ namespace QuickMedia {
time_t unix_time = iso_utc_to_unix_time(publish_at_json.asCString());
if(unix_time != 0) {
body_item->set_description("Uploaded: " + unix_time_to_local_time_str(unix_time));
- body_item->set_description_color(sf::Color(179, 179, 179));
+ body_item->set_description_color(get_current_theme().faded_text_color);
}
}
diff --git a/src/plugins/Manganelo.cpp b/src/plugins/Manganelo.cpp
index caa3f9a..094d096 100644
--- a/src/plugins/Manganelo.cpp
+++ b/src/plugins/Manganelo.cpp
@@ -2,6 +2,7 @@
#include "../../include/Notification.hpp"
#include "../../include/StringUtils.hpp"
#include "../../include/NetUtils.hpp"
+#include "../../include/Theme.hpp"
#include <quickmedia/HtmlSearch.h>
namespace QuickMedia {
@@ -62,7 +63,7 @@ namespace QuickMedia {
if(text && class_attr && strstr(class_attr, "chapter-time") && item_data->index < item_data->body_items->size()) {
std::string uploaded_date = strip(text);
(*item_data->body_items)[item_data->index]->set_description("Uploaded: " + uploaded_date);
- (*item_data->body_items)[item_data->index]->set_description_color(sf::Color(179, 179, 179));
+ (*item_data->body_items)[item_data->index]->set_description_color(get_current_theme().faded_text_color);
item_data->index++;
}
}, &body_item_context);
@@ -127,7 +128,7 @@ namespace QuickMedia {
item->url = "https://manganelo.com/manga/" + url_param_encode(nameunsigned.asString());
if(lastchapter.isString() && lastchapter.asCString()[0] != '\0') {
item->set_description("Latest chapter: " + lastchapter.asString());
- item->set_description_color(sf::Color(179, 179, 179));
+ item->set_description_color(get_current_theme().faded_text_color);
}
Json::Value image = child.get("image", "");
if(image.isString() && image.asCString()[0] != '\0')
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index 1e20bf6..9f5faf0 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -8,6 +8,7 @@
#include "../../include/Json.hpp"
#include "../../include/AsyncImageLoader.hpp"
#include "../../include/Utils.hpp"
+#include "../../include/Theme.hpp"
#include <rapidjson/document.h>
#include <rapidjson/writer.h>
#include <rapidjson/stringbuffer.h>
@@ -624,20 +625,20 @@ namespace QuickMedia {
int unread_notification_count = room->unread_notification_count;
if(unread_notification_count > 0 && set_room_as_unread) {
room_desc += "\n** " + std::to_string(unread_notification_count) + " unread mention(s) **"; // TODO: Better notification?
- room->body_item->set_description_color(sf::Color(255, 100, 100));
+ room->body_item->set_description_color(get_current_theme().attention_alert_text_color);
} else {
- room->body_item->set_description_color(sf::Color(179, 179, 179));
+ room->body_item->set_description_color(get_current_theme().faded_text_color);
}
room->body_item->set_description(std::move(room_desc));
if(set_room_as_unread)
- room->body_item->set_title_color(sf::Color(255, 100, 100));
+ room->body_item->set_title_color(get_current_theme().attention_alert_text_color);
room->last_message_read = false;
rooms_page->move_room_to_top(room);
room_tags_page->move_room_to_top(room);
} else if(is_initial_sync) {
room->body_item->set_description(extract_first_line_remove_newline_elipses(matrix->message_get_author_displayname(last_new_message.get()), AUTHOR_MAX_LENGTH) + ": " + message_to_room_description_text(last_new_message.get()));
- room->body_item->set_description_color(sf::Color(179, 179, 179));
+ room->body_item->set_description_color(get_current_theme().faded_text_color);
}
}
@@ -910,7 +911,7 @@ namespace QuickMedia {
body_item->set_author(std::move(display_name));
body_item->set_author_color(user_id_to_color(user_info.user_id));
body_item->set_description(user_info.user_id);
- body_item->set_description_color(sf::Color(179, 179, 179));
+ body_item->set_description_color(get_current_theme().faded_text_color);
if(user_info.avatar_url)
body_item->thumbnail_url = user_info.avatar_url.value();
body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
@@ -1056,8 +1057,8 @@ namespace QuickMedia {
body_item->url = notification.event_id;
if(!notification.read) {
- body_item->set_author_color(sf::Color(255, 100, 100));
- body_item->set_description_color(sf::Color(255, 100, 100));
+ body_item->set_author_color(get_current_theme().attention_alert_text_color);
+ body_item->set_description_color(get_current_theme().attention_alert_text_color);
}
body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
@@ -1116,8 +1117,8 @@ namespace QuickMedia {
NotificationsExtraData *extra_data = static_cast<NotificationsExtraData*>(body_item->extra.get());
if(!extra_data->read && extra_data->room == room) {
extra_data->read = true;
- body_item->set_author_color(sf::Color::White);
- body_item->set_description_color(sf::Color::White);
+ body_item->set_author_color(get_current_theme().text_color);
+ body_item->set_description_color(get_current_theme().text_color);
}
}
}
diff --git a/src/plugins/Soundcloud.cpp b/src/plugins/Soundcloud.cpp
index 01d12a8..abc8c18 100644
--- a/src/plugins/Soundcloud.cpp
+++ b/src/plugins/Soundcloud.cpp
@@ -3,6 +3,7 @@
#include "../../include/StringUtils.hpp"
#include "../../include/Utils.hpp"
#include "../../include/Scale.hpp"
+#include "../../include/Theme.hpp"
#include <quickmedia/HtmlSearch.h>
namespace QuickMedia {
@@ -203,7 +204,7 @@ namespace QuickMedia {
}
body_item->set_description(std::move(description));
- body_item->set_description_color(sf::Color(179, 179, 179));
+ body_item->set_description_color(get_current_theme().faded_text_color);
return body_item;
}
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index 2be4f8d..79eb3d5 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -7,6 +7,7 @@
#include "../../include/Notification.hpp"
#include "../../include/VideoPlayer.hpp"
#include "../../include/Utils.hpp"
+#include "../../include/Theme.hpp"
#include <json/reader.h>
extern "C" {
#include <HtmlParser.h>
@@ -282,7 +283,7 @@ R"END(
desc += std::move(description_snippet_stripped);
}
body_item->set_description(std::move(desc));
- body_item->set_description_color(sf::Color(179, 179, 179));
+ body_item->set_description_color(get_current_theme().faded_text_color);
if(scheduled_text.empty())
body_item->url = "https://www.youtube.com/watch?v=" + video_id_str;
@@ -341,7 +342,7 @@ R"END(
desc += std::move(description_snippet_stripped);
}
body_item->set_description(std::move(desc));
- body_item->set_description_color(sf::Color(179, 179, 179));
+ body_item->set_description_color(get_current_theme().faded_text_color);
body_item->url = "https://www.youtube.com/channel/" + channel_id_json.asString();
if(thumbnail) {
if(string_starts_with(thumbnail->url, "https:"))
@@ -1529,7 +1530,7 @@ R"END(
description += subscription_data.author;
}
body_item->set_description(std::move(description));
- body_item->set_description_color(sf::Color(179, 179, 179));
+ body_item->set_description_color(get_current_theme().faded_text_color);
body_item->url = "https://www.youtube.com/watch?v=" + subscription_entry.video_id;
body_item->thumbnail_url = "https://img.youtube.com/vi/" + subscription_entry.video_id + "/mqdefault.jpg";
body_item->thumbnail_size = sf::Vector2i(192, 108);