aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md12
-rw-r--r--example-config.json25
-rw-r--r--include/Config.hpp45
-rw-r--r--include/Theme.hpp6
-rw-r--r--include/Utils.hpp2
-rw-r--r--src/Body.cpp99
-rw-r--r--src/BodyItem.cpp4
-rw-r--r--src/Config.cpp142
-rw-r--r--src/Entry.cpp13
-rw-r--r--src/ImageViewer.cpp8
-rw-r--r--src/QuickMedia.cpp122
-rw-r--r--src/SearchBar.cpp13
-rw-r--r--src/Tabs.cpp20
-rw-r--r--src/Text.cpp8
-rw-r--r--src/Theme.cpp8
-rw-r--r--src/Utils.cpp80
-rw-r--r--src/plugins/Matrix.cpp4
17 files changed, 368 insertions, 243 deletions
diff --git a/README.md b/README.md
index 5db0713..cafd61b 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
# QuickMedia
-A dmenu-inspired native client for web services.
+A rofi inspired native client for web services.
Currently supported web services: `youtube`, `soundcloud`, `nyaa.si`, `manganelo`, `manganelos`, `mangatown`, `mangakatana`, `mangadex`, `readm`, `onimanga`, `4chan`, `matrix`, `saucenao`, `hotexamples`, `anilist` and _others_.\
Config data, including manga progress is stored under `$XDG_CONFIG_HOME/quickmedia` or `$HOME/.config/quickmedia`.\
Cache is stored under `$XDG_CACHE_HOME/quickmedia` or `$HOME/.cache/quickmedia`.
@@ -148,18 +148,16 @@ Type text and then wait and QuickMedia will automatically search.\
`/leave`: Leave the current room.\
`/me [text]`: Send a message of type "m.emote".\
`/react [text]`: React to the selected message (also works if you are replying to a message).
+## Config
+Config is loaded from `$XDG_CACHE_HOME/quickmedia/config.json` if it exists. See [example-config.json](example-config.json) for an example config. All fields in the config file are optional.
## Environment variables
-Set `QM_THEME` to one of the following: `default, nord` to change the theme.\
-Set `QM_SCALE` to scale UI.\
-Set `QM_FONT_SCALE` to scale fonts.\
-Set `QM_USE_SYSTEM_FONTS` to `1` to use system fonts instead of noto fonts.
If `xdg-open` is not installed then the `BROWSER` environment variable is used to open links in a browser.\
Set `QM_PHONE_FACTOR=1` to disable the room list side panel in matrix.
## UI scaling
-Either set the `QM_SCALE` or `GDK_SCALE` environment variable or add `Xft.dpi` to `$HOME/.Xresources` (`xrdb` which is part of the `xorg-xrdb` package needs to be installed).\
+Set `GDK_SCALE` environment variable or add `Xft.dpi` to `$HOME/.Xresources` (`xrdb` which is part of the `xorg-xrdb` package needs to be installed).\
For example a value of 96 for the `Xft.dpi` means 1.0 scaling and 144 (96*1.5) means 1.5 scaling.\
Note that at the moment, images do also not scale above their original size.\
-Set `QM_THEME` to scale fonts.
+Scaling can also be set in `$XDG_CACHE_HOME/quickmedia/config.json`, which will override `GDK_SCALE` and `$HOME/.Xresources`.
## Tabs
[tabbed](https://tools.suckless.org/tabbed/) can be used to put quickmedia windows into tabs. After installing `tabbed`, run `tabbed -c -k quickmedia launcher -e`.
## License
diff --git a/example-config.json b/example-config.json
new file mode 100644
index 0000000..6eb294f
--- /dev/null
+++ b/example-config.json
@@ -0,0 +1,25 @@
+{
+ "search": {
+ "font_size": 16
+ },
+ "tab": {
+ "font_size": 16
+ },
+ "body": {
+ "title_font_size": 16,
+ "author_font_size": 14,
+ "description_font_size": 14,
+ "timestamp_font_size": 10,
+ "reaction_font_size": 14,
+ "progress_font_size": 14,
+ "replies_font_size": 14,
+ "embedded_load_font_size": 14
+ },
+ "input": {
+ "font_size": 16
+ },
+ "use_system_fonts": false,
+ "theme": "default",
+ "scale": 1.0,
+ "font_scale": 1.0
+} \ No newline at end of file
diff --git a/include/Config.hpp b/include/Config.hpp
new file mode 100644
index 0000000..0cdabe9
--- /dev/null
+++ b/include/Config.hpp
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <string>
+
+namespace QuickMedia {
+ struct SearchConfig {
+ int font_size = 16;
+ };
+
+ struct TabConfig {
+ int font_size = 16;
+ };
+
+ struct BodyConfig {
+ int title_font_size = 16;
+ int author_font_size = 14;
+ int description_font_size = 14;
+ int timestamp_font_size = 10;
+ int reaction_font_size = 14;
+ int progress_font_size = 14;
+ int replies_font_size = 14;
+ int embedded_load_font_size = 14;
+ };
+
+ struct InputConfig {
+ int font_size = 16;
+ };
+
+ struct Config {
+ Config() = default;
+ Config(const Config&) = delete;
+ Config&operator=(const Config&) = delete;
+
+ SearchConfig search;
+ TabConfig tab;
+ BodyConfig body;
+ InputConfig input;
+ bool use_system_fonts = false;
+ std::string theme = "default";
+ float scale = 1.0f;
+ float font_scale = 1.0f;
+ };
+
+ const Config& get_config();
+} \ No newline at end of file
diff --git a/include/Theme.hpp b/include/Theme.hpp
index 3b49b4f..25372a6 100644
--- a/include/Theme.hpp
+++ b/include/Theme.hpp
@@ -5,8 +5,8 @@
namespace QuickMedia {
struct Theme {
Theme() = default;
- Theme(Theme&) = delete;
- Theme&operator=(Theme&) = delete;
+ Theme(const Theme&) = delete;
+ Theme&operator=(const Theme&) = delete;
sf::Color background_color;
sf::Color text_color;
@@ -35,5 +35,5 @@ namespace QuickMedia {
};
void init_themes();
- Theme& get_current_theme();
+ const Theme& get_current_theme();
}
diff --git a/include/Utils.hpp b/include/Utils.hpp
index 08bf4db..0bdf69f 100644
--- a/include/Utils.hpp
+++ b/include/Utils.hpp
@@ -4,8 +4,6 @@
#include <string>
namespace QuickMedia {
- float get_ui_scale();
- float get_font_scale();
void show_virtual_keyboard();
void hide_virtual_keyboard();
bool is_touch_enabled();
diff --git a/src/Body.cpp b/src/Body.cpp
index afa1dae..68e34e8 100644
--- a/src/Body.cpp
+++ b/src/Body.cpp
@@ -3,6 +3,7 @@
#include "../include/Scale.hpp"
#include "../include/ResourceLoader.hpp"
#include "../include/AsyncImageLoader.hpp"
+#include "../include/Config.hpp"
#include "../include/Utils.hpp"
#include "../include/Theme.hpp"
#include "../include/StringUtils.hpp"
@@ -31,13 +32,13 @@ struct BodySpacing {
};
namespace QuickMedia {
- static const int card_width = 250.0f * get_ui_scale() * get_font_scale();
- static const int card_height = 350.0f * get_ui_scale() * get_font_scale();
+ static const int card_width = 250.0f * get_config().scale * get_config().font_scale;
+ static const int card_height = 350.0f * get_config().scale * get_config().font_scale;
- static const int min_column_spacing = 10 * get_ui_scale();
- static const int card_padding_x = 20 * get_ui_scale();
- static const int card_padding_y = 20 * get_ui_scale();
- static const int card_image_text_padding = 10 * get_ui_scale();
+ static const int min_column_spacing = 10 * get_config().scale;
+ static const int card_padding_x = 20 * get_config().scale;
+ static const int card_padding_y = 20 * get_config().scale;
+ static const int card_image_text_padding = 10 * get_config().scale;
static const sf::Vector2i card_max_image_size(card_width - card_padding_x * 2, (card_height - card_padding_y * 2) / 2);
static const int num_columns_switch_to_list = 1;
static const int embedded_item_border_width = 4;
@@ -46,37 +47,37 @@ namespace QuickMedia {
static bool themes_initialized = false;
static void init_body_theme_minimal() {
- body_spacing[BODY_THEME_MINIMAL].spacing_y = std::floor(10.0f * get_ui_scale());
- body_spacing[BODY_THEME_MINIMAL].padding_x = std::floor(10.0f * get_ui_scale());
- body_spacing[BODY_THEME_MINIMAL].image_padding_x = std::floor(5.0f * get_ui_scale());
- body_spacing[BODY_THEME_MINIMAL].padding_y = std::floor(5.0f * get_ui_scale());
- body_spacing[BODY_THEME_MINIMAL].padding_y_text_only = std::floor(5.0f * get_ui_scale());
- body_spacing[BODY_THEME_MINIMAL].embedded_item_padding_y = std::floor(0.0f * get_ui_scale());
- body_spacing[BODY_THEME_MINIMAL].body_padding_horizontal = std::floor(10.0f * get_ui_scale());
- body_spacing[BODY_THEME_MINIMAL].body_padding_vertical = std::floor(10.0f * get_ui_scale());
-
- body_spacing[BODY_THEME_MINIMAL].reaction_background_padding_x = std::floor(7.0f * get_ui_scale());
- body_spacing[BODY_THEME_MINIMAL].reaction_background_padding_y = std::floor(3.0f * get_ui_scale());
- body_spacing[BODY_THEME_MINIMAL].reaction_spacing_x = std::floor(5.0f * get_ui_scale());
- body_spacing[BODY_THEME_MINIMAL].reaction_padding_y = std::floor(7.0f * get_ui_scale());
- body_spacing[BODY_THEME_MINIMAL].embedded_item_font_size = std::floor(14 * get_ui_scale());
+ body_spacing[BODY_THEME_MINIMAL].spacing_y = std::floor(10.0f * get_config().scale);
+ body_spacing[BODY_THEME_MINIMAL].padding_x = std::floor(10.0f * get_config().scale);
+ body_spacing[BODY_THEME_MINIMAL].image_padding_x = std::floor(5.0f * get_config().scale);
+ body_spacing[BODY_THEME_MINIMAL].padding_y = std::floor(5.0f * get_config().scale);
+ body_spacing[BODY_THEME_MINIMAL].padding_y_text_only = std::floor(5.0f * get_config().scale);
+ body_spacing[BODY_THEME_MINIMAL].embedded_item_padding_y = std::floor(0.0f * get_config().scale);
+ body_spacing[BODY_THEME_MINIMAL].body_padding_horizontal = std::floor(10.0f * get_config().scale);
+ body_spacing[BODY_THEME_MINIMAL].body_padding_vertical = std::floor(10.0f * get_config().scale);
+
+ body_spacing[BODY_THEME_MINIMAL].reaction_background_padding_x = std::floor(7.0f * get_config().scale);
+ body_spacing[BODY_THEME_MINIMAL].reaction_background_padding_y = std::floor(3.0f * get_config().scale);
+ body_spacing[BODY_THEME_MINIMAL].reaction_spacing_x = std::floor(5.0f * get_config().scale);
+ body_spacing[BODY_THEME_MINIMAL].reaction_padding_y = std::floor(7.0f * get_config().scale);
+ body_spacing[BODY_THEME_MINIMAL].embedded_item_font_size = std::floor(get_config().body.embedded_load_font_size * get_config().scale * get_config().font_scale);
}
static void init_body_theme_modern_spacious() {
- body_spacing[BODY_THEME_MODERN_SPACIOUS].spacing_y = std::floor(20.0f * get_ui_scale());
- body_spacing[BODY_THEME_MODERN_SPACIOUS].padding_x = std::floor(20.0f * get_ui_scale());
- body_spacing[BODY_THEME_MODERN_SPACIOUS].image_padding_x = std::floor(15.0f * get_ui_scale());
- body_spacing[BODY_THEME_MODERN_SPACIOUS].padding_y = std::floor(15.0f * get_ui_scale());
- body_spacing[BODY_THEME_MODERN_SPACIOUS].padding_y_text_only = std::floor(7.0f * get_ui_scale());
- body_spacing[BODY_THEME_MODERN_SPACIOUS].embedded_item_padding_y = std::floor(0.0f * get_ui_scale());
- body_spacing[BODY_THEME_MODERN_SPACIOUS].body_padding_horizontal = std::floor(20.0f * get_ui_scale());
- body_spacing[BODY_THEME_MODERN_SPACIOUS].body_padding_vertical = std::floor(20.0f * get_ui_scale());
-
- body_spacing[BODY_THEME_MODERN_SPACIOUS].reaction_background_padding_x = std::floor(7.0f * get_ui_scale());
- body_spacing[BODY_THEME_MODERN_SPACIOUS].reaction_background_padding_y = std::floor(3.0f * get_ui_scale());
- body_spacing[BODY_THEME_MODERN_SPACIOUS].reaction_spacing_x = std::floor(5.0f * get_ui_scale());
- body_spacing[BODY_THEME_MODERN_SPACIOUS].reaction_padding_y = std::floor(7.0f * get_ui_scale());
- body_spacing[BODY_THEME_MODERN_SPACIOUS].embedded_item_font_size = std::floor(14 * get_ui_scale());
+ body_spacing[BODY_THEME_MODERN_SPACIOUS].spacing_y = std::floor(20.0f * get_config().scale);
+ body_spacing[BODY_THEME_MODERN_SPACIOUS].padding_x = std::floor(20.0f * get_config().scale);
+ body_spacing[BODY_THEME_MODERN_SPACIOUS].image_padding_x = std::floor(15.0f * get_config().scale);
+ body_spacing[BODY_THEME_MODERN_SPACIOUS].padding_y = std::floor(15.0f * get_config().scale);
+ body_spacing[BODY_THEME_MODERN_SPACIOUS].padding_y_text_only = std::floor(7.0f * get_config().scale);
+ body_spacing[BODY_THEME_MODERN_SPACIOUS].embedded_item_padding_y = std::floor(0.0f * get_config().scale);
+ body_spacing[BODY_THEME_MODERN_SPACIOUS].body_padding_horizontal = std::floor(20.0f * get_config().scale);
+ body_spacing[BODY_THEME_MODERN_SPACIOUS].body_padding_vertical = std::floor(20.0f * get_config().scale);
+
+ body_spacing[BODY_THEME_MODERN_SPACIOUS].reaction_background_padding_x = std::floor(7.0f * get_config().scale);
+ body_spacing[BODY_THEME_MODERN_SPACIOUS].reaction_background_padding_y = std::floor(3.0f * get_config().scale);
+ body_spacing[BODY_THEME_MODERN_SPACIOUS].reaction_spacing_x = std::floor(5.0f * get_config().scale);
+ body_spacing[BODY_THEME_MODERN_SPACIOUS].reaction_padding_y = std::floor(7.0f * get_config().scale);
+ body_spacing[BODY_THEME_MODERN_SPACIOUS].embedded_item_font_size = std::floor(get_config().body.embedded_load_font_size * get_config().scale * get_config().font_scale);
}
static void init_body_themes() {
@@ -100,8 +101,8 @@ namespace QuickMedia {
selected_item(0),
prev_selected_item(0),
loading_icon(loading_icon_texture),
- progress_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(14 * get_ui_scale() * get_font_scale())),
- replies_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(14 * get_ui_scale() * get_font_scale())),
+ progress_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(get_config().body.progress_font_size * get_config().scale * get_config().font_scale)),
+ replies_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(get_config().body.replies_font_size * get_config().scale * get_config().font_scale)),
num_visible_items(0),
top_cut_off(false),
bottom_cut_off(false),
@@ -850,7 +851,7 @@ namespace QuickMedia {
body_item->title_text->setString(std::move(str));
body_item->title_text->setMaxWidth(width);
} else {
- body_item->title_text = std::make_unique<Text>(std::move(str), false, std::floor(16 * get_ui_scale() * get_font_scale()), width, title_mark_urls);
+ body_item->title_text = std::make_unique<Text>(std::move(str), false, std::floor(get_config().body.title_font_size * get_config().scale * get_config().font_scale), width, title_mark_urls);
}
body_item->title_text->setFillColor(body_item->get_title_color());
body_item->title_text->updateGeometry();
@@ -863,7 +864,7 @@ namespace QuickMedia {
body_item->description_text->setString(std::move(str));
body_item->description_text->setMaxWidth(width);
} else {
- body_item->description_text = std::make_unique<Text>(std::move(str), false, std::floor(14 * get_ui_scale() * get_font_scale()), width, true);
+ body_item->description_text = std::make_unique<Text>(std::move(str), false, std::floor(get_config().body.description_font_size * get_config().scale * get_config().font_scale), width, true);
}
body_item->description_text->setFillColor(body_item->get_description_color());
body_item->description_text->updateGeometry();
@@ -876,7 +877,7 @@ namespace QuickMedia {
body_item->author_text->setString(std::move(str));
body_item->author_text->setMaxWidth(width);
} else {
- body_item->author_text = std::make_unique<Text>(std::move(str), true, std::floor(14 * get_ui_scale() * get_font_scale()), width);
+ body_item->author_text = std::make_unique<Text>(std::move(str), true, std::floor(get_config().body.author_font_size * get_config().scale * get_config().font_scale), width);
}
body_item->author_text->setFillColor(body_item->get_author_color());
body_item->author_text->updateGeometry();
@@ -901,7 +902,7 @@ namespace QuickMedia {
if(body_item->timestamp_text) {
body_item->timestamp_text->setString(time_str);
} else {
- body_item->timestamp_text = std::make_unique<sf::Text>(time_str, *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(10 * get_ui_scale() * get_font_scale()));
+ body_item->timestamp_text = std::make_unique<sf::Text>(time_str, *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(get_config().body.timestamp_font_size * get_config().scale * get_config().font_scale));
}
body_item->timestamp_text->setFillColor(get_current_theme().timestamp_text_color);
@@ -932,11 +933,11 @@ namespace QuickMedia {
sf::Vector2i Body::get_item_thumbnail_size(BodyItem *item) const {
sf::Vector2i content_size;
- sf::Vector2i thumbnail_max_size_scaled = (card_view && card_view_enabled) ? card_max_image_size : sf::Vector2i(thumbnail_max_size.x * get_ui_scale(), thumbnail_max_size.y * get_ui_scale());
+ sf::Vector2i thumbnail_max_size_scaled = (card_view && card_view_enabled) ? card_max_image_size : sf::Vector2i(thumbnail_max_size.x * get_config().scale, thumbnail_max_size.y * get_config().scale);
if(item->thumbnail_size.x > 0 && item->thumbnail_size.y > 0)
- content_size = clamp_to_size(sf::Vector2i(std::floor(item->thumbnail_size.x * get_ui_scale()), std::floor(item->thumbnail_size.y * get_ui_scale())), thumbnail_max_size_scaled);
+ content_size = clamp_to_size(sf::Vector2i(std::floor(item->thumbnail_size.x * get_config().scale), std::floor(item->thumbnail_size.y * get_config().scale)), thumbnail_max_size_scaled);
else
- content_size = sf::Vector2i(250 * get_ui_scale(), 141 * get_ui_scale());
+ content_size = sf::Vector2i(250 * get_config().scale, 141 * get_config().scale);
return content_size;
}
@@ -1424,7 +1425,7 @@ namespace QuickMedia {
text_offset_x += body_spacing[body_theme].image_padding_x + item->loaded_image_size.x;
}
- const float text_offset_y = std::floor(6.0f * get_ui_scale() * get_font_scale());
+ const float text_offset_y = std::floor(6.0f * get_config().scale * get_config().font_scale);
const float timestamp_text_y = std::floor(item_pos.y + padding_y - text_offset_y);
if(item->author_text && !merge_with_previous) {
@@ -1444,7 +1445,7 @@ namespace QuickMedia {
replies_text.setString(std::move(replies_text_str));
window.draw(replies_text);
- item_pos.y += item->author_text->getHeight() - 2.0f + std::floor(3.0f * get_ui_scale());
+ item_pos.y += item->author_text->getHeight() - 2.0f + std::floor(3.0f * get_config().scale);
}
if(include_embedded_item && item->embedded_item_status != FetchStatus::NONE) {
@@ -1473,7 +1474,7 @@ namespace QuickMedia {
if(item->title_text) {
item->title_text->setPosition(std::floor(item_pos.x + text_offset_x), std::floor(item_pos.y + padding_y - text_offset_y));
item->title_text->draw(window);
- item_pos.y += item->title_text->getHeight() - 2.0f + std::floor(3.0f * get_ui_scale());
+ item_pos.y += item->title_text->getHeight() - 2.0f + std::floor(3.0f * get_config().scale);
}
if(item->description_text) {
@@ -1574,11 +1575,11 @@ namespace QuickMedia {
float item_height = 0.0f;
bool has_loaded_text = false;
if(item->title_text) {
- item_height += item->title_text->getHeight() - 2.0f + std::floor(3.0f * get_ui_scale());
+ item_height += item->title_text->getHeight() - 2.0f + std::floor(3.0f * get_config().scale);
has_loaded_text = true;
}
if(item->author_text && !merge_with_previous) {
- item_height += item->author_text->getHeight() - 2.0f + std::floor(3.0f * get_ui_scale());
+ item_height += item->author_text->getHeight() - 2.0f + std::floor(3.0f * get_config().scale);
has_loaded_text = true;
}
if(include_embedded_item && item->embedded_item_status != FetchStatus::NONE) {
@@ -1607,7 +1608,7 @@ namespace QuickMedia {
reaction_offset_x += reaction.text->getWidth() + body_spacing[body_theme].reaction_background_padding_x * 2.0f + body_spacing[body_theme].reaction_spacing_x;
if(text_offset_x + reaction_offset_x + reaction.text->getWidth() + body_spacing[body_theme].reaction_background_padding_x * 2.0f > width && i < (int)item->reactions.size() - 1) {
reaction_offset_x = 0.0f;
- item_height += reaction.text->getHeight() + body_spacing[body_theme].reaction_padding_y + std::floor(6.0f * get_ui_scale());
+ item_height += reaction.text->getHeight() + body_spacing[body_theme].reaction_padding_y + std::floor(6.0f * get_config().scale);
reaction_max_height = reaction.text->getHeight();
}
}
diff --git a/src/BodyItem.cpp b/src/BodyItem.cpp
index 8fd5362..70d9d45 100644
--- a/src/BodyItem.cpp
+++ b/src/BodyItem.cpp
@@ -1,6 +1,6 @@
#include "../include/BodyItem.hpp"
#include "../include/Theme.hpp"
-#include "../include/Utils.hpp"
+#include "../include/Config.hpp"
#include <cmath>
namespace QuickMedia {
@@ -72,7 +72,7 @@ namespace QuickMedia {
void BodyItem::add_reaction(std::string text, void *userdata) {
sf::String str = sf::String::fromUtf8(text.begin(), text.end());
Reaction reaction;
- reaction.text = std::make_unique<Text>(std::move(str), false, std::floor(14 * get_ui_scale() * get_font_scale()), 0.0f);
+ reaction.text = std::make_unique<Text>(std::move(str), false, std::floor(get_config().body.reaction_font_size * get_config().scale * get_config().font_scale), 0.0f);
reaction.userdata = userdata;
reactions.push_back(std::move(reaction));
}
diff --git a/src/Config.cpp b/src/Config.cpp
new file mode 100644
index 0000000..03be824
--- /dev/null
+++ b/src/Config.cpp
@@ -0,0 +1,142 @@
+#include "../include/Config.hpp"
+#include "../include/Storage.hpp"
+#include <assert.h>
+
+namespace QuickMedia {
+ static bool config_initialized = false;
+ static Config config;
+
+ static float scale = 1.0f;
+ static bool scale_set = false;
+
+ static const int XFT_DPI_DEFAULT = 96;
+ // Returns 96 on error
+ static int xrdb_get_dpi() {
+ int xft_dpi = XFT_DPI_DEFAULT;
+
+ FILE *xrdb_query = popen("xrdb -query", "r");
+ if(!xrdb_query)
+ return xft_dpi;
+
+ char line[512];
+ while(fgets(line, sizeof(line), xrdb_query)) {
+ int line_length = strlen(line);
+ if(line_length > 0 && line[line_length - 1] == '\n') {
+ line[line_length - 1] = '\0';
+ line_length--;
+ }
+
+ if(line_length > 8 && memcmp(line, "Xft.dpi:", 8) == 0) {
+ int xft_dpi_file = atoi(line + 8);
+ if(xft_dpi_file > 0) {
+ xft_dpi = xft_dpi_file;
+ break;
+ }
+ }
+ }
+
+ pclose(xrdb_query);
+ return xft_dpi;
+ }
+
+ static float get_ui_scale() {
+ if(scale_set)
+ return scale;
+
+ char *gdk_scale = getenv("GDK_SCALE");
+ if(gdk_scale) {
+ setlocale(LC_ALL, "C"); // Sigh... stupid C
+ scale = atof(gdk_scale);
+ if(scale < 0.0001f)
+ scale = 1.0f;
+ } else {
+ scale = (float)xrdb_get_dpi() / (float)XFT_DPI_DEFAULT;
+ }
+
+ scale_set = true;
+ return scale;
+ }
+
+ // No-op if this has already been called before
+ void init_config() {
+ if(config_initialized)
+ return;
+
+ config_initialized = true;
+ Path config_path = get_storage_dir().join("config.json");
+ Json::Value json_root;
+ if(!read_file_as_json(config_path, json_root))
+ return;
+
+ const Json::Value &search_json = json_root["search"];
+ if(search_json.isObject()) {
+ const Json::Value &font_size_json = search_json["font_size"];
+ if(font_size_json.isNumeric())
+ config.search.font_size = font_size_json.asDouble();
+ }
+
+ const Json::Value &tab_json = json_root["tab"];
+ if(tab_json.isObject()) {
+ const Json::Value &font_size_json = tab_json["font_size"];
+ if(font_size_json.isNumeric())
+ config.tab.font_size = font_size_json.asDouble();
+ }
+
+ const Json::Value &body_json = json_root["body"];
+ if(body_json.isObject()) {
+ const Json::Value &title_font_size = body_json["title_font_size"];
+ if(title_font_size.isNumeric())
+ config.body.title_font_size = title_font_size.asDouble();
+
+ const Json::Value &author_font_size = body_json["author_font_size"];
+ if(author_font_size.isNumeric())
+ config.body.author_font_size = author_font_size.asDouble();
+
+ const Json::Value &description_font_size = body_json["description_font_size"];
+ if(description_font_size.isNumeric())
+ config.body.description_font_size = description_font_size.asDouble();
+
+ const Json::Value &timestamp_font_size = body_json["timestamp_font_size"];
+ if(timestamp_font_size.isNumeric())
+ config.body.timestamp_font_size = timestamp_font_size.asDouble();
+
+ const Json::Value &reaction_font_size = body_json["reaction_font_size"];
+ if(reaction_font_size.isNumeric())
+ config.body.reaction_font_size = reaction_font_size.asDouble();
+
+ const Json::Value &embedded_load_font_size = body_json["embedded_load_font_size"];
+ if(embedded_load_font_size.isNumeric())
+ config.body.embedded_load_font_size = embedded_load_font_size.asDouble();
+ }
+
+ const Json::Value &input_json = json_root["input"];
+ if(input_json.isObject()) {
+ const Json::Value &font_size_json = input_json["font_size"];
+ if(font_size_json.isNumeric())
+ config.input.font_size = font_size_json.asDouble();
+ }
+
+ const Json::Value &use_system_fonts_json = json_root["use_system_fonts"];
+ if(use_system_fonts_json.isBool())
+ config.use_system_fonts = use_system_fonts_json.asBool();
+
+ const Json::Value &theme_json = json_root["theme"];
+ if(theme_json.isString())
+ config.theme = theme_json.asString();
+
+ const Json::Value &scale_json = json_root["scale"];
+ if(scale_json.isNumeric())
+ config.scale = scale_json.asDouble();
+ else
+ config.scale = get_ui_scale();
+
+ const Json::Value &font_scale = json_root["font_scale"];
+ if(font_scale.isNumeric())
+ config.font_scale = font_scale.asDouble();
+ }
+
+ const Config& get_config() {
+ init_config();
+ return config;
+ }
+} \ No newline at end of file
diff --git a/src/Entry.cpp b/src/Entry.cpp
index 771e2fd..f35e34f 100644
--- a/src/Entry.cpp
+++ b/src/Entry.cpp
@@ -1,5 +1,6 @@
#include "../include/Entry.hpp"
#include "../include/ResourceLoader.hpp"
+#include "../include/Config.hpp"
#include "../include/Utils.hpp"
#include "../include/Theme.hpp"
#include <SFML/Graphics/RenderWindow.hpp>
@@ -8,17 +9,17 @@
#include <math.h>
namespace QuickMedia {
- static const float background_margin_horizontal = std::floor(5.0f * get_ui_scale());
- static const float padding_vertical = std::floor(5.0f * get_ui_scale());
- static const float background_margin_vertical = std::floor(0.0f * get_ui_scale());
+ static const float background_margin_horizontal = std::floor(5.0f * get_config().scale);
+ static const float padding_vertical = std::floor(5.0f * get_config().scale);
+ static const float background_margin_vertical = std::floor(0.0f * get_config().scale);
Entry::Entry(const std::string &placeholder_text, sf::Shader *rounded_rectangle_shader) :
on_submit_callback(nullptr),
draw_background(true),
- text("", false, std::floor(16 * get_ui_scale() * get_font_scale()), 0.0f),
+ text("", false, std::floor(get_config().input.font_size * get_config().scale * get_config().font_scale), 0.0f),
width(0.0f),
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() * get_font_scale())),
+ placeholder(placeholder_text, *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(get_config().input.font_size * get_config().scale * get_config().font_scale)),
mouse_left_inside(false)
{
text.setEditable(true);
@@ -107,7 +108,7 @@ namespace QuickMedia {
void Entry::set_position(const sf::Vector2f &pos) {
background.set_position(pos);
text.setPosition(pos + sf::Vector2f(background_margin_horizontal, background_margin_vertical));
- placeholder.setPosition(pos + sf::Vector2f(background_margin_horizontal, background_margin_vertical + std::floor(5.0f * get_ui_scale())));
+ placeholder.setPosition(pos + sf::Vector2f(background_margin_horizontal, background_margin_vertical + std::floor(5.0f * get_config().scale)));
}
void Entry::set_max_width(float width) {
diff --git a/src/ImageViewer.cpp b/src/ImageViewer.cpp
index f60e796..9bc177d 100644
--- a/src/ImageViewer.cpp
+++ b/src/ImageViewer.cpp
@@ -4,7 +4,7 @@
#include "../include/SfmlFixes.hpp"
#include "../include/ResourceLoader.hpp"
#include "../include/Scale.hpp"
-#include "../include/Utils.hpp"
+#include "../include/Config.hpp"
#include <cmath>
#include <malloc.h>
#include <SFML/Window/Event.hpp>
@@ -37,7 +37,7 @@ namespace QuickMedia {
chapter_cache_dir(chapter_cache_dir),
focused_page(current_page),
font(FontLoader::get_font(FontLoader::FontType::LATIN)),
- page_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), 14 * get_ui_scale() * get_font_scale()),
+ page_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), 14 * get_config().scale * get_config().font_scale),
fit_image_to_window(fit_image_to_window)
{
current_page = std::min(current_page, num_pages);
@@ -135,7 +135,7 @@ namespace QuickMedia {
msg = "Failed to load image for page " + page_str;
}
- sf::Text error_message(std::move(msg), *font, 30 * get_ui_scale() * get_font_scale());
+ sf::Text error_message(std::move(msg), *font, 30 * get_config().scale * get_config().font_scale);
auto text_bounds = error_message.getLocalBounds();
error_message.setFillColor(sf::Color::Black);
sf::Vector2<double> render_pos_text(std::floor(window_size.x * 0.5 - text_bounds.width * 0.5), - text_bounds.height * 0.5 + scroll + offset_y);
@@ -154,7 +154,7 @@ namespace QuickMedia {
} else {
std::string page_str = std::to_string(1 + page);
- sf::Text error_message("Downloading page " + page_str, *font, 30 * get_ui_scale() * get_font_scale());
+ sf::Text error_message("Downloading page " + page_str, *font, 30 * get_config().scale * get_config().font_scale);
auto text_bounds = error_message.getLocalBounds();
error_message.setFillColor(sf::Color::Black);
sf::Vector2<double> render_pos_text(std::floor(window_size.x * 0.5 - text_bounds.width * 0.5), - text_bounds.height * 0.5 + scroll + offset_y);
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index f66e23f..361df25 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -29,9 +29,10 @@
#include "../include/NetUtils.hpp"
#include "../include/SfmlFixes.hpp"
#include "../include/ResourceLoader.hpp"
-#include "../include/Utils.hpp"
+#include "../include/Config.hpp"
#include "../include/Tabs.hpp"
#include "../include/Theme.hpp"
+#include "../include/Utils.hpp"
#include "../include/Downloader.hpp"
#include "../plugins/youtube/YoutubeMediaProxy.hpp"
#include "../include/gui/Button.hpp"
@@ -603,11 +604,6 @@ namespace QuickMedia {
return focused_monitor_center;
}
- static bool config_use_system_fonts() {
- char *qm_use_system_fonts = getenv("QM_USE_SYSTEM_FONTS");
- return qm_use_system_fonts && qm_use_system_fonts[0] == '1';
- }
-
void Program::init(Window parent_window, std::string &program_path) {
disp = XOpenDisplay(NULL);
if (!disp) {
@@ -673,7 +669,7 @@ namespace QuickMedia {
}
set_resource_loader_root_path(resources_root.c_str());
- set_use_system_fonts(config_use_system_fonts());
+ set_use_system_fonts(get_config().use_system_fonts);
init_themes();
if(!is_touch_enabled()) {
@@ -1529,7 +1525,7 @@ namespace QuickMedia {
float tab_h = Tabs::get_shade_height();
if(!search_bar)
- tab_h += std::floor(10.0f * get_ui_scale());
+ tab_h += std::floor(10.0f * get_config().scale);
if(!has_tabs)
tab_h = 0.0f;
@@ -1722,7 +1718,7 @@ namespace QuickMedia {
float shade_extra_height = 0.0f;
if(!tabs[selected_tab].search_bar) {
- shade_extra_height = std::floor(10.0f * get_ui_scale());
+ shade_extra_height = std::floor(10.0f * get_config().scale);
sf::RectangleShape shade_top(sf::Vector2f(window_size.x, shade_extra_height));
shade_top.setFillColor(get_current_theme().shade_color);
window.draw(shade_top);
@@ -1744,7 +1740,7 @@ namespace QuickMedia {
}
if(!tabs[selected_tab].page->is_ready()) {
- sf::Text loading_text("Loading...", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(30 * get_ui_scale() * get_font_scale()));
+ sf::Text loading_text("Loading...", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(30 * get_config().scale * get_config().font_scale));
auto text_bounds = loading_text.getLocalBounds();
loading_text.setPosition(
std::floor(body_pos.x + body_size.x * 0.5f - text_bounds.width * 0.5f),
@@ -1851,7 +1847,7 @@ namespace QuickMedia {
std::vector<TabAssociatedData> tab_associated_data;
for(size_t i = 0; i < tabs.size(); ++i) {
TabAssociatedData data;
- data.search_result_text = sf::Text("", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(30 * get_ui_scale() * get_font_scale()));
+ data.search_result_text = sf::Text("", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(30 * get_config().scale * get_config().font_scale));
tab_associated_data.push_back(std::move(data));
}
@@ -3595,7 +3591,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() * get_font_scale()));
+ sf::Text error_message("", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(30 * get_config().scale * get_config().font_scale));
error_message.setFillColor(get_current_theme().text_color);
bool download_in_progress = false;
@@ -3651,7 +3647,7 @@ namespace QuickMedia {
bool error = !error_message.getString().isEmpty();
bool redraw = true;
- sf::Text chapter_text(images_page->manga_name + " | " + images_page->get_chapter_name() + " | Page " + std::to_string(image_index + 1) + "/" + std::to_string(num_manga_pages), *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(14 * get_ui_scale() * get_font_scale()));
+ sf::Text chapter_text(images_page->manga_name + " | " + images_page->get_chapter_name() + " | Page " + std::to_string(image_index + 1) + "/" + std::to_string(num_manga_pages), *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(14 * get_config().scale * get_config().font_scale));
if(image_index == num_manga_pages)
chapter_text.setString(images_page->manga_name + " | " + images_page->get_chapter_name() + " | End");
chapter_text.setFillColor(sf::Color::White);
@@ -3910,14 +3906,14 @@ namespace QuickMedia {
captcha_texture.setSmooth(true);
captcha_bg_texture.setSmooth(true);
- const float captcha_slide_padding_x = std::floor(4.0f * get_ui_scale());
- const float captcha_slide_padding_y = std::floor(4.0f * get_ui_scale());
+ const float captcha_slide_padding_x = std::floor(4.0f * get_config().scale);
+ const float captcha_slide_padding_y = std::floor(4.0f * get_config().scale);
sf::Color background_color_darker = get_current_theme().background_color;
background_color_darker.r = std::max(0, (int)background_color_darker.r - 20);
background_color_darker.g = std::max(0, (int)background_color_darker.g - 20);
background_color_darker.b = std::max(0, (int)background_color_darker.b - 20);
- RoundedRectangle captcha_slide_bg(sf::Vector2f(1.0f, 1.0f), std::floor(10.0f * get_ui_scale()), background_color_darker, &rounded_rectangle_shader);
- RoundedRectangle captcha_slide_fg(sf::Vector2f(1.0f, 1.0f), std::floor(10.0f * get_ui_scale() - captcha_slide_padding_y), get_current_theme().loading_bar_color, &rounded_rectangle_shader);
+ RoundedRectangle captcha_slide_bg(sf::Vector2f(1.0f, 1.0f), std::floor(10.0f * get_config().scale), background_color_darker, &rounded_rectangle_shader);
+ RoundedRectangle captcha_slide_fg(sf::Vector2f(1.0f, 1.0f), std::floor(10.0f * get_config().scale - captcha_slide_padding_y), get_current_theme().loading_bar_color, &rounded_rectangle_shader);
auto attached_image_texture = std::make_unique<sf::Texture>();
sf::Sprite attached_image_sprite;
@@ -3925,7 +3921,7 @@ namespace QuickMedia {
std::string captcha_post_id;
std::string captcha_solution;
std::string comment_to_post;
- const int captcha_solution_text_height = 18 * get_ui_scale() * get_font_scale();
+ const int captcha_solution_text_height = 18 * get_config().scale * get_config().font_scale;
sf::Text captcha_solution_text("", *FontLoader::get_font(FontLoader::FontType::LATIN_BOLD), captcha_solution_text_height);
int solved_captcha_ttl = 0;
int64_t last_posted_time = time(nullptr);
@@ -4027,20 +4023,20 @@ namespace QuickMedia {
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());
+ logo_sprite.setScale(0.8f * get_config().scale, 0.8f * get_config().scale);
sf::Vector2f logo_size(std::floor(plugin_logo.getSize().x * logo_sprite.getScale().x), std::floor(plugin_logo.getSize().y * logo_sprite.getScale().y));
sf::Sprite file_to_upload_sprite;
bool sprite_applied_texture = false;
std::shared_ptr<ThumbnailData> file_to_upload_thumbnail_data;
- const float logo_file_to_upload_spacing = std::floor(10.0f * get_ui_scale());
+ const float logo_file_to_upload_spacing = std::floor(10.0f * get_config().scale);
float prev_chat_height = comment_input.get_height();
float chat_input_height_full = 0.0f;
- const float logo_padding_x = std::floor(15.0f * get_ui_scale());
- const float chat_input_padding_x = std::floor(10.0f * get_ui_scale());
- const float chat_input_padding_y = std::floor(10.0f * get_ui_scale());
+ const float logo_padding_x = std::floor(15.0f * get_config().scale);
+ const float chat_input_padding_x = std::floor(10.0f * get_config().scale);
+ const float chat_input_padding_y = std::floor(10.0f * get_config().scale);
sf::RectangleShape more_items_above_rect;
more_items_above_rect.setFillColor(get_current_theme().more_items_color);
@@ -4483,7 +4479,7 @@ namespace QuickMedia {
cut_off_rectangle.setPosition(captcha_sprite.getPosition() + sf::Vector2f(captcha_image_size.x, 0.0f));
window.draw(cut_off_rectangle);
- const float captcha_slide_bg_height = std::floor(20.0f * get_ui_scale());
+ const float captcha_slide_bg_height = std::floor(20.0f * get_config().scale);
captcha_slide_bg.set_size(sf::Vector2f(captcha_image_size.x, captcha_slide_bg_height));
captcha_slide_bg.set_position(sf::Vector2f(captcha_sprite.getPosition().x, captcha_sprite.getPosition().y + image_height + 10.0f));
@@ -4551,7 +4547,7 @@ namespace QuickMedia {
time_left_bg.setFillColor(sf::Color(0, 0, 0, 100));
window.draw(time_left_bg);
- sf::Text time_left_text("Wait " + std::to_string(time_left_until_post_again) + " second(s) before posting again", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(18 * get_ui_scale() * get_font_scale()));
+ sf::Text time_left_text("Wait " + std::to_string(time_left_until_post_again) + " second(s) before posting again", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(18 * get_config().scale * get_config().font_scale));
time_left_text.setPosition(time_left_bg.getPosition() +
sf::Vector2f(
std::floor(time_left_bg.getSize().x * 0.5f - time_left_text.getLocalBounds().width * 0.5f),
@@ -4618,9 +4614,9 @@ namespace QuickMedia {
inputs[i]->onTextSubmitCallback = text_submit_callback;
}
inputs[focused_input]->caret_visible = true;
- const float padding_x = std::floor(20.0f * get_ui_scale());
- const float padding_y = std::floor(20.0f * get_ui_scale());
- const float spacing_y = std::floor(20.0f * get_ui_scale());
+ const float padding_x = std::floor(20.0f * get_config().scale);
+ const float padding_y = std::floor(20.0f * get_config().scale);
+ const float spacing_y = std::floor(20.0f * get_config().scale);
sf::Vector2f body_pos;
sf::Vector2f body_size;
@@ -4969,23 +4965,23 @@ namespace QuickMedia {
ChatState chat_state = ChatState::NAVIGATING;
std::shared_ptr<BodyItem> currently_operating_on_item;
- sf::Text replying_to_text("Replying to:", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(18 * get_ui_scale() * get_font_scale()));
+ sf::Text replying_to_text("Replying to:", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(18 * get_config().scale * get_config().font_scale));
sf::Sprite logo_sprite(plugin_logo);
- logo_sprite.setScale(0.8f * get_ui_scale(), 0.8f * get_ui_scale());
+ logo_sprite.setScale(0.8f * get_config().scale, 0.8f * get_config().scale);
sf::Vector2f logo_size(plugin_logo.getSize().x * logo_sprite.getScale().x, plugin_logo.getSize().y * logo_sprite.getScale().y);
- const float room_name_text_height = std::floor(18.0f * get_ui_scale() * get_font_scale());
+ const float room_name_text_height = std::floor(18.0f * get_config().scale * get_config().font_scale);
sf::Text room_name_text("", *FontLoader::get_font(FontLoader::FontType::LATIN_BOLD), room_name_text_height);
- const float room_name_text_padding_y = std::floor(10.0f * get_ui_scale());
+ const float room_name_text_padding_y = std::floor(10.0f * get_config().scale);
const float room_name_total_height = room_name_text_height + room_name_text_padding_y * 2.0f;
const float room_avatar_height = 32.0f;
- const float room_topic_text_height = std::floor(12.0f * get_ui_scale() * get_font_scale());
+ const float room_topic_text_height = std::floor(12.0f * get_config().scale * get_config().font_scale);
sf::Text room_topic_text("", *FontLoader::get_font(FontLoader::FontType::LATIN), room_topic_text_height);
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() * get_font_scale()));
+ sf::Text room_label(matrix_chat_page->rooms_page->get_title(), *FontLoader::get_font(FontLoader::FontType::LATIN_BOLD), std::floor(18 * get_config().scale * get_config().font_scale));
room_label.setPosition(15.0f, room_name_text_padding_y + 4.0f);
sf::Sprite room_avatar_sprite;
@@ -5367,7 +5363,7 @@ namespace QuickMedia {
Mention mention;
mention.users_tab_body = tabs[USERS_TAB_INDEX].body.get();
- const float user_mention_body_height = std::floor(300.0f * get_ui_scale() * get_font_scale());
+ const float user_mention_body_height = std::floor(300.0f * get_config().scale * get_config().font_scale);
bool frame_skip_text_entry = false;
@@ -5735,9 +5731,9 @@ namespace QuickMedia {
float prev_chat_height = chat_input.get_height();
float chat_input_height_full = 0.0f;
- const float logo_padding_x = std::floor(10.0f * get_ui_scale());
- const float chat_input_padding_x = std::floor(10.0f * get_ui_scale());
- const float chat_input_padding_y = std::floor(10.0f * get_ui_scale());
+ const float logo_padding_x = std::floor(10.0f * get_config().scale);
+ const float chat_input_padding_x = std::floor(10.0f * get_config().scale);
+ const float chat_input_padding_y = std::floor(10.0f * get_config().scale);
bool avatar_applied = false;
@@ -6577,7 +6573,7 @@ namespace QuickMedia {
float width_ratio = (float)texture_size.x / (float)texture_size.y;
float height_scale = room_avatar_height / (float)texture_size.y;
float width_scale = height_scale * width_ratio;
- room_avatar_sprite.setScale(width_scale * get_ui_scale(), height_scale * get_ui_scale());
+ room_avatar_sprite.setScale(width_scale * get_config().scale, height_scale * get_config().scale);
}
redraw = true;
}
@@ -6602,7 +6598,7 @@ namespace QuickMedia {
redraw = false;
if(selected_tab == MESSAGES_TAB_INDEX || selected_tab == PINNED_TAB_INDEX || selected_tab == USERS_TAB_INDEX) {
- tab_vertical_offset = std::floor(10.0f * get_ui_scale());
+ tab_vertical_offset = std::floor(10.0f * get_config().scale);
}
tab_shade_height = std::floor(tab_vertical_offset) + Tabs::get_shade_height() + room_name_padding_y;
@@ -6610,8 +6606,8 @@ namespace QuickMedia {
const float body_width = window_size.x;
this->body_pos = sf::Vector2f(0.0f, tab_shade_height);
- if(window_size.x > 900.0f * get_ui_scale() * get_font_scale() && show_room_side_panel) {
- this->body_size = sf::Vector2f(std::floor(300.0f * get_ui_scale() * get_font_scale()), window_size.y - tab_shade_height);
+ if(window_size.x > 900.0f * get_config().scale * get_config().font_scale && show_room_side_panel) {
+ this->body_size = sf::Vector2f(std::floor(300.0f * get_config().scale * get_config().font_scale), window_size.y - tab_shade_height);
draw_room_list = true;
} else {
this->body_size = sf::Vector2f(0.0f, 0.0f);
@@ -6748,15 +6744,15 @@ namespace QuickMedia {
//window.draw(tab_shade);
if(selected_tab == MESSAGES_TAB_INDEX || selected_tab == PINNED_TAB_INDEX || selected_tab == USERS_TAB_INDEX) {
- float room_name_text_offset_x = 0.0f;
+ float room_name_text_offset_x = std::floor(10.0f * get_config().scale);
if(room_avatar_thumbnail_data->loading_state == LoadingState::APPLIED_TO_TEXTURE && room_avatar_sprite.getTexture() && room_avatar_sprite.getTexture()->getNativeHandle() != 0) {
auto room_avatar_texture_size = room_avatar_sprite.getTexture()->getSize();
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 + std::floor(10.0f * get_ui_scale()), room_name_total_height * 0.5f - room_avatar_texture_size.y * 0.5f + 5.0f);
+ room_avatar_sprite.setPosition(body_pos.x + std::floor(10.0f * get_config().scale), room_name_total_height * 0.5f - room_avatar_texture_size.y * 0.5f + 5.0f);
circle_mask_shader.setUniform("resolution", sf::Vector2f(room_avatar_texture_size.x, room_avatar_texture_size.y));
window.draw(room_avatar_sprite, &circle_mask_shader);
- room_name_text_offset_x += std::floor(10.0f * get_ui_scale()) + room_avatar_texture_size.x + 10.0f;
+ 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);
@@ -6794,7 +6790,7 @@ namespace QuickMedia {
overlay.setFillColor(sf::Color(0, 0, 0, 240));
window.draw(overlay);
- const float padding_x = std::floor(10.0f * get_ui_scale());
+ const float padding_x = std::floor(10.0f * get_config().scale);
sf::Vector2f body_item_pos(body_pos.x + padding_x, window_size.y - chat_input_height_full - item_height);
sf::Vector2f body_item_size(body_size.x - padding_x * 2.0f, item_height);
@@ -7251,8 +7247,8 @@ namespace QuickMedia {
sf::Vector2i monitor_size;
sf::Vector2i focused_monitor_center = get_focused_monitor_center(disp, monitor_size);
- window_size.x = std::min(monitor_size.x, (int)(300.0f + 380.0f * get_ui_scale()));
- window_size.y = std::min(monitor_size.y, (int)(50.0f + 130.0f * get_ui_scale()));
+ window_size.x = std::min(monitor_size.x, (int)(300.0f + 380.0f * get_config().scale));
+ window_size.y = std::min(monitor_size.y, (int)(50.0f + 130.0f * get_config().scale));
window.setSize(sf::Vector2u(window_size.x, window_size.y));
XSizeHints *size_hints = XAllocSizeHints();
if(size_hints) {
@@ -7283,20 +7279,20 @@ namespace QuickMedia {
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()), 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 loading_bar_padding_x = std::floor(4.0f * get_config().scale);
+ const float loading_bar_padding_y = std::floor(4.0f * get_config().scale);
+ RoundedRectangle loading_bar_background(sf::Vector2f(1.0f, 1.0f), std::floor(10.0f * get_config().scale), get_current_theme().background_color, &rounded_rectangle_shader);
+ RoundedRectangle loading_bar(sf::Vector2f(1.0f, 1.0f), std::floor(10.0f * get_config().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());
- const float loading_bar_height = std::floor(20.0f * get_ui_scale());
+ const float padding_x = std::floor(30.0f * get_config().scale);
+ const float spacing_y = std::floor(15.0f * get_config().scale);
+ const float loading_bar_height = std::floor(20.0f * get_config().scale);
- sf::Text progress_text("0kb/Unknown", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(20.0f * get_ui_scale() * get_font_scale()));
- sf::Text status_text("Downloading", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(20.0f * get_ui_scale() * get_font_scale()));
- sf::Text filename_text(filename.c_str(), *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(14.0f * get_ui_scale() * get_font_scale()));
+ sf::Text progress_text("0kb/Unknown", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(20.0f * get_config().scale * get_config().font_scale));
+ sf::Text status_text("Downloading", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(20.0f * get_config().scale * get_config().font_scale));
+ sf::Text filename_text(filename.c_str(), *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(14.0f * get_config().scale * get_config().font_scale));
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() * get_font_scale()));
+ sf::Text download_speed_text("0 bytes/s", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(14.0f * get_config().scale * get_config().font_scale));
download_speed_text.setFillColor(get_current_theme().faded_text_color);
bool redraw = true;
@@ -7478,13 +7474,13 @@ namespace QuickMedia {
const float bottom_panel_padding = 10.0f;
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() * get_font_scale());
+ Button cancel_button("Cancel", FontLoader::get_font(FontLoader::FontType::LATIN), 16, 100.0f, &rounded_rectangle_shader, get_config().scale * get_config().font_scale);
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() * get_font_scale());
+ Button save_button("Save", FontLoader::get_font(FontLoader::FontType::LATIN), 16, 100.0f, &rounded_rectangle_shader, get_config().scale * get_config().font_scale);
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() * get_font_scale()));
+ sf::Text file_name_label("File name:", *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(16.0f * get_config().scale * get_config().font_scale));
Entry file_name_entry("", &rounded_rectangle_shader);
file_name_entry.set_text(filename);
@@ -7594,7 +7590,7 @@ namespace QuickMedia {
body_size.y -= Tabs::get_shade_height();
save_button.set_position(window_size - sf::Vector2f(save_button.get_width(), save_button.get_height()) - sf::Vector2f(bottom_panel_padding, bottom_panel_padding));
cancel_button.set_position(save_button.get_position() - sf::Vector2f(cancel_button.get_width() + bottom_panel_spacing, 0.0f));
- file_name_label.setPosition(sf::Vector2f(bottom_panel_spacing, std::floor(window_size.y - bottom_panel_padding - file_name_entry.get_height() * 0.5f - file_name_label.getLocalBounds().height * 0.5f - 5.0f * get_ui_scale())));
+ file_name_label.setPosition(sf::Vector2f(bottom_panel_spacing, std::floor(window_size.y - bottom_panel_padding - file_name_entry.get_height() * 0.5f - file_name_label.getLocalBounds().height * 0.5f - 5.0f * get_config().scale)));
file_name_entry.set_position(sf::Vector2f(file_name_label.getPosition().x + file_name_label.getLocalBounds().width + bottom_panel_spacing, window_size.y - file_name_entry.get_height() - bottom_panel_padding));
file_name_entry.set_max_width(std::floor(cancel_button.get_position().x - bottom_panel_spacing - file_name_label.getLocalBounds().width - bottom_panel_spacing - bottom_panel_spacing));
bottom_panel_background.setPosition(0.0f, window_size.y - std::floor(bottom_panel_padding * 2.0f + file_name_entry.get_height()));
diff --git a/src/SearchBar.cpp b/src/SearchBar.cpp
index a34b302..cc93169 100644
--- a/src/SearchBar.cpp
+++ b/src/SearchBar.cpp
@@ -2,6 +2,7 @@
#include "../include/Theme.hpp"
#include "../include/Scale.hpp"
#include "../include/ResourceLoader.hpp"
+#include "../include/Config.hpp"
#include "../include/Utils.hpp"
#include <SFML/Window/Event.hpp>
#include <SFML/Window/Clipboard.hpp>
@@ -12,10 +13,10 @@
// TODO: Use a seperate placeholder sf::Text instead of switching the text to placeholder text....
namespace QuickMedia {
- static const float background_margin_horizontal = 10.0f + std::floor(5.0f * get_ui_scale());
- static const float padding_top_default = std::floor(10.0f * get_ui_scale());
- static const float padding_bottom_default = std::floor(15.0f * get_ui_scale());
- static const float background_margin_vertical = std::floor(4.0f * get_ui_scale());
+ static const float background_margin_horizontal = 10.0f + std::floor(5.0f * get_config().scale);
+ static const float padding_top_default = std::floor(10.0f * get_config().scale);
+ static const float padding_bottom_default = std::floor(15.0f * get_config().scale);
+ static const float background_margin_vertical = std::floor(4.0f * get_config().scale);
SearchBar::SearchBar(sf::Texture *plugin_logo, sf::Shader *rounded_rectangle_shader, const std::string &placeholder, bool input_masked) :
onTextUpdateCallback(nullptr),
@@ -23,7 +24,7 @@ namespace QuickMedia {
onTextBeginTypingCallback(nullptr),
text_autosearch_delay(50),
caret_visible(true),
- text(placeholder, *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(16 * get_ui_scale() * get_font_scale())),
+ text(placeholder, *FontLoader::get_font(FontLoader::FontType::LATIN), std::floor(get_config().search.font_size * get_config().scale * get_config().font_scale)),
background(sf::Vector2f(1.0f, 1.0f), 10.0f, get_current_theme().selected_color, rounded_rectangle_shader),
placeholder_str(placeholder),
show_placeholder(true),
@@ -165,7 +166,7 @@ namespace QuickMedia {
background.set_size(sf::Vector2f(width, rect_height));
shade.setSize(sf::Vector2f(size.x, padding_top + rect_height + padding_bottom));
- caret.setSize(sf::Vector2f(std::floor(2.0f * get_ui_scale()), text.getCharacterSize() + std::floor(2.0f * get_ui_scale())));
+ caret.setSize(sf::Vector2f(std::floor(2.0f * get_config().scale), text.getCharacterSize() + std::floor(2.0f * get_config().scale)));
background.set_position(sf::Vector2f(pos.x + offset_x, pos.y + padding_top));
shade.setPosition(pos);
diff --git a/src/Tabs.cpp b/src/Tabs.cpp
index de9e2b3..3745973 100644
--- a/src/Tabs.cpp
+++ b/src/Tabs.cpp
@@ -1,7 +1,7 @@
#include "../include/Tabs.hpp"
#include "../include/Body.hpp"
#include "../include/ResourceLoader.hpp"
-#include "../include/Utils.hpp"
+#include "../include/Config.hpp"
#include "../include/Theme.hpp"
#include <SFML/Window/Event.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
@@ -9,8 +9,8 @@
#include <cmath>
namespace QuickMedia {
- static const float tab_text_size = std::floor(16.0f * get_ui_scale() * get_font_scale());
- static const float tab_height = tab_text_size + std::floor(10.0f * get_ui_scale());
+ static const float tab_text_size = std::floor(get_config().tab.font_size * get_config().scale * get_config().font_scale);
+ static const float tab_height = tab_text_size + std::floor(10.0f * get_config().scale);
static const float tab_min_width = 250.0f;
static const float tab_margin_x = 10.0f;
@@ -21,7 +21,7 @@ namespace QuickMedia {
// static
float Tabs::get_shade_height() {
- return tab_height + std::floor(10.0f * get_ui_scale());
+ return tab_height + std::floor(10.0f * get_config().scale);
}
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) {
@@ -91,7 +91,7 @@ namespace QuickMedia {
const int num_visible_tabs = std::min((int)tabs.size(), std::max(1, (int)(width / tab_min_width)));
width_per_tab = std::floor(width / num_visible_tabs);
- const float tab_text_y = std::floor(pos.y + tab_height*0.5f - (tab_text_size + 5.0f*get_ui_scale())*0.5f);
+ const float tab_text_y = std::floor(pos.y + tab_height*0.5f - (tab_text_size + 5.0f*get_config().scale)*0.5f);
tab_background_width = std::floor(width_per_tab - tab_margin_x*2.0f);
background.set_size(sf::Vector2f(tab_background_width, tab_height));
@@ -145,7 +145,7 @@ namespace QuickMedia {
glDisable(GL_SCISSOR_TEST);
}
- float lw = std::floor(25.0f * get_ui_scale());
+ float lw = std::floor(25.0f * get_config().scale);
float lh = background.get_size().y;
float line_offset_y = std::floor(lw * 0.35f);
@@ -164,7 +164,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())));
+ sf::RectangleShape line(sf::Vector2f(std::floor(10.0f * get_config().scale), std::floor(2.0f * get_config().scale)));
line.setFillColor(get_current_theme().arrow_color);
line.setOrigin(line.getSize().x * 0.5f, line.getSize().y * 0.5f);
@@ -173,7 +173,7 @@ namespace QuickMedia {
window.draw(line);
line.rotate(-90.0f);
- line.setPosition(std::floor(start_pos.x + line.getLocalBounds().width), std::floor(pos.y + background.get_size().y * 0.5f - lh * 0.5f + line_offset_y + std::floor(7.0f * get_ui_scale())));
+ line.setPosition(std::floor(start_pos.x + line.getLocalBounds().width), std::floor(pos.y + background.get_size().y * 0.5f - lh * 0.5f + line_offset_y + std::floor(7.0f * get_config().scale)));
window.draw(line);
}
@@ -191,7 +191,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())));
+ sf::RectangleShape line(sf::Vector2f(std::floor(10.0f * get_config().scale), std::floor(2.0f * get_config().scale)));
line.setFillColor(get_current_theme().arrow_color);
line.setOrigin(line.getSize().x * 0.5f, line.getSize().y * 0.5f);
@@ -200,7 +200,7 @@ namespace QuickMedia {
window.draw(line);
line.rotate(-90.0f);
- line.setPosition(std::floor(start_pos.x + width - lw*0.75f + line.getLocalBounds().width), std::floor(pos.y + background.get_size().y * 0.5f - lh * 0.5f + line_offset_y + std::floor(7.0f * get_ui_scale())));
+ line.setPosition(std::floor(start_pos.x + width - lw*0.75f + line.getLocalBounds().width), std::floor(pos.y + background.get_size().y * 0.5f - lh * 0.5f + line_offset_y + std::floor(7.0f * get_config().scale)));
window.draw(line);
}
}
diff --git a/src/Text.cpp b/src/Text.cpp
index e6edb6e..c5f1ce2 100644
--- a/src/Text.cpp
+++ b/src/Text.cpp
@@ -1,6 +1,6 @@
#include "../include/Text.hpp"
#include "../include/ResourceLoader.hpp"
-#include "../include/Utils.hpp"
+#include "../include/Config.hpp"
#include "../include/Theme.hpp"
#include "../generated/Emoji.hpp"
#include <SFML/Graphics/RectangleShape.hpp>
@@ -965,10 +965,10 @@ namespace QuickMedia
if(!editable) return true;
pos.y -= floor(vspace * 2.0f);
- const float caret_margin = std::floor(2.0f * get_ui_scale());
+ const float caret_margin = std::floor(2.0f * get_config().scale);
- sf::RectangleShape caretRect(sf::Vector2f(std::floor(2.0f * get_ui_scale()), floor(vspace - caret_margin * 2.0f)));
- caretRect.setPosition(floor(pos.x + caretPosition.x), floor(pos.y + caretPosition.y + caret_margin + std::floor(4.0f * get_ui_scale())));
+ sf::RectangleShape caretRect(sf::Vector2f(std::floor(2.0f * get_config().scale), floor(vspace - caret_margin * 2.0f)));
+ caretRect.setPosition(floor(pos.x + caretPosition.x), floor(pos.y + caretPosition.y + caret_margin + std::floor(4.0f * get_config().scale)));
target.draw(caretRect);
return true;
}
diff --git a/src/Theme.cpp b/src/Theme.cpp
index 18581ff..a197848 100644
--- a/src/Theme.cpp
+++ b/src/Theme.cpp
@@ -1,4 +1,5 @@
#include "../include/Theme.hpp"
+#include "../include/Config.hpp"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -76,10 +77,7 @@ namespace QuickMedia {
init_theme_dark();
init_theme_nord();
- char *theme = getenv("QM_THEME");
- if(!theme)
- return;
-
+ const char *theme = get_config().theme.c_str();
if(strcmp(theme, "default") == 0)
current_theme = THEME_DARK;
else if(strcmp(theme, "nord") == 0)
@@ -92,7 +90,7 @@ namespace QuickMedia {
current_theme = theme;
}
- Theme& get_current_theme() {
+ const Theme& get_current_theme() {
assert(themes_initialized);
return themes[current_theme];
}
diff --git a/src/Utils.cpp b/src/Utils.cpp
index 3919bec..fec8bb9 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -5,91 +5,11 @@
#include <locale.h>
namespace QuickMedia {
- static float scale = 1.0f;
- static bool scale_set = false;
- static float font_scale = 1.0f;
- static bool font_scale_set = false;
static bool qm_enable_touch = false;
static bool qm_enable_touch_set = false;
static bool wayland_display_set = false;
static const char *wayland_display = nullptr;
- static const int XFT_DPI_DEFAULT = 96;
- // Returns 96 on error
- static int xrdb_get_dpi() {
- int xft_dpi = XFT_DPI_DEFAULT;
-
- FILE *xrdb_query = popen("xrdb -query", "r");
- if(!xrdb_query)
- return xft_dpi;
-
- char line[512];
- while(fgets(line, sizeof(line), xrdb_query)) {
- int line_length = strlen(line);
- if(line_length > 0 && line[line_length - 1] == '\n') {
- line[line_length - 1] = '\0';
- line_length--;
- }
-
- if(line_length > 8 && memcmp(line, "Xft.dpi:", 8) == 0) {
- int xft_dpi_file = atoi(line + 8);
- if(xft_dpi_file > 0) {
- xft_dpi = xft_dpi_file;
- break;
- }
- }
- }
-
- pclose(xrdb_query);
- return xft_dpi;
- }
-
- float get_ui_scale() {
- if(scale_set)
- return scale;
-
- setlocale(LC_ALL, "C"); // Sigh... stupid C
- char *qm_scale = getenv("QM_SCALE");
- if(qm_scale) {
- scale = atof(qm_scale);
- if(scale < 0.0001f)
- scale = 1.0f;
-
- scale_set = true;
- return scale;
- }
-
- char *gdk_scale = getenv("GDK_SCALE");
- if(gdk_scale) {
- scale = atof(gdk_scale);
- if(scale < 0.0001f)
- scale = 1.0f;
- } else {
- scale = (float)xrdb_get_dpi() / (float)XFT_DPI_DEFAULT;
- }
-
- scale_set = true;
- return scale;
- }
-
- float get_font_scale() {
- if(font_scale_set)
- return font_scale;
-
- char *qm_font_scale = getenv("QM_FONT_SCALE");
- if(qm_font_scale) {
- setlocale(LC_ALL, "C"); // Sigh... stupid C
- font_scale = atof(qm_font_scale);
- if(font_scale < 0.0001f)
- font_scale = 1.0f;
- } else {
- font_scale = 1.0f;
- }
-
- font_scale_set = true;
- return font_scale;
- }
-
void show_virtual_keyboard() {
if(!is_touch_enabled())
return;
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index e95b74b..6d8148d 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -7,7 +7,7 @@
#include "../../external/cppcodec/base64_url.hpp"
#include "../../include/Json.hpp"
#include "../../include/AsyncImageLoader.hpp"
-#include "../../include/Utils.hpp"
+#include "../../include/Config.hpp"
#include "../../include/Theme.hpp"
#include <rapidjson/document.h>
#include <rapidjson/writer.h>
@@ -1881,7 +1881,7 @@ namespace QuickMedia {
if(mxc_id.empty())
return "";
- std::string size = std::to_string(int(32 * get_ui_scale()));
+ std::string size = std::to_string(int(32 * get_config().scale));
return homeserver + "/_matrix/media/r0/thumbnail/" + mxc_id + "?width=" + size + "&height=" + size + "&method=crop";
}