mirror of
https://github.com/aristocratos/btop.git
synced 2024-06-02 10:35:14 +12:00
160 lines
4.9 KiB
C++
160 lines
4.9 KiB
C++
/* Copyright 2021 Aristocratos (jakob@qvantnet.com)
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
indent = tab
|
|
tab-size = 4
|
|
*/
|
|
|
|
#ifndef _btop_theme_included_
|
|
#define _btop_theme_included_
|
|
|
|
#include <string>
|
|
#include <cmath>
|
|
#include <vector>
|
|
#include <map>
|
|
|
|
#include <btop_globs.h>
|
|
#include <btop_tools.h>
|
|
#include <btop_config.h>
|
|
|
|
using namespace std;
|
|
|
|
namespace Theme {
|
|
|
|
namespace {
|
|
//* Convert 24-bit colors to 256 colors using 6x6x6 color cube
|
|
int truecolor_to_256(uint r, uint g, uint b){
|
|
if (r / 11 == g / 11 && g / 11 == b / 11) {
|
|
return 232 + r / 11;
|
|
} else {
|
|
return round((float)(r / 51)) * 36 + round((float)(g / 51)) * 6 + round((float)(b / 51)) + 16;
|
|
}
|
|
}
|
|
}
|
|
|
|
//* Generate escape sequence for 24-bit or 256 color and return as a string
|
|
//* Args hexa: ["#000000"-"#ffffff"] for color, ["#00"-"#ff"] for greyscale
|
|
//* t_to_256: [true|false] convert 24bit value to 256 color value
|
|
//* depth: ["fg"|"bg"] for either a foreground color or a background color
|
|
string hex_to_color(string hexa, bool t_to_256=false, string depth="fg"){
|
|
if (hexa.size() > 1){
|
|
hexa.erase(0, 1);
|
|
for (auto& c : hexa) if (!isxdigit(c)) return "";
|
|
depth = (depth == "fg") ? "38" : "48";
|
|
string pre = Fx::e + depth + ";";
|
|
pre += (t_to_256) ? "5;" : "2;";
|
|
|
|
if (hexa.size() == 2){
|
|
uint h_int = stoi(hexa, 0, 16);
|
|
if (t_to_256){
|
|
return pre + to_string(truecolor_to_256(h_int, h_int, h_int)) + "m";
|
|
} else {
|
|
string h_str = to_string(h_int);
|
|
return pre + h_str + ";" + h_str + ";" + h_str + "m";
|
|
}
|
|
}
|
|
else if (hexa.size() == 6){
|
|
if (t_to_256){
|
|
return pre + to_string(truecolor_to_256(
|
|
stoi(hexa.substr(0, 2), 0, 16),
|
|
stoi(hexa.substr(2, 2), 0, 16),
|
|
stoi(hexa.substr(4, 2), 0, 16))) + "m";
|
|
} else {
|
|
return pre +
|
|
to_string(stoi(hexa.substr(0, 2), 0, 16)) + ";" +
|
|
to_string(stoi(hexa.substr(2, 2), 0, 16)) + ";" +
|
|
to_string(stoi(hexa.substr(4, 2), 0, 16)) + "m";
|
|
}
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
//* Generate escape sequence for 24-bit or 256 color and return as a string
|
|
//* Args r: [0-255], g: [0-255], b: [0-255]
|
|
//* t_to_256: [true|false] convert 24bit value to 256 color value
|
|
//* depth: ["fg"|"bg"] for either a foreground color or a background color
|
|
string dec_to_color(uint r, uint g, uint b, bool t_to_256=false, string depth="fg"){
|
|
depth = (depth == "fg") ? "38" : "48";
|
|
string pre = Fx::e + depth + ";";
|
|
pre += (t_to_256) ? "5;" : "2;";
|
|
r = (r > 255) ? 255 : r;
|
|
g = (g > 255) ? 255 : g;
|
|
b = (b > 255) ? 255 : b;
|
|
if (t_to_256) return pre + to_string(truecolor_to_256(r, g, b)) + "m";
|
|
else return pre + to_string(r) + ";" + to_string(g) + ";" + to_string(b) + "m";
|
|
}
|
|
|
|
//* Return a map of "r", "g", "b", 0-255 values for a 24-bit color escape string
|
|
map<string, int> rgb(string c_string){
|
|
map<string, int> rgb = {{"r", 0}, {"g", 0}, {"b", 0}};
|
|
if (c_string.size() >= 14){
|
|
c_string.erase(0, 7);
|
|
auto c_split = ssplit(c_string, ";");
|
|
if (c_split.size() == 3){
|
|
rgb["r"] = stoi(c_split[0]);
|
|
rgb["g"] = stoi(c_split[1]);
|
|
rgb["b"] = stoi(c_split[2].erase(c_split[2].size()));
|
|
}
|
|
}
|
|
return rgb;
|
|
}
|
|
|
|
namespace {
|
|
map<string, string> color;
|
|
map<string, vector<string>> gradient;
|
|
|
|
//* Generate the theme
|
|
map<string,string> generate(map<string, string>& source){
|
|
map<string, string> out;
|
|
vector<string> t_rgb;
|
|
string depth;
|
|
for (auto& item : Global::Default_theme) {
|
|
depth = (item.first.ends_with("bg")) ? "bg" : "fg";
|
|
if (source.contains(item.first)) {
|
|
if (source.at(item.first)[0] == '#') out[item.first] = hex_to_color(source.at(item.first), !Config::getB("truecolor"), depth);
|
|
else {
|
|
t_rgb = ssplit(source.at(item.first), " ");
|
|
out[item.first] = dec_to_color(stoi(t_rgb[0]), stoi(t_rgb[1]), stoi(t_rgb[2]), !Config::getB("truecolor"), depth);
|
|
}
|
|
}
|
|
else out[item.first] = "";
|
|
if (out[item.first].empty()) out[item.first] = hex_to_color(item.second, !Config::getB("truecolor"), depth);
|
|
}
|
|
return out;
|
|
}
|
|
}
|
|
|
|
|
|
//* Set current theme using <source> map
|
|
void set(map<string, string> source){
|
|
color = generate(source);
|
|
Term::fg = color.at("main_fg");
|
|
Term::bg = color.at("main_bg");
|
|
Fx::reset = Fx::reset_base + Term::fg + Term::bg;
|
|
}
|
|
|
|
//* Return escape code for color <name>
|
|
auto c(string name){
|
|
return color.at(name);
|
|
}
|
|
|
|
//* Return vector of escape codes for color gradient <name>
|
|
auto g(string name){
|
|
return gradient.at(name);
|
|
}
|
|
|
|
};
|
|
|
|
#endif |