aboutsummaryrefslogtreecommitdiff
path: root/src/Theme.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Theme.cpp')
-rw-r--r--src/Theme.cpp183
1 files changed, 104 insertions, 79 deletions
diff --git a/src/Theme.cpp b/src/Theme.cpp
index a197848..8f52240 100644
--- a/src/Theme.cpp
+++ b/src/Theme.cpp
@@ -1,97 +1,122 @@
#include "../include/Theme.hpp"
#include "../include/Config.hpp"
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
+#include "../include/Storage.hpp"
#include <assert.h>
namespace QuickMedia {
- enum {
- THEME_DARK, // Default theme
- THEME_NORD,
-
- __NUM_THEMES__ // This should always be the last item
- };
-
- static bool themes_initialized = false;
- static int current_theme = THEME_DARK;
- static Theme themes[__NUM_THEMES__];
-
- static void init_theme_dark() {
- themes[THEME_DARK].background_color = sf::Color(18, 21, 26);
- themes[THEME_DARK].text_color = sf::Color(255, 255, 255);
- themes[THEME_DARK].faded_text_color = sf::Color(255, 255, 255, 179);
- themes[THEME_DARK].shade_color = sf::Color(28, 32, 39);
- themes[THEME_DARK].selected_color = sf::Color(55, 60, 68);
- themes[THEME_DARK].card_item_background_color = sf::Color(28, 32, 39);
- themes[THEME_DARK].replies_text_color = sf::Color(129, 162, 190);
- themes[THEME_DARK].placeholder_text_color = sf::Color(255, 255, 255, 100);
- themes[THEME_DARK].image_loading_background_color = sf::Color(52, 58, 70);
- themes[THEME_DARK].attention_alert_text_color = sf::Color(255, 100, 100);
- themes[THEME_DARK].cancel_button_background_color = sf::Color(41, 45, 50);
- themes[THEME_DARK].confirm_button_background_color = sf::Color(31, 117, 255);
- themes[THEME_DARK].loading_bar_color = sf::Color(31, 117, 255);
- themes[THEME_DARK].embedded_item_border_color = sf::Color(255, 255, 255);
- themes[THEME_DARK].provisional_message_color = sf::Color(255, 255, 255, 150);
- themes[THEME_DARK].failed_text_color = sf::Color(255, 0, 0);
- themes[THEME_DARK].timestamp_text_color = sf::Color(185, 190, 198, 100);
- themes[THEME_DARK].new_items_alert_color = sf::Color(128, 50, 50);
- themes[THEME_DARK].arrow_color = sf::Color(255, 255, 255, 175);
- themes[THEME_DARK].url_text_color = sf::Color(35, 140, 245);
- themes[THEME_DARK].loading_page_color = sf::Color(175, 180, 188);
- themes[THEME_DARK].more_items_color = sf::Color(150, 175, 255, 100);
- themes[THEME_DARK].blur_enabled = false;
+ static bool theme_initialized = false;
+ static Theme *theme = nullptr;
+
+ static bool get_theme_by_name(const std::string &theme_name, Json::Value &json_root) {
+ Path config_path = get_storage_dir().join("themes").join(theme_name).append(".json");
+ if(read_file_as_json(config_path, json_root) && json_root.isObject())
+ return true;
+
+ config_path = Path("/usr/share/quickmedia/themes/").join(theme_name).append(".json");
+ if(read_file_as_json(config_path, json_root) && json_root.isObject())
+ return true;
+
+ return false;
}
- static void init_theme_nord() {
- themes[THEME_NORD].background_color = sf::Color(46, 52, 64);
- themes[THEME_NORD].text_color = sf::Color(236, 239, 244);
- themes[THEME_NORD].faded_text_color = sf::Color(229, 233, 240);
- themes[THEME_NORD].shade_color = sf::Color(67, 76, 94);
- themes[THEME_NORD].selected_color = sf::Color(59, 66, 82);
- themes[THEME_NORD].card_item_background_color = sf::Color(76, 86, 106);
- themes[THEME_NORD].replies_text_color = sf::Color(136, 192, 208);
- themes[THEME_NORD].placeholder_text_color = sf::Color(236, 239, 244);
- themes[THEME_NORD].image_loading_background_color = sf::Color(216, 222, 233);
- themes[THEME_NORD].attention_alert_text_color = sf::Color(191, 97, 106);
- themes[THEME_NORD].cancel_button_background_color = sf::Color(229, 233, 240);
- themes[THEME_NORD].confirm_button_background_color = sf::Color(229, 233, 240);
- themes[THEME_NORD].loading_bar_color = sf::Color(136, 192, 208);
- themes[THEME_NORD].embedded_item_border_color = sf::Color(216, 222, 233);
- themes[THEME_NORD].provisional_message_color = sf::Color(236, 239, 244);
- themes[THEME_NORD].failed_text_color = sf::Color(191, 97, 106);
- themes[THEME_NORD].timestamp_text_color = sf::Color(76, 86, 106);
- themes[THEME_NORD].new_items_alert_color = sf::Color(235, 203, 139);
- themes[THEME_NORD].arrow_color = sf::Color(236, 239, 244);
- themes[THEME_NORD].url_text_color = sf::Color(136, 192, 208);
- themes[THEME_NORD].loading_page_color = sf::Color(229, 233, 240);
- themes[THEME_NORD].more_items_color = sf::Color(150, 175, 255, 100);
- themes[THEME_NORD].blur_enabled = false;
+ // Returns -1 if its not a hex value
+ static int get_hex_value(char c) {
+ if(c >= '0' && c <= '9')
+ return c - '0';
+ else if(c >= 'a' && c <= 'f')
+ return 10 + (c - 'a');
+ else if(c >= 'A' && c <= 'F')
+ return 10 + (c - 'A');
+ else
+ return -1;
}
- void init_themes() {
- if(themes_initialized)
+ static void parse_hex_set_color(const Json::Value &json_obj, const char *field_name, sf::Color &color) {
+ const Json::Value &json_val = json_obj[field_name];
+ if(!json_val.isString()) {
+ fprintf(stderr, "Warning: theme variable \"%s\" does not exists or is not a string\n", field_name);
return;
+ }
- themes_initialized = true;
- init_theme_dark();
- init_theme_nord();
+ // #RRGGBB(AA), case insensitive hex
+ const char *color_str = json_val.asCString();
+ if(color_str[0] != '#') {
+ fprintf(stderr, "Warning: theme variable \"%s\" is an invalid color value. Expected #RRGGBB or #RRGGBBAA, was: %s\n", field_name, color_str);
+ return;
+ }
- const char *theme = get_config().theme.c_str();
- if(strcmp(theme, "default") == 0)
- current_theme = THEME_DARK;
- else if(strcmp(theme, "nord") == 0)
- current_theme = THEME_NORD;
- else
- fprintf(stderr, "Warning: Invalid theme %s, using the default theme\n", theme);
+ const int color_str_len = strlen(color_str);
+ if(color_str_len - 1 != 6 && color_str_len - 1 != 8) {
+ fprintf(stderr, "Warning: theme variable \"%s\" is an invalid color value. Expected #RRGGBB or #RRGGBBAA, was: %s\n", field_name, color_str);
+ return;
+ }
+
+ sf::Color new_color;
+ for(int i = 1; i < color_str_len; i += 2) {
+ const int c1 = get_hex_value(color_str[i + 0]);
+ const int c2 = get_hex_value(color_str[i + 1]);
+ if(c1 == -1 || c2 == -1) {
+ fprintf(stderr, "Warning: theme variable \"%s\" is an invalid color value. Expected #RRGGBB or #RRGGBBAA, was: %s\n", field_name, color_str);
+ return;
+ }
+
+ // TODO: Test on big endian systems
+ (&new_color.r)[(i - 1)/2] = (c1 << 4) | c2;
+ }
+ color = new_color;
}
- void set_current_theme(int theme) {
- current_theme = theme;
+ static void get_bool_value(const Json::Value &json_obj, const char *field_name, bool &val) {
+ const Json::Value &json_val = json_obj[field_name];
+ if(!json_val.isBool()) {
+ fprintf(stderr, "Warning: theme variable \"%s\" does not exists or is not a boolean\n", field_name);
+ return;
+ }
+ val = json_val.asBool();
+ }
+
+ static void init_theme() {
+ if(theme_initialized)
+ return;
+
+ theme_initialized = true;
+ // Wtf? can't use static non-pointer config because it causes a segfault.
+ // It looks like a libc bug??? crashes for both gcc and clang.
+ theme = new Theme();
+
+ Json::Value json_root;
+ if(!get_theme_by_name(get_config().theme, json_root)) {
+ fprintf(stderr, "Warning: failed to load theme: \"%s\", using \"default\" theme\n", get_config().theme.c_str());
+ return;
+ }
+
+ parse_hex_set_color(json_root, "background_color", theme->background_color);
+ parse_hex_set_color(json_root, "text_color", theme->text_color);
+ parse_hex_set_color(json_root, "faded_text_color", theme->faded_text_color);
+ parse_hex_set_color(json_root, "shade_color", theme->shade_color);
+ parse_hex_set_color(json_root, "selected_color", theme->selected_color);
+ parse_hex_set_color(json_root, "card_item_background_color", theme->card_item_background_color);
+ parse_hex_set_color(json_root, "replies_text_color", theme->replies_text_color);
+ parse_hex_set_color(json_root, "placeholder_text_color", theme->placeholder_text_color);
+ parse_hex_set_color(json_root, "image_loading_background_color", theme->image_loading_background_color);
+ parse_hex_set_color(json_root, "attention_alert_text_color", theme->attention_alert_text_color);
+ parse_hex_set_color(json_root, "cancel_button_background_color", theme->cancel_button_background_color);
+ parse_hex_set_color(json_root, "confirm_button_background_color", theme->confirm_button_background_color);
+ parse_hex_set_color(json_root, "loading_bar_color", theme->loading_bar_color);
+ parse_hex_set_color(json_root, "embedded_item_border_color", theme->embedded_item_border_color);
+ parse_hex_set_color(json_root, "provisional_message_color", theme->provisional_message_color);
+ parse_hex_set_color(json_root, "failed_text_color", theme->failed_text_color);
+ parse_hex_set_color(json_root, "timestamp_text_color", theme->timestamp_text_color);
+ parse_hex_set_color(json_root, "new_items_alert_color", theme->new_items_alert_color);
+ parse_hex_set_color(json_root, "arrow_color", theme->arrow_color);
+ parse_hex_set_color(json_root, "url_text_color", theme->url_text_color);
+ parse_hex_set_color(json_root, "loading_page_color", theme->loading_page_color);
+ parse_hex_set_color(json_root, "more_items_color", theme->more_items_color);
+ get_bool_value(json_root, "drop_shadow", theme->drop_shadow);
}
- const Theme& get_current_theme() {
- assert(themes_initialized);
- return themes[current_theme];
+ const Theme& get_theme() {
+ init_theme();
+ return *theme;
}
}